diff --git a/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx b/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx index 1d2ac0bfa..35308356e 100644 --- a/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx +++ b/client/src/components/accounting-payments-table/accounting-payments-table.component.jsx @@ -7,7 +7,7 @@ import CurrencyFormatter from "../../utils/CurrencyFormatter"; import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter"; import { alphaSort } from "../../utils/sorters"; import PaymentExportButton from "../payment-export-button/payment-export-button.component"; -import { PaymentsExportAllButton } from "../payments-export-all-button/payments-export-all-button.component"; +import PaymentsExportAllButton from "../payments-export-all-button/payments-export-all-button.component"; export default function AccountingPayablesTableComponent({ loading, diff --git a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx index ba08a8639..a7b1da714 100644 --- a/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx +++ b/client/src/components/job-checklist/components/job-checklist-form/job-checklist-form.component.jsx @@ -15,6 +15,7 @@ import { } from "../../../../redux/user/user.selectors"; import ConfigFormComponents from "../../../config-form-components/config-form-components.component"; import DateTimePicker from "../../../form-date-time-picker/form-date-time-picker.component"; +import moment from "moment-business-days"; const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, @@ -133,7 +134,14 @@ export function JobChecklistForm({ initialValues={{ ...(type === "intake" && { addToProduction: true, - scheduled_completion: job && job.scheduled_completion, + scheduled_completion: + (job && job.scheduled_completion) || + moment().businessAdd( + (job.labhrs.aggregate.sum.mod_lb_hrs + + job.larhrs.aggregate.sum.mod_lb_hrs) / + bodyshop.target_touchtime, + "days" + ), scheduled_delivery: job && job.scheduled_delivery, }), ...(type === "deliver" && { diff --git a/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx b/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx index 24839ac89..07e9cc009 100644 --- a/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx +++ b/client/src/components/job-lines-upsert-modal/job-lines-upsert-modal.component.jsx @@ -123,7 +123,7 @@ export default function JobLinesUpsertModalComponent({ // }), // ]} > - + diff --git a/client/src/components/jobs-create-jobs-info/jobs-create-jobs-info.component.jsx b/client/src/components/jobs-create-jobs-info/jobs-create-jobs-info.component.jsx index 8e9bb44b6..95bad7368 100644 --- a/client/src/components/jobs-create-jobs-info/jobs-create-jobs-info.component.jsx +++ b/client/src/components/jobs-create-jobs-info/jobs-create-jobs-info.component.jsx @@ -51,7 +51,13 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) { - + diff --git a/client/src/components/jobs-create-vehicle-info/jobs-create-vehicle-info.new.component.jsx b/client/src/components/jobs-create-vehicle-info/jobs-create-vehicle-info.new.component.jsx index aceb28f82..6e5e34cf3 100644 --- a/client/src/components/jobs-create-vehicle-info/jobs-create-vehicle-info.new.component.jsx +++ b/client/src/components/jobs-create-vehicle-info/jobs-create-vehicle-info.new.component.jsx @@ -83,24 +83,12 @@ export default function JobsCreateVehicleInfoNewComponent() { diff --git a/client/src/components/jobs-detail-general/jobs-detail-general.component.jsx b/client/src/components/jobs-detail-general/jobs-detail-general.component.jsx index 0492f6761..6d77cadd4 100644 --- a/client/src/components/jobs-detail-general/jobs-detail-general.component.jsx +++ b/client/src/components/jobs-detail-general/jobs-detail-general.component.jsx @@ -54,7 +54,13 @@ export function JobsDetailGeneral({ bodyshop, jobRO, job, form }) { - + diff --git a/client/src/components/jobs-documents-gallery/jobs-document-gallery.download.component.jsx b/client/src/components/jobs-documents-gallery/jobs-document-gallery.download.component.jsx index 50a8be4ca..b172e0806 100644 --- a/client/src/components/jobs-documents-gallery/jobs-document-gallery.download.component.jsx +++ b/client/src/components/jobs-documents-gallery/jobs-document-gallery.download.component.jsx @@ -1,11 +1,17 @@ -import { Button } from "antd"; +import { Button, Space } from "antd"; import axios from "axios"; -import React from "react"; +import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { logImEXEvent } from "../../firebase/firebase.utils"; +import cleanAxios from "../../utils/CleanAxios"; +import formatBytes from "../../utils/formatbytes"; -export default function JobsDocumentsDownloadButton({ galleryImages }) { +export default function JobsDocumentsDownloadButton({ + galleryImages, + identifier, +}) { const { t } = useTranslation(); + const [download, setDownload] = useState(null); const imagesToDownload = [ ...galleryImages.images.filter((image) => image.isSelected), ...galleryImages.other.filter((image) => image.isSelected), @@ -18,13 +24,68 @@ export default function JobsDocumentsDownloadButton({ galleryImages }) { ids: imagesToDownload.map((_) => _.key), }) .then((r) => { - window.open(r.data); + // window.open(r.data); + downloadAs( + r.data, + `${identifier || "images"}.zip`, + (progressEvent) => { + const percentage = Math.round( + (progressEvent.loaded * 100) / progressEvent.total + ); + console.log(progressEvent, percentage); + setDownload((currentDownloadState) => { + return { + downloaded: progressEvent.loaded || 0, + speed: + (progressEvent.loaded || 0) - + ((currentDownloadState && currentDownloadState.downloaded) || + 0), + }; + }); + }, + () => setDownload(null) + ); }); }; return ( - + <> + + ); } + +const downloadAs = (url, name, onDownloadProgress, onCompleted) => { + cleanAxios + .get(url, { + headers: { + "Content-Type": "application/octet-stream", + }, + responseType: "blob", + onDownloadProgress: onDownloadProgress, + }) + .then((response) => { + onCompleted && onCompleted(); + const a = document.createElement("a"); + const url = window.URL.createObjectURL(response.data); + a.href = url; + a.download = name; + a.click(); + }) + .catch((err) => { + console.log("error", err); + }); +}; diff --git a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx index 9d017c71f..2c50c9672 100644 --- a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx +++ b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.component.jsx @@ -17,7 +17,7 @@ function JobsDocumentsComponent({ billId, billsCallback, totalSize, - bodyshop, + downloadIdentifier, ignoreSizeLimit, }) { const [galleryImages, setgalleryImages] = useState({ images: [], other: [] }); @@ -117,7 +117,10 @@ function JobsDocumentsComponent({ galleryImages={galleryImages} setGalleryImages={setgalleryImages} /> - + , height: "100%", width: "100%", + cursor: "pointer", }; }} onClickThumbnail={(index) => { diff --git a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx index 41ea08e29..37df28f1b 100644 --- a/client/src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx +++ b/client/src/components/jobs-documents-gallery/jobs-documents-gallery.container.jsx @@ -23,6 +23,7 @@ export default function JobsDocumentsContainer({ return ( ( 0 ? "green" : "red", + color: record.difference >= 0 ? "green" : "red", }} > {record.difference} diff --git a/client/src/components/owner-detail-form/owner-detail-form.component.jsx b/client/src/components/owner-detail-form/owner-detail-form.component.jsx index 8dc3772c6..f8886f3ce 100644 --- a/client/src/components/owner-detail-form/owner-detail-form.component.jsx +++ b/client/src/components/owner-detail-form/owner-detail-form.component.jsx @@ -31,55 +31,19 @@ export default function OwnerDetailFormComponent({ form, loading }) { - + - + - + - + diff --git a/client/src/components/vehicle-detail-form/vehicle-detail-form.component.jsx b/client/src/components/vehicle-detail-form/vehicle-detail-form.component.jsx index be0cb80b8..86c587afe 100644 --- a/client/src/components/vehicle-detail-form/vehicle-detail-form.component.jsx +++ b/client/src/components/vehicle-detail-form/vehicle-detail-form.component.jsx @@ -76,28 +76,10 @@ export default function VehicleDetailFormComponent({ form, loading }) { - + - + diff --git a/client/src/graphql/appointments.queries.js b/client/src/graphql/appointments.queries.js index 2e727fde7..7c005890b 100644 --- a/client/src/graphql/appointments.queries.js +++ b/client/src/graphql/appointments.queries.js @@ -85,6 +85,7 @@ export const INSERT_APPOINTMENT = gql` title isintake block + color } } update_jobs( @@ -110,6 +111,7 @@ export const QUERY_APPOINTMENT_BY_DATE = gql` title isintake block + color job { alt_transport ro_number diff --git a/client/src/graphql/bodyshop.queries.js b/client/src/graphql/bodyshop.queries.js index e19a8aa89..5f456e88a 100644 --- a/client/src/graphql/bodyshop.queries.js +++ b/client/src/graphql/bodyshop.queries.js @@ -197,6 +197,28 @@ export const QUERY_INTAKE_CHECKLIST = gql` scheduled_delivery intakechecklist status + labhrs: joblines_aggregate( + where: { + _and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }] + } + ) { + aggregate { + sum { + mod_lb_hrs + } + } + } + larhrs: joblines_aggregate( + where: { + _and: [{ mod_lbr_ty: { _eq: "LAR" } }, { removed: { _eq: false } }] + } + ) { + aggregate { + sum { + mod_lb_hrs + } + } + } } } `; diff --git a/client/src/graphql/documents.queries.js b/client/src/graphql/documents.queries.js index 6e490d1e5..8959e49a9 100644 --- a/client/src/graphql/documents.queries.js +++ b/client/src/graphql/documents.queries.js @@ -2,6 +2,10 @@ import { gql } from "@apollo/client"; export const GET_DOCUMENTS_BY_JOB = gql` query GET_DOCUMENTS_BY_JOB($jobId: uuid!) { + jobs_by_pk(id: $jobId) { + id + ro_number + } documents_aggregate(where: { jobid: { _eq: $jobId } }) { aggregate { sum {