Merged in feature/payroll (pull request #1014)

Feature/payroll
This commit is contained in:
Patrick Fic
2023-10-18 16:51:50 +00:00
11 changed files with 151 additions and 7 deletions

View File

@@ -2349,6 +2349,27 @@
<folder_node>
<name>actions</name>
<children>
<concept_node>
<name>deductallhours</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>edit</name>
<definition_loaded>false</definition_loaded>
@@ -31108,6 +31129,27 @@
</concept_node>
</children>
</folder_node>
<concept_node>
<name>missingprofileinfo</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>multipayers</name>
<definition_loaded>false</definition_loaded>

View File

@@ -98,6 +98,7 @@ function BillEnterModalContainer({
} = values;
let adjustmentsToInsert = {};
let payrollAdjustmentsToInsert = [];
const r1 = await insertBill({
variables: {
@@ -121,6 +122,24 @@ function BillEnterModalContainer({
(adjustmentsToInsert[lbr_adjustment.mod_lbr_ty] || 0) -
restI.actual_price / lbr_adjustment.rate;
}
//If deduct from labor has lines,
//
if (
deductedfromlbr &&
true //payroll is on
) {
payrollAdjustmentsToInsert.push({
id: i.joblineid,
convertedtolbr: true,
convertedtolbr_data: {
mod_lb_hrs:
(restI.actual_price / lbr_adjustment.rate) * -1,
mod_lbr_ty: lbr_adjustment.mod_lbr_ty,
},
});
}
return {
...restI,
deductedfromlbr: deductedfromlbr,
@@ -146,6 +165,20 @@ function BillEnterModalContainer({
refetchQueries: ["QUERY_PARTS_BILLS_BY_JOBID"],
});
await Promise.all(
payrollAdjustmentsToInsert.map((li) => {
return updateJobLines({
variables: {
lineId: li.id,
line: {
convertedtolbr: li.convertedtolbr,
convertedtolbr_data: li.convertedtolbr_data,
},
},
});
})
);
const adjKeys = Object.keys(adjustmentsToInsert);
if (adjKeys.length > 0) {
//Query the adjustments, merge, and update them.

View File

@@ -40,7 +40,7 @@ export function BillEnterModalLinesComponent({
billid,
}) {
const { t } = useTranslation();
const { setFieldsValue, getFieldsValue, getFieldValue } = form;
const { setFieldsValue, getFieldsValue, getFieldValue, setFieldValue } = form;
const { Simple_Inventory } = useTreatments(
["Simple_Inventory"],
{},
@@ -376,9 +376,43 @@ export function BillEnterModalLinesComponent({
"rate",
]);
const billline = getFieldValue(["billlines", record.name]);
const jobline = lineData.find(
(line) => line.id === billline?.joblineid
);
const employeeTeamName = bodyshop.employee_teams.find(
(team) => team.id === jobline?.assigned_team
);
if (getFieldValue(["billlines", record.name, "deductedfromlbr"]))
return (
<div>
<Space>
{t("joblines.fields.assigned_team", {
name: employeeTeamName?.name,
})}
{`${jobline.mod_lb_hrs} units`}
<Button
onClick={() => {
const applicableRate =
billline.actual_price / jobline.mod_lb_hrs;
setFieldValue(
[
"billlines",
record.name,
"lbr_adjustment",
"rate",
],
applicableRate
);
}}
>
{t("bills.actions.deductallhours")}
</Button>
</Space>
<Form.Item
label={t("joblines.fields.mod_lbr_ty")}
key={`${index}modlbrty`}
@@ -448,9 +482,11 @@ export function BillEnterModalLinesComponent({
>
<InputNumber precision={2} min={0.01} />
</Form.Item>
{price &&
adjustmentRate &&
`${(price / adjustmentRate).toFixed(1)} hrs`}
<Space>
{price &&
adjustmentRate &&
`${(price / adjustmentRate).toFixed(1)} hrs`}
</Space>
</div>
);
return <></>;

View File

@@ -63,6 +63,12 @@ const BillLineSearchSelect = (
item.oem_partno ? ` - ${item.oem_partno}` : ""
}${item.alt_partno ? ` (${item.alt_partno})` : ""}`.trim()}
</span>
{item.act_price === 0 && item.mod_lb_hrs > 0 && (
<span style={{ float: "right", paddingleft: "1rem" }}>
{`${item.mod_lb_hrs} units`}
</span>
)}
<span style={{ float: "right", paddingleft: "1rem" }}>
{item.act_price
? `$${item.act_price && item.act_price.toFixed(2)}`

View File

@@ -0,0 +1,18 @@
import { Alert } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
export default function JobProfileDataWarning({ job }) {
const { t } = useTranslation();
let missingProfileInfo =
Object.keys(job.cieca_pft).length === 0 ||
Object.keys(job.cieca_pfl).length === 0 ||
Object.keys(job.materials).length === 0;
if (missingProfileInfo)
return (
<Alert type="error" message={t("jobs.labels.missingprofileinfo")}></Alert>
);
return null;
}

View File

@@ -239,7 +239,7 @@ export function PayrollLaborAllocationsTable({
});
if (response.status === 200) {
if (response.data.success) {
if (response.data.success !== false) {
notification.open({
type: "success",
message: t("timetickets.successes.payall"),

View File

@@ -274,6 +274,7 @@ export const GET_JOB_LINES_TO_ENTER_BILL = gql`
lbr_amt
op_code_desc
alt_partno
assigned_team
}
jobs_by_pk(id: $id) {
id

View File

@@ -54,6 +54,7 @@ import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gal
import UndefinedToNull from "../../utils/undefinedtonull";
import NoteUpsertModalComponent from "../../components/note-upsert-modal/note-upsert-modal.container";
import _ from "lodash";
import JobProfileDataWarning from "../../components/job-profile-data-warning/job-profile-data-warning.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -288,6 +289,7 @@ export function JobsDetailPage({
/>
<JobsDetailHeader job={job} />
<Divider type="horizontal" />
<JobProfileDataWarning job={job} />
<FormFieldsChanged form={form} />
<Tabs
defaultActiveKey={search.tab}

View File

@@ -155,6 +155,7 @@
},
"bills": {
"actions": {
"deductallhours": "Deduct all",
"edit": "Edit",
"receive": "Receive Part",
"return": "Return Items"
@@ -1242,7 +1243,7 @@
"fields": {
"act_price": "Retail Price",
"ah_detail_line": "Mark as Detail Labor Line (Autohouse Only)",
"assigned_team": "Team",
"assigned_team": "Team {{name}}",
"db_price": "List Price",
"lbr_types": {
"LA1": "LA1",
@@ -1753,7 +1754,7 @@
"closejob": "Close Job {{ro_number}}",
"closingperiod": "This Invoice Date is outside of the Closing Period.",
"contracts": "CC Contracts",
"convertedtolabor": "Lines Converted to Labor",
"convertedtolabor": "Labor Line Adjustments",
"cost": "Cost",
"cost_Additional": "Cost - Additional",
"cost_labor": "Cost - Labor",
@@ -1824,6 +1825,7 @@
"materials": {
"mapa": ""
},
"missingprofileinfo": "This job has missing tax profile info. To ensure correct totals calculations, re-import the job.",
"multipayers": "Additional Payers",
"net_repairs": "Net Repairs",
"notes": "Notes",

View File

@@ -155,6 +155,7 @@
},
"bills": {
"actions": {
"deductallhours": "",
"edit": "",
"receive": "",
"return": ""
@@ -1824,6 +1825,7 @@
"materials": {
"mapa": ""
},
"missingprofileinfo": "",
"multipayers": "",
"net_repairs": "",
"notes": "Notas",

View File

@@ -155,6 +155,7 @@
},
"bills": {
"actions": {
"deductallhours": "",
"edit": "",
"receive": "",
"return": ""
@@ -1824,6 +1825,7 @@
"materials": {
"mapa": ""
},
"missingprofileinfo": "",
"multipayers": "",
"net_repairs": "",
"notes": "Remarques",