| @@ -75,6 +75,7 @@ export interface invoiceList { | |||||
| receivedAmount: number; | receivedAmount: number; | ||||
| team: string; | team: string; | ||||
| teamCodeName: string; | teamCodeName: string; | ||||
| settled: boolean; | |||||
| } | } | ||||
| export interface invoiceColum { | export interface invoiceColum { | ||||
| @@ -142,6 +143,7 @@ export interface issuedInvoiceSearchForm { | |||||
| invoiceDateTo: string; | invoiceDateTo: string; | ||||
| dueDate: string; | dueDate: string; | ||||
| dueDateTo: string; | dueDateTo: string; | ||||
| settled: boolean; | |||||
| // issuedAmount: string; | // issuedAmount: string; | ||||
| } | } | ||||
| @@ -171,3 +171,15 @@ export function timestampToDateString(timestamp: string): string { | |||||
| // console.log(`${year}-${month}-${day}`); | // console.log(`${year}-${month}-${day}`); | ||||
| return `${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}`; | |||||
| } | |||||
| @@ -96,6 +96,9 @@ const BulkAddPaymentModal: React.FC<Props> = ({ | |||||
| description | description | ||||
| ) { | ) { | ||||
| const dividedAmount = truncateMoney(amountToDivide / numberOfEntries)!; | const dividedAmount = truncateMoney(amountToDivide / numberOfEntries)!; | ||||
| const amountForLastItem = truncateMoney( | |||||
| amountToDivide - dividedAmount * (numberOfEntries - 1), | |||||
| )!; | |||||
| return Array(numberOfEntries) | return Array(numberOfEntries) | ||||
| .fill(undefined) | .fill(undefined) | ||||
| .map((_, index) => { | .map((_, index) => { | ||||
| @@ -109,7 +112,8 @@ const BulkAddPaymentModal: React.FC<Props> = ({ | |||||
| return { | return { | ||||
| id: getID(), | id: getID(), | ||||
| amount: dividedAmount, | |||||
| amount: | |||||
| index === numberOfEntries - 1 ? amountForLastItem : dividedAmount, | |||||
| description: replaceTemplateString(description, { | description: replaceTemplateString(description, { | ||||
| "{index}": (index + 1).toString(), | "{index}": (index + 1).toString(), | ||||
| "{date}": date.format(OUTPUT_DATE_FORMAT), | "{date}": date.format(OUTPUT_DATE_FORMAT), | ||||
| @@ -70,6 +70,12 @@ const InvoiceSearch: React.FC<Props> & SubComponents = ({ invoices, projects, ab | |||||
| }, | }, | ||||
| { label: t("Issue Date"), label2: t("Issue Date To"), paramName: "invoiceDate", type: "dateRange" }, | { 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("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], | [t, invoices], | ||||
| ); | ); | ||||
| @@ -351,13 +357,33 @@ const InvoiceSearch: React.FC<Props> & SubComponents = ({ invoices, projects, ab | |||||
| [t] | [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")) { | if ((!startDate || startDate === "Invalid Date") && (!endDate || endDate === "Invalid Date")) { | ||||
| return true; | 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 startDateObj = new Date(startDate); | ||||
| const endDateObj = new Date(endDate); | const endDateObj = new Date(endDate); | ||||
| @@ -496,8 +522,9 @@ const InvoiceSearch: React.FC<Props> & SubComponents = ({ invoices, projects, ab | |||||
| (s) => (s.invoiceNo.toLowerCase().includes(query.invoiceNo.toLowerCase())) | (s) => (s.invoiceNo.toLowerCase().includes(query.invoiceNo.toLowerCase())) | ||||
| && (s.projectCode.toLowerCase().includes(query.projectCode.toLowerCase())) | && (s.projectCode.toLowerCase().includes(query.projectCode.toLowerCase())) | ||||
| && (query.team === "All" || query.team.includes(s.team)) | && (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) | |||||
| ), | ), | ||||
| ); | ); | ||||
| }} | }} | ||||
| @@ -3,7 +3,7 @@ import React from "react"; | |||||
| import InvoiceSearch from "./InvoiceSearch"; | import InvoiceSearch from "./InvoiceSearch"; | ||||
| import InvoiceSearchLoading from "./InvoiceSearchLoading"; | import InvoiceSearchLoading from "./InvoiceSearchLoading"; | ||||
| import { fetchInvoicesV3, fetchIssuedInvoices, fetchReceivedInvoices, issuedInvoiceList, issuedInvoiceResult } from "@/app/api/invoices"; | 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 { fetchTeam } from "@/app/api/team"; | ||||
| import { fetchUserAbilities, fetchUserStaff } from "@/app/utils/fetchUtil"; | import { fetchUserAbilities, fetchUserStaff } from "@/app/utils/fetchUtil"; | ||||
| import { fetchProjects } from "@/app/api/projects"; | import { fetchProjects } from "@/app/api/projects"; | ||||
| @@ -40,10 +40,11 @@ const InvoiceSearchWrapper: React.FC & SubComponents = async () => { | |||||
| projectName: invoice.projectName, | projectName: invoice.projectName, | ||||
| team: invoice.teamCodeName, | team: invoice.teamCodeName, | ||||
| teamCodeName: invoice.teamCodeName, | teamCodeName: invoice.teamCodeName, | ||||
| issuedDate: timestampToDateString(invoice.invoiceDate)!!, | |||||
| receiptDate: timestampToDateString(invoice.receiptDate)!!, | |||||
| issuedDate: timestampToDateStringV2(invoice.invoiceDate)!!, | |||||
| receiptDate: timestampToDateStringV2(invoice.receiptDate)!!, | |||||
| issuedAmount: invoice.issueAmount, | issuedAmount: invoice.issueAmount, | ||||
| receivedAmount: invoice.paidAmount | |||||
| receivedAmount: invoice.paidAmount, | |||||
| settled: invoice.paidAmount===null ? false : invoice.paidAmount === invoice.issueAmount | |||||
| } | } | ||||
| }) | }) | ||||
| @@ -568,10 +568,10 @@ const StaffUtilization: React.FC<Props> = ({ abilities, staff }) => { | |||||
| const manhoursResult = fetchResult[0].individualStaffManhoursSpentWeekly | const manhoursResult = fetchResult[0].individualStaffManhoursSpentWeekly | ||||
| const totalResult = fetchResult[0].individualStaffTotalManhoursSpentWeekly | const totalResult = fetchResult[0].individualStaffTotalManhoursSpentWeekly | ||||
| const leaveResult = fetchResult[0].individualStaffTotalLeaveHoursWeekly | 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 | var maxValue = 12 | ||||
| if (manhoursResult.length > 0) { | if (manhoursResult.length > 0) { | ||||
| for (var i = 0; i < manhoursResult.length; i++) { | for (var i = 0; i < manhoursResult.length; i++) { | ||||
| @@ -591,6 +591,15 @@ const StaffUtilization: React.FC<Props> = ({ abilities, staff }) => { | |||||
| setTotalNormalConsumption(totalResult[0].normalManhours) | setTotalNormalConsumption(totalResult[0].normalManhours) | ||||
| setTotalOtConsumption(totalResult[0].otManhours) | setTotalOtConsumption(totalResult[0].otManhours) | ||||
| setTotalLeaveHours(leaveResult[0].leaveHours) | 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<Props> = ({ abilities, staff }) => { | |||||
| const manhoursResult = fetchResult[0].individualStaffManhoursSpentByMonth | const manhoursResult = fetchResult[0].individualStaffManhoursSpentByMonth | ||||
| const totalResult = fetchResult[0].individualStaffTotalManhoursSpentByMonth | const totalResult = fetchResult[0].individualStaffTotalManhoursSpentByMonth | ||||
| const leaveResult = fetchResult[0].individualStaffTotalLeaveHoursByMonth | 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 | var maxValue = 12 | ||||
| if (manhoursResult.length > 0) { | if (manhoursResult.length > 0) { | ||||
| for (var i = 0; i < manhoursResult.length; i++) { | for (var i = 0; i < manhoursResult.length; i++) { | ||||
| @@ -623,6 +632,15 @@ const StaffUtilization: React.FC<Props> = ({ abilities, staff }) => { | |||||
| setTotalNormalConsumption(totalResult[0].normalManhours) | setTotalNormalConsumption(totalResult[0].normalManhours) | ||||
| setTotalOtConsumption(totalResult[0].otManhours) | setTotalOtConsumption(totalResult[0].otManhours) | ||||
| setTotalLeaveHours(leaveResult[0].leaveHours) | setTotalLeaveHours(leaveResult[0].leaveHours) | ||||
| }else{ | |||||
| setIndividualManhoursMaxValue(maxValue) | |||||
| setIndividualStaffProjectList(projectList) | |||||
| setIndividualStaffProjectCodeList(projectCodeList) | |||||
| setIndividualStaffManhours(result) | |||||
| setIndividualStaffManhoursPercentage(percentageList) | |||||
| setTotalNormalConsumption(0) | |||||
| setTotalOtConsumption(0) | |||||
| setTotalLeaveHours(0) | |||||
| } | } | ||||
| } | } | ||||