From 3bdbb3f19dd9c186e7c2b558eb94efa2a54c4846 Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Tue, 14 May 2024 19:10:28 +0800 Subject: [PATCH] update export gdn --- src/layout/MainLayout/Header/index.js | 9 + src/pages/DemandNote/Export/DataGrid.js | 204 +++++++++++++ src/pages/DemandNote/Export/SearchForm.js | 278 ++++++++++++++++++ src/pages/DemandNote/Export/index.js | 103 +++++++ src/pages/Holiday/DataGrid.js | 4 +- src/pages/Holiday/index.js | 2 +- .../ListPanel/PendingPaymentTab.js | 38 ++- src/pages/PublicNotice/Search_GLD/DataGrid.js | 7 +- src/routes/GLDUserRoutes.js | 7 + src/translations/en.json | 2 +- src/translations/zh-CN.json | 2 +- src/translations/zh-HK.json | 2 +- src/utils/ApiPathConst.js | 4 + 13 files changed, 637 insertions(+), 25 deletions(-) create mode 100644 src/pages/DemandNote/Export/DataGrid.js create mode 100644 src/pages/DemandNote/Export/SearchForm.js create mode 100644 src/pages/DemandNote/Export/index.js diff --git a/src/layout/MainLayout/Header/index.js b/src/layout/MainLayout/Header/index.js index a85a0c2..2f570ba 100644 --- a/src/layout/MainLayout/Header/index.js +++ b/src/layout/MainLayout/Header/index.js @@ -149,6 +149,15 @@ function Header(props) { <> } + { + isGranted("MAINTAIN_DEMANDNOTE") ? +
  • + Export for GDN +
  • + : + <> + } + : diff --git a/src/pages/DemandNote/Export/DataGrid.js b/src/pages/DemandNote/Export/DataGrid.js new file mode 100644 index 0000000..c0cc4de --- /dev/null +++ b/src/pages/DemandNote/Export/DataGrid.js @@ -0,0 +1,204 @@ +// material-ui +import * as React from 'react'; +import * as UrlUtils from "utils/ApiPathConst"; +import * as DateUtils from "utils/DateUtils"; +import * as FormatUtils from "utils/FormatUtils"; +// import * as PublicNoteStatusUtils from "utils/statusUtils/PublicNoteStatusUtils" +import { FiDataGrid } from "components/FiDataGrid"; +import { clickableLink } from 'utils/CommonFunction'; +// ==============================|| EVENT TABLE ||============================== // + +export default function SearchPublicNoticeTable({ searchCriteria,}) { + const _sx = { + padding: "4 2 4 2", + boxShadow: 1, + border: 1, + borderColor: '#DDD', + '& .MuiDataGrid-cell': { + borderTop: 1, + borderBottom: 1, + borderColor: "#EEE" + }, + '& .MuiDataGrid-footerContainer': { + border: 1, + borderColor: "#EEE" + } + } + const [_searchCriteria, set_searchCriteria] = React.useState(searchCriteria); + React.useEffect(() => { + set_searchCriteria(searchCriteria); + }, [searchCriteria]); + + const handleEditClick = (params) => () => { + window.open('/application/' + params.row.id); + }; + + const columns = [ + { + id: 'itemNo', + field: 'itemNo', + headerName: 'Item No.', + flex: 1, + minWidth: 50, + renderCell: (params) => { + // const regex = /^(\D+)(\d+)$/; + // const [, category, itemNo] = params.row.groupNo.match(regex); + const itemNo = parseInt(params.row.groupNo.substring(1)) + return itemNo + }, + }, + { + field: 'category', + headerName: 'Category', + flex: 1, + minWidth: 50, + renderCell: (params) => { + const category = params.row.groupNo.substring(0, 1); + return category + } + }, + { + id: 'appNo', + field: 'appNo', + headerName: 'App No.', + flex: 1, + minWidth: 50, + renderCell: (params) => { + return clickableLink('/application/' + params.row.id, params.row.appNo) + }, + }, + { + id: 'user', + field: 'user', + headerName: 'User', + flex: 1, + minWidth: 50, + renderCell: (params) => { + // let user = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; + let user = params.row.contactPerson; + // user = user != null ? user : ""; + if (params.row.sysType != null && params.row.sysType == "dummy"){ + user = "Dummy - PD" + } + return
    + {user} +
    ; + } + }, + { + id: 'contactPerson', + field: 'contactPerson', + headerName: 'Customer Name', + flex: 1, + minWidth: 50, + renderCell: (params) => { + let company = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; + company = company != null ? company : ""; + if (params.row.sysType != null && params.row.sysType == "dummy"){ + company = params.row.contactPerson + } + return
    + {company} +
    ; + } + }, + { + id: 'careOf', + field: 'careOf', + headerName: "Customer's Client/Case Node.", + flex: 2, + minWidth: 200, + renderCell: (params) => { + return <>{(params?.value)}; + } + }, + { + id: 'dimension', + field: 'dimension', + headerName: 'Dimension', + flex: 1, + minWidth: 100, + valueGetter: (params) => { + let length = params.row.length + let colCount = params.row.colCount + let noOfPages = params.row.noOfPages + let dimension = 0 + if (noOfPages != null){ + dimension = length*colCount*noOfPages + }else{ + dimension = length*colCount + } + return dimension; + } + }, + { + id: 'fee', + field: 'fee', + headerName: 'Amount(HK$)', + flex: 1, + minWidth: 100, + valueGetter: (params) => { + return FormatUtils.currencyFormat(params?.value); + } + }, + { + id: 'emailAddress', + field: 'emailAddress', + headerName: 'Contact E-mail Address', + flex:2, + minWidth: 100, + valueGetter: (params) => { + let email = params.row.emailBus != null && params.row.emailBus != "" ? params.row.emailBus : params.row.emailAddress; + email = email != null ? email : ""; + if (params.row.sysType != null && params.row.sysType == "dummy"){ + email = params.row.remarks + } + return email; + }, + }, + { + id: 'deadline', + field: 'deadline', + headerName: 'Payment Deadline', + flex: 2, + minWidth: 100, + renderCell: (params) => { + return <>{DateUtils.dateStr(params.row.closingDate) + " 12noon"}; + } + }, + { + id: 'exported', + field: 'exported', + headerName: 'Exported', + flex: 1, + minWidth: 50, + renderCell: (params) => { + let exported = params.row.exported ? "Y" : "N"; + return exported + } + }, + ]; + + return ( +
    + + 'auto'} + columns={columns} + customPageSize={10} + onRowDoubleClick={handleEditClick} + doLoad={{ + url: _searchCriteria.issueId>0?UrlUtils.GDN_VIEW:null, + params: { + issueId: _searchCriteria.issueId + }, + // callback: (responseData) => { + // setPaymentCount(responseData.paymentCount); + // setPublishCount(responseData.publishCount); + // } + }} + /> +
    + ); +} diff --git a/src/pages/DemandNote/Export/SearchForm.js b/src/pages/DemandNote/Export/SearchForm.js new file mode 100644 index 0000000..849867a --- /dev/null +++ b/src/pages/DemandNote/Export/SearchForm.js @@ -0,0 +1,278 @@ +// material-ui +import { + Button, + Grid, TextField, + Autocomplete, + Typography, + Dialog, DialogTitle, DialogContent, DialogActions, +} from '@mui/material'; +import MainCard from "components/MainCard"; +import * as React from "react"; +import * as FormatUtils from "utils/FormatUtils"; +import * as DateUtils from "utils/DateUtils"; +import * as UrlUtils from "utils/ApiPathConst"; +import * as HttpUtils from "utils/HttpUtils"; +// import { useNavigate } from "react-router-dom"; +// import { notifyDownloadSuccess } from 'utils/CommonFunction'; +import { PNSPS_BUTTON_THEME } from "../../../themes/buttonConst"; +import { ThemeProvider } from "@emotion/react"; +import { useIntl } from "react-intl"; + + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + + +const SearchPublicNoticeForm = ({ applySearch, issueComboData }) => { + + const [isFailPopUp, setIsFailPopUp] = React.useState(false); + const [failText, setFailText] = React.useState(""); + + const [confirmPopUp, setConfirmPopUp] = React.useState(false); + const [dueDate, setDueDate] = React.useState(DateUtils.dateValue(DateUtils.dateValue((new Date().setDate(new Date().getDate() + 1))))); + + // const [isSuccessPopUp, setIsSuccessPopUp] = React.useState(false); + // const [resultCount, setResultCount] = React.useState(0); + // const [dnIdList, setDnIdList] = React.useState([]); + + const [issueSelected, setIssueSelected] = React.useState({}); + // const [paymentCount, setPaymentCount] = React.useState(0); + // const [publishCount, setPublishCount] = React.useState(0); + const [issueCombo, setIssueCombo] = React.useState([]); + const [waitDownload, setWaitDownload] = React.useState(false); + // const navigate = useNavigate() + + const intl = useIntl(); + const { locale } = intl; + + React.useEffect(() => { + if (issueComboData && issueComboData.length > 0) { + setIssueCombo(issueComboData); + } + }, [issueComboData]); + + // React.useEffect(() => { + // setPaymentCount(_paymentCount); + // }, [_paymentCount]); + + // React.useEffect(() => { + // setPublishCount(_publishCount); + // }, [_publishCount]); + + React.useEffect(() => { + onPreView(); + }, [issueSelected]); + + function getIssueLabel(data) { + let issueYear = data.issueYear + let volume = data.volume; + let issueNo = data.issueNo; + let issueDate = data.issueDate; + if (locale === 'zh-HK') { + return issueYear + + " 第" + volume + "卷," + + " 第" + issueNo + "期," + + " " + DateUtils.dateFormat(issueDate, "YYYY年MM月DD日") + + " (" + DateUtils.getWeekdayStr_ZH(issueDate) + ")"; + } else if (locale === 'zh-CN') { + return issueYear + + " 第" + volume + "卷," + + " 第" + issueNo + "期," + + " " + DateUtils.dateFormat(issueDate, "YYYY年MM月DD日") + + " (" + DateUtils.getWeekdayStr_CN(issueDate) + ")"; + } + return issueYear + + " Vol. " + FormatUtils.zeroPad(volume, 3) + + ", No. " + FormatUtils.zeroPad(issueNo, 2) + + ", " + DateUtils.dateFormat(issueDate, "D MMM YYYY (ddd)"); + } + + const onSubmit = () => { + if (!issueSelected?.id) { + setFailText("Fail Create: Please select Gazette Issue."); + setIsFailPopUp(true); + return; + } else { + setDueDate(DateUtils.dateValue((new Date().setDate(new Date().getDate() + 1)))); + doDnExport(); + } + }; + + const doDnExport= () => { + // setConfirmPopUp(false); + setWaitDownload(true) + HttpUtils.fileDownload({ + url: UrlUtils.GDN_EXPORT, + params: { + issueId: issueSelected.id + }, + onResponse: () => { + setTimeout(()=> setWaitDownload(false), 500) + } + }); + } + + // const fileDownload = () => { + // HttpUtils.fileDownload({ + // method: 'post', + // url: UrlUtils.DEMAND_NOTE_EXPORT, + // params: { + // "dnIdList": dnIdList + // }, + // onSuccess: function () { + // notifyDownloadSuccess(); + // } + // }); + // } + + // const onNavigate = () => { + // setIsSuccessPopUp(false); + // if (resultCount > 0) + // navigate('/paymentPage/demandNote'); + // }; + + const onPreView = () => { + if (!issueSelected?.id) { + return; + } + const temp = { + issueId: issueSelected.id, + }; + applySearch(temp); + }; + + return ( + + +
    + {/*row 1*/} + + {/*row 1*/} + + + Please Select Gazette Issue : + + + {/*row 2*/} + + + getIssueLabel(option)} + onChange={(event, newValue) => { + if (newValue !== null) { + setIssueSelected(newValue); + } + }} + renderInput={(params) => ( + + )} + /> + + + + + + + + + {/* + + + Pending Payment: {paymentCount} + + + + Pending Publish: {publishCount} + + + */} + +
    +
    + setIsFailPopUp(false)} + PaperProps={{ + sx: { + minWidth: '40vw', + maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, + maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } + } + }} + > + Action Fail + + {failText} + + + + + +
    +
    + setConfirmPopUp(false)} + PaperProps={{ + sx: { + minWidth: '40vw', + maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' }, + maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' } + } + }} + > + Create Confirm + + + + Due Date: + + + + { + setDueDate(newValue.currentTarget.value) + }} + InputLabelProps={{ + shrink: true + }} + /> + + + + + + + + +
    +
    + ); +}; + +export default SearchPublicNoticeForm; diff --git a/src/pages/DemandNote/Export/index.js b/src/pages/DemandNote/Export/index.js new file mode 100644 index 0000000..16d3e61 --- /dev/null +++ b/src/pages/DemandNote/Export/index.js @@ -0,0 +1,103 @@ +// material-ui +import { + Grid, + Typography, + Stack +} from '@mui/material'; +import MainCard from "components/MainCard"; +import * as UrlUtils from "utils/ApiPathConst"; +import * as HttpUtils from "utils/HttpUtils"; +import * as React from "react"; + + +import Loadable from 'components/Loadable'; +const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); +const SearchForm = Loadable(React.lazy(() => import('./SearchForm'))); +const EventTable = Loadable(React.lazy(() => import('./DataGrid'))); +import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' + +const BackgroundHead = { + backgroundImage: `url(${titleBackgroundImg})`, + width: '100%', + height: '100%', + backgroundSize: 'contain', + backgroundRepeat: 'no-repeat', + backgroundColor: '#0C489E', + backgroundPosition: 'right' +} + +// ==============================|| DASHBOARD - DEFAULT ||============================== // + +const Index = () => { + + const [issueCombo, setIssueCombo] = React.useState([]); + const [searchCriteria, setSearchCriteria] = React.useState({}); + const [onReady, setOnReady] = React.useState(false); + + // const [paymentCount, setPaymentCount] = React.useState(0); + // const [publishCount, setPublishCount] = React.useState(0); + + React.useEffect(() => { + getIssueCombo(); + }, []); + + React.useEffect(() => { + setOnReady(true); + }, [searchCriteria]); + + function getIssueCombo() { + HttpUtils.get({ + url: UrlUtils.GET_ISSUE_COMBO, + onSuccess: function (responseData) { + let combo = responseData; + setIssueCombo(combo); + } + }); + } + + + function applySearch(input) { + setSearchCriteria(input); + } + + return ( + !onReady ? + + : + + +
    + + + Export for GDN (Non Creditor) + + +
    +
    + {/*row 1*/} + + + + {/*row 2*/} + + + + + +
    + ); +}; + +export default Index; diff --git a/src/pages/Holiday/DataGrid.js b/src/pages/Holiday/DataGrid.js index 5120dff..bca77f6 100644 --- a/src/pages/Holiday/DataGrid.js +++ b/src/pages/Holiday/DataGrid.js @@ -15,8 +15,8 @@ export default function HolidayTable({ recordList }) { // const navigate = useNavigate() useEffect(() => { - // console.log(recordList) - setRows(recordList); + console.log(recordList) + setRows(recordList.records); }, [recordList]); const columns = [ diff --git a/src/pages/Holiday/index.js b/src/pages/Holiday/index.js index 6401ffe..9a7d59d 100644 --- a/src/pages/Holiday/index.js +++ b/src/pages/Holiday/index.js @@ -73,7 +73,7 @@ const Index = () => { url: UrlUtils.GET_HOLIDAY, params: searchCriteria, onSuccess: (responseData) => { - // console.log(comboData) + // console.log(responseData) setRecord(responseData); if (comboData.length == 0) { loadCombo(); diff --git a/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js b/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js index 24aaaa0..3d7fce2 100644 --- a/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js +++ b/src/pages/PublicNotice/ListPanel/PendingPaymentTab.js @@ -24,6 +24,7 @@ import { useNavigate } from "react-router-dom"; import { isORGLoggedIn, } from "utils/Utils"; +import { dateStr } from "utils/DateUtils"; import { ThemeProvider, useTheme } from "@emotion/react"; import { PNSPS_BUTTON_THEME } from "../../../themes/buttonConst"; import { FormattedMessage, useIntl } from "react-intl"; @@ -210,25 +211,30 @@ export default function SubmittedTab({ setCount, url }) { }, }, { - id: 'paymentMethod', - field: 'paymentMethod', - headerName: intl.formatMessage({ id: 'paymentMethod' }), + id: 'paymentMethodAndDeadLine', + field: 'paymentMethodAndDeadLine', + headerName: intl.formatMessage({ id: 'paymentMethodAndDeadLine' }), width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, - renderCell: (params) => { - return params.row.paymentMethod!=null?intl.formatMessage({ id: utils.getPaymentMethod(params.row.paymentMethod)}):"" - }, - }, - { - id: 'paymentMethod', - field: 'paymentMethod', - headerName: intl.formatMessage({ id: 'paymentMethod' }), - width: isMdOrLg ? 'auto' : 160, - flex: isMdOrLg ? 1 : undefined, - renderCell: (params) => { - return params.row.paymentMethod!=null?intl.formatMessage({ id: utils.getPaymentMethod(params.row.paymentMethod)}):"" - }, + renderCell: (params) => ( +
    +
    +
    {dateStr(params.row.closingDateOff)}
    +
    + ) }, + // { + // id: 'closingDateOff', + // field: 'closingDateOff', + // headerName: intl.formatMessage({ id: 'paymentMethod' }), + // width: isMdOrLg ? 'auto' : 160, + // flex: isMdOrLg ? 1 : undefined, + // renderCell: (params) => { + // // console.log(params) + // let closingDateOff = params.row.closingDateOff; + // return
    {dateStr(closingDateOff)}
    + // }, + // }, { id: 'status', field: 'status', diff --git a/src/pages/PublicNotice/Search_GLD/DataGrid.js b/src/pages/PublicNotice/Search_GLD/DataGrid.js index 8de6f3a..6e6ed13 100644 --- a/src/pages/PublicNotice/Search_GLD/DataGrid.js +++ b/src/pages/PublicNotice/Search_GLD/DataGrid.js @@ -17,6 +17,7 @@ import { useNavigate } from "react-router-dom"; import { FiDataGrid } from "components/FiDataGrid"; import { notifyActionSuccess, clickableLink } from 'utils/CommonFunction'; import { FormattedMessage, useIntl } from "react-intl"; +import * as utils from "auth/utils" // ==============================|| EVENT TABLE ||============================== // export default function SearchPublicNoticeTable({ searchCriteria }) { @@ -94,16 +95,16 @@ export default function SearchPublicNoticeTable({ searchCriteria }) { { id: 'contactPerson', field: 'contactPerson', - headerName: 'Client', + headerName: 'Client / Payment Method', sortable: false, minWidth: 250, flex: 2, renderCell: (params) => { let company = params.row.enCompanyName != null ? params.row.enCompanyName : params.row.chCompanyName; company = company != null ? company : ""; - + let paymentMethod = params.row.paymentMethod!=null?intl.formatMessage({ id: utils.getPaymentMethod(params.row.paymentMethod)}):"" return (<> - {params?.value}
    {company} + {params?.value}
    {company}
    {paymentMethod} ); } }, diff --git a/src/routes/GLDUserRoutes.js b/src/routes/GLDUserRoutes.js index 39c1b59..53dcfc7 100644 --- a/src/routes/GLDUserRoutes.js +++ b/src/routes/GLDUserRoutes.js @@ -16,6 +16,7 @@ const ProofReply_GLD = Loadable(lazy(() => import('pages/Proof/Reply_GLD'))); const PaymentSearch_GLD = Loadable(lazy(() => import('pages/Payment/Search_GLD'))); const PaymentDetails_GLD = Loadable(lazy(() => import('pages/Payment/Details_GLD'))); const DemandNote_Create = Loadable(lazy(() => import('pages/DemandNote/Create'))); +const DemandNote_Export = Loadable(lazy(() => import('pages/DemandNote/Export'))); const DemandNote_Search = Loadable(lazy(() => import('pages/DemandNote/Search'))); const DemandNote_Details = Loadable(lazy(() => import('pages/DemandNote/Details'))); const GFMIS_Search = Loadable(lazy(() => import('pages/GFMIS'))); @@ -90,6 +91,12 @@ const GLDUserRoutes = { element: }:{}, + isGranted(["MAINTAIN_DEMANDNOTE"])? + { + path: '/paymentPage/exportGDN', + element: + }:{}, + isGrantedAny(["VIEW_DEMANDNOTE","MAINTAIN_DEMANDNOTE"])? { path: '/paymentPage/demandNote', diff --git a/src/translations/en.json b/src/translations/en.json index e48f270..1706d33 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -428,7 +428,7 @@ "post":"By Post", "cheque":"Cheque", "cash":"Cash", - "paymentMethod":"Payment Method", + "paymentMethodAndDeadLine":"Payment Method / DeadLine", "payOnlineMethod":"Online", "payDnMethod":"Demand Note", "payNPGOMethod":"NPGO Collection Office", diff --git a/src/translations/zh-CN.json b/src/translations/zh-CN.json index 663db84..f38b859 100644 --- a/src/translations/zh-CN.json +++ b/src/translations/zh-CN.json @@ -57,7 +57,7 @@ "post":"通过邮寄", "cheque":"支票", "cash":"现金", - "paymentMethod":"付款方式", + "paymentMethodAndDeadLine":"付款方式/期限", "payOnlineMethod":"网上支付", "payDnMethod":"缴款单支付", "payNPGOMethod":"收款办公室付款", diff --git a/src/translations/zh-HK.json b/src/translations/zh-HK.json index 2440c08..14a4646 100644 --- a/src/translations/zh-HK.json +++ b/src/translations/zh-HK.json @@ -57,7 +57,7 @@ "post":"透過郵寄", "cheque":"支票", "cash":"現金", - "paymentMethod":"付款方式", + "paymentMethodAndDeadLine":"付款方式/期限", "payOnlineMethod":"網上支付", "payDnMethod":"繳款單支付", "payNPGOMethod":"收款辦公室付款", diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js index 6ab9a82..8531d3a 100644 --- a/src/utils/ApiPathConst.js +++ b/src/utils/ApiPathConst.js @@ -168,6 +168,10 @@ export const DEMAND_NOTE_MARK_PAID = apiPath+'/demandNote/mark-as-paid';//POST export const DEMAND_NOTE_ATTACH = apiPath+'/demandNote/attach';//POST export const DEMAND_NOTE_EXPORT = apiPath+'/demandNote/export';//POST +export const GDN_VIEW = apiPath+'/application/list-Demand-Notice';//GET +export const GDN_EXPORT = apiPath+'/application/export';//GET + + export const GFIMIS_LIST = apiPath+'/gfmis/list';//GET