IO-244 IOU Parts

This commit is contained in:
Patrick Fic
2021-12-03 17:39:58 -08:00
parent b539ecaeb1
commit 2e843bbd8a
24 changed files with 422 additions and 5 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project be_version="2.7.1" version="1.2">
<babeledit_project version="1.2" be_version="2.7.1">
<!--
BabelEdit project file
@@ -1348,6 +1348,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>jobioucreated</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>jobmodifylbradj</name>
<definition_loaded>false</definition_loaded>
@@ -2716,6 +2737,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>iouexists</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>local_tax</name>
<definition_loaded>false</definition_loaded>
@@ -17339,6 +17381,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>ioucreated</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>new</name>
<definition_loaded>false</definition_loaded>
@@ -17800,6 +17863,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>createiou</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>deliver</name>
<definition_loaded>false</definition_loaded>
@@ -24763,6 +24847,27 @@
</concept_node>
</children>
</folder_node>
<concept_node>
<name>createiouwarning</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>creating_new_job</name>
<definition_loaded>false</definition_loaded>
@@ -27098,6 +27203,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>ioucreated</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>partsqueue</name>
<definition_loaded>false</definition_loaded>

View File

@@ -1,6 +1,8 @@
import { UploadOutlined } from "@ant-design/icons";
import Icon, { UploadOutlined } from "@ant-design/icons";
import { useApolloClient } from "@apollo/client";
import { MdOpenInNew } from "react-icons/md";
import {
Alert,
Divider,
Form,
Input,
@@ -13,6 +15,7 @@ import {
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { CHECK_BILL_INVOICE_NUMBER } from "../../graphql/bills.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
@@ -132,6 +135,30 @@ export function BillFormComponent({
/>
</Form.Item>
</LayoutFormRow>
{job &&
job.ious &&
job.ious.length > 0 &&
job.ious.map((iou) => (
<Alert
key={iou.id}
type="warning"
message={
<Space>
{t("bills.labels.iouexists")}
<Link
target="_blank"
rel="noopener noreferrer"
to={`/manage/jobs/${iou.id}?tab=repairdata`}
>
<Space>
{iou.ro_number}
<Icon component={MdOpenInNew} />
</Space>
</Link>
</Space>
}
/>
))}
<LayoutFormRow>
<Form.Item
label={t("bills.fields.invoice_number")}
@@ -337,6 +364,7 @@ export function BillFormComponent({
responsibilityCenters={responsibilityCenters}
disabled={disabled}
/>
<Form.Item
name="upload"
label="Upload"

View File

@@ -0,0 +1,95 @@
import { useApolloClient } from "@apollo/client";
import { useTreatments } from "@splitsoftware/splitio-react";
import { Button, notification, Popconfirm } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useHistory } from "react-router";
import { createStructuredSelector } from "reselect";
import { UPDATE_JOB_LINES_IOU } from "../../graphql/jobs-lines.queries";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import { CreateIouForJob } from "../jobs-detail-header-actions/jobs-detail-header-actions.duplicate.util";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(JobCreateIOU);
export function JobCreateIOU({
bodyshop,
currentUser,
jobid,
selectedJobLines,
}) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const client = useApolloClient();
const history = useHistory();
const { IOU_Tracking } = useTreatments(
["IOU_Tracking"],
{},
bodyshop.imexshopid
);
if (IOU_Tracking.treatment !== "on") return null;
const handleCreateIou = async () => {
setLoading(true);
//Query all of the job details to recreate.
const iouId = await CreateIouForJob(
client,
jobid,
{
status: bodyshop.md_ro_statuses.default_open,
bodyshopid: bodyshop.id,
useremail: currentUser.email,
},
selectedJobLines
);
notification.open({
type: "success",
message: t("jobs.successes.ioucreated"),
onClick: () => history.push(`/manage/jobs/${iouId}`),
});
const selectedJobLinesIds = selectedJobLines.map((l) => l.id);
await client.mutate({
mutation: UPDATE_JOB_LINES_IOU,
variables: { ids: selectedJobLinesIds },
update(cache) {
cache.modify({
id: cache.identify(jobid),
fields: {
joblines(existingJobLines, { readField }) {
return existingJobLines.map((a) => {
if (!selectedJobLinesIds.includes(a.id)) return a;
return { ...a, ioucreated: true };
});
},
},
});
},
});
setLoading(false);
};
return (
<Popconfirm
title={t("jobs.labels.createiouwarning")}
onConfirm={handleCreateIou}
>
<Button
loading={loading}
disabled={!selectedJobLines || selectedJobLines.length === 0}
>
{t("jobs.actions.createiou")}
</Button>
</Popconfirm>
);
}

View File

@@ -37,6 +37,7 @@ import JobLinesBillRefernece from "../job-lines-bill-reference/job-lines-bill-re
// import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
import _ from "lodash";
import JobCreateIOU from "../job-create-iou/job-create-iou.component";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
@@ -427,6 +428,7 @@ export function JobLinesComponent({
>
{t("joblines.actions.new")}
</Button>
<JobCreateIOU jobid={job.id} selectedJobLines={selectedLines} />
<Input.Search
placeholder={t("general.labels.search")}
onChange={(e) => {

View File

@@ -1,5 +1,6 @@
import React, { useState, useEffect } from "react";
import { Input, notification } from "antd";
import { Input, notification, Space } from "antd";
import { FieldTimeOutlined } from "@ant-design/icons";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import { useMutation } from "@apollo/client";
import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries";
@@ -59,6 +60,12 @@ export default function JobLineNotePopup({ jobline, disabled }) {
style={{ width: "100%", minHeight: "2rem", cursor: "pointer" }}
onClick={() => !disabled && setEditing(true)}
>
{jobline.ioucreated && (
<Space>
<FieldTimeOutlined />
{t("joblines.labels.ioucreated")}
</Space>
)}
{jobline.notes}
</div>
);

View File

@@ -2,6 +2,8 @@ import Axios from "axios";
import _ from "lodash";
import { logImEXEvent } from "../../firebase/firebase.utils";
import { INSERT_NEW_JOB, QUERY_JOB_FOR_DUPE } from "../../graphql/jobs.queries";
import moment from "moment";
import i18n from "i18next";
export default async function DuplicateJob(
apolloClient,
@@ -57,3 +59,71 @@ export default async function DuplicateJob(
return;
}
export async function CreateIouForJob(
apolloClient,
jobId,
config,
jobLinesToKeep
) {
logImEXEvent("job_create_iou");
const { status } = config;
//get a list of all fields on the job
const res = await apolloClient.query({
query: QUERY_JOB_FOR_DUPE,
variables: { id: jobId },
});
const { jobs_by_pk } = res.data;
const existingJob = _.cloneDeep(jobs_by_pk);
delete existingJob.__typename;
delete existingJob.id;
delete existingJob.createdat;
delete existingJob.updatedat;
const newJob = {
...existingJob,
converted: true,
status: status,
iouparent: jobId,
date_open: moment(),
audit_trails: {
data: [
{
useremail: config.useremail,
bodyshopid: config.bodyshopid,
operation: i18n.t("audit_trail.messages.jobioucreated"),
},
],
},
};
const selectedJoblinesIds = jobLinesToKeep.map((l) => l.id);
const _tempLines = _.cloneDeep(existingJob.joblines).filter((l) =>
selectedJoblinesIds.includes(l.id)
);
_tempLines.forEach((line) => {
delete line.id;
delete line.__typename;
line.manual_line = true;
});
delete newJob.joblines;
newJob.joblines = { data: _tempLines };
const res2 = await apolloClient.mutate({
mutation: INSERT_NEW_JOB,
variables: { job: [newJob] },
});
Axios.post("/job/totalsssu", {
id: res2.data.insert_jobs.returning[0].id,
});
//insert the new job. call the callback with the returned ID when done.
return res2.data.insert_jobs.returning[0].id;
}

View File

@@ -179,6 +179,10 @@ export const GET_JOB_LINES_TO_ENTER_BILL = gql`
jobs_by_pk(id: $id) {
id
status
ious {
id
ro_number
}
}
}
`;
@@ -226,3 +230,14 @@ export const DELETE_JOB_LINE_BY_PK = gql`
}
}
`;
export const UPDATE_JOB_LINES_IOU = gql`
mutation UPDATE_JOB_LINES_IOU($ids: [uuid!]!) {
update_joblines(where: { id: { _in: $ids } }, _set: { ioucreated: true }) {
returning {
ioucreated
id
}
}
}
`;

View File

@@ -529,6 +529,7 @@ export const GET_JOB_BY_PK = gql`
manual_line
prt_dsmk_p
prt_dsmk_m
ioucreated
billlines(limit: 1, order_by: { bill: { date: desc } }) {
id
quantity
@@ -1253,9 +1254,7 @@ export const QUERY_JOB_FOR_DUPE = gql`
servicing_dealer
servicing_dealer_contact
shopid
state_tax_rate
tax_lbr_rt
tax_levies_rt
tax_paint_mat_rt
@@ -1320,9 +1319,19 @@ export const QUERY_JOB_FOR_DUPE = gql`
tax_part
unq_seq
manual_line
notes
line_no
tran_code
}
driveable
towin
adj_g_disc
adj_strdis
adj_towdis
ca_gst_registrant
special_coverage_policy
tax_registration_number
tax_shop_mat_rt
}
}
`;

View File

@@ -95,6 +95,7 @@
"jobfieldchanged": "Job field $t(jobs.fields.{{field}}) changed to {{value}}.",
"jobimported": "Job imported.",
"jobinproductionchange": "Job production status set to {{inproduction}}",
"jobioucreated": "IOU Created.",
"jobmodifylbradj": "Labor adjustments modified.",
"jobnoteadded": "Note added to job.",
"jobnotedeleted": "Note deleted from job.",
@@ -176,6 +177,7 @@
"entered_total": "Total of Entered Lines",
"enteringcreditmemo": "You are entering a credit memo. Please ensure you are also entering positive values.",
"federal_tax": "Federal Tax",
"iouexists": "An IOU exists that is associated to this RO.",
"local_tax": "Local Tax",
"markforreexport": "Mark for Re-export",
"new": "New Bill",
@@ -1082,6 +1084,7 @@
"labels": {
"billref": "Latest Bill",
"edit": "Edit Line",
"ioucreated": "IOU",
"new": "New Line",
"nostatus": "No Status",
"presets": "Jobline Presets"
@@ -1111,6 +1114,7 @@
"changestatus": "Change Status",
"changestimator": "Change Estimator",
"convert": "Convert",
"createiou": "Create IOU",
"deliver": "Deliver",
"dms": {
"addpayer": "Add Payer",
@@ -1469,6 +1473,7 @@
"ownerinfo": "Owner Info",
"vehicleinfo": "Vehicle Info"
},
"createiouwarning": "Are you sure you want to create an IOU for these lines? A new RO will be created based on those lines for this customer.",
"creating_new_job": "Creating new job...",
"deductible": {
"stands": "Stands",
@@ -1589,6 +1594,7 @@
"duplicated": "Job duplicated successfully. ",
"exported": "Job(s) exported successfully. ",
"invoiced": "Job closed and invoiced successfully.",
"ioucreated": "IOU created successfully. Click to see.",
"partsqueue": "Job added to parts queue.",
"save": "Job saved successfully.",
"savetitle": "Record saved successfully.",

View File

@@ -95,6 +95,7 @@
"jobfieldchanged": "",
"jobimported": "",
"jobinproductionchange": "",
"jobioucreated": "",
"jobmodifylbradj": "",
"jobnoteadded": "",
"jobnotedeleted": "",
@@ -176,6 +177,7 @@
"entered_total": "",
"enteringcreditmemo": "",
"federal_tax": "",
"iouexists": "",
"local_tax": "",
"markforreexport": "",
"new": "",
@@ -1082,6 +1084,7 @@
"labels": {
"billref": "",
"edit": "Línea de edición",
"ioucreated": "",
"new": "Nueva línea",
"nostatus": "",
"presets": ""
@@ -1111,6 +1114,7 @@
"changestatus": "Cambiar Estado",
"changestimator": "",
"convert": "Convertir",
"createiou": "",
"deliver": "",
"dms": {
"addpayer": "",
@@ -1469,6 +1473,7 @@
"ownerinfo": "",
"vehicleinfo": ""
},
"createiouwarning": "",
"creating_new_job": "Creando nuevo trabajo ...",
"deductible": {
"stands": "",
@@ -1589,6 +1594,7 @@
"duplicated": "",
"exported": "",
"invoiced": "",
"ioucreated": "",
"partsqueue": "",
"save": "Trabajo guardado con éxito.",
"savetitle": "Registro guardado con éxito.",

View File

@@ -95,6 +95,7 @@
"jobfieldchanged": "",
"jobimported": "",
"jobinproductionchange": "",
"jobioucreated": "",
"jobmodifylbradj": "",
"jobnoteadded": "",
"jobnotedeleted": "",
@@ -176,6 +177,7 @@
"entered_total": "",
"enteringcreditmemo": "",
"federal_tax": "",
"iouexists": "",
"local_tax": "",
"markforreexport": "",
"new": "",
@@ -1082,6 +1084,7 @@
"labels": {
"billref": "",
"edit": "Ligne d'édition",
"ioucreated": "",
"new": "Nouvelle ligne",
"nostatus": "",
"presets": ""
@@ -1111,6 +1114,7 @@
"changestatus": "Changer le statut",
"changestimator": "",
"convert": "Convertir",
"createiou": "",
"deliver": "",
"dms": {
"addpayer": "",
@@ -1469,6 +1473,7 @@
"ownerinfo": "",
"vehicleinfo": ""
},
"createiouwarning": "",
"creating_new_job": "Création d'un nouvel emploi ...",
"deductible": {
"stands": "",
@@ -1589,6 +1594,7 @@
"duplicated": "",
"exported": "",
"invoiced": "",
"ioucreated": "",
"partsqueue": "",
"save": "Le travail a été enregistré avec succès.",
"savetitle": "Enregistrement enregistré avec succès.",

View File

@@ -2123,6 +2123,7 @@
- est_seq
- glass_flag
- id
- ioucreated
- jobid
- lbr_amt
- lbr_hrs_j
@@ -2185,6 +2186,7 @@
- est_seq
- glass_flag
- id
- ioucreated
- jobid
- lbr_amt
- lbr_hrs_j
@@ -2258,6 +2260,7 @@
- est_seq
- glass_flag
- id
- ioucreated
- jobid
- lbr_amt
- lbr_hrs_j
@@ -2390,6 +2393,9 @@
- name: employee_refinish_rel
using:
foreign_key_constraint_on: employee_refinish
- name: iouparent_rel
using:
foreign_key_constraint_on: iouparent
- name: owner
using:
foreign_key_constraint_on: ownerid
@@ -2453,6 +2459,13 @@
table:
schema: public
name: exportlog
- name: ious
using:
foreign_key_constraint_on:
column: iouparent
table:
schema: public
name: jobs
- name: job_conversations
using:
foreign_key_constraint_on:
@@ -2678,6 +2691,7 @@
- intakechecklist
- invoice_allocation
- invoice_date
- iouparent
- job_totals
- kanbanparent
- kmin
@@ -2931,6 +2945,7 @@
- intakechecklist
- invoice_allocation
- invoice_date
- iouparent
- job_totals
- kanbanparent
- kmin
@@ -3194,6 +3209,7 @@
- intakechecklist
- invoice_allocation
- invoice_date
- iouparent
- job_totals
- kanbanparent
- kmin

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."jobs" add column "iouparent" uuid
-- null;

View File

@@ -0,0 +1,2 @@
alter table "public"."jobs" add column "iouparent" uuid
null;

View File

@@ -0,0 +1 @@
alter table "public"."jobs" drop constraint "jobs_iouparent_fkey";

View File

@@ -0,0 +1,5 @@
alter table "public"."jobs"
add constraint "jobs_iouparent_fkey"
foreign key ("iouparent")
references "public"."jobs"
("id") on update set null on delete set null;

View File

@@ -0,0 +1 @@
DROP INDEX IF EXISTS "jobs_idx_iouparent";

View File

@@ -0,0 +1,2 @@
CREATE INDEX "jobs_idx_iouparent" on
"public"."jobs" using btree ("iouparent");

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."joblines" add column "ioucreated" boolean
-- not null default 'false';

View File

@@ -0,0 +1,2 @@
alter table "public"."joblines" add column "ioucreated" boolean
not null default 'false';

View File

@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."joblines" add column "iou" boolean
-- not null default 'false';

View File

@@ -0,0 +1,2 @@
alter table "public"."joblines" add column "iou" boolean
not null default 'false';

View File

@@ -0,0 +1,3 @@
alter table "public"."joblines" alter column "iou" set default false;
alter table "public"."joblines" alter column "iou" drop not null;
alter table "public"."joblines" add column "iou" bool;

View File

@@ -0,0 +1 @@
alter table "public"."joblines" drop column "iou" cascade;