Add audit trail and resolve status update.

This commit is contained in:
Patrick Fic
2023-08-01 15:29:19 -07:00
parent ff153cdd81
commit 1d7f1cccba
17 changed files with 471 additions and 36 deletions

View File

@@ -301,7 +301,11 @@ export function JobLinesComponent({
dataIndex: "assigned_team",
key: "assigned_team",
render: (text, record) => (
<JoblineTeamAssignment disabled={jobRO} jobline={record} />
<JoblineTeamAssignment
disabled={jobRO}
jobline={record}
jobId={job.id}
/>
),
},
]
@@ -442,9 +446,20 @@ export function JobLinesComponent({
<Menu.Item key="PAL">{t("joblines.fields.part_types.PAL")}</Menu.Item>
<Menu.Item key="PAS">{t("joblines.fields.part_types.PAS")}</Menu.Item>
<Menu.Divider />
<Menu.Item key="LAA">{t("joblines.fields.lbr_types.LAA")}</Menu.Item>
<Menu.Item key="LAB">{t("joblines.fields.lbr_types.LAB")}</Menu.Item>
<Menu.Item key="LAR">{t("joblines.fields.lbr_types.LAR")}</Menu.Item>
<Menu.Item key="LAD">{t("joblines.fields.lbr_types.LAD")}</Menu.Item>
<Menu.Item key="LAE">{t("joblines.fields.lbr_types.LAE")}</Menu.Item>
<Menu.Item key="LAF">{t("joblines.fields.lbr_types.LAF")}</Menu.Item>
<Menu.Item key="LAG">{t("joblines.fields.lbr_types.LAG")}</Menu.Item>
<Menu.Item key="LAM">{t("joblines.fields.lbr_types.LAM")}</Menu.Item>
<Menu.Item key="LAR">{t("joblines.fields.lbr_types.LAR")}</Menu.Item>
<Menu.Item key="LAS">{t("joblines.fields.lbr_types.LAS")}</Menu.Item>
<Menu.Item key="LAU">{t("joblines.fields.lbr_types.LAU")}</Menu.Item>
<Menu.Item key="LA1">{t("joblines.fields.lbr_types.LA1")}</Menu.Item>
<Menu.Item key="LA2">{t("joblines.fields.lbr_types.LA2")}</Menu.Item>
<Menu.Item key="LA3">{t("joblines.fields.lbr_types.LA3")}</Menu.Item>
<Menu.Item key="LA4">{t("joblines.fields.lbr_types.LA2")}</Menu.Item>
<Menu.Divider />
<Menu.Item key="clear">{t("general.labels.clear")}</Menu.Item>
</Menu>

View File

@@ -11,20 +11,23 @@ import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import { insertAuditTrail } from "../../redux/application/application.actions";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
jobRO: selectJobReadOnly,
currentUser: selectCurrentUser,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
insertAuditTrail: ({ jobid, operation }) =>
dispatch(insertAuditTrail({ jobid, operation })),
});
export default connect(mapStateToProps, mapDispatchToProps)(JoblineBulkAssign);
export function JoblineBulkAssign({
setSelectedLines,
selectedLines,
insertAuditTrail,
bodyshop,
jobRO,
job,
@@ -55,8 +58,28 @@ export function JoblineBulkAssign({
error: JSON.stringify(result.errors),
}),
});
} else {
//Insert the audit trail here.
const teamName = bodyshop.employee_teams.find(
(et) => et.id === values.assigned_team
)?.name;
const hours = selectedLines.reduce(
(acc, val) => (acc += val.mod_lb_hrs),
0
);
insertAuditTrail({
jobid: job.id,
operation: AuditTrailMapping.assignedlinehours(
teamName,
hours.toFixed(1)
),
});
setVisible(false);
}
setVisible(false);
} catch (error) {
notification.open({
type: "error",

View File

@@ -7,16 +7,25 @@ import { createStructuredSelector } from "reselect";
import { UPDATE_JOB_LINE } from "../../graphql/jobs-lines.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import { insertAuditTrail } from "../../redux/application/application.actions";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
const mapStateToProps = createStructuredSelector({
//currentUser: selectCurrentUser
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
insertAuditTrail: ({ jobid, operation }) =>
dispatch(insertAuditTrail({ jobid, operation })),
});
export function JoblineTeamAssignment({ bodyshop, jobline, disabled }) {
export function JoblineTeamAssignment({
bodyshop,
jobline,
disabled,
jobId,
insertAuditTrail,
}) {
const [editing, setEditing] = useState(false);
const [loading, setLoading] = useState(false);
const [assignedTeam, setAssignedTeam] = useState(jobline.assigned_team);
@@ -40,16 +49,19 @@ export function JoblineTeamAssignment({ bodyshop, jobline, disabled }) {
},
});
if (
assignedTeam === null ||
assignedTeam === undefined ||
assignedTeam === ""
) {
alert("TODO - implement calculation to reduce assigned hours if needed.");
}
if (!!!result.errors) {
notification["success"]({ message: t("joblines.successes.saved") });
//insert the audit trail here.
const teamName = bodyshop.employee_teams.find(
(et) => et.id === assignedTeam
)?.name;
insertAuditTrail({
jobid: jobId,
operation: AuditTrailMapping.assignedlinehours(
teamName,
jobline.mod_lb_hrs
),
});
} else {
notification["error"]({
message: t("joblines.errors.saving", {

View File

@@ -107,6 +107,13 @@ export function TechSider({
>
<Link to={`/tech/board`}> {t("menus.tech.productionboard")}</Link>
</Menu.Item>
<Menu.Item
key="TechAssignedProdJobs"
disabled={!!!technician}
icon={<Icon component={BsKanban} />}
>
<Link to={`/tech/assigned`}> {t("menus.tech.assignedjobs")}</Link>
</Menu.Item>
<Menu.Item
key="7"
disabled={!!!technician}

View File

@@ -64,7 +64,9 @@ export function TimeTicketTaskModalComponent({
options={bodyshop.md_tasks_presets.presets.map((preset) => ({
value: preset.name,
label: preset.name,
disabled: completedTasks.includes(preset.name),
disabled: completedTasks
.map((task) => task.name)
.includes(preset.name),
}))}
/>
)}

View File

@@ -7,15 +7,21 @@ import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { toggleModalVisible } from "../../redux/modals/modals.actions";
import { selectTimeTicketTasks } from "../../redux/modals/modals.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import TimeTicketTaskModalComponent from "./time-ticket-task-modal.component";
import { useApolloClient } from "@apollo/client";
import { QUERY_COMPLETED_TASKS } from "../../graphql/jobs.queries";
import "./time-ticket-task-modal.styles.scss";
import { selectTechnician } from "../../redux/tech/tech.selectors";
const mapStateToProps = createStructuredSelector({
timeTicketTasksModal: selectTimeTicketTasks,
bodyshop: selectBodyshop,
currentUser: selectCurrentUser,
technician: selectTechnician,
});
const mapDispatchToProps = (dispatch) => ({
toggleModalVisible: () => dispatch(toggleModalVisible("timeTicketTask")),
@@ -27,6 +33,8 @@ export default connect(
export function TimeTickeTaskModalContainer({
bodyshop,
currentUser,
technician,
timeTicketTasksModal,
toggleModalVisible,
}) {
@@ -80,6 +88,12 @@ export function TimeTickeTaskModalContainer({
jobid: values.jobid,
task: values.task,
calculateOnly: !handleFinish,
employee: technician
? {
name: `${technician.first_name} ${technician.last_name}`.trim(),
employeeid: technician.id,
}
: { name: currentUser.displayName, email: currentUser.email },
});
if (response.status === 200 && handleFinish) {
//Close the modal