Merged in release/2022-03-04 (pull request #406)

release/2022-03-04

Approved-by: Patrick Fic
This commit is contained in:
Patrick Fic
2022-03-02 01:27:33 +00:00
9 changed files with 87 additions and 48 deletions

View File

@@ -9,7 +9,7 @@ import { DateFormatter } from "../../utils/DateFormatter";
import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel-select.component"; import CourtesyCarFuelSlider from "../courtesy-car-fuel-select/courtesy-car-fuel-select.component";
import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.component"; import CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.component";
import FormDatePicker from "../form-date-picker/form-date-picker.component"; import FormDatePicker from "../form-date-picker/form-date-picker.component";
import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component"; //import FormFieldsChanged from "../form-fields-changed-alert/form-fields-changed-alert.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component"; import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component"; import LayoutFormRow from "../layout-form-row/layout-form-row.component";
@@ -32,7 +32,7 @@ export default function CourtesyCarCreateFormComponent({ form, saveLoading }) {
} }
/> />
<FormFieldsChanged form={form} /> {/* <FormFieldsChanged form={form} /> */}
<LayoutFormRow header={t("courtesycars.labels.vehicle")}> <LayoutFormRow header={t("courtesycars.labels.vehicle")}>
<Form.Item <Form.Item
label={t("courtesycars.fields.make")} label={t("courtesycars.fields.make")}

View File

@@ -55,15 +55,17 @@ export function JobEmployeeAssignments({
0 0
} }
> >
{bodyshop.employees.map((emp) => ( {bodyshop.employees
<Select.Option .filter((emp) => emp.active)
value={emp.id} .map((emp) => (
key={emp.id} <Select.Option
name={`${emp.first_name} ${emp.last_name}`} value={emp.id}
> key={emp.id}
{`${emp.first_name} ${emp.last_name}`} name={`${emp.first_name} ${emp.last_name}`}
</Select.Option> >
))} {`${emp.first_name} ${emp.last_name}`}
</Select.Option>
))}
</Select> </Select>
</Col> </Col>
<Col span={24}> <Col span={24}>

View File

@@ -10,7 +10,7 @@ export default function JobLinesBillRefernece({ jobline }) {
{subletRequired && <WarningFilled />} {subletRequired && <WarningFilled />}
{`${(billLine.actual_price * billLine.quantity).toFixed(2)} (${ {`${(billLine.actual_price * billLine.quantity).toFixed(2)} (${
billLine.bill.vendor.name billLine.bill.vendor.name
})`} } #${billLine.bill.invoice_number})`}
</div> </div>
); );
} }

View File

@@ -116,15 +116,17 @@ export function ProductionListEmpAssignment({
0 0
} }
> >
{bodyshop.employees.map((emp) => ( {bodyshop.employees
<Select.Option .filter((emp) => emp.active)
value={emp.id} .map((emp) => (
key={emp.id} <Select.Option
name={`${emp.first_name} ${emp.last_name}`} value={emp.id}
> key={emp.id}
{`${emp.first_name} ${emp.last_name}`} name={`${emp.first_name} ${emp.last_name}`}
</Select.Option> >
))} {`${emp.first_name} ${emp.last_name}`}
</Select.Option>
))}
</Select> </Select>
</Col> </Col>
<Col span={24}> <Col span={24}>

View File

