Merged in feature/2021-07-30 (pull request #151)

feature/2021-07-30

Approved-by: Patrick Fic
This commit is contained in:
Patrick Fic
2021-07-29 20:24:45 +00:00
10 changed files with 108 additions and 17 deletions

View File

@@ -20730,6 +20730,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>special_coverage_policy</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>specialcoveragepolicy</name> <name>specialcoveragepolicy</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

View File

@@ -15,7 +15,11 @@ export default function DashboardProjectedMonthlySales({ data, ...cardProps }) {
data.projected_monthly_sales.reduce( data.projected_monthly_sales.reduce(
(acc, val) => (acc, val) =>
acc.add( acc.add(
Dinero(val.job_totals.totals && val.job_totals.totals.subtotal) Dinero(
val.job_totals &&
val.job_totals.totals &&
val.job_totals.totals.subtotal
)
), ),
Dinero() Dinero()
); );

View File

@@ -57,7 +57,7 @@ export function JobsAvailableComponent({
title: t("jobs.fields.cieca_id"), title: t("jobs.fields.cieca_id"),
dataIndex: "cieca_id", dataIndex: "cieca_id",
key: "cieca_id", key: "cieca_id",
sorter: (a, b) => alphaSort(a, b), sorter: (a, b) => alphaSort(a.cieca_id, b.cieca_id),
sortOrder: sortOrder:
state.sortedInfo.columnKey === "cieca_id" && state.sortedInfo.order, state.sortedInfo.columnKey === "cieca_id" && state.sortedInfo.order,
}, },
@@ -68,9 +68,10 @@ export function JobsAvailableComponent({
//width: "8%", //width: "8%",
// onFilter: (value, record) => record.ro_number.includes(value), // onFilter: (value, record) => record.ro_number.includes(value),
// filteredValue: state.filteredInfo.text || null, // filteredValue: state.filteredInfo.text || null,
sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), sorter: (a, b) =>
alphaSort(a.job && a.job.ro_number, b.job && b.job.ro_number),
sortOrder: sortOrder:
state.sortedInfo.columnKey === "cieca_id" && state.sortedInfo.order, state.sortedInfo.columnKey === "job_id" && state.sortedInfo.order,
render: (text, record) => render: (text, record) =>
record.job ? ( record.job ? (
<Link to={`/manage/jobs/${record.job.id}`}> <Link to={`/manage/jobs/${record.job.id}`}>
@@ -87,7 +88,7 @@ export function JobsAvailableComponent({
dataIndex: "ownr_name", dataIndex: "ownr_name",
key: "ownr_name", key: "ownr_name",
ellipsis: true, ellipsis: true,
sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln), sorter: (a, b) => alphaSort(a.ownr_name, b.ownr_name),
sortOrder: sortOrder:
state.sortedInfo.columnKey === "ownr_name" && state.sortedInfo.order, state.sortedInfo.columnKey === "ownr_name" && state.sortedInfo.order,
}, },

View File

@@ -14,12 +14,25 @@ import IndefiniteLoading from "../indefinite-loading/indefinite-loading.componen
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import ProductionBoardFilters from "../production-board-filters/production-board-filters.component"; import ProductionBoardFilters from "../production-board-filters/production-board-filters.component";
import { selectTechnician } from "../../redux/tech/tech.selectors"; import { selectTechnician } from "../../redux/tech/tech.selectors";
import { insertAuditTrail } from "../../redux/application/application.actions";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
technician: selectTechnician, technician: selectTechnician,
}); });
export function ProductionBoardKanbanComponent({ data, bodyshop, technician }) { const mapDispatchToProps = (dispatch) => ({
insertAuditTrail: ({ jobid, operation }) =>
dispatch(insertAuditTrail({ jobid, operation })),
});
export function ProductionBoardKanbanComponent({
data,
bodyshop,
technician,
insertAuditTrail,
}) {
const [boardLanes, setBoardLanes] = useState({ const [boardLanes, setBoardLanes] = useState({
columns: [{ id: "Loading...", title: "Loading...", cards: [] }], columns: [{ id: "Loading...", title: "Loading...", cards: [] }],
}); });
@@ -104,6 +117,11 @@ export function ProductionBoardKanbanComponent({ data, bodyshop, technician }) {
newChildCardNewParent newChildCardNewParent
), ),
}); });
insertAuditTrail({
jobid: card.id,
operation: AuditTrailMapping.jobstatuschange(destination.toColumnId),
});
if (update.errors) { if (update.errors) {
notification["error"]({ notification["error"]({
message: t("production.errors.boardupdate", { message: t("production.errors.boardupdate", {
@@ -130,4 +148,7 @@ export function ProductionBoardKanbanComponent({ data, bodyshop, technician }) {
</div> </div>
); );
} }
export default connect(mapStateToProps, null)(ProductionBoardKanbanComponent); export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductionBoardKanbanComponent);

View File

@@ -16,24 +16,32 @@ import { connect } from "react-redux";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { insertAuditTrail } from "../../redux/application/application.actions";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
const iconStyle = { marginLeft: ".3rem" }; const iconStyle = { marginLeft: ".3rem" };
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language)) insertAuditTrail: ({ jobid, operation }) =>
dispatch(insertAuditTrail({ jobid, operation })),
}); });
export function ProductionListEmpAssignment({ bodyshop, record, type }) { export function ProductionListEmpAssignment({
insertAuditTrail,
bodyshop,
record,
type,
}) {
const { t } = useTranslation(); const { t } = useTranslation();
const [updateJob] = useMutation(UPDATE_JOB); const [updateJob] = useMutation(UPDATE_JOB);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const handleAdd = async (assignment) => { const handleAdd = async (assignment) => {
setLoading(true); setLoading(true);
const { operation, employeeid } = assignment; const { operation, employeeid, name } = assignment;
logImEXEvent("job_assign_employee", { operation }); logImEXEvent("job_assign_employee", { operation });
let empAssignment = determineFieldName(operation); let empAssignment = determineFieldName(operation);
@@ -44,6 +52,11 @@ export function ProductionListEmpAssignment({ bodyshop, record, type }) {
awaitRefetchQueries: true, awaitRefetchQueries: true,
}); });
insertAuditTrail({
jobid: record.id,
operation: AuditTrailMapping.jobassignmentchange(empAssignment, name),
});
if (!!result.errors) { if (!!result.errors) {
notification["error"]({ notification["error"]({
message: t("jobs.errors.assigning", { message: t("jobs.errors.assigning", {
@@ -64,6 +77,11 @@ export function ProductionListEmpAssignment({ bodyshop, record, type }) {
awaitRefetchQueries: true, awaitRefetchQueries: true,
}); });
insertAuditTrail({
jobid: record.id,
operation: AuditTrailMapping.jobassignmentremoved(empAssignment),
});
if (!!result.errors) { if (!!result.errors) {
notification["error"]({ notification["error"]({
message: t("jobs.errors.assigning", { message: t("jobs.errors.assigning", {
@@ -80,8 +98,8 @@ export function ProductionListEmpAssignment({ bodyshop, record, type }) {
}); });
const [visibility, setVisibility] = useState(false); const [visibility, setVisibility] = useState(false);
const onChange = (e) => { const onChange = (e, option) => {
setAssignment({ ...assignment, employeeid: e }); setAssignment({ ...assignment, employeeid: e, name: option.name });
}; };
const popContent = ( const popContent = (
@@ -99,7 +117,11 @@ export function ProductionListEmpAssignment({ bodyshop, record, type }) {
} }
> >
{bodyshop.employees.map((emp) => ( {bodyshop.employees.map((emp) => (
<Select.Option value={emp.id} key={emp.id}> <Select.Option
value={emp.id}
key={emp.id}
name={`${emp.first_name} ${emp.last_name}`}
>
{`${emp.first_name} ${emp.last_name}`} {`${emp.first_name} ${emp.last_name}`}
</Select.Option> </Select.Option>
))} ))}

View File

@@ -6,12 +6,21 @@ import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.utils"; import { logImEXEvent } from "../../firebase/firebase.utils";
import { UPDATE_JOB } from "../../graphql/jobs.queries"; import { UPDATE_JOB } from "../../graphql/jobs.queries";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import { insertAuditTrail } from "../../redux/application/application.actions";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
const mapStateToProps = createStructuredSelector({ const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop, bodyshop: selectBodyshop,
}); });
const mapDispatchToProps = (dispatch) => ({
export function ProductionListColumnStatus({ record, bodyshop }) { insertAuditTrail: ({ jobid, operation }) =>
dispatch(insertAuditTrail({ jobid, operation })),
});
export function ProductionListColumnStatus({
record,
bodyshop,
insertAuditTrail,
}) {
const [updateJob] = useMutation(UPDATE_JOB); const [updateJob] = useMutation(UPDATE_JOB);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@@ -28,6 +37,11 @@ export function ProductionListColumnStatus({ record, bodyshop }) {
}, },
}, },
}); });
insertAuditTrail({
jobid: record.id,
operation: AuditTrailMapping.jobstatuschange(key),
});
setLoading(false); setLoading(false);
}; };
@@ -52,4 +66,7 @@ export function ProductionListColumnStatus({ record, bodyshop }) {
</Dropdown> </Dropdown>
); );
} }
export default connect(mapStateToProps, null)(ProductionListColumnStatus); export default connect(
mapStateToProps,
mapDispatchToProps
)(ProductionListColumnStatus);

View File

@@ -162,7 +162,9 @@ export function JobsDetailPage({
jobid: job.id, jobid: job.id,
operation: AuditTrailMapping.jobfieldchange( operation: AuditTrailMapping.jobfieldchange(
key, key,
changedAuditFields[key] changedAuditFields[key] instanceof moment
? moment(changedAuditFields[key]).format("MM/DD/YYYY hh:mm a")
: changedAuditFields[key]
), ),
}); });
}); });

