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 CourtesyCarStatus from "../courtesy-car-status-select/courtesy-car-status-select.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 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")}>
<Form.Item
label={t("courtesycars.fields.make")}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -214,7 +214,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
Street: job.ownr_addr1 || "",
City: job.ownr_city || "",
State: job.ownr_st || "",
Zip: job.ownr_zip || "",
Zip: (job.ownr_zip && job.ownr_zip.substring(0, 3)) || "",
Phone1: job.ownr_ph1 || "",
Phone2: null,
Phone2Extension: null,
@@ -488,8 +488,8 @@ const CreateRepairOrderTag = (job, errorCallback) => {
PartsReconditionedCost:
repairCosts.PartsReconditionedCost.toFormat(AHDineroFormat),
PartsRecycled: Dinero(
job.job_totals.parts.parts.list.PAR &&
job.job_totals.parts.parts.list.PAR.total
job.job_totals.parts.parts.list.PAL &&
job.job_totals.parts.parts.list.PAL.total
).toFormat(AHDineroFormat),
PartsRecycledCost:
repairCosts.PartsRecycledCost.toFormat(AHDineroFormat),
@@ -555,7 +555,9 @@ const CreateRepairOrderTag = (job, errorCallback) => {
AHDineroFormat
),
BMTotalCost: repairCosts.BMTotalCost.toFormat(AHDineroFormat),
MiscTotal: 0,
MiscTotal: Dinero(job.job_totals.additional.additionalCosts).toFormat(
AHDineroFormat
),
MiscTotalCost: 0,
TowingTotal: Dinero(job.job_totals.additional.towing).toFormat(
AHDineroFormat
@@ -673,7 +675,7 @@ const CreateCosts = (job) => {
});
return bill_acc;
}, {});
const materialsHours = { mapaHrs: 0, mashHrs: 0 };
//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 (
@@ -694,9 +696,32 @@ const CreateCosts = (job) => {
(job.bodyshop.jc_hourly_rates &&
job.bodyshop.jc_hourly_rates.mapa * 100) ||
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(
(ticket_acc, ticket_val) => {
//At the invoice level.

View File

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