Merged in feature/payroll (pull request #1020)

Feature/payroll
This commit is contained in:
Patrick Fic
2023-10-19 00:29:56 +00:00
9 changed files with 165 additions and 24 deletions

View File

@@ -2250,6 +2250,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>mod_lbr_adjustment</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> <concept_node>
<name>other</name> <name>other</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>
@@ -2349,6 +2370,27 @@
<folder_node> <folder_node>
<name>actions</name> <name>actions</name>
<children> <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> <concept_node>
<name>edit</name> <name>edit</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -29,6 +29,7 @@ import BillFormContainer from "../bill-form/bill-form.container";
import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility"; import { CalculateBillTotal } from "../bill-form/bill-form.totals.utility";
import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility"; import { handleUpload as handleLocalUpload } from "../documents-local-upload/documents-local-upload.utility";
import { handleUpload } from "../documents-upload/documents-upload.utility"; import { handleUpload } from "../documents-upload/documents-upload.utility";
import { useTreatments } from "@splitsoftware/splitio-react";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
billEnterModal: selectBillEnterModal, billEnterModal: selectBillEnterModal,
@@ -63,6 +64,11 @@ function BillEnterModalContainer({
"enter_bill_generate_label", "enter_bill_generate_label",
false false
); );
const { Enhanced_Payroll } = useTreatments(
["Enhanced_Payroll"],
{},
bodyshop.imexshopid
);
const formValues = useMemo(() => { const formValues = useMemo(() => {
return { return {
...billEnterModal.context.bill, ...billEnterModal.context.bill,
@@ -98,6 +104,7 @@ function BillEnterModalContainer({
} = values; } = values;
let adjustmentsToInsert = {}; let adjustmentsToInsert = {};
let payrollAdjustmentsToInsert = [];
const r1 = await insertBill({ const r1 = await insertBill({
variables: { variables: {
@@ -116,11 +123,28 @@ function BillEnterModalContainer({
...restI ...restI
} = i; } = i;
if (deductedfromlbr) { if (Enhanced_Payroll.treatment === "on") {
adjustmentsToInsert[lbr_adjustment.mod_lbr_ty] = if (
(adjustmentsToInsert[lbr_adjustment.mod_lbr_ty] || 0) - deductedfromlbr &&
restI.actual_price / lbr_adjustment.rate; true //payroll is on
) {
payrollAdjustmentsToInsert.push({
id: i.joblineid,
convertedtolbr: true,
convertedtolbr_data: {
mod_lb_hrs: lbr_adjustment.mod_lb_hrs * -1,
mod_lbr_ty: lbr_adjustment.mod_lbr_ty,
},
});
}
} else {
if (deductedfromlbr) {
adjustmentsToInsert[lbr_adjustment.mod_lbr_ty] =
(adjustmentsToInsert[lbr_adjustment.mod_lbr_ty] || 0) -
restI.actual_price / lbr_adjustment.rate;
}
} }
return { return {
...restI, ...restI,
deductedfromlbr: deductedfromlbr, deductedfromlbr: deductedfromlbr,
@@ -146,6 +170,20 @@ function BillEnterModalContainer({
refetchQueries: ["QUERY_PARTS_BILLS_BY_JOBID"], 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); const adjKeys = Object.keys(adjustmentsToInsert);
if (adjKeys.length > 0) { if (adjKeys.length > 0) {
//Query the adjustments, merge, and update them. //Query the adjustments, merge, and update them.

View File

@@ -40,12 +40,19 @@ export function BillEnterModalLinesComponent({
billid, billid,
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { setFieldsValue, getFieldsValue, getFieldValue } = form; const { setFieldsValue, getFieldsValue, getFieldValue, setFieldValue } = form;
const { Simple_Inventory } = useTreatments( const { Simple_Inventory } = useTreatments(
["Simple_Inventory"], ["Simple_Inventory"],
{}, {},
bodyshop && bodyshop.imexshopid bodyshop && bodyshop.imexshopid
); );
const { Enhanced_Payroll } = useTreatments(
["Enhanced_Payroll"],
{},
bodyshop.imexshopid
);
const columns = (remove) => { const columns = (remove) => {
return [ return [
{ {
@@ -376,12 +383,31 @@ export function BillEnterModalLinesComponent({
"rate", "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"])) if (getFieldValue(["billlines", record.name, "deductedfromlbr"]))
return ( return (
<div> <div>
<Space>
{t("joblines.fields.assigned_team", {
name: employeeTeamName?.name,
})}
{`${jobline.mod_lb_hrs} units/${t(
`joblines.fields.lbr_types.${jobline.mod_lbr_ty}`
)}`}
</Space>
<Form.Item <Form.Item
label={t("joblines.fields.mod_lbr_ty")} label={t("joblines.fields.mod_lbr_ty")}
key={`${index}modlbrty`} key={`${index}modlbrty`}
initialValue={jobline ? jobline.mod_lbr_ty : null}
rules={[ rules={[
{ {
required: true, required: true,
@@ -435,22 +461,44 @@ export function BillEnterModalLinesComponent({
</Select.Option> </Select.Option>
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item {Enhanced_Payroll.treatment === "on" ? (
label={t("jobs.labels.adjustmentrate")} <Form.Item
name={[record.name, "lbr_adjustment", "rate"]} label={t("billlines.labels.mod_lbr_adjustment")}
initialValue={bodyshop.default_adjustment_rate} name={[record.name, "lbr_adjustment", "mod_lb_hrs"]}
rules={[ rules={[
{ {
required: true, required: true,
//message: t("general.validation.required"), //message: t("general.validation.required"),
}, },
]} ]}
> >
<InputNumber precision={2} min={0.01} /> <InputNumber
</Form.Item> precision={5}
{price && min={0.01}
adjustmentRate && max={jobline ? jobline.mod_lb_hrs : 0}
`${(price / adjustmentRate).toFixed(1)} hrs`} />
</Form.Item>
) : (
<Form.Item
label={t("jobs.labels.adjustmentrate")}
name={[record.name, "lbr_adjustment", "rate"]}
initialValue={bodyshop.default_adjustment_rate}
rules={[
{
required: true,
//message: t("general.validation.required"),
},
]}
>
<InputNumber precision={2} min={0.01} />
</Form.Item>
)}
<Space>
{price &&
adjustmentRate &&
`${(price / adjustmentRate).toFixed(1)} hrs`}
</Space>
</div> </div>
); );
return <></>; return <></>;

View File

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

View File

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

View File

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

View File

@@ -145,6 +145,7 @@
"deductedfromlbr": "Deduct from Labor?", "deductedfromlbr": "Deduct from Labor?",
"entered": "Entered", "entered": "Entered",
"from": "From", "from": "From",
"mod_lbr_adjustment": "Adjustment Units",
"other": "-- Not On Estimate --", "other": "-- Not On Estimate --",
"reconciled": "Reconciled!", "reconciled": "Reconciled!",
"unreconciled": "Unreconciled" "unreconciled": "Unreconciled"
@@ -155,6 +156,7 @@
}, },
"bills": { "bills": {
"actions": { "actions": {
"deductallhours": "Deduct all",
"edit": "Edit", "edit": "Edit",
"receive": "Receive Part", "receive": "Receive Part",
"return": "Return Items" "return": "Return Items"
@@ -1242,7 +1244,7 @@
"fields": { "fields": {
"act_price": "Retail Price", "act_price": "Retail Price",
"ah_detail_line": "Mark as Detail Labor Line (Autohouse Only)", "ah_detail_line": "Mark as Detail Labor Line (Autohouse Only)",
"assigned_team": "Team", "assigned_team": "Team {{name}}",
"db_price": "List Price", "db_price": "List Price",
"lbr_types": { "lbr_types": {
"LA1": "LA1", "LA1": "LA1",
@@ -1753,7 +1755,7 @@
"closejob": "Close Job {{ro_number}}", "closejob": "Close Job {{ro_number}}",
"closingperiod": "This Invoice Date is outside of the Closing Period.", "closingperiod": "This Invoice Date is outside of the Closing Period.",
"contracts": "CC Contracts", "contracts": "CC Contracts",
"convertedtolabor": "Lines Converted to Labor", "convertedtolabor": "Labor Line Adjustments",
"cost": "Cost", "cost": "Cost",
"cost_Additional": "Cost - Additional", "cost_Additional": "Cost - Additional",
"cost_labor": "Cost - Labor", "cost_labor": "Cost - Labor",

View File

@@ -145,6 +145,7 @@
"deductedfromlbr": "", "deductedfromlbr": "",
"entered": "", "entered": "",
"from": "", "from": "",
"mod_lbr_adjustment": "",
"other": "", "other": "",
"reconciled": "", "reconciled": "",
"unreconciled": "" "unreconciled": ""
@@ -155,6 +156,7 @@
}, },
"bills": { "bills": {
"actions": { "actions": {
"deductallhours": "",
"edit": "", "edit": "",
"receive": "", "receive": "",
"return": "" "return": ""

View File

@@ -145,6 +145,7 @@
"deductedfromlbr": "", "deductedfromlbr": "",
"entered": "", "entered": "",
"from": "", "from": "",
"mod_lbr_adjustment": "",
"other": "", "other": "",
"reconciled": "", "reconciled": "",
"unreconciled": "" "unreconciled": ""
@@ -155,6 +156,7 @@
}, },
"bills": { "bills": {
"actions": { "actions": {
"deductallhours": "",
"edit": "", "edit": "",
"receive": "", "receive": "",
"return": "" "return": ""