View File

@@ -1247,6 +1247,7 @@
"servicecar": "Service Car", "servicecar": "Service Car",
"servicing_dealer": "Servicing Dealer", "servicing_dealer": "Servicing Dealer",
"servicing_dealer_contact": "Servicing Dealer Contact", "servicing_dealer_contact": "Servicing Dealer Contact",
"special_coverage_policy": "Special Coverage Policy",
"specialcoveragepolicy": "Special Coverage Policy", "specialcoveragepolicy": "Special Coverage Policy",
"state_tax_rate": "Provincial/State Tax Rate", "state_tax_rate": "Provincial/State Tax Rate",
"status": "Job Status", "status": "Job Status",

View File

@@ -1247,6 +1247,7 @@
"servicecar": "Auto de servicio", "servicecar": "Auto de servicio",
"servicing_dealer": "Distribuidor de servicio", "servicing_dealer": "Distribuidor de servicio",
"servicing_dealer_contact": "Servicio Contacto con el concesionario", "servicing_dealer_contact": "Servicio Contacto con el concesionario",
"special_coverage_policy": "Política de cobertura especial",
"specialcoveragepolicy": "Política de cobertura especial", "specialcoveragepolicy": "Política de cobertura especial",
"state_tax_rate": "", "state_tax_rate": "",
"status": "Estado del trabajo", "status": "Estado del trabajo",

View File

@@ -1247,6 +1247,7 @@
"servicecar": "Voiture de service", "servicecar": "Voiture de service",
"servicing_dealer": "Concessionnaire", "servicing_dealer": "Concessionnaire",
"servicing_dealer_contact": "Contacter le concessionnaire", "servicing_dealer_contact": "Contacter le concessionnaire",
"special_coverage_policy": "Politique de couverture spéciale",
"specialcoveragepolicy": "Politique de couverture spéciale", "specialcoveragepolicy": "Politique de couverture spéciale",
"state_tax_rate": "", "state_tax_rate": "",
"status": "Statut de l'emploi", "status": "Statut de l'emploi",