From 47d3dd17847c4d6093e790eb18473751924433ca Mon Sep 17 00:00:00 2001 From: "MSI\\2Fi" Date: Wed, 18 Dec 2024 15:26:27 +0800 Subject: [PATCH 1/2] 1. Update invoice date format from yyyy-MM-dd to dd/MM/yyyy 2. Add settled and unsettled filter option 3. Update staff uitlization, submitted record --- src/app/api/invoices/index.ts | 2 ++ src/app/utils/formatUtil.ts | 12 +++++++ .../InvoiceSearch/InvoiceSearch.tsx | 35 ++++++++++++++++--- .../InvoiceSearch/InvoiceSearchWrapper.tsx | 9 ++--- .../StaffUtilization/StaffUtilization.tsx | 34 +++++++++++++----- 5 files changed, 76 insertions(+), 16 deletions(-) diff --git a/src/app/api/invoices/index.ts b/src/app/api/invoices/index.ts index adab207..b456ca0 100644 --- a/src/app/api/invoices/index.ts +++ b/src/app/api/invoices/index.ts @@ -75,6 +75,7 @@ export interface invoiceList { receivedAmount: number; team: string; teamCodeName: string; + settled: boolean; } export interface invoiceColum { @@ -142,6 +143,7 @@ export interface issuedInvoiceSearchForm { invoiceDateTo: string; dueDate: string; dueDateTo: string; + settled: boolean; // issuedAmount: string; } diff --git a/src/app/utils/formatUtil.ts b/src/app/utils/formatUtil.ts index a35dd02..15c7d82 100644 --- a/src/app/utils/formatUtil.ts +++ b/src/app/utils/formatUtil.ts @@ -171,3 +171,15 @@ export function timestampToDateString(timestamp: string): string { // console.log(`${year}-${month}-${day}`); return `${year}-${month}-${day}`; } + +export function timestampToDateStringV2(timestamp: string): string { + if (timestamp === null) { + return "-"; + } + const date = new Date(timestamp); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + // console.log(`${year}-${month}-${day}`); + return `${day}/${month}/${year}`; +} diff --git a/src/components/InvoiceSearch/InvoiceSearch.tsx b/src/components/InvoiceSearch/InvoiceSearch.tsx index d40badb..f7c3abe 100644 --- a/src/components/InvoiceSearch/InvoiceSearch.tsx +++ b/src/components/InvoiceSearch/InvoiceSearch.tsx @@ -70,6 +70,12 @@ const InvoiceSearch: React.FC & SubComponents = ({ invoices, projects, ab }, { label: t("Issue Date"), label2: t("Issue Date To"), paramName: "invoiceDate", type: "dateRange" }, { label: t("Settle Date"), label2: t("Settle Date To"), paramName: "dueDate", type: "dateRange" }, + { + label: t("Settled"), + paramName: "settled", + type: "select", + options: [t("Settled"), t("Unsettled")], + }, ], [t, invoices], ); @@ -351,13 +357,33 @@ const InvoiceSearch: React.FC & SubComponents = ({ invoices, projects, ab [t] ) - function isDateInRange(dateToCheck: string, startDate: string, endDate: string): boolean { + function convertDateFormat(dateString: string) { + // Split the input date string by '/' + const parts = dateString.split('/'); + + // Extract day, month, and year + const day = parts[0]; + const month = parts[1]; + const year = parts[2]; + + // Return the formatted date string + return `${year}-${month}-${day}`; +} + + function isDateInRange(dateToCheck: string, startDate: string, endDate: string, dash: boolean): boolean { if ((!startDate || startDate === "Invalid Date") && (!endDate || endDate === "Invalid Date")) { return true; } + let tempDateToCheckObj + if(dash){ + tempDateToCheckObj = new Date(dateToCheck) + }else{ + tempDateToCheckObj = new Date(convertDateFormat(dateToCheck)) + } + - const dateToCheckObj = new Date(dateToCheck); + const dateToCheckObj = tempDateToCheckObj; const startDateObj = new Date(startDate); const endDateObj = new Date(endDate); @@ -496,8 +522,9 @@ const InvoiceSearch: React.FC & SubComponents = ({ invoices, projects, ab (s) => (s.invoiceNo.toLowerCase().includes(query.invoiceNo.toLowerCase())) && (s.projectCode.toLowerCase().includes(query.projectCode.toLowerCase())) && (query.team === "All" || query.team.includes(s.team)) - && (isDateInRange(s.issuedDate, query.invoiceDate ?? undefined, query.invoiceDateTo ?? undefined)) - && (isDateInRange(s.receiptDate, query.dueDate ?? undefined, query.dueDateTo ?? undefined)) + && (isDateInRange(s.issuedDate, query.invoiceDate ?? undefined, query.invoiceDateTo ?? undefined, false)) + && (isDateInRange(s.receiptDate, query.dueDate ?? undefined, query.dueDateTo ?? undefined, false)) + && (query.settled === "All" || (query.settled === t("Settled")) === s.settled) ), ); }} diff --git a/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx b/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx index 6a4bb0e..c5599f1 100644 --- a/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx +++ b/src/components/InvoiceSearch/InvoiceSearchWrapper.tsx @@ -3,7 +3,7 @@ import React from "react"; import InvoiceSearch from "./InvoiceSearch"; import InvoiceSearchLoading from "./InvoiceSearchLoading"; import { fetchInvoicesV3, fetchIssuedInvoices, fetchReceivedInvoices, issuedInvoiceList, issuedInvoiceResult } from "@/app/api/invoices"; -import { INPUT_DATE_FORMAT, convertDateArrayToString, convertDateToString, moneyFormatter, timestampToDateString } from "@/app/utils/formatUtil"; +import { INPUT_DATE_FORMAT, convertDateArrayToString, convertDateToString, moneyFormatter, timestampToDateString, timestampToDateStringV2 } from "@/app/utils/formatUtil"; import { fetchTeam } from "@/app/api/team"; import { fetchUserAbilities, fetchUserStaff } from "@/app/utils/fetchUtil"; import { fetchProjects } from "@/app/api/projects"; @@ -40,10 +40,11 @@ const InvoiceSearchWrapper: React.FC & SubComponents = async () => { projectName: invoice.projectName, team: invoice.teamCodeName, teamCodeName: invoice.teamCodeName, - issuedDate: timestampToDateString(invoice.invoiceDate)!!, - receiptDate: timestampToDateString(invoice.receiptDate)!!, + issuedDate: timestampToDateStringV2(invoice.invoiceDate)!!, + receiptDate: timestampToDateStringV2(invoice.receiptDate)!!, issuedAmount: invoice.issueAmount, - receivedAmount: invoice.paidAmount + receivedAmount: invoice.paidAmount, + settled: invoice.paidAmount===null ? false : invoice.paidAmount === invoice.issueAmount } }) diff --git a/src/components/StaffUtilization/StaffUtilization.tsx b/src/components/StaffUtilization/StaffUtilization.tsx index 9c585c4..645098a 100644 --- a/src/components/StaffUtilization/StaffUtilization.tsx +++ b/src/components/StaffUtilization/StaffUtilization.tsx @@ -568,10 +568,10 @@ const StaffUtilization: React.FC = ({ abilities, staff }) => { const manhoursResult = fetchResult[0].individualStaffManhoursSpentWeekly const totalResult = fetchResult[0].individualStaffTotalManhoursSpentWeekly const leaveResult = fetchResult[0].individualStaffTotalLeaveHoursWeekly - const result = [] - const projectList = [] - const projectCodeList = [] - const percentageList = [] + const result: any[] = [] + const projectList: any[] = [] + const projectCodeList: any[] = [] + const percentageList: any[] = [] var maxValue = 12 if (manhoursResult.length > 0) { for (var i = 0; i < manhoursResult.length; i++) { @@ -591,6 +591,15 @@ const StaffUtilization: React.FC = ({ abilities, staff }) => { setTotalNormalConsumption(totalResult[0].normalManhours) setTotalOtConsumption(totalResult[0].otManhours) setTotalLeaveHours(leaveResult[0].leaveHours) + }else{ + setIndividualManhoursMaxValue(maxValue) + setIndividualStaffProjectList(projectList) + setIndividualStaffProjectCodeList(projectCodeList) + setIndividualStaffManhours(result) + setIndividualStaffManhoursPercentage(percentageList) + setTotalNormalConsumption(0) + setTotalOtConsumption(0) + setTotalLeaveHours(0) } } @@ -600,10 +609,10 @@ const StaffUtilization: React.FC = ({ abilities, staff }) => { const manhoursResult = fetchResult[0].individualStaffManhoursSpentByMonth const totalResult = fetchResult[0].individualStaffTotalManhoursSpentByMonth const leaveResult = fetchResult[0].individualStaffTotalLeaveHoursByMonth - const result = [] - const projectList = [] - const projectCodeList = [] - const percentageList = [] + const result: any[] = [] + const projectList: any[] = [] + const projectCodeList: any[] = [] + const percentageList: any[] = [] var maxValue = 12 if (manhoursResult.length > 0) { for (var i = 0; i < manhoursResult.length; i++) { @@ -623,6 +632,15 @@ const StaffUtilization: React.FC = ({ abilities, staff }) => { setTotalNormalConsumption(totalResult[0].normalManhours) setTotalOtConsumption(totalResult[0].otManhours) setTotalLeaveHours(leaveResult[0].leaveHours) + }else{ + setIndividualManhoursMaxValue(maxValue) + setIndividualStaffProjectList(projectList) + setIndividualStaffProjectCodeList(projectCodeList) + setIndividualStaffManhours(result) + setIndividualStaffManhoursPercentage(percentageList) + setTotalNormalConsumption(0) + setTotalOtConsumption(0) + setTotalLeaveHours(0) } } From 236f1446579208cd4073d512db9ae3b10b991221 Mon Sep 17 00:00:00 2001 From: Wayne Date: Wed, 18 Dec 2024 22:44:36 +0900 Subject: [PATCH 2/2] Adjust last bulk milestone payment to be the remaining amount to divide --- src/components/CreateProject/BulkAddPaymentModal.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/CreateProject/BulkAddPaymentModal.tsx b/src/components/CreateProject/BulkAddPaymentModal.tsx index ff4594e..0d61bb6 100644 --- a/src/components/CreateProject/BulkAddPaymentModal.tsx +++ b/src/components/CreateProject/BulkAddPaymentModal.tsx @@ -96,6 +96,9 @@ const BulkAddPaymentModal: React.FC = ({ description ) { const dividedAmount = truncateMoney(amountToDivide / numberOfEntries)!; + const amountForLastItem = truncateMoney( + amountToDivide - dividedAmount * (numberOfEntries - 1), + )!; return Array(numberOfEntries) .fill(undefined) .map((_, index) => { @@ -109,7 +112,8 @@ const BulkAddPaymentModal: React.FC = ({ return { id: getID(), - amount: dividedAmount, + amount: + index === numberOfEntries - 1 ? amountForLastItem : dividedAmount, description: replaceTemplateString(description, { "{index}": (index + 1).toString(), "{date}": date.format(OUTPUT_DATE_FORMAT),