IO-134 Prevent doc reassignment with limit
This commit is contained in:
@@ -10211,6 +10211,48 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>reassign_limitexceeded</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>reassign_limitexceeded_title</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>storageexceeded</name>
|
<name>storageexceeded</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -28533,6 +28575,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>supplement_ratio_source</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>timetickets</name>
|
<name>timetickets</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export function DocumentsUploadComponent({
|
|||||||
billId,
|
billId,
|
||||||
callbackAfterUpload,
|
callbackAfterUpload,
|
||||||
totalSize,
|
totalSize,
|
||||||
|
ignoreSizeLimit = false,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ export function DocumentsUploadComponent({
|
|||||||
);
|
);
|
||||||
}, [bodyshop, totalSize]);
|
}, [bodyshop, totalSize]);
|
||||||
|
|
||||||
if (pct > 100)
|
if (pct > 100 && !ignoreSizeLimit)
|
||||||
return (
|
return (
|
||||||
<Result
|
<Result
|
||||||
status="error"
|
status="error"
|
||||||
@@ -46,6 +47,7 @@ export function DocumentsUploadComponent({
|
|||||||
<Upload.Dragger
|
<Upload.Dragger
|
||||||
multiple={true}
|
multiple={true}
|
||||||
beforeUpload={(file, fileList) => {
|
beforeUpload={(file, fileList) => {
|
||||||
|
if (ignoreSizeLimit) return true;
|
||||||
const newFiles = fileList.reduce((acc, val) => acc + val.size, 0);
|
const newFiles = fileList.reduce((acc, val) => acc + val.size, 0);
|
||||||
const shouldStopUpload =
|
const shouldStopUpload =
|
||||||
(totalSize + newFiles) / ((bodyshop && bodyshop.jobsizelimit) || 1) >=
|
(totalSize + newFiles) / ((bodyshop && bodyshop.jobsizelimit) || 1) >=
|
||||||
@@ -84,16 +86,18 @@ export function DocumentsUploadComponent({
|
|||||||
<p className="ant-upload-text">
|
<p className="ant-upload-text">
|
||||||
Click or drag files to this area to upload.
|
Click or drag files to this area to upload.
|
||||||
</p>
|
</p>
|
||||||
<Space wrap className="ant-upload-text">
|
{!ignoreSizeLimit && (
|
||||||
<Progress type="dashboard" percent={pct} size="small" />
|
<Space wrap className="ant-upload-text">
|
||||||
<span>
|
<Progress type="dashboard" percent={pct} size="small" />
|
||||||
{t("documents.labels.usage", {
|
<span>
|
||||||
percent: pct,
|
{t("documents.labels.usage", {
|
||||||
used: formatBytes(totalSize),
|
percent: pct,
|
||||||
total: formatBytes(bodyshop && bodyshop.jobsizelimit),
|
used: formatBytes(totalSize),
|
||||||
})}
|
total: formatBytes(bodyshop && bodyshop.jobsizelimit),
|
||||||
</span>
|
})}
|
||||||
</Space>
|
</span>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Upload.Dragger>
|
</Upload.Dragger>
|
||||||
|
|||||||
@@ -1,12 +1,29 @@
|
|||||||
import { Button, Form, Popover, notification, Space } from "antd";
|
import { useApolloClient, useMutation } from "@apollo/client";
|
||||||
import React, { useState, useMemo } from "react";
|
import { Button, Form, notification, Popover, Space } from "antd";
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import JobSearchSelect from "../job-search-select/job-search-select.component";
|
|
||||||
import { useMutation } from "@apollo/client";
|
|
||||||
import { UPDATE_DOCUMENT } from "../../graphql/documents.queries";
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import React, { useMemo, useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import {
|
||||||
|
GET_DOC_SIZE_BY_JOB,
|
||||||
|
UPDATE_DOCUMENT,
|
||||||
|
} from "../../graphql/documents.queries";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import JobSearchSelect from "../job-search-select/job-search-select.component";
|
||||||
|
|
||||||
export default function JobsDocumentsGalleryReassign({ galleryImages }) {
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(JobsDocumentsGalleryReassign);
|
||||||
|
|
||||||
|
export function JobsDocumentsGalleryReassign({ bodyshop, galleryImages }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
|
||||||
@@ -16,7 +33,7 @@ export default function JobsDocumentsGalleryReassign({ galleryImages }) {
|
|||||||
...galleryImages.other.filter((image) => image.isSelected),
|
...galleryImages.other.filter((image) => image.isSelected),
|
||||||
];
|
];
|
||||||
}, [galleryImages]);
|
}, [galleryImages]);
|
||||||
|
const client = useApolloClient();
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [updateDocument] = useMutation(UPDATE_DOCUMENT);
|
const [updateDocument] = useMutation(UPDATE_DOCUMENT);
|
||||||
@@ -48,10 +65,37 @@ export default function JobsDocumentsGalleryReassign({ galleryImages }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
console.log("selectedImages :>> ", selectedImages);
|
||||||
const handleFinish = async ({ jobid }) => {
|
const handleFinish = async ({ jobid }) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
|
//Check to see if the space remaining on the new job is sufficient. If it isn't cancel this.
|
||||||
|
const newJobData = await client.query({
|
||||||
|
query: GET_DOC_SIZE_BY_JOB,
|
||||||
|
variables: { jobId: jobid },
|
||||||
|
});
|
||||||
|
|
||||||
|
const transferedDocSizeTotal = selectedImages.reduce(
|
||||||
|
(acc, val) => acc + val.size,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
const shouldPreventTransfer =
|
||||||
|
bodyshop.jobsizelimit -
|
||||||
|
newJobData.data.documents_aggregate.aggregate.sum.size <
|
||||||
|
transferedDocSizeTotal;
|
||||||
|
|
||||||
|
if (shouldPreventTransfer) {
|
||||||
|
notification.open({
|
||||||
|
key: "cannotuploaddocuments",
|
||||||
|
type: "error",
|
||||||
|
message: t("documents.labels.reassign_limitexceeded_title"),
|
||||||
|
description: t("documents.labels.reassign_limitexceeded"),
|
||||||
|
});
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const res = await axios.post("/media/rename", {
|
const res = await axios.post("/media/rename", {
|
||||||
documents: selectedImages.map((i) => {
|
documents: selectedImages.map((i) => {
|
||||||
//Need to check if the current key folder is null, or another job.
|
//Need to check if the current key folder is null, or another job.
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ function JobsDocumentsComponent({
|
|||||||
billsCallback,
|
billsCallback,
|
||||||
totalSize,
|
totalSize,
|
||||||
bodyshop,
|
bodyshop,
|
||||||
|
ignoreSizeLimit,
|
||||||
}) {
|
}) {
|
||||||
const [galleryImages, setgalleryImages] = useState({ images: [], other: [] });
|
const [galleryImages, setgalleryImages] = useState({ images: [], other: [] });
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -43,6 +44,7 @@ function JobsDocumentsComponent({
|
|||||||
extension: value.extension,
|
extension: value.extension,
|
||||||
id: value.id,
|
id: value.id,
|
||||||
type: value.type,
|
type: value.type,
|
||||||
|
size: value.size,
|
||||||
tags: [{ value: value.type, title: value.type }],
|
tags: [{ value: value.type, title: value.type }],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -95,6 +97,7 @@ function JobsDocumentsComponent({
|
|||||||
key: value.key,
|
key: value.key,
|
||||||
id: value.id,
|
id: value.id,
|
||||||
type: value.type,
|
type: value.type,
|
||||||
|
size: value.size,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +134,7 @@ function JobsDocumentsComponent({
|
|||||||
totalSize={totalSize}
|
totalSize={totalSize}
|
||||||
billId={billId}
|
billId={billId}
|
||||||
callbackAfterUpload={billsCallback || refetch}
|
callbackAfterUpload={billsCallback || refetch}
|
||||||
|
ignoreSizeLimit={ignoreSizeLimit}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ export const QUERY_BILL_BY_PK = gql`
|
|||||||
key
|
key
|
||||||
name
|
name
|
||||||
type
|
type
|
||||||
|
size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export const GET_DOCUMENTS_BY_JOB = gql`
|
|||||||
name
|
name
|
||||||
key
|
key
|
||||||
type
|
type
|
||||||
|
size
|
||||||
bill {
|
bill {
|
||||||
id
|
id
|
||||||
invoice_number
|
invoice_number
|
||||||
@@ -27,6 +28,18 @@ export const GET_DOCUMENTS_BY_JOB = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const GET_DOC_SIZE_BY_JOB = gql`
|
||||||
|
query GET_DOC_SIZE_BY_JOB($jobId: uuid!) {
|
||||||
|
documents_aggregate(where: { jobid: { _eq: $jobId } }) {
|
||||||
|
aggregate {
|
||||||
|
sum {
|
||||||
|
size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const INSERT_NEW_DOCUMENT = gql`
|
export const INSERT_NEW_DOCUMENT = gql`
|
||||||
mutation INSERT_NEW_DOCUMENT($docInput: [documents_insert_input!]!) {
|
mutation INSERT_NEW_DOCUMENT($docInput: [documents_insert_input!]!) {
|
||||||
insert_documents(objects: $docInput) {
|
insert_documents(objects: $docInput) {
|
||||||
@@ -34,6 +47,7 @@ export const INSERT_NEW_DOCUMENT = gql`
|
|||||||
id
|
id
|
||||||
name
|
name
|
||||||
key
|
key
|
||||||
|
size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,6 +74,7 @@ export const QUERY_TEMPORARY_DOCS = gql`
|
|||||||
key
|
key
|
||||||
type
|
type
|
||||||
extension
|
extension
|
||||||
|
size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@@ -75,6 +90,7 @@ export const UPDATE_DOCUMENT = gql`
|
|||||||
name
|
name
|
||||||
type
|
type
|
||||||
key
|
key
|
||||||
|
size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -811,6 +811,7 @@ export const QUERY_TECH_JOB_DETAILS = gql`
|
|||||||
documents(order_by: { created_at: desc }) {
|
documents(order_by: { created_at: desc }) {
|
||||||
id
|
id
|
||||||
key
|
key
|
||||||
|
size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export default function TemporaryDocsComponent() {
|
|||||||
jobId={null}
|
jobId={null}
|
||||||
billId={null}
|
billId={null}
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
|
ignoreSizeLimit
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -658,11 +658,13 @@
|
|||||||
"confirmdelete": "Are you sure you want to delete these documents. This CANNOT be undone.",
|
"confirmdelete": "Are you sure you want to delete these documents. This CANNOT be undone.",
|
||||||
"doctype": "Document Type",
|
"doctype": "Document Type",
|
||||||
"newjobid": "Assign to Job",
|
"newjobid": "Assign to Job",
|
||||||
|
"reassign_limitexceeded": "Reassigning all selected documents will exceed the job storage limit for your shop. ",
|
||||||
|
"reassign_limitexceeded_title": "Unable to reassign document(s)",
|
||||||
"storageexceeded": "You've exceeded your storage limit for this job. Please remove documents, or increase your storage plan.",
|
"storageexceeded": "You've exceeded your storage limit for this job. Please remove documents, or increase your storage plan.",
|
||||||
"storageexceeded_title": "Storage Limit Exceeded",
|
"storageexceeded_title": "Storage Limit Exceeded",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"upload_limitexceeded": "Uploading all selected files will exceed the job storage limit for your shop. ",
|
"upload_limitexceeded": "Uploading all selected documents will exceed the job storage limit for your shop. ",
|
||||||
"upload_limitexceeded_title": "Unable to upload file(s)",
|
"upload_limitexceeded_title": "Unable to upload document(s)",
|
||||||
"usage": "of job storage used. ({{used}} / {{total}})"
|
"usage": "of job storage used. ({{used}} / {{total}})"
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -1719,6 +1721,7 @@
|
|||||||
"purchases_by_vendor_detailed_date_range": "Purchases By Vendor - Detailed",
|
"purchases_by_vendor_detailed_date_range": "Purchases By Vendor - Detailed",
|
||||||
"purchases_by_vendor_summary_date_range": "Purchases by Vendor - Summary",
|
"purchases_by_vendor_summary_date_range": "Purchases by Vendor - Summary",
|
||||||
"schedule": "Appointment Schedule",
|
"schedule": "Appointment Schedule",
|
||||||
|
"supplement_ratio_source": "Supplement Ratio by Source",
|
||||||
"timetickets": "Time Tickets",
|
"timetickets": "Time Tickets",
|
||||||
"timetickets_employee": "Employee Time Tickets",
|
"timetickets_employee": "Employee Time Tickets",
|
||||||
"timetickets_summary": "Time Tickets Summary"
|
"timetickets_summary": "Time Tickets Summary"
|
||||||
|
|||||||
@@ -658,6 +658,8 @@
|
|||||||
"confirmdelete": "",
|
"confirmdelete": "",
|
||||||
"doctype": "",
|
"doctype": "",
|
||||||
"newjobid": "",
|
"newjobid": "",
|
||||||
|
"reassign_limitexceeded": "",
|
||||||
|
"reassign_limitexceeded_title": "",
|
||||||
"storageexceeded": "",
|
"storageexceeded": "",
|
||||||
"storageexceeded_title": "",
|
"storageexceeded_title": "",
|
||||||
"upload": "Subir",
|
"upload": "Subir",
|
||||||
@@ -1719,6 +1721,7 @@
|
|||||||
"purchases_by_vendor_detailed_date_range": "",
|
"purchases_by_vendor_detailed_date_range": "",
|
||||||
"purchases_by_vendor_summary_date_range": "",
|
"purchases_by_vendor_summary_date_range": "",
|
||||||
"schedule": "",
|
"schedule": "",
|
||||||
|
"supplement_ratio_source": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
"timetickets_employee": "",
|
"timetickets_employee": "",
|
||||||
"timetickets_summary": ""
|
"timetickets_summary": ""
|
||||||
|
|||||||
@@ -658,6 +658,8 @@
|
|||||||
"confirmdelete": "",
|
"confirmdelete": "",
|
||||||
"doctype": "",
|
"doctype": "",
|
||||||
"newjobid": "",
|
"newjobid": "",
|
||||||
|
"reassign_limitexceeded": "",
|
||||||
|
"reassign_limitexceeded_title": "",
|
||||||
"storageexceeded": "",
|
"storageexceeded": "",
|
||||||
"storageexceeded_title": "",
|
"storageexceeded_title": "",
|
||||||
"upload": "Télécharger",
|
"upload": "Télécharger",
|
||||||
@@ -1719,6 +1721,7 @@
|
|||||||
"purchases_by_vendor_detailed_date_range": "",
|
"purchases_by_vendor_detailed_date_range": "",
|
||||||
"purchases_by_vendor_summary_date_range": "",
|
"purchases_by_vendor_summary_date_range": "",
|
||||||
"schedule": "",
|
"schedule": "",
|
||||||
|
"supplement_ratio_source": "",
|
||||||
"timetickets": "",
|
"timetickets": "",
|
||||||
"timetickets_employee": "",
|
"timetickets_employee": "",
|
||||||
"timetickets_summary": ""
|
"timetickets_summary": ""
|
||||||
|
|||||||
@@ -511,6 +511,14 @@ export const TemplateList = (type, context) => {
|
|||||||
//idtype: "vendor",
|
//idtype: "vendor",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
|
supplement_ratio_source: {
|
||||||
|
title: i18n.t("reportcenter.templates.supplement_ratio_source"),
|
||||||
|
description: "",
|
||||||
|
subject: i18n.t("reportcenter.templates.supplement_ratio_source"),
|
||||||
|
key: "supplement_ratio_source",
|
||||||
|
//idtype: "vendor",
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
: {}),
|
: {}),
|
||||||
...(!type || type === "courtesycarcontract"
|
...(!type || type === "courtesycarcontract"
|
||||||
|
|||||||
Reference in New Issue
Block a user