Resolve master merge conflicts.
This commit is contained in:
@@ -18340,6 +18340,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>ah_detail_line</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>db_price</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -19667,6 +19688,27 @@
|
||||
<folder_node>
|
||||
<name>validations</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>ahdetailonlyonuserdefinedtypes</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>hrsrequirediflbrtyp</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -46585,6 +46627,48 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>changepassword</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>profileinfo</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>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
|
||||
@@ -8,6 +8,8 @@ export default function DataLabel({
|
||||
vertical,
|
||||
visible = true,
|
||||
valueStyle = {},
|
||||
valueClassName,
|
||||
onValueClick,
|
||||
...props
|
||||
}) {
|
||||
if (!visible || (hideIfNull && !!!children)) return null;
|
||||
@@ -28,7 +30,10 @@ export default function DataLabel({
|
||||
marginLeft: ".3rem",
|
||||
fontWeight: "bolder",
|
||||
wordWrap: "break-word",
|
||||
cursor: onValueClick !== undefined ? "pointer" : "",
|
||||
}}
|
||||
className={valueClassName}
|
||||
onClick={onValueClick}
|
||||
>
|
||||
{typeof children === "string" ? (
|
||||
<Typography.Text style={valueStyle}>{children}</Typography.Text>
|
||||
|
||||
@@ -40,6 +40,11 @@ export function JobLinesUpsertModalComponent({
|
||||
{},
|
||||
bodyshop.imexshopid
|
||||
);
|
||||
const { Autohouse_Detail_line } = useTreatments(
|
||||
["Autohouse_Detail_line"],
|
||||
{},
|
||||
bodyshop.imexshopid
|
||||
);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -155,6 +160,40 @@ export function JobLinesUpsertModalComponent({
|
||||
>
|
||||
<InputNumber precision={1} />
|
||||
</Form.Item>
|
||||
{Autohouse_Detail_line.treatment === "on" && (
|
||||
<Form.Item
|
||||
label={t("joblines.fields.ah_detail_line")}
|
||||
name="ah_detail_line"
|
||||
valuePropName="checked"
|
||||
dependencies={["mod_lbr_ty"]}
|
||||
rules={[
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
console.log(
|
||||
value === true,
|
||||
["LA1", "LA2", "LA3", "LA4", "LAU"].includes(
|
||||
getFieldValue("mod_lbr_ty")
|
||||
)
|
||||
);
|
||||
if (value === false) return Promise.resolve();
|
||||
if (
|
||||
value === true &&
|
||||
["LA1", "LA2", "LA3", "LA4", "LAU"].includes(
|
||||
getFieldValue("mod_lbr_ty")
|
||||
)
|
||||
) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(
|
||||
t("joblines.validations.ahdetailonlyonuserdefinedtypes")
|
||||
);
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
)}
|
||||
</LayoutFormRow>
|
||||
<LayoutFormRow>
|
||||
<Form.Item label={t("joblines.fields.part_type")} name="part_type">
|
||||
@@ -218,7 +257,6 @@ export function JobLinesUpsertModalComponent({
|
||||
rules={[
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
console.log(value);
|
||||
if (!value || getFieldValue("part_type") !== "PAE") {
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -229,7 +267,6 @@ export function JobLinesUpsertModalComponent({
|
||||
}),
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
console.log(value, !!value);
|
||||
if (
|
||||
!!getFieldValue("part_type") === (!!value || value === 0)
|
||||
) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
BranchesOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Card, Col, Row, Space, Tag, Tooltip } from "antd";
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
@@ -56,7 +56,7 @@ const colSpan = {
|
||||
|
||||
export function JobsDetailHeader({ job, bodyshop, disabled }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [notesClamped, setNotesClamped] = useState(true);
|
||||
const vehicleTitle = `${job.v_model_yr || ""} ${job.v_color || ""}
|
||||
${job.v_make_desc || ""}
|
||||
${job.v_model_desc || ""}`.trim();
|
||||
@@ -229,6 +229,8 @@ export function JobsDetailHeader({ job, bodyshop, disabled }) {
|
||||
<DataLabel
|
||||
label={t("vehicles.fields.notes")}
|
||||
valueStyle={{ whiteSpace: "pre-wrap" }}
|
||||
valueClassName={notesClamped ? "clamp" : ""}
|
||||
onValueClick={() => setNotesClamped(!notesClamped)}
|
||||
>
|
||||
{job.vehicle.notes}
|
||||
</DataLabel>
|
||||
|
||||
@@ -6,3 +6,12 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.clamp {
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ export function JobsExportAllButton({
|
||||
|
||||
return (
|
||||
<Button onClick={handleQbxml} loading={loading} disabled={disabled}>
|
||||
{t("jobs.actions.export")}
|
||||
{t("jobs.actions.exportselected")}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button, Form, Input, notification } from "antd";
|
||||
import { Button, Card, Col, Form, Input, notification } from "antd";
|
||||
import { LockOutlined } from "@ant-design/icons";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -48,81 +48,99 @@ export default connect(
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Form
|
||||
onFinish={handleFinish}
|
||||
autoComplete={"no"}
|
||||
initialValues={currentUser}
|
||||
layout="vertical"
|
||||
>
|
||||
<LayoutFormRow>
|
||||
<Form.Item
|
||||
label={t("user.fields.displayname")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
name="displayName"
|
||||
<>
|
||||
<Col span={24}>
|
||||
<Form
|
||||
onFinish={handleFinish}
|
||||
autoComplete={"no"}
|
||||
initialValues={currentUser}
|
||||
layout="vertical"
|
||||
>
|
||||
<Card
|
||||
title={t("user.labels.profileinfo")}
|
||||
extra={
|
||||
<Button type="primary" key="submit" htmlType="submit">
|
||||
{t("user.actions.updateprofile")}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("user.fields.photourl")} name="photoURL">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
|
||||
<Button type="primary" key="submit" htmlType="submit">
|
||||
{t("user.actions.updateprofile")}
|
||||
</Button>
|
||||
</Form>
|
||||
<Form
|
||||
onFinish={handleChangePassword}
|
||||
autoComplete={"no"}
|
||||
initialValues={currentUser}
|
||||
layout="vertical"
|
||||
>
|
||||
<LayoutFormRow>
|
||||
<Form.Item label={t("general.labels.newpassword")} name="password">
|
||||
<Input
|
||||
prefix={<LockOutlined />}
|
||||
type="password"
|
||||
placeholder={t("general.labels.password")}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("general.labels.confirmpassword")}
|
||||
name="password-confirm"
|
||||
dependencies={["password"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
if (!value || getFieldValue("password") === value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(
|
||||
t("general.labels.passwordsdonotmatch")
|
||||
);
|
||||
},
|
||||
}),
|
||||
]}
|
||||
<LayoutFormRow noDivider>
|
||||
<Form.Item
|
||||
label={t("user.fields.displayname")}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
]}
|
||||
name="displayName"
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label={t("user.fields.photourl")} name="photoURL">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
</Card>
|
||||
</Form>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form
|
||||
onFinish={handleChangePassword}
|
||||
autoComplete={"no"}
|
||||
initialValues={currentUser}
|
||||
layout="vertical"
|
||||
>
|
||||
<Card
|
||||
title={t("user.labels.changepassword")}
|
||||
extra={
|
||||
<Button type="primary" key="submit" htmlType="submit">
|
||||
{t("user.actions.changepassword")}
|
||||
</Button>
|
||||
}
|
||||
>
|
||||
<Input
|
||||
prefix={<LockOutlined />}
|
||||
type="password"
|
||||
placeholder={t("general.labels.password")}
|
||||
/>
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
<Button type="primary" key="submit" htmlType="submit">
|
||||
{t("user.actions.changepassword")}
|
||||
</Button>
|
||||
</Form>
|
||||
</div>
|
||||
<LayoutFormRow>
|
||||
<Form.Item
|
||||
label={t("general.labels.newpassword")}
|
||||
name="password"
|
||||
>
|
||||
<Input
|
||||
prefix={<LockOutlined />}
|
||||
type="password"
|
||||
placeholder={t("general.labels.password")}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t("general.labels.confirmpassword")}
|
||||
name="password-confirm"
|
||||
dependencies={["password"]}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
//message: t("general.validation.required"),
|
||||
},
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
if (!value || getFieldValue("password") === value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(
|
||||
t("general.labels.passwordsdonotmatch")
|
||||
);
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
prefix={<LockOutlined />}
|
||||
type="password"
|
||||
placeholder={t("general.labels.password")}
|
||||
/>
|
||||
</Form.Item>
|
||||
</LayoutFormRow>
|
||||
</Card>
|
||||
</Form>
|
||||
</Col>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from "react";
|
||||
import { Button, Card, Col, Input, Table, Typography } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Table, Button, Typography } from "antd";
|
||||
export default function ProfileShopsComponent({
|
||||
loading,
|
||||
data,
|
||||
updateActiveShop,
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [search, setSearch] = useState("");
|
||||
const columns = [
|
||||
{
|
||||
title: t("associations.fields.shopname"),
|
||||
@@ -39,18 +39,39 @@ export default function ProfileShopsComponent({
|
||||
),
|
||||
},
|
||||
];
|
||||
console.log("🚀 ~ file: profile-shops.component.jsx:45 ~ data", data);
|
||||
const filteredData =
|
||||
search === ""
|
||||
? data
|
||||
: data.filter((d) =>
|
||||
d.bodyshop.shopname.toLowerCase().includes(search.toLowerCase())
|
||||
);
|
||||
|
||||
return (
|
||||
<Table
|
||||
title={() => (
|
||||
<Typography.Title level={4}>
|
||||
{t("profile.labels.activeshop")}
|
||||
</Typography.Title>
|
||||
)}
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={data}
|
||||
/>
|
||||
<Col span={24}>
|
||||
<Card
|
||||
title={
|
||||
<Typography.Title level={4}>
|
||||
{t("profile.labels.activeshop")}
|
||||
</Typography.Title>
|
||||
}
|
||||
extra={
|
||||
<Input.Search
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
allowClear
|
||||
placeholder={t("general.labels.search")}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Table
|
||||
pagination={false}
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
rowKey="id"
|
||||
dataSource={filteredData}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1344,7 +1344,14 @@ export default function ShopInfoGeneral({ form }) {
|
||||
>
|
||||
<InputNumber precision={0} min={0} max={100} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t("joblines.fields.ah_detail_line")}
|
||||
key={`${index}ah_detail_line`}
|
||||
name={[field.name, "ah_detail_line"]}
|
||||
valuePropName="checked"
|
||||
>
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
<Space wrap>
|
||||
<DeleteFilled
|
||||
onClick={() => {
|
||||
|
||||
@@ -720,6 +720,7 @@ export const GET_JOB_BY_PK = gql`
|
||||
prt_dsmk_m
|
||||
ioucreated
|
||||
convertedtolbr
|
||||
ah_detail_line
|
||||
billlines(limit: 1, order_by: { bill: { date: desc } }) {
|
||||
id
|
||||
quantity
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Row } from "antd";
|
||||
import React from "react";
|
||||
import ProfileMyComponent from "../../components/profile-my/profile-my.component";
|
||||
import ProfileShopsContainer from "../../components/profile-shops/profile-shops.container";
|
||||
@@ -5,8 +6,10 @@ import ProfileShopsContainer from "../../components/profile-shops/profile-shops.
|
||||
export default function ProfilePage() {
|
||||
return (
|
||||
<div>
|
||||
<ProfileMyComponent />
|
||||
<ProfileShopsContainer />
|
||||
<Row gutter={[16, 16]}>
|
||||
<ProfileMyComponent />
|
||||
<ProfileShopsContainer />
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1142,6 +1142,7 @@
|
||||
},
|
||||
"fields": {
|
||||
"act_price": "Retail Price",
|
||||
"ah_detail_line": "Mark as Detail Labor Line (Autohouse Only)",
|
||||
"db_price": "List Price",
|
||||
"lbr_types": {
|
||||
"LA1": "LA1",
|
||||
@@ -1214,6 +1215,7 @@
|
||||
"updated": "Job line updated successfully."
|
||||
},
|
||||
"validations": {
|
||||
"ahdetailonlyonuserdefinedtypes": "Detail line indicator can only be set for LA1, LA2, LA3, LA4, and LAU labor types.",
|
||||
"hrsrequirediflbrtyp": "Labor hours are required if a labor type is selected. Clear the labor type if there are no labor hours.",
|
||||
"requiredifparttype": "Required if a part type has been specified.",
|
||||
"zeropriceexistingpart": "This line cannot have any price since it uses an existing part."
|
||||
@@ -2745,7 +2747,9 @@
|
||||
"photourl": "Avatar URL"
|
||||
},
|
||||
"labels": {
|
||||
"actions": "Actions"
|
||||
"actions": "Actions",
|
||||
"changepassword": "Change Password",
|
||||
"profileinfo": "Profile Info"
|
||||
},
|
||||
"successess": {
|
||||
"passwordchanged": "Password changed successfully. "
|
||||
|
||||
@@ -1142,6 +1142,7 @@
|
||||
},
|
||||
"fields": {
|
||||
"act_price": "Precio actual",
|
||||
"ah_detail_line": "",
|
||||
"db_price": "Precio de base de datos",
|
||||
"lbr_types": {
|
||||
"LA1": "",
|
||||
@@ -1214,6 +1215,7 @@
|
||||
"updated": ""
|
||||
},
|
||||
"validations": {
|
||||
"ahdetailonlyonuserdefinedtypes": "",
|
||||
"hrsrequirediflbrtyp": "",
|
||||
"requiredifparttype": "",
|
||||
"zeropriceexistingpart": ""
|
||||
@@ -2745,7 +2747,9 @@
|
||||
"photourl": "URL de avatar"
|
||||
},
|
||||
"labels": {
|
||||
"actions": ""
|
||||
"actions": "",
|
||||
"changepassword": "",
|
||||
"profileinfo": ""
|
||||
},
|
||||
"successess": {
|
||||
"passwordchanged": ""
|
||||
|
||||
@@ -1142,6 +1142,7 @@
|
||||
},
|
||||
"fields": {
|
||||
"act_price": "Prix actuel",
|
||||
"ah_detail_line": "",
|
||||
"db_price": "Prix de la base de données",
|
||||
"lbr_types": {
|
||||
"LA1": "",
|
||||
@@ -1214,6 +1215,7 @@
|
||||
"updated": ""
|
||||
},
|
||||
"validations": {
|
||||
"ahdetailonlyonuserdefinedtypes": "",
|
||||
"hrsrequirediflbrtyp": "",
|
||||
"requiredifparttype": "",
|
||||
"zeropriceexistingpart": ""
|
||||
@@ -2745,7 +2747,9 @@
|
||||
"photourl": "URL de l'avatar"
|
||||
},
|
||||
"labels": {
|
||||
"actions": ""
|
||||
"actions": "",
|
||||
"changepassword": "",
|
||||
"profileinfo": ""
|
||||
},
|
||||
"successess": {
|
||||
"passwordchanged": ""
|
||||
|
||||
@@ -2482,6 +2482,7 @@
|
||||
_eq: true
|
||||
columns:
|
||||
- act_price
|
||||
- ah_detail_line
|
||||
- alt_co_id
|
||||
- alt_overrd
|
||||
- alt_part_i
|
||||
@@ -2547,6 +2548,7 @@
|
||||
permission:
|
||||
columns:
|
||||
- act_price
|
||||
- ah_detail_line
|
||||
- alt_co_id
|
||||
- alt_overrd
|
||||
- alt_part_i
|
||||
@@ -2623,6 +2625,7 @@
|
||||
permission:
|
||||
columns:
|
||||
- act_price
|
||||
- ah_detail_line
|
||||
- alt_co_id
|
||||
- alt_overrd
|
||||
- alt_part_i
|
||||
|
||||
@@ -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 "ah_detail_line" boolean
|
||||
-- not null default 'false';
|
||||
@@ -0,0 +1,2 @@
|
||||
alter table "public"."joblines" add column "ah_detail_line" boolean
|
||||
not null default 'false';
|
||||
43065
logs/oAuthClient-log.log
43065
logs/oAuthClient-log.log
File diff suppressed because one or more lines are too long
@@ -7,7 +7,7 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"setup": "yarn && cd client && yarn",
|
||||
"setup": "rm -rf node_modules && yarn && cd client && rm -rf node_modules && yarn",
|
||||
"admin": "cd admin && yarn start",
|
||||
"client": "cd client && yarn start",
|
||||
"server": "nodemon server.js",
|
||||
|
||||
@@ -214,6 +214,30 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
|
||||
const repairCosts = CreateCosts(job);
|
||||
|
||||
if (job.ro_number === "QBD209") {
|
||||
console.log("Stop here");
|
||||
}
|
||||
//Calculate detail only lines.
|
||||
const detailAdjustments = job.joblines
|
||||
.filter((jl) => jl.ah_detail_line && jl.mod_lbr_ty)
|
||||
.reduce(
|
||||
(acc, val) => {
|
||||
return {
|
||||
hours: acc.hours + val.mod_lb_hrs,
|
||||
amount: acc.amount.add(
|
||||
Dinero({
|
||||
amount: Math.round(
|
||||
(job.job_totals.rates[val.mod_lbr_ty.toLowerCase()].rate || 0) *
|
||||
val.mod_lb_hrs *
|
||||
100
|
||||
),
|
||||
})
|
||||
),
|
||||
};
|
||||
},
|
||||
{ hours: 0, amount: Dinero() }
|
||||
);
|
||||
|
||||
try {
|
||||
const ret = {
|
||||
RepairOrderInformation: {
|
||||
@@ -405,7 +429,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
ElectricalRate: job.rate_lae || 0,
|
||||
FrameRate: job.rate_laf || 0,
|
||||
GlassRate: job.rate_lag || 0,
|
||||
DetailRate: job.rate_lad || 0,
|
||||
DetailRate: 0, // job.rate_lad || 0,
|
||||
LaborMiscRate: 0,
|
||||
PMRate: job.rate_mapa || 0,
|
||||
BMRate: job.rate_mash || 0,
|
||||
@@ -500,13 +524,14 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
ElectricalHours: job.job_totals.rates.lae.hours.toFixed(2),
|
||||
FrameHours: job.job_totals.rates.laf.hours.toFixed(2),
|
||||
GlassHours: job.job_totals.rates.lag.hours.toFixed(2),
|
||||
DetailHours: job.job_totals.rates.lad.hours.toFixed(2),
|
||||
DetailHours: detailAdjustments.hours, //job.job_totals.rates.lad.hours.toFixed(2),
|
||||
LaborMiscHours: (
|
||||
job.job_totals.rates.la1.hours +
|
||||
job.job_totals.rates.la2.hours +
|
||||
job.job_totals.rates.la3.hours +
|
||||
job.job_totals.rates.la4.hours +
|
||||
job.job_totals.rates.lau.hours
|
||||
job.job_totals.rates.lau.hours -
|
||||
detailAdjustments.hours
|
||||
).toFixed(2),
|
||||
|
||||
PartsTotal: Dinero(job.job_totals.parts.parts.total).toFormat(
|
||||
@@ -585,16 +610,18 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
),
|
||||
GlassLaborTotalCost:
|
||||
repairCosts.GlassLaborTotalCost.toFormat(AHDineroFormat),
|
||||
DetailLaborTotal: Dinero(job.job_totals.rates.lad.total).toFormat(
|
||||
AHDineroFormat
|
||||
),
|
||||
DetailLaborTotalCost:
|
||||
repairCosts.DetailLaborTotalCost.toFormat(AHDineroFormat),
|
||||
DetailLaborTotal: detailAdjustments.amount.toFormat(AHDineroFormat),
|
||||
// Dinero(job.job_totals.rates.lad.total).toFormat(
|
||||
// AHDineroFormat
|
||||
// ),
|
||||
DetailLaborTotalCost: Dinero().toFormat(AHDineroFormat),
|
||||
// repairCosts.DetailLaborTotalCost.toFormat(AHDineroFormat),
|
||||
LaborMiscTotal: Dinero(job.job_totals.rates.la1.total)
|
||||
.add(Dinero(job.job_totals.rates.la2.total))
|
||||
.add(Dinero(job.job_totals.rates.la3.total))
|
||||
.add(Dinero(job.job_totals.rates.la4.total))
|
||||
.add(Dinero(job.job_totals.rates.lau.total))
|
||||
.subtract(detailAdjustments.amount)
|
||||
.toFormat(AHDineroFormat),
|
||||
LaborMiscTotalCost:
|
||||
repairCosts.LaborMiscTotalCost.toFormat(AHDineroFormat),
|
||||
@@ -620,7 +647,7 @@ const CreateRepairOrderTag = (job, errorCallback) => {
|
||||
AHDineroFormat
|
||||
),
|
||||
StorageTotalCost: repairCosts.StorageTotalCost.toFormat(AHDineroFormat),
|
||||
DetailTotal: 0,
|
||||
DetailTotal: detailAdjustments.amount.toFormat(AHDineroFormat),
|
||||
DetailTotalCost: 0,
|
||||
SalesTaxTotal: Dinero(job.job_totals.totals.local_tax)
|
||||
.add(Dinero(job.job_totals.totals.state_tax))
|
||||
@@ -867,8 +894,8 @@ const CreateCosts = (job) => {
|
||||
ticketTotalsByCostCenter[defaultCosts.LAE] || Dinero(),
|
||||
FrameLaborTotalCost: ticketTotalsByCostCenter[defaultCosts.LAF] || Dinero(),
|
||||
GlassLaborTotalCost: ticketTotalsByCostCenter[defaultCosts.LAG] || Dinero(),
|
||||
DetailLaborTotalCost:
|
||||
ticketTotalsByCostCenter[defaultCosts.LAD] || Dinero(),
|
||||
DetailLaborTotalCost: Dinero(),
|
||||
// ticketTotalsByCostCenter[defaultCosts.LAD] || Dinero(),
|
||||
LaborMiscTotalCost: (ticketTotalsByCostCenter[defaultCosts.LA1] || Dinero())
|
||||
.add(ticketTotalsByCostCenter[defaultCosts.LA2] || Dinero())
|
||||
.add(ticketTotalsByCostCenter[defaultCosts.LA2] || Dinero())
|
||||
|
||||
@@ -715,6 +715,7 @@ exports.AUTOHOUSE_QUERY = `query AUTOHOUSE_EXPORT($start: timestamptz, $bodyshop
|
||||
lbr_op
|
||||
profitcenter_part
|
||||
profitcenter_labor
|
||||
ah_detail_line
|
||||
parts_order_lines(order_by: {parts_order: {order_date: desc_nulls_last}} limit: 1){
|
||||
parts_order{
|
||||
id
|
||||
|
||||
Reference in New Issue
Block a user