diff --git a/backend/api/serializers/model_year_report.py b/backend/api/serializers/model_year_report.py index 9ccebf2a4..100509728 100644 --- a/backend/api/serializers/model_year_report.py +++ b/backend/api/serializers/model_year_report.py @@ -223,6 +223,7 @@ class ModelYearReportListSerializer( obligation_credits = SerializerMethodField() ldv_sales = SerializerMethodField() supplemental_status = SerializerMethodField() + supplemental_id = SerializerMethodField() def get_ldv_sales(self, obj): request = self.context.get('request') @@ -336,13 +337,25 @@ def get_supplemental_status(self, obj): ModelYearReportStatuses.RETURNED]: return ModelYearReportStatuses.SUBMITTED.value return obj.get_validation_status_display() - + + def get_supplemental_id(self, obj): + request = self.context.get('request') + supplemental_records = SupplementalReport.objects.filter( + model_year_report=obj + ).order_by('-create_timestamp') + + if supplemental_records: + supplemental_record = supplemental_records[0] + return supplemental_record.id + + return None + class Meta: model = ModelYearReport fields = ( 'id', 'organization_name', 'model_year', 'validation_status', 'ldv_sales', 'supplier_class', 'compliant', 'obligation_total', - 'obligation_credits', 'supplemental_status' + 'obligation_credits', 'supplemental_status', 'supplemental_id' ) diff --git a/backend/api/viewsets/model_year_report.py b/backend/api/viewsets/model_year_report.py index ebf844466..4301c3da0 100644 --- a/backend/api/viewsets/model_year_report.py +++ b/backend/api/viewsets/model_year_report.py @@ -943,9 +943,10 @@ def supplemental_comment_save(self, request, pk): report = get_object_or_404(ModelYearReport, pk=pk) comment = request.data.get('from_govt_comment') director = request.data.get('director') + supplemental_id = request.data.get('supplemental_id', report.supplemental.id) if comment and director: SupplementalReportAssessmentComment.objects.create( - supplemental_report_id=report.supplemental.id, + supplemental_report_id=supplemental_id, comment=comment, to_director=True, create_user=request.user.username, @@ -953,7 +954,7 @@ def supplemental_comment_save(self, request, pk): ) elif comment and not director: assessment_comment = SupplementalReportAssessmentComment.objects.filter( - supplemental_report_id=report.supplemental.id, + supplemental_report_id=supplemental_id, to_director=False ).order_by('-update_timestamp').first() @@ -963,7 +964,7 @@ def supplemental_comment_save(self, request, pk): assessment_comment.save() else: SupplementalReportAssessmentComment.objects.create( - supplemental_report_id=report.supplemental.id, + supplemental_report_id=supplemental_id, to_director=False, comment=comment, create_user=request.user.username, diff --git a/frontend/src/app/components/Comment.js b/frontend/src/app/components/Comment.js index 37759899a..8fd3f7f1c 100644 --- a/frontend/src/app/components/Comment.js +++ b/frontend/src/app/components/Comment.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment-timezone'; -//shows array of comments like +// shows array of comments like // Name, Date: Comment const Comment = (props) => { const { diff --git a/frontend/src/app/components/CommentInput.js b/frontend/src/app/components/CommentInput.js index e29a4d41e..9159af50d 100644 --- a/frontend/src/app/components/CommentInput.js +++ b/frontend/src/app/components/CommentInput.js @@ -38,8 +38,8 @@ const CommentInput = (props) => { {!disable && buttonText && ( <> - {tooltip !== '' && } - + {tooltip !== '' && buttonDisable && } + { handleAddComment(); }} diff --git a/frontend/src/app/components/DisplayComment.js b/frontend/src/app/components/DisplayComment.js index 0876602b3..ba03a3140 100644 --- a/frontend/src/app/components/DisplayComment.js +++ b/frontend/src/app/components/DisplayComment.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment-timezone'; import parse from 'html-react-parser'; -//shows array of comments like +// shows array of comments like // Comments (bold) - Name, Date: Comment const DisplayComment = (props) => { const { diff --git a/frontend/src/compliance/components/ComplianceReportsTable.js b/frontend/src/compliance/components/ComplianceReportsTable.js index 6ecf8b26b..7a5663794 100644 --- a/frontend/src/compliance/components/ComplianceReportsTable.js +++ b/frontend/src/compliance/components/ComplianceReportsTable.js @@ -5,6 +5,7 @@ import ReactTable from '../../app/components/ReactTable'; import CustomPropTypes from '../../app/utilities/props'; import history from '../../app/History'; import ROUTES_COMPLIANCE from '../../app/routes/Compliance'; +import ROUTES_SUPPLEMENTARY from '../../app/routes/SupplementaryReport'; import formatNumeric from '../../app/utilities/formatNumeric'; import getClassAReduction from '../../app/utilities/getClassAReduction'; import getTotalReduction from '../../app/utilities/getTotalReduction'; @@ -154,8 +155,10 @@ const ComplianceReportsTable = (props) => { if (row && row.original && user) { return { onClick: () => { - const { id, validationStatus } = row.original; - if (validationStatus === 'ASSESSED' || user.isGovernment) { + const { id, validationStatus, supplementalId } = row.original; + if (supplementalId) { + history.push(ROUTES_SUPPLEMENTARY.SUPPLEMENTARY_DETAILS.replace(/:id/g, id).replace(/:supplementaryId/g, supplementalId)); + } else if (validationStatus === 'ASSESSED' || user.isGovernment) { history.push(ROUTES_COMPLIANCE.REPORT_ASSESSMENT.replace(/:id/g, id)); } else { history.push(ROUTES_COMPLIANCE.REPORT_SUPPLIER_INFORMATION.replace(/:id/g, id)); diff --git a/frontend/src/dashboard/DashboardContainer.js b/frontend/src/dashboard/DashboardContainer.js index 2ff5b80b8..a843a300f 100644 --- a/frontend/src/dashboard/DashboardContainer.js +++ b/frontend/src/dashboard/DashboardContainer.js @@ -116,7 +116,9 @@ const DashboardContainer = (props) => { } } // model year reports! - if (user.hasPermission('SUBMIT_COMPLIANCE_REPORT') || user.hasPermission('RECOMMEND_COMPLIANCE_REPORT')) { + if (user.hasPermission('SUBMIT_COMPLIANCE_REPORT') || user.hasPermission('RECOMMEND_COMPLIANCE_REPORT') + || user.hasPermission('SIGN_COMPLIANCE_REPORT') + ) { if (!user.isGovernment) { let reportsDraft = dashboard.modelYearReport.find((report) => report.status === 'DRAFT'); reportsDraft = reportsDraft ? reportsDraft.total : 0; @@ -135,7 +137,7 @@ const DashboardContainer = (props) => { reportsDraft = reportsDraft ? reportsDraft.total : 0; let reportsAnalyst = dashboard.modelYearReport.find((report) => report.status === 'SUBMITTED'); reportsAnalyst = reportsAnalyst ? reportsAnalyst.total : 0; - reportsAnalyst += reportsDraft + reportsAnalyst += reportsDraft; let reportsReturned = dashboard.modelYearReport.find((report) => report.status === 'RETURNED'); reportsReturned = reportsReturned ? reportsReturned.total : 0; let reportsDirector = dashboard.modelYearReport.find((report) => report.status === 'RECOMMENDED'); diff --git a/frontend/src/supplementary/SupplementaryContainer.js b/frontend/src/supplementary/SupplementaryContainer.js index a6455202c..c3f7a2284 100644 --- a/frontend/src/supplementary/SupplementaryContainer.js +++ b/frontend/src/supplementary/SupplementaryContainer.js @@ -22,7 +22,7 @@ const SupplementaryContainer = (props) => { const [files, setFiles] = useState([]); const [deleteFiles, setDeleteFiles] = useState([]); const [errorMessage, setErrorMessage] = useState(null); - const [newData, setNewData] = useState({ zevSales: {}, creditActivity: [] }); + const [newData, setNewData] = useState({ zevSales: [], creditActivity: [] }); let [obligationDetails, setObligationDetails] = useState([]); const [ldvSales, setLdvSales] = useState(); const [ratios, setRatios] = useState(); @@ -72,6 +72,7 @@ const SupplementaryContainer = (props) => { 'creditsIssuedSales', 'initiativeAgreement', 'purchaseAgreement', + 'pendingBalance', 'transfersIn', ].indexOf(each.category) >= 0) { const found = creditActivity.findIndex((activity) => ( @@ -117,14 +118,40 @@ const SupplementaryContainer = (props) => { const handleAddIdirComment = () => { const commentData = { fromGovtComment: idirComment, director: true }; - axios.post(ROUTES_SUPPLEMENTARY.COMMENT_SAVE.replace(':id', id), commentData).then(() => { - history.push(ROUTES_COMPLIANCE.REPORTS); - if (supplementaryId) { - history.replace(ROUTES_SUPPLEMENTARY.SUPPLEMENTARY_DETAILS.replace(':id', id).replace(':supplementaryId', supplementaryId)); - } else { - history.replace(ROUTES_SUPPLEMENTARY.SUPPLEMENTARY_DETAILS.replace(':id', id).replace(':supplementaryId', '')); + if (query.reassessment === 'Y') { + const zevSales = newData && newData.zevSales && newData.zevSales.filter((each) => Number(each.sales) > 0); + + const data = { + ...newData, + zevSales, + status: 'DRAFT', + }; + + if (analystAction) { + data.analystAction = true; + data.penalty = supplementaryAssessmentData.supplementaryAssessment.assessmentPenalty; + data.description = supplementaryAssessmentData.supplementaryAssessment.decision.id; } - }); + + axios.patch(ROUTES_SUPPLEMENTARY.SAVE.replace(':id', id), data).then((response) => { + const { id: supplementalId } = response.data; + commentData.supplementalId = supplementalId; + + axios.post(ROUTES_SUPPLEMENTARY.COMMENT_SAVE.replace(':id', id), commentData).then(() => { + history.push(ROUTES_COMPLIANCE.REPORTS); + history.replace(ROUTES_SUPPLEMENTARY.SUPPLEMENTARY_DETAILS.replace(':id', id).replace(':supplementaryId', supplementalId)); + }); + }); + } else { + axios.post(ROUTES_SUPPLEMENTARY.COMMENT_SAVE.replace(':id', id), commentData).then(() => { + history.push(ROUTES_COMPLIANCE.REPORTS); + if (supplementaryId) { + history.replace(ROUTES_SUPPLEMENTARY.SUPPLEMENTARY_DETAILS.replace(':id', id).replace(':supplementaryId', supplementaryId)); + } else { + history.replace(ROUTES_SUPPLEMENTARY.SUPPLEMENTARY_DETAILS.replace(':id', id).replace(':supplementaryId', '')); + } + }); + } }; const handleCommentChangeIdir = (text) => { @@ -245,6 +272,7 @@ const SupplementaryContainer = (props) => { if ((status === 'ASSESSED' && paramNewReport) || (status === 'SUBMITTED' && analystAction)) { status = 'DRAFT'; } + const uploadPromises = handleUpload(id); Promise.all(uploadPromises).then((attachments) => { const evidenceAttachments = {}; @@ -252,9 +280,12 @@ const SupplementaryContainer = (props) => { evidenceAttachments.attachments = attachments; } + const zevSales = newData && newData.zevSales && newData.zevSales.filter((each) => Number(each.sales) > 0); + if (status) { const data = { ...newData, + zevSales, status, evidenceAttachments, deleteFiles, diff --git a/frontend/src/supplementary/components/CreditActivity.js b/frontend/src/supplementary/components/CreditActivity.js index 3e52027cf..83c6ddbf4 100644 --- a/frontend/src/supplementary/components/CreditActivity.js +++ b/frontend/src/supplementary/components/CreditActivity.js @@ -296,7 +296,7 @@ const CreditActivity = (props) => { {formatNumeric(leftoverReduction, 2)} - + {newLdvSales && ( {formatNumeric(newLeftoverReduction, 2)} )} @@ -359,7 +359,7 @@ const CreditActivity = (props) => { 0.00 )} - + {getNewDeduction(deduction, newDeductions).creditA > 0 && ( -{formatNumeric(getNewDeduction(deduction, newDeductions).creditA, 2)} )} @@ -367,7 +367,7 @@ const CreditActivity = (props) => { 0.00 )} - + {getNewDeduction(deduction, newDeductions).creditB > 0 && ( -{formatNumeric(getNewDeduction(deduction, newDeductions).creditB, 2)} )} diff --git a/frontend/src/supplementary/components/SupplementaryDetailsPage.js b/frontend/src/supplementary/components/SupplementaryDetailsPage.js index 4f604a29f..15630b522 100644 --- a/frontend/src/supplementary/components/SupplementaryDetailsPage.js +++ b/frontend/src/supplementary/components/SupplementaryDetailsPage.js @@ -240,12 +240,6 @@ const SupplementaryDetailsPage = (props) => { )} - {currentStatus !== 'DRAFT' && commentArray && commentArray.bceidComment && commentArray.bceidComment.length > 0 - && ( - - )} {isEditable && user.isGovernment && ( @@ -262,7 +256,6 @@ const SupplementaryDetailsPage = (props) => { title={analystAction ? 'Add comment to director: ' : 'Add comment to the analyst'} buttonText="Add Comment" handleAddComment={handleAddIdirComment} - buttonDisable={!details.id} tooltip="Please save the report first, before adding comments" /> @@ -320,7 +313,7 @@ const SupplementaryDetailsPage = (props) => { setUploadFiles={setUploadFiles} /> )} - {user.isGovernment && details && currentStatus === 'SUBMITTED' + {details && details.status === 'SUBMITTED' && ((details.fromSupplierComments && details.fromSupplierComments.length > 0) || (details.attachments && details.attachments.length > 0)) && ( diff --git a/frontend/src/supplementary/components/ZevSales.js b/frontend/src/supplementary/components/ZevSales.js index 13f471e60..ef439ab9c 100644 --- a/frontend/src/supplementary/components/ZevSales.js +++ b/frontend/src/supplementary/components/ZevSales.js @@ -25,7 +25,7 @@ const ZevSales = (props) => { defaultValue={item.original.newData.sales ? item.original.newData.sales : item.original.oldData.sales} onChange={handleInputChange} readOnly={!isEditable} - className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.sales !== item.original.oldData.sales ? 'highlight' : ''}`} + className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.sales && item.original.newData.sales !== item.original.oldData.sales ? 'highlight' : ''}`} /> > ), @@ -47,7 +47,7 @@ const ZevSales = (props) => { maxLength="4" defaultValue={item.original.newData.modelYear ? item.original.newData.modelYear : item.original.oldData.modelYear} readOnly={!isEditable} - className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.modelYear !== item.original.oldData.modelYear ? 'highlight' : ''}`} + className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.modelYear && item.original.newData.modelYear !== item.original.oldData.modelYear ? 'highlight' : ''}`} /> > ), @@ -68,7 +68,7 @@ const ZevSales = (props) => { onChange={handleInputChange} defaultValue={item.original.newData.make ? item.original.newData.make : item.original.oldData.make} readOnly={!isEditable} - className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.make !== item.original.oldData.make ? 'highlight' : ''}`} + className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.make && item.original.newData.make !== item.original.oldData.make ? 'highlight' : ''}`} /> > ), @@ -89,7 +89,7 @@ const ZevSales = (props) => { onChange={handleInputChange} defaultValue={item.original.newData.modelName ? item.original.newData.modelName : item.original.oldData.model} readOnly={!isEditable} - className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.modelName !== item.original.oldData.model ? 'highlight' : ''}`} + className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.modelName && item.original.newData.modelName !== item.original.oldData.model ? 'highlight' : ''}`} /> > ), @@ -110,7 +110,7 @@ const ZevSales = (props) => { onChange={handleInputChange} defaultValue={item.original.newData.vehicleZevType ? item.original.newData.vehicleZevType : item.original.oldData.zevType} readOnly={!isEditable} - className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.vehicleZevType !== item.original.oldData.zevType ? 'highlight' : ''}`} + className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.vehicleZevType && item.original.newData.vehicleZevType !== item.original.oldData.zevType ? 'highlight' : ''}`} /> > ), @@ -131,7 +131,7 @@ const ZevSales = (props) => { onChange={handleInputChange} defaultValue={item.original.newData.range ? item.original.newData.range : item.original.oldData.range} readOnly={!isEditable} - className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.range !== item.original.oldData.range ? 'highlight' : ''}`} + className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.range && item.original.newData.range !== item.original.oldData.range ? 'highlight' : ''}`} /> > ), @@ -153,7 +153,7 @@ const ZevSales = (props) => { onChange={handleInputChange} defaultValue={item.original.newData.zevClass ? item.original.newData.zevClass : item.original.oldData.zevClass} readOnly={!isEditable} - className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.zevClass !== item.original.oldData.zevClass ? 'highlight' : ''}`} + className={`${!isEditable ? 'supplementary-input-disabled' : ''} ${item.original.newData.zevClass && item.original.newData.zevClass !== item.original.oldData.zevClass ? 'highlight' : ''}`} /> > ),