@@ -696,6 +696,7 @@ export const GET_JOB_BY_PK = gql`
joblineid joblineid
bill { bill {
id id
invoice_number
vendor { vendor {
id id
name name

View File

@@ -181,12 +181,13 @@ async function InsertBill(oauthClient, qbo_realmId, req, bill, vendor) {
TxnDate: moment(bill.date) TxnDate: moment(bill.date)
//.tz(bill.job.bodyshop.timezone) //.tz(bill.job.bodyshop.timezone)
.format("YYYY-MM-DD"), .format("YYYY-MM-DD"),
...(bill.vendor.due_date && { ...(!bill.is_credit_memo &&
DueDate: moment(bill.date) bill.vendor.due_date && {
//.tz(bill.job.bodyshop.timezone) DueDate: moment(bill.date)
.add(bill.vendor.due_date, "days") //.tz(bill.job.bodyshop.timezone)
.format("YYYY-MM-DD"), .add(bill.vendor.due_date, "days")
}), .format("YYYY-MM-DD"),
}),
DocNumber: bill.invoice_number, DocNumber: bill.invoice_number,
//...(bill.job.class ? { ClassRef: { Id: classes[bill.job.class] } } : {}), //...(bill.job.class ? { ClassRef: { Id: classes[bill.job.class] } } : {}),

View File

@@ -75,12 +75,13 @@ const generateBill = (bill) => {
TxnDate: moment(bill.date) TxnDate: moment(bill.date)
//.tz(bill.job.bodyshop.timezone) //.tz(bill.job.bodyshop.timezone)
.format("YYYY-MM-DD"), .format("YYYY-MM-DD"),
...(bill.vendor.due_date && { ...(!bill.is_credit_memo &&
DueDate: moment(bill.date) bill.vendor.due_date && {
// .tz(bill.job.bodyshop.timezone) DueDate: moment(bill.date)
.add(bill.vendor.due_date, "days") // .tz(bill.job.bodyshop.timezone)
.format("YYYY-MM-DD"), .add(bill.vendor.due_date, "days")
}), .format("YYYY-MM-DD"),
}),
RefNumber: bill.invoice_number, RefNumber: bill.invoice_number,
Memo: `RO ${bill.job.ro_number || ""}`, Memo: `RO ${bill.job.ro_number || ""}`,
ExpenseLineAdd: bill.billlines.map((il) => ExpenseLineAdd: bill.billlines.map((il) =>

View File

@@ -214,7 +214,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
Street: job.ownr_addr1 || "", Street: job.ownr_addr1 || "",
City: job.ownr_city || "", City: job.ownr_city || "",
State: job.ownr_st || "", State: job.ownr_st || "",
Zip: job.ownr_zip || "", Zip: (job.ownr_zip && job.ownr_zip.substring(0, 3)) || "",
Phone1: job.ownr_ph1 || "", Phone1: job.ownr_ph1 || "",
Phone2: null, Phone2: null,
Phone2Extension: null, Phone2Extension: null,
@@ -488,8 +488,8 @@ const CreateRepairOrderTag = (job, errorCallback) => {
PartsReconditionedCost: PartsReconditionedCost:
repairCosts.PartsReconditionedCost.toFormat(AHDineroFormat), repairCosts.PartsReconditionedCost.toFormat(AHDineroFormat),
PartsRecycled: Dinero( PartsRecycled: Dinero(
job.job_totals.parts.parts.list.PAR && job.job_totals.parts.parts.list.PAL &&
job.job_totals.parts.parts.list.PAR.total job.job_totals.parts.parts.list.PAL.total
).toFormat(AHDineroFormat), ).toFormat(AHDineroFormat),
PartsRecycledCost: PartsRecycledCost:
repairCosts.PartsRecycledCost.toFormat(AHDineroFormat), repairCosts.PartsRecycledCost.toFormat(AHDineroFormat),
@@ -555,7 +555,9 @@ const CreateRepairOrderTag = (job, errorCallback) => {
AHDineroFormat AHDineroFormat
), ),
BMTotalCost: repairCosts.BMTotalCost.toFormat(AHDineroFormat), BMTotalCost: repairCosts.BMTotalCost.toFormat(AHDineroFormat),
MiscTotal: 0, MiscTotal: Dinero(job.job_totals.additional.additionalCosts).toFormat(
AHDineroFormat
),
MiscTotalCost: 0, MiscTotalCost: 0,
TowingTotal: Dinero(job.job_totals.additional.towing).toFormat( TowingTotal: Dinero(job.job_totals.additional.towing).toFormat(
AHDineroFormat AHDineroFormat
@@ -673,7 +675,7 @@ const CreateCosts = (job) => {
}); });
return bill_acc; return bill_acc;
}, {}); }, {});
const materialsHours = { mapaHrs: 0, mashHrs: 0 };
//If the hourly rates for job costing are set, add them in. //If the hourly rates for job costing are set, add them in.
if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mapa) { if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mapa) {
if ( if (
@@ -694,9 +696,32 @@ const CreateCosts = (job) => {
(job.bodyshop.jc_hourly_rates && (job.bodyshop.jc_hourly_rates &&
job.bodyshop.jc_hourly_rates.mapa * 100) || job.bodyshop.jc_hourly_rates.mapa * 100) ||
0, 0,
}).multiply(materialsHours.mapaHrs) }).multiply(job.job_totals.rates.mapa.hours)
); );
} }
if (job.bodyshop.jc_hourly_rates && job.bodyshop.jc_hourly_rates.mash) {
if (
!billTotalsByCostCenters[
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
]
)
billTotalsByCostCenters[
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
] = Dinero();
billTotalsByCostCenters[
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
] = billTotalsByCostCenters[
job.bodyshop.md_responsibility_centers.defaults.costs.MASH
].add(
Dinero({
amount:
(job.bodyshop.jc_hourly_rates &&
job.bodyshop.jc_hourly_rates.mash * 100) ||
0,
}).multiply(job.job_totals.rates.mash.hours)
);
}
const ticketTotalsByCostCenter = job.timetickets.reduce( const ticketTotalsByCostCenter = job.timetickets.reduce(
(ticket_acc, ticket_val) => { (ticket_acc, ticket_val) => {
//At the invoice level. //At the invoice level.

View File

@@ -111,10 +111,9 @@ exports.job = async (req, res) => {
} }
if ( if (
moment(item.actual_completion || item.scheduled_completion).tz(timezone).isBefore( moment(item.actual_completion || item.scheduled_completion)
moment().tz(timezone), .tz(timezone)
"day" .isBefore(moment().tz(timezone), "day")
)
) { ) {
console.log("Job should have already gone. Ignoring it.", item); console.log("Job should have already gone. Ignoring it.", item);
return; return;
@@ -128,7 +127,9 @@ exports.job = async (req, res) => {
} else { } else {
const itemDate = moment( const itemDate = moment(
item.actual_completion || item.scheduled_completion item.actual_completion || item.scheduled_completion
).tz(timezone).format("yyyy-MM-DD"); )
.tz(timezone)
.format("yyyy-MM-DD");
if (!!load[itemDate]) { if (!!load[itemDate]) {
load[itemDate].hoursOut = load[itemDate].hoursOut =
(load[itemDate].hoursOut || 0) + (load[itemDate].hoursOut || 0) +
@@ -153,14 +154,20 @@ exports.job = async (req, res) => {
const end = moment.max([ const end = moment.max([
...filteredArrJobs.map((a) => moment(a.scheduled_in).tz(timezone)), ...filteredArrJobs.map((a) => moment(a.scheduled_in).tz(timezone)),
...filteredCompJobs ...filteredCompJobs
.map((p) => moment(p.actual_completion || p.scheduled_completion).tz(timezone)) .map((p) =>
moment(p.actual_completion || p.scheduled_completion).tz(timezone)
)
.filter((p) => p.isValid() && p.isAfter(yesterday)), .filter((p) => p.isValid() && p.isAfter(yesterday)),
moment().tz(timezone).add(15, "days"), moment().tz(timezone).add(15, "days"),
]); ]);
const range = Math.round(moment.duration(end.diff(today)).asDays()); const range = Math.round(moment.duration(end.diff(today)).asDays());
for (var day = 0; day < range; day++) { for (var day = 0; day < range; day++) {
const current = moment(today).tz(timezone).add(day, "days").format("yyyy-MM-DD"); const current = moment(today)
const prev = moment(today).tz(timezone) .tz(timezone)
.add(day, "days")
.format("yyyy-MM-DD");
const prev = moment(today)
.tz(timezone)
.add(day - 1, "days") .add(day - 1, "days")
.format("yyyy-MM-DD"); .format("yyyy-MM-DD");
if (!!!load[current]) { if (!!!load[current]) {
@@ -204,7 +211,7 @@ exports.job = async (req, res) => {
loadKeys.forEach((loadKey) => { loadKeys.forEach((loadKey) => {
const isShopOpen = const isShopOpen =
(workingdays[dayOfWeekMapper(moment(loadKey).tz(timezone).day())] || false) && (workingdays[dayOfWeekMapper(moment(loadKey).day())] || false) &&
!load[loadKey].blocked; !load[loadKey].blocked;
if ( if (