| Аутор | SHA1 | Порука | Датум |
|---|---|---|---|
|
|
604b83480b | CR-024 update | пре 1 недеља |
|
|
5aa204b7a3 | payment view update | пре 1 недеља |
|
|
ea26429c9b | GFMIS fix | пре 1 недеља |
|
|
dafeb7ebb8 | update payment label | пре 1 недеља |
|
|
c7eb604d61 | fix payment search again | пре 2 недеља |
|
|
025acf7b3d | fix payment search | пре 2 недеља |
|
|
ad367709fd | CR-024 Item 3 | пре 1 месец |
|
|
d1d844b633 | CR-024 Item 1 | пре 1 месец |
|
|
b0ee1b0714 | CR-022 Item 7 | пре 1 месец |
|
|
f447cb1dae | CR-022 Item 5 | пре 1 месец |
|
|
7b7a913398 | CR-022 Item 3 | пре 1 месец |
|
|
c5a1153aa7 | CR-022 Item 2 | пре 1 месец |
|
|
cdb9062c90 | CR-022 Item 2 | пре 1 месец |
|
|
4214676dcf | CR-022 Item 1 | пре 1 месец |
| @@ -61,7 +61,7 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a | |||||
| }, | }, | ||||
| { | { | ||||
| field: 'actions', | field: 'actions', | ||||
| headerName: 'Transaction No.', | |||||
| headerName: 'Payment No.', | |||||
| flex: 1, | flex: 1, | ||||
| minWidth: 200, | minWidth: 200, | ||||
| cellClassName: 'actions', | cellClassName: 'actions', | ||||
| @@ -72,7 +72,7 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a | |||||
| { | { | ||||
| id: 'transDateTime', | id: 'transDateTime', | ||||
| field: 'transDateTime', | field: 'transDateTime', | ||||
| headerName: 'Transaction Date', | |||||
| headerName: 'Payment Date', | |||||
| flex: 1, | flex: 1, | ||||
| minWidth: 150, | minWidth: 150, | ||||
| // sorting/filtering uses this value | // sorting/filtering uses this value | ||||
| @@ -126,20 +126,21 @@ const Index = () => { | |||||
| const xmlDoc = parser.parseFromString(responseData, 'application/xml'); | const xmlDoc = parser.parseFromString(responseData, 'application/xml'); | ||||
| const dcbHeader = xmlDoc.querySelector("DCBHeader"); | const dcbHeader = xmlDoc.querySelector("DCBHeader"); | ||||
| const receiptElement = dcbHeader.querySelector("Receipt"); | |||||
| const allocationElement = dcbHeader.querySelector("Allocation"); | |||||
| const receiptElements = Array.from(dcbHeader.querySelectorAll("Receipt")); | |||||
| const allocationElements = Array.from(dcbHeader.querySelectorAll("Allocation")); | |||||
| const paymentMethodElements = Array.from(dcbHeader.querySelectorAll("PaymentMethod")); | const paymentMethodElements = Array.from(dcbHeader.querySelectorAll("PaymentMethod")); | ||||
| dcbHeader.innerHTML = ""; | dcbHeader.innerHTML = ""; | ||||
| dcbHeader.appendChild(receiptElement); | |||||
| dcbHeader.appendChild(allocationElement); | |||||
| if (paymentMethodElements) { | |||||
| paymentMethodElements.forEach((paymentMethodElement) => { | |||||
| dcbHeader.appendChild(paymentMethodElement); | |||||
| }); | |||||
| } | |||||
| receiptElements.forEach((receiptElement) => { | |||||
| dcbHeader.appendChild(receiptElement); | |||||
| }); | |||||
| allocationElements.forEach((allocationElement) => { | |||||
| dcbHeader.appendChild(allocationElement); | |||||
| }); | |||||
| paymentMethodElements.forEach((paymentMethodElement) => { | |||||
| dcbHeader.appendChild(paymentMethodElement); | |||||
| }); | |||||
| const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc); | const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc); | ||||
| const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename'); | const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename'); | ||||
| @@ -3,24 +3,33 @@ import { | |||||
| Grid, | Grid, | ||||
| Typography, | Typography, | ||||
| FormLabel, | FormLabel, | ||||
| Button | |||||
| Button, | |||||
| Dialog, | |||||
| DialogTitle, | |||||
| DialogContent, | |||||
| DialogActions, | |||||
| Box | |||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import * as React from "react"; | import * as React from "react"; | ||||
| import * as FormatUtils from "utils/FormatUtils"; | import * as FormatUtils from "utils/FormatUtils"; | ||||
| import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | import * as PaymentStatus from "utils/statusUtils/PaymentStatus"; | ||||
| import * as DateUtils from "utils/DateUtils"; | import * as DateUtils from "utils/DateUtils"; | ||||
| import * as HttpUtils from "utils/HttpUtils"; | |||||
| import { PAYMENT_MARK_AS_PAID } from "utils/ApiPathConst"; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | const MainCard = Loadable(React.lazy(() => import('components/MainCard'))); | ||||
| const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent'))); | ||||
| import DownloadIcon from '@mui/icons-material/Download'; | import DownloadIcon from '@mui/icons-material/Download'; | ||||
| import {useIntl} from "react-intl"; | import {useIntl} from "react-intl"; | ||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| const PaymentDetails = ({ formData, doPrint, onDownload, onRefresh }) => { | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| const [data, setData] = React.useState({}); | const [data, setData] = React.useState({}); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| const [confirmOpen, setConfirmOpen] = React.useState(false); | |||||
| const [markingPaid, setMarkingPaid] = React.useState(false); | |||||
| // const { locale } = intl; | // const { locale } = intl; | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| @@ -40,9 +49,29 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| if("01" == paymentmethod) return "PPS"; | if("01" == paymentmethod) return "PPS"; | ||||
| if("02" == paymentmethod || "03" == paymentmethod) return "Credit Card"; | if("02" == paymentmethod || "03" == paymentmethod) return "Credit Card"; | ||||
| if("04" == paymentmethod) return "FPS"; | if("04" == paymentmethod) return "FPS"; | ||||
| if (data.payMethod === "04,BCFP,FPS") return "FPS"; | |||||
| return paymentmethod; | return paymentmethod; | ||||
| } | } | ||||
| const showMarkAsPaid = data.status === "REJT" && getPaymentMethod() === "FPS"; | |||||
| const handleMarkAsPaid = () => { | |||||
| setMarkingPaid(true); | |||||
| HttpUtils.post({ | |||||
| url: PAYMENT_MARK_AS_PAID + "/" + data.id, | |||||
| onSuccess: () => { | |||||
| setConfirmOpen(false); | |||||
| setMarkingPaid(false); | |||||
| if (onRefresh) { | |||||
| onRefresh(); | |||||
| } | |||||
| }, | |||||
| onError: () => { | |||||
| setMarkingPaid(false); | |||||
| } | |||||
| }); | |||||
| }; | |||||
| return ( | return ( | ||||
| !onReady ? | !onReady ? | ||||
| <LoadingComponent /> | <LoadingComponent /> | ||||
| @@ -51,9 +80,21 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| border={false} | border={false} | ||||
| content={false} | content={false} | ||||
| > | > | ||||
| <Typography variant="h5" sx={{ textAlign: "left", mb: 2, borderBottom: "1px solid black" }}> | |||||
| Payment Details | |||||
| </Typography> | |||||
| <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2, borderBottom: "1px solid black" }}> | |||||
| <Typography variant="h5" sx={{ textAlign: "left" }}> | |||||
| Payment Details | |||||
| </Typography> | |||||
| {showMarkAsPaid && ( | |||||
| <Button | |||||
| className="printHidden" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| onClick={() => setConfirmOpen(true)} | |||||
| > | |||||
| Mark as Paid | |||||
| </Button> | |||||
| )} | |||||
| </Box> | |||||
| <form> | <form> | ||||
| <Grid container> | <Grid container> | ||||
| <Grid item xs={12} md={12} > | <Grid item xs={12} md={12} > | ||||
| @@ -116,7 +157,7 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| <Grid container > | <Grid container > | ||||
| <Grid item xs={6} md={6} sx={{ml:-5, textAlign: "right" }}> | <Grid item xs={6} md={6} sx={{ml:-5, textAlign: "right" }}> | ||||
| <FormLabel sx={{ color: "#000000" }}> | <FormLabel sx={{ color: "#000000" }}> | ||||
| EGIS Reference No.: | |||||
| Payment Reference No.: | |||||
| </FormLabel> | </FormLabel> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | <Grid item xs={6} md={5} sx={{ml:5, textAlign: "left" }}> | ||||
| @@ -176,6 +217,25 @@ const PaymentDetails = ({ formData,doPrint,onDownload }) => { | |||||
| } | } | ||||
| </Grid> | </Grid> | ||||
| </form> | </form> | ||||
| <Dialog | |||||
| open={confirmOpen} | |||||
| onClose={() => !markingPaid && setConfirmOpen(false)} | |||||
| > | |||||
| <DialogTitle>Confirm</DialogTitle> | |||||
| <DialogContent> | |||||
| <Typography variant="h5" sx={{ padding: '16px' }}> | |||||
| {`Are you sure to mark as paid for Payment No. ${data.transNo || data.payload?.transactionid} ?`} | |||||
| </Typography> | |||||
| </DialogContent> | |||||
| <DialogActions> | |||||
| <Button onClick={() => setConfirmOpen(false)} disabled={markingPaid}> | |||||
| <Typography variant="h5">Cancel</Typography> | |||||
| </Button> | |||||
| <Button onClick={handleMarkAsPaid} disabled={markingPaid}> | |||||
| <Typography variant="h5">Confirm</Typography> | |||||
| </Button> | |||||
| </DialogActions> | |||||
| </Dialog> | |||||
| </MainCard> | </MainCard> | ||||
| ); | ); | ||||
| }; | }; | ||||
| @@ -35,6 +35,9 @@ const Index = () => { | |||||
| const params = useParams(); | const params = useParams(); | ||||
| const navigate = useNavigate() | const navigate = useNavigate() | ||||
| const [responeData, setResponeData] = React.useState({}); | |||||
| const [transactionData, setTransactionData] = React.useState({}); | |||||
| const [record, setRecord] = React.useState(); | const [record, setRecord] = React.useState(); | ||||
| const [itemList, setItemList] = React.useState([]); | const [itemList, setItemList] = React.useState([]); | ||||
| const [onReady, setOnReady] = React.useState(false); | const [onReady, setOnReady] = React.useState(false); | ||||
| @@ -47,8 +50,16 @@ const Index = () => { | |||||
| }, []); | }, []); | ||||
| React.useEffect(() => { | React.useEffect(() => { | ||||
| setOnReady(true); | |||||
| }, [record]); | |||||
| if (Object.keys(responeData).length > 0) { | |||||
| setTransactionData(responeData); | |||||
| } | |||||
| }, [responeData]); | |||||
| React.useEffect(() => { | |||||
| if (Object.keys(transactionData).length > 0) { | |||||
| setOnReady(true); | |||||
| } | |||||
| }, [transactionData]); | |||||
| // const handleResize = () => { | // const handleResize = () => { | ||||
| // setDetailsOrder(window.innerWidth > 1023 ? 2 : -1); | // setDetailsOrder(window.innerWidth > 1023 ? 2 : -1); | ||||
| @@ -70,17 +81,40 @@ const Index = () => { | |||||
| const loadForm = () => { | const loadForm = () => { | ||||
| if (params.id > 0) { | if (params.id > 0) { | ||||
| HttpUtils.get({ | HttpUtils.get({ | ||||
| url: UrlUtils.PAYMENT_LOAD + "/" + params.id, | url: UrlUtils.PAYMENT_LOAD + "/" + params.id, | ||||
| onSuccess: (responseData) => { | onSuccess: (responseData) => { | ||||
| if (!responseData.data?.id) { | if (!responseData.data?.id) { | ||||
| navigate("/paymentPage/search"); | navigate("/paymentPage/search"); | ||||
| } | } | ||||
| responseData.data["transDateStr"] = responseData.data.transDateTime; | |||||
| responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||||
| setItemList(responseData.paymentItemList) | |||||
| setRecord(responseData.data); | |||||
| if (responseData.data.status == null || responseData.data.status == "INPR") { | |||||
| HttpUtils.post({ | |||||
| url: UrlUtils.PAYMENT_RETRY_STATUS_API, | |||||
| params: { | |||||
| "paymentId": params.id | |||||
| }, | |||||
| onSuccess: function (responseData2) { | |||||
| responseData2.data["transDateStr"] = responseData2.data.transDateTime; | |||||
| responseData2.data["transTimeStr"] = DateUtils.dateFormat(responseData2.data.transDateTime, "HH:mm:ss"); | |||||
| setResponeData(responseData2.transactionData); | |||||
| setItemList(responseData2.paymentItemList); | |||||
| setRecord(responseData2.data); | |||||
| }, | |||||
| onError: function () { | |||||
| responseData.data["transDateStr"] = responseData.data.transDateTime; | |||||
| responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||||
| setResponeData(responseData); | |||||
| setItemList(responseData.paymentItemList); | |||||
| setRecord(responseData.data); | |||||
| } | |||||
| }); | |||||
| } else { | |||||
| responseData.data["transDateStr"] = responseData.data.transDateTime; | |||||
| responseData.data["transTimeStr"] = DateUtils.dateFormat(responseData.data.transDateTime, "HH:mm:ss"); | |||||
| setResponeData(responseData); | |||||
| setItemList(responseData.paymentItemList); | |||||
| setRecord(responseData.data); | |||||
| } | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| @@ -125,6 +159,7 @@ const Index = () => { | |||||
| formData={record} | formData={record} | ||||
| doPrint={doPrint} | doPrint={doPrint} | ||||
| onDownload={onDownload} | onDownload={onDownload} | ||||
| onRefresh={loadForm} | |||||
| style={{ | style={{ | ||||
| display: "flex", | display: "flex", | ||||
| height: "100%", | height: "100%", | ||||
| @@ -87,7 +87,7 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a | |||||
| }, | }, | ||||
| { | { | ||||
| field: 'actions', | field: 'actions', | ||||
| headerName: 'Transaction No.', | |||||
| headerName: 'Payment No.', | |||||
| flex: 1, | flex: 1, | ||||
| minWidth: 200, | minWidth: 200, | ||||
| cellClassName: 'actions', | cellClassName: 'actions', | ||||
| @@ -95,6 +95,12 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a | |||||
| return clickableLink('/paymentPage/details/' + params.row.id, params.row.transNo); | return clickableLink('/paymentPage/details/' + params.row.id, params.row.transNo); | ||||
| }, | }, | ||||
| }, | }, | ||||
| { | |||||
| field: 'egisRefNo', | |||||
| headerName: 'Payment Reference No.', | |||||
| flex: 1, | |||||
| minWidth: 200, | |||||
| }, | |||||
| { | { | ||||
| field: 'payMethod', | field: 'payMethod', | ||||
| headerName: 'Payment Method', | headerName: 'Payment Method', | ||||
| @@ -107,7 +113,7 @@ export default function SearchPaymentTable({ searchCriteria, applyGridOnReady, a | |||||
| { | { | ||||
| id: 'transDateTime', | id: 'transDateTime', | ||||
| field: 'transDateTime', | field: 'transDateTime', | ||||
| headerName: 'Transaction Date', | |||||
| headerName: 'Payment Date', | |||||
| flex: 1, | flex: 1, | ||||
| minWidth: 150, | minWidth: 150, | ||||
| @@ -158,7 +158,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => | |||||
| // }, | // }, | ||||
| }} | }} | ||||
| format="DD/MM/YYYY" | format="DD/MM/YYYY" | ||||
| label="Transaction Date (From)" | |||||
| label="Payment Date (From)" | |||||
| value={minDate === null ? null : dayjs(minDate)} | value={minDate === null ? null : dayjs(minDate)} | ||||
| maxDate={maxDate === null ? null : dayjs(maxDate)} | maxDate={maxDate === null ? null : dayjs(maxDate)} | ||||
| onChange={(newValue) => { | onChange={(newValue) => { | ||||
| @@ -184,7 +184,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => | |||||
| // }, | // }, | ||||
| }} | }} | ||||
| format="DD/MM/YYYY" | format="DD/MM/YYYY" | ||||
| label="Transaction Date (To)" | |||||
| label="Payment Date (To)" | |||||
| value={maxDate === null ? null : dayjs(maxDate)} | value={maxDate === null ? null : dayjs(maxDate)} | ||||
| minDate={minDate === null ? null : dayjs(minDate)} | minDate={minDate === null ? null : dayjs(minDate)} | ||||
| onChange={(newValue) => { | onChange={(newValue) => { | ||||
| @@ -205,7 +205,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => | |||||
| fullWidth | fullWidth | ||||
| {...register("transNo")} | {...register("transNo")} | ||||
| id='transNo' | id='transNo' | ||||
| label="Transaction No." | |||||
| label="Payment No. / Payment Reference No." | |||||
| defaultValue={searchCriteria.transNo} | defaultValue={searchCriteria.transNo} | ||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| shrink: true | shrink: true | ||||
| @@ -11,6 +11,7 @@ import { FiDataGrid } from "components/FiDataGrid"; | |||||
| import {useTheme} from "@emotion/react"; | import {useTheme} from "@emotion/react"; | ||||
| import {useIntl} from "react-intl"; | import {useIntl} from "react-intl"; | ||||
| import { clickableLink } from 'utils/CommonFunction'; | import { clickableLink } from 'utils/CommonFunction'; | ||||
| import { getPaymentMethodByCode } from "auth/utils"; | |||||
| import {PAYMENT_LIST} from "utils/ApiPathConst"; | import {PAYMENT_LIST} from "utils/ApiPathConst"; | ||||
| // ==============================|| EVENT TABLE ||============================== // | // ==============================|| EVENT TABLE ||============================== // | ||||
| @@ -58,6 +59,12 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea | |||||
| return clickableLink('/paymentPage/details/' + params.row.id, params.row.transNo); | return clickableLink('/paymentPage/details/' + params.row.id, params.row.transNo); | ||||
| }, | }, | ||||
| }, | }, | ||||
| { | |||||
| field: 'egisRefNo', | |||||
| headerName: intl.formatMessage({id: 'paymentRefCode'}), | |||||
| width: isMdOrLg ? 'auto' : 160, | |||||
| flex: isMdOrLg ? 1 : undefined, | |||||
| }, | |||||
| { | { | ||||
| id: 'appNos', | id: 'appNos', | ||||
| field: 'appNos', | field: 'appNos', | ||||
| @@ -69,6 +76,13 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea | |||||
| return <div style={{ margin: 4 }}>{appNo}</div> | return <div style={{ margin: 4 }}>{appNo}</div> | ||||
| }, | }, | ||||
| }, | }, | ||||
| { | |||||
| field: 'payMethod', | |||||
| headerName: intl.formatMessage({id: 'paymentMethod'}), | |||||
| width: isMdOrLg ? 'auto' : 160, | |||||
| flex: isMdOrLg ? 1 : undefined, | |||||
| renderCell: (params) => getPaymentMethodByCode(params?.value), | |||||
| }, | |||||
| { | { | ||||
| id: 'transDateTime', | id: 'transDateTime', | ||||
| field: 'transDateTime', | field: 'transDateTime', | ||||
| @@ -76,8 +90,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea | |||||
| width: isMdOrLg ? 'auto' : 160, | width: isMdOrLg ? 'auto' : 160, | ||||
| flex: isMdOrLg ? 1 : undefined, | flex: isMdOrLg ? 1 : undefined, | ||||
| valueGetter: (params) => { | valueGetter: (params) => { | ||||
| // console.log(params) | |||||
| return DateUtils.dateStr(params?.value?params.value:params.row.created); | |||||
| return params?.value ? DateUtils.dateStr(params.value) : ""; | |||||
| } | } | ||||
| }, | }, | ||||
| { | { | ||||
| @@ -224,7 +224,7 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => | |||||
| fullWidth | fullWidth | ||||
| {...register("transNo")} | {...register("transNo")} | ||||
| id='transNo' | id='transNo' | ||||
| label={intl.formatMessage({id: 'payId'})} | |||||
| label={intl.formatMessage({id: 'payIdNRefer'})} | |||||
| defaultValue={searchCriteria.transNo} | defaultValue={searchCriteria.transNo} | ||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| shrink: true | shrink: true | ||||
| @@ -256,7 +256,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateReport, onLoad }) => { | |||||
| }, | }, | ||||
| }} | }} | ||||
| format="DD/MM/YYYY" | format="DD/MM/YYYY" | ||||
| label="PNSPS Transaction Date (From)" | |||||
| label="PNSPS Payment Date (From)" | |||||
| value={sysTxnMinDate === null ? null : dayjs(sysTxnMinDate)} | value={sysTxnMinDate === null ? null : dayjs(sysTxnMinDate)} | ||||
| maxDate={sysTxnMaxDate === null ? null : dayjs(sysTxnMaxDate)} | maxDate={sysTxnMaxDate === null ? null : dayjs(sysTxnMaxDate)} | ||||
| onChange={(newValue) => { | onChange={(newValue) => { | ||||
| @@ -280,7 +280,7 @@ const SearchPublicNoticeForm = ({ applySearch, generateReport, onLoad }) => { | |||||
| }, | }, | ||||
| }} | }} | ||||
| format="DD/MM/YYYY" | format="DD/MM/YYYY" | ||||
| label="PNSPS Transaction Date (To)" | |||||
| label="PNSPS Payment Date (To)" | |||||
| value={sysTxnMaxDate === null ? null : dayjs(sysTxnMaxDate)} | value={sysTxnMaxDate === null ? null : dayjs(sysTxnMaxDate)} | ||||
| minDate={sysTxnMinDate === null ? null : dayjs(sysTxnMinDate)} | minDate={sysTxnMinDate === null ? null : dayjs(sysTxnMinDate)} | ||||
| onChange={(newValue) => { | onChange={(newValue) => { | ||||
| @@ -0,0 +1,100 @@ | |||||
| import * as React from "react"; | |||||
| import * as HttpUtils from "utils/HttpUtils"; | |||||
| import * as DateUtils from "utils/DateUtils"; | |||||
| import * as UrlUtils from "utils/ApiPathConst"; | |||||
| import { | |||||
| Grid, Typography, Button, | |||||
| Stack, Box, CircularProgress, | |||||
| } from '@mui/material'; | |||||
| import { notifyActionError } from 'utils/CommonFunction'; | |||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||||
| const formatLog = (responData) => { | |||||
| if (responData?.msg && !responData?.log) { | |||||
| return <>{DateUtils.datetimeStr(new Date())}<br/><span style={{ color: "red" }}>Error</span><br/>{responData.msg}</>; | |||||
| } | |||||
| const statusColor = responData?.success ? "green" : "red"; | |||||
| const statusText = responData?.success ? "Success" : "Completed with errors"; | |||||
| const logText = (responData?.log || []).join("\n"); | |||||
| return ( | |||||
| <> | |||||
| {DateUtils.datetimeStr(new Date())}<br/> | |||||
| <span style={{ color: statusColor }}>{responData?.dryRun ? "Dry-run " : ""}{statusText}</span><br/> | |||||
| Total: {responData?.total ?? 0}, OK: {responData?.successCount ?? 0}, Skipped: {responData?.skipped ?? 0}, Failed: {responData?.failed ?? 0}<br/> | |||||
| <span style={{ whiteSpace: "pre-line" }}>{logText}</span> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| const HkidKeyMigration = () => { | |||||
| const [resultStr, setResultStr] = React.useState(""); | |||||
| const [wait, setWait] = React.useState(false); | |||||
| const BackgroundHead = { | |||||
| backgroundImage: `url(${titleBackgroundImg})`, | |||||
| width: 'auto', | |||||
| height: 'auto', | |||||
| backgroundSize: 'contain', | |||||
| backgroundRepeat: 'no-repeat', | |||||
| backgroundColor: '#0C489E', | |||||
| backgroundPosition: 'right' | |||||
| }; | |||||
| const runMigration = (dryRun) => { | |||||
| setWait(true); | |||||
| HttpUtils.post({ | |||||
| url: `${UrlUtils.HKID_REKEY_MIGRATION}?dryRun=${dryRun}&batchSize=100`, | |||||
| params: {}, | |||||
| onSuccess: function (responData) { | |||||
| setWait(false); | |||||
| setResultStr(formatLog(responData)); | |||||
| }, | |||||
| onError: function () { | |||||
| setWait(false); | |||||
| notifyActionError("HKID re-key migration failed"); | |||||
| } | |||||
| }); | |||||
| }; | |||||
| return ( | |||||
| <Grid container sx={{ minHeight: '87vh', backgroundColor: "backgroundColor.default" }} direction="column"> | |||||
| <Grid item xs={12}> | |||||
| <div style={BackgroundHead}> | |||||
| <Stack direction="row" height='70px' justifyContent="space-between" alignItems="center"> | |||||
| <Typography ml={15} color='#FFF' variant="h4" sx={{ textShadow: "0px 0px 25px #0C489E" }}> | |||||
| Encryption Key Migration | |||||
| </Typography> | |||||
| </Stack> | |||||
| </div> | |||||
| </Grid> | |||||
| <Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1 }} width="98%"> | |||||
| <Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}> | |||||
| <Typography variant="body1" sx={{ mb: 2 }}> | |||||
| Re-encrypt identification and checkDigit from the legacy key to the new key. | |||||
| </Typography> | |||||
| <Stack direction="row" spacing={2}> | |||||
| <Button variant="outlined" size="large" disabled={wait} onClick={() => runMigration(true)}> | |||||
| Dry Run | |||||
| </Button> | |||||
| <Button variant="contained" size="large" disabled={wait} onClick={() => runMigration(false)}> | |||||
| Run Migration | |||||
| </Button> | |||||
| {wait ? <CircularProgress size={32} /> : null} | |||||
| </Stack> | |||||
| </Box> | |||||
| </Grid> | |||||
| <Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1, mb: 2 }} width="98%"> | |||||
| <Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}> | |||||
| <Typography variant="h4">Result:</Typography> | |||||
| <Box sx={{ pl: 2, pt: 2 }}>{resultStr}</Box> | |||||
| </Box> | |||||
| </Grid> | |||||
| </Grid> | |||||
| ); | |||||
| }; | |||||
| export default HkidKeyMigration; | |||||
| @@ -0,0 +1,133 @@ | |||||
| import * as React from "react"; | |||||
| import * as HttpUtils from "utils/HttpUtils"; | |||||
| import * as DateUtils from "utils/DateUtils"; | |||||
| import * as UrlUtils from "utils/ApiPathConst"; | |||||
| import { | |||||
| Grid, Typography, Button, | |||||
| Stack, Box, CircularProgress, | |||||
| } from '@mui/material'; | |||||
| import { notifyActionError } from 'utils/CommonFunction'; | |||||
| import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png' | |||||
| const formatEncryptLog = (responData) => { | |||||
| if (responData?.msg && !responData?.log) { | |||||
| return <>{DateUtils.datetimeStr(new Date())}<br/><span style={{ color: "red" }}>Error</span><br/>{responData.msg}</>; | |||||
| } | |||||
| const statusColor = responData?.success ? "green" : "red"; | |||||
| const statusText = responData?.success ? "Success" : "Completed with errors"; | |||||
| const logText = (responData?.log || []).join("\n"); | |||||
| return ( | |||||
| <> | |||||
| {DateUtils.datetimeStr(new Date())}<br/> | |||||
| <span style={{ color: statusColor }}>{responData?.dryRun ? "Dry-run " : ""}{statusText}</span><br/> | |||||
| Total: {responData?.total ?? 0}, OK: {responData?.successCount ?? 0}, Skipped: {responData?.skipped ?? 0}, Failed: {responData?.failed ?? 0}<br/> | |||||
| <span style={{ whiteSpace: "pre-line" }}>{logText}</span> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| const formatVerifyLog = (responData) => { | |||||
| const tests = responData?.tests || []; | |||||
| const logText = tests.map(t => `${t.passed ? "PASS" : "FAIL"} - ${t.name}: ${t.message}`).join("\n"); | |||||
| const statusColor = responData?.success ? "green" : "red"; | |||||
| return ( | |||||
| <> | |||||
| {DateUtils.datetimeStr(new Date())}<br/> | |||||
| <span style={{ color: statusColor }}>{responData?.success ? "All tests passed" : "Some tests failed"}</span><br/> | |||||
| Passed: {responData?.passed ?? 0}, Failed: {responData?.failed ?? 0}<br/> | |||||
| <span style={{ whiteSpace: "pre-line" }}>{logText}</span> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| const UserPiiEncryption = () => { | |||||
| const [resultStr, setResultStr] = React.useState(""); | |||||
| const [wait, setWait] = React.useState(false); | |||||
| const BackgroundHead = { | |||||
| backgroundImage: `url(${titleBackgroundImg})`, | |||||
| width: 'auto', | |||||
| height: 'auto', | |||||
| backgroundSize: 'contain', | |||||
| backgroundRepeat: 'no-repeat', | |||||
| backgroundColor: '#0C489E', | |||||
| backgroundPosition: 'right' | |||||
| }; | |||||
| const runEncrypt = (dryRun) => { | |||||
| setWait(true); | |||||
| HttpUtils.post({ | |||||
| url: `${UrlUtils.USER_PII_ENCRYPT_MIGRATION}?dryRun=${dryRun}&batchSize=100`, | |||||
| params: {}, | |||||
| onSuccess: function (responData) { | |||||
| setWait(false); | |||||
| setResultStr(formatEncryptLog(responData)); | |||||
| }, | |||||
| onError: function () { | |||||
| setWait(false); | |||||
| notifyActionError("User PII encryption failed"); | |||||
| } | |||||
| }); | |||||
| }; | |||||
| const runVerify = () => { | |||||
| setWait(true); | |||||
| HttpUtils.post({ | |||||
| url: UrlUtils.USER_PII_VERIFY_MIGRATION, | |||||
| params: {}, | |||||
| onSuccess: function (responData) { | |||||
| setWait(false); | |||||
| setResultStr(formatVerifyLog(responData)); | |||||
| }, | |||||
| onError: function () { | |||||
| setWait(false); | |||||
| notifyActionError("User PII verification failed"); | |||||
| } | |||||
| }); | |||||
| }; | |||||
| return ( | |||||
| <Grid container sx={{ minHeight: '87vh', backgroundColor: "backgroundColor.default" }} direction="column"> | |||||
| <Grid item xs={12}> | |||||
| <div style={BackgroundHead}> | |||||
| <Stack direction="row" height='70px' justifyContent="space-between" alignItems="center"> | |||||
| <Typography ml={15} color='#FFF' variant="h4" sx={{ textShadow: "0px 0px 25px #0C489E" }}> | |||||
| User Fields Encryption | |||||
| </Typography> | |||||
| </Stack> | |||||
| </div> | |||||
| </Grid> | |||||
| <Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1 }} width="98%"> | |||||
| <Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}> | |||||
| <Typography variant="body1" sx={{ mb: 2 }}> | |||||
| Encrypt enName, chName, mobileNumber, and address for existing user records, then verify data retrieval. | |||||
| </Typography> | |||||
| <Stack direction="row" spacing={2} flexWrap="wrap"> | |||||
| <Button variant="outlined" size="large" disabled={wait} onClick={() => runEncrypt(true)}> | |||||
| Dry Run Encrypt | |||||
| </Button> | |||||
| <Button variant="contained" size="large" disabled={wait} onClick={() => runEncrypt(false)}> | |||||
| Run Encrypt | |||||
| </Button> | |||||
| <Button variant="contained" color="secondary" size="large" disabled={wait} onClick={runVerify}> | |||||
| Verify Retrieval | |||||
| </Button> | |||||
| {wait ? <CircularProgress size={32} /> : null} | |||||
| </Stack> | |||||
| </Box> | |||||
| </Grid> | |||||
| <Grid item xs={12} sx={{ backgroundColor: '#ffffff', ml: 2, mt: 1, mb: 2 }} width="98%"> | |||||
| <Box sx={{ borderRadius: '10px', backgroundColor: '#fff', p: 4 }}> | |||||
| <Typography variant="h4">Result:</Typography> | |||||
| <Box sx={{ pl: 2, pt: 2 }}>{resultStr}</Box> | |||||
| </Box> | |||||
| </Grid> | |||||
| </Grid> | |||||
| ); | |||||
| }; | |||||
| export default UserPiiEncryption; | |||||
| @@ -80,7 +80,10 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => { | |||||
| addressLine3: yup.string().max(40, getMaxErrStr(40)).nullable(), | addressLine3: yup.string().max(40, getMaxErrStr(40)).nullable(), | ||||
| emailAddress: yup.string().email(intl.formatMessage({ id: 'validEmailFormat' })).max(255).required(intl.formatMessage({ id: 'requireEmail' })), | emailAddress: yup.string().email(intl.formatMessage({ id: 'validEmailFormat' })).max(255).required(intl.formatMessage({ id: 'requireEmail' })), | ||||
| idDocType: yup.string().max(255, getMaxErrStr(255)).required(intl.formatMessage({ id: 'requireIdDocType' })), | idDocType: yup.string().max(255, getMaxErrStr(255)).required(intl.formatMessage({ id: 'requireIdDocType' })), | ||||
| identification: yup.string().required(getRequiredErrStr('number')) | |||||
| identification: yup.string().when('verifiedBy', { | |||||
| is: (verifiedBy) => verifiedBy != null, | |||||
| then: (schema) => schema.notRequired(), | |||||
| otherwise: (schema) => schema.required(getRequiredErrStr('number')) | |||||
| .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) }) | .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) }) | ||||
| .matches(/^\S*$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpace' })}`) }) | .matches(/^\S*$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpace' })}`) }) | ||||
| .test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredValid' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`), function (value) { | .test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredValid' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`), function (value) { | ||||
| @@ -132,8 +135,12 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => { | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| }) | |||||
| }), | }), | ||||
| checkDigit: yup.string().max(1, getMaxErrStr(1)).nullable() | |||||
| checkDigit: yup.string().when('verifiedBy', { | |||||
| is: (verifiedBy) => verifiedBy != null, | |||||
| then: (schema) => schema.notRequired(), | |||||
| otherwise: (schema) => schema.max(1, getMaxErrStr(1)).nullable() | |||||
| .matches(/^[A-Z0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) }) | .matches(/^[A-Z0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) }) | ||||
| .test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredNumberInQuote' })}`), function (value) { | .test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredNumberInQuote' })}`), function (value) { | ||||
| // console.log(selectedIdDocInputType) | // console.log(selectedIdDocInputType) | ||||
| @@ -161,7 +168,8 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => { | |||||
| return false | return false | ||||
| } | } | ||||
| } | } | ||||
| }), | |||||
| }) | |||||
| }), | |||||
| tel_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })).required(intl.formatMessage({ id: 'requireDialingCode' })), | tel_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })).required(intl.formatMessage({ id: 'requireDialingCode' })), | ||||
| fax_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })), | fax_countryCode: yup.string().min(3, intl.formatMessage({ id: 'require3Number' })), | ||||
| phoneNumber: yup.string().min(8, intl.formatMessage({ id: 'require8Number' })).required(intl.formatMessage({ id: 'requireContactNumber' })), | phoneNumber: yup.string().min(8, intl.formatMessage({ id: 'require8Number' })).required(intl.formatMessage({ id: 'requireContactNumber' })), | ||||
| @@ -185,8 +193,10 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => { | |||||
| countryCode: values.tel_countryCode, | countryCode: values.tel_countryCode, | ||||
| phoneNumber: values.phoneNumber | phoneNumber: values.phoneNumber | ||||
| }, | }, | ||||
| identification: values.identification, | |||||
| checkDigit: values.checkDigit, | |||||
| ...(values.verifiedBy == null ? { | |||||
| identification: values.identification, | |||||
| checkDigit: values.checkDigit, | |||||
| } : {}), | |||||
| faxNo: { | faxNo: { | ||||
| countryCode: values.fax_countryCode, | countryCode: values.fax_countryCode, | ||||
| faxNumber: values.faxNumber | faxNumber: values.faxNumber | ||||
| @@ -470,6 +480,11 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} sm={12} md={9} lg={6}> | <Grid item xs={12} sm={12} md={9} lg={6}> | ||||
| {currentUserData.verifiedBy ? | |||||
| <Typography variant="h5" mt={1}> | |||||
| Hidden for security purpose | |||||
| </Typography> | |||||
| : | |||||
| <Grid container> | <Grid container> | ||||
| {formik.values.idDocType === "HKID" ? | {formik.values.idDocType === "HKID" ? | ||||
| editMode ? | editMode ? | ||||
| @@ -548,6 +563,7 @@ const UserInformationCard_Individual = ({ formData, loadDataFun }) => { | |||||
| </Stack> | </Stack> | ||||
| } | } | ||||
| </Grid> | </Grid> | ||||
| } | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -2,8 +2,6 @@ | |||||
| import { | import { | ||||
| Grid, Button, Typography, | Grid, Button, Typography, | ||||
| FormHelperText, | FormHelperText, | ||||
| Stack, | |||||
| IconButton | |||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import MainCard from "components/MainCard"; | import MainCard from "components/MainCard"; | ||||
| import * as React from "react"; | import * as React from "react"; | ||||
| @@ -22,7 +20,6 @@ import {notifySaveSuccess,} from 'utils/CommonFunction'; | |||||
| import {FormattedMessage, useIntl} from "react-intl"; | import {FormattedMessage, useIntl} from "react-intl"; | ||||
| import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst"; | import {PNSPS_BUTTON_THEME} from "../../../themes/buttonConst"; | ||||
| import {ThemeProvider} from "@emotion/react"; | import {ThemeProvider} from "@emotion/react"; | ||||
| import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons'; | |||||
| // ==============================|| DASHBOARD - DEFAULT ||============================== // | // ==============================|| DASHBOARD - DEFAULT ||============================== // | ||||
| @@ -33,15 +30,6 @@ const UserInformationCard_Individual_Pub = ({ formData, loadDataFun }) => { | |||||
| const [editMode, setEditMode] = useState(false); | const [editMode, setEditMode] = useState(false); | ||||
| const [onReady, setOnReady] = useState(false); | const [onReady, setOnReady] = useState(false); | ||||
| const [errorMsg, setErrorMsg] = useState(""); | const [errorMsg, setErrorMsg] = useState(""); | ||||
| const [showId, setshowId] = useState(false); | |||||
| const handleClickShowId = () => { | |||||
| setshowId(!showId); | |||||
| }; | |||||
| const handleMouseDownId = (event) => { | |||||
| event.preventDefault(); | |||||
| }; | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (Object.keys(formData).length > 0) { | if (Object.keys(formData).length > 0) { | ||||
| @@ -251,79 +239,9 @@ const UserInformationCard_Individual_Pub = ({ formData, loadDataFun }) => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} sm={12} md={9} lg={6}> | <Grid item xs={12} sm={12} md={9} lg={6}> | ||||
| <Grid container> | |||||
| {formik.values.idDocType === "HKID" ? | |||||
| // <> | |||||
| // <Grid item xs={6} sm={6} md={6} lg={7.5} sx={{mr:1}}> | |||||
| // {FieldUtils.initField({ | |||||
| // valueName: "identification", | |||||
| // disabled: true, | |||||
| // form: formik, | |||||
| // placeholder: intl.formatMessage({id: 'idDocNumber'}), | |||||
| // inputProps: { | |||||
| // maxLength: 7, | |||||
| // onKeyDown: (e) => { | |||||
| // if (e.key === 'Enter') { | |||||
| // e.preventDefault(); | |||||
| // } | |||||
| // }, | |||||
| // } | |||||
| // })} | |||||
| // </Grid> | |||||
| // <Grid item xs={2} sm={2} md={2} lg={2} style={{minWidth:40}}> | |||||
| // {FieldUtils.initField({ | |||||
| // valueName: "checkDigit", | |||||
| // disabled: true, | |||||
| // form: formik, | |||||
| // })} | |||||
| // </Grid> | |||||
| // </> | |||||
| <Stack direction="row"> | |||||
| <Typography variant="h5" mt={1}> | |||||
| {formik.values.identification?.slice(0, 4)} | |||||
| </Typography> | |||||
| <Typography variant="h5"mt={1}> | |||||
| {/* {showId ?formik.values.identification.slice(4):"****"}{showId ? '(' + formik.values.checkDigit + ')' :null} */} | |||||
| {showId ? formik.values.identification?.slice(4) : "****"}{showId ? formik.values.checkDigit?'(' +formik.values.checkDigit+ ')': "()" : ""} | |||||
| </Typography> | |||||
| <IconButton | |||||
| aria-label={intl.formatMessage({ id: 'ariaToggleIdVisibility' })} | |||||
| onClick={handleClickShowId} | |||||
| onMouseDown={handleMouseDownId} | |||||
| edge="end" | |||||
| size="large" | |||||
| > | |||||
| {showId ? <EyeOutlined /> : <EyeInvisibleOutlined />} | |||||
| </IconButton> | |||||
| </Stack> | |||||
| : | |||||
| // <Grid item xs={10} sm={4} md={4} lg={10}> | |||||
| // {FieldUtils.initField({ | |||||
| // valueName: "identification", | |||||
| // disabled: true, | |||||
| // form: formik | |||||
| // })} | |||||
| // </Grid> | |||||
| <Stack direction="row"> | |||||
| <Typography variant="h5" mt={1}> | |||||
| {formik.values.identification?.slice(0, 4)} | |||||
| </Typography> | |||||
| <Typography variant="h5"mt={1}> | |||||
| {showId ?formik.values.identification?.slice(4):"****"} | |||||
| </Typography> | |||||
| <IconButton | |||||
| aria-label={intl.formatMessage({ id: 'ariaToggleIdVisibility' })} | |||||
| onClick={handleClickShowId} | |||||
| onMouseDown={handleMouseDownId} | |||||
| edge="end" | |||||
| size="large" | |||||
| > | |||||
| {showId ? <EyeOutlined /> : <EyeInvisibleOutlined />} | |||||
| </IconButton> | |||||
| </Stack> | |||||
| } | |||||
| </Grid> | |||||
| <Typography variant="h5" mt={1}> | |||||
| {formik.values.identification?.slice(0, 4)} | |||||
| </Typography> | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -30,6 +30,8 @@ const EmailTemplateDetailPage = Loadable(lazy(() => import('pages/EmailTemplate/ | |||||
| const HolidayPage = Loadable(lazy(() => import('pages/Holiday'))); | const HolidayPage = Loadable(lazy(() => import('pages/Holiday'))); | ||||
| const GazetteIssuePage = Loadable(lazy(() => import('pages/GazetteIssue/index'))); | const GazetteIssuePage = Loadable(lazy(() => import('pages/GazetteIssue/index'))); | ||||
| const DrImport = Loadable(lazy(() => import('pages/Setting/DrImport'))); | const DrImport = Loadable(lazy(() => import('pages/Setting/DrImport'))); | ||||
| const HkidKeyMigration = Loadable(lazy(() => import('pages/Setting/HkidKeyMigration'))); | |||||
| const UserPiiEncryption = Loadable(lazy(() => import('pages/Setting/UserPiiEncryption'))); | |||||
| const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index'))); | const AuditLogPage = Loadable(lazy(() => import('pages/AuditLog/index'))); | ||||
| const ReconReportPage = Loadable(lazy(() => import('pages/Recon'))); | const ReconReportPage = Loadable(lazy(() => import('pages/Recon'))); | ||||
| const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage'))); | const ChangePasswordPage = Loadable(lazy(() => import('pages/User/ChangePasswordPage'))); | ||||
| @@ -190,6 +192,18 @@ const GLDUserRoutes = { | |||||
| element: <DrImport /> | element: <DrImport /> | ||||
| }:{}, | }:{}, | ||||
| isGranted("MAINTAIN_SETTING")? | |||||
| { | |||||
| path: '/setting/hkidKeyMigration', | |||||
| element: <HkidKeyMigration /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_SETTING")? | |||||
| { | |||||
| path: '/setting/userPiiEncryption', | |||||
| element: <UserPiiEncryption /> | |||||
| }:{}, | |||||
| isGranted("MAINTAIN_SETTING")? | isGranted("MAINTAIN_SETTING")? | ||||
| { | { | ||||
| path: '/setting/auditLog', | path: '/setting/auditLog', | ||||
| @@ -413,6 +413,7 @@ | |||||
| "payDateTo": "Payment Date (To)", | "payDateTo": "Payment Date (To)", | ||||
| "payStatus": "Payment Status", | "payStatus": "Payment Status", | ||||
| "payId": "Payment No.", | "payId": "Payment No.", | ||||
| "payIdNRefer": "Payment No. / Payment Reference No.", | |||||
| "payConfirm": "Confirm payment", | "payConfirm": "Confirm payment", | ||||
| "payCancel": "Cancel payment", | "payCancel": "Cancel payment", | ||||
| "payAlert": "Please don’t close this window, you may either complete this payment or cancel this payment by the button at the bottom of this page.", | "payAlert": "Please don’t close this window, you may either complete this payment or cancel this payment by the button at the bottom of this page.", | ||||
| @@ -421,7 +422,7 @@ | |||||
| "payTotal": "Total Payment Amount", | "payTotal": "Total Payment Amount", | ||||
| "payDetail": "Payment Details", | "payDetail": "Payment Details", | ||||
| "payMethod": "Payment methods", | "payMethod": "Payment methods", | ||||
| "epayMethod": " e-Payment Method", | |||||
| "epayMethod": " Payment Method", | |||||
| "selectPaymentMethod": "Please select a payment method", | "selectPaymentMethod": "Please select a payment method", | ||||
| "payReceipt": "Payment Receipt", | "payReceipt": "Payment Receipt", | ||||
| "contactPerson": "Contact Person", | "contactPerson": "Contact Person", | ||||
| @@ -447,7 +448,7 @@ | |||||
| "paymentLimitPrice2":" is only applicable when minimum amount is HK$0.10 and maximum amount is HK$9,999,999.99", | "paymentLimitPrice2":" is only applicable when minimum amount is HK$0.10 and maximum amount is HK$9,999,999.99", | ||||
| "paymentLimitPPS":" Payment could not be made via mobile device browsers, please use desktop computers to make payment.", | "paymentLimitPPS":" Payment could not be made via mobile device browsers, please use desktop computers to make payment.", | ||||
| "paymentMethod": "Payment Method", | "paymentMethod": "Payment Method", | ||||
| "paymentProcessLimited":"Payment process must be completed within 30 minutes and return to this system.", | |||||
| "paymentProcessLimited":"Please complete the payment process within 15 minutes. Note: For FPS payments, scanning, payment and all necessary approvals must be finished within 3 minutes due to security-related QR code expiry.", | |||||
| "publicNoticeDetailTitle": "Public Notice Application Information", | "publicNoticeDetailTitle": "Public Notice Application Information", | ||||
| "applyPerson": "Applicant", | "applyPerson": "Applicant", | ||||
| @@ -446,6 +446,7 @@ | |||||
| "payDateTo": "付款日期 (到)", | "payDateTo": "付款日期 (到)", | ||||
| "payStatus": "付款状况", | "payStatus": "付款状况", | ||||
| "payId": "付款编号", | "payId": "付款编号", | ||||
| "payIdNRefer": "付款编号 / 付款参考编号", | |||||
| "payConfirm": "确认付款", | "payConfirm": "确认付款", | ||||
| "payCancel": "取消付款", | "payCancel": "取消付款", | ||||
| "payAlert": "请不要关闭此窗口,您可以通过此页面底部的按钮完成此付款或取消此付款。", | "payAlert": "请不要关闭此窗口,您可以通过此页面底部的按钮完成此付款或取消此付款。", | ||||
| @@ -454,7 +455,7 @@ | |||||
| "payTotal": "付款总额", | "payTotal": "付款总额", | ||||
| "payDetail": "付款详情", | "payDetail": "付款详情", | ||||
| "payMethod": "付款方式", | "payMethod": "付款方式", | ||||
| "epayMethod": "电子付款方法", | |||||
| "epayMethod": "付款方法", | |||||
| "selectPaymentMethod": "请选择付款方法", | "selectPaymentMethod": "请选择付款方法", | ||||
| "payReceipt": "付款收据", | "payReceipt": "付款收据", | ||||
| "contactPerson": "联络人", | "contactPerson": "联络人", | ||||
| @@ -481,7 +482,7 @@ | |||||
| "paymentLimitPrice2":"只适用于最小金额为 0.10 港元及最高金额为 9,999,999.99港元", | "paymentLimitPrice2":"只适用于最小金额为 0.10 港元及最高金额为 9,999,999.99港元", | ||||
| "paymentLimitPPS":"付款不适用于流动装置的浏览器,请使用桌面电脑。", | "paymentLimitPPS":"付款不适用于流动装置的浏览器,请使用桌面电脑。", | ||||
| "paymentMethod": "付款方式", | "paymentMethod": "付款方式", | ||||
| "paymentProcessLimited":"付款过程必须在 30 分钟内完成及返回本系统。", | |||||
| "paymentProcessLimited":"请于15分钟内完成付款程序。 注意:使用转数快(FPS)时,因二维码具安全时效限制,须于3分钟内完成扫码、付款及所有相关审核程序。", | |||||
| "publicNoticeDetailTitle": "公共启事申请资料", | "publicNoticeDetailTitle": "公共启事申请资料", | ||||
| "applyPerson": "申请人", | "applyPerson": "申请人", | ||||
| @@ -447,6 +447,7 @@ | |||||
| "payDateTo": "付款日期 (到)", | "payDateTo": "付款日期 (到)", | ||||
| "payStatus": "付款狀況", | "payStatus": "付款狀況", | ||||
| "payId": "付款編號", | "payId": "付款編號", | ||||
| "payIdNRefer": "付款編號 / 付款參考編號", | |||||
| "payConfirm": "確認付款", | "payConfirm": "確認付款", | ||||
| "payCancel": "取消付款", | "payCancel": "取消付款", | ||||
| "payAlert": "請不要關閉此窗口,您可以透過本頁底部的按鈕完成此付款或取消本付款。", | "payAlert": "請不要關閉此窗口,您可以透過本頁底部的按鈕完成此付款或取消本付款。", | ||||
| @@ -455,7 +456,7 @@ | |||||
| "payTotal": "付款總額", | "payTotal": "付款總額", | ||||
| "payDetail": "付款詳情", | "payDetail": "付款詳情", | ||||
| "payMethod": "付款方式", | "payMethod": "付款方式", | ||||
| "epayMethod": "電子付款方法", | |||||
| "epayMethod": "付款方法", | |||||
| "selectPaymentMethod": "請選擇付款方法", | "selectPaymentMethod": "請選擇付款方法", | ||||
| "payReceipt": "付款收據", | "payReceipt": "付款收據", | ||||
| "contactPerson": "聯絡人", | "contactPerson": "聯絡人", | ||||
| @@ -482,7 +483,7 @@ | |||||
| "paymentLimitPrice2":"只適用於最小金額為 0.10 港元及最高金額為 9,999,999.99港元", | "paymentLimitPrice2":"只適用於最小金額為 0.10 港元及最高金額為 9,999,999.99港元", | ||||
| "paymentLimitPPS":"付款不適用於流動裝置的瀏覽器,請使用桌面電腦。", | "paymentLimitPPS":"付款不適用於流動裝置的瀏覽器,請使用桌面電腦。", | ||||
| "paymentMethod": "付款方法", | "paymentMethod": "付款方法", | ||||
| "paymentProcessLimited":"付款程序必須在 30 分鐘內完成及返回本系统。", | |||||
| "paymentProcessLimited":"請於15分鐘內完成付款程序。 注意:使用轉數快(FPS)時,因二維碼具安全時效限制,須於3分鐘內完成掃碼、付款及所有相關審核程序。", | |||||
| "publicNoticeDetailTitle": "公共啟事申請資料", | "publicNoticeDetailTitle": "公共啟事申請資料", | ||||
| "applyPerson": "申請人", | "applyPerson": "申請人", | ||||
| @@ -84,6 +84,9 @@ export const GET_FILE_DELETE = apiPath+'/file/delete'; | |||||
| export const DR_EXPORT = apiPath+'/settings/dr/export'; | export const DR_EXPORT = apiPath+'/settings/dr/export'; | ||||
| export const DR_IMPORT = apiPath+'/settings/dr/import'; | export const DR_IMPORT = apiPath+'/settings/dr/import'; | ||||
| export const OFFLINE_IMPORT = apiPath+'/settings/dr/importOffline'; | export const OFFLINE_IMPORT = apiPath+'/settings/dr/importOffline'; | ||||
| export const HKID_REKEY_MIGRATION = apiPath+'/settings/migration/hkid-rekey'; | |||||
| export const USER_PII_ENCRYPT_MIGRATION = apiPath+'/settings/migration/user-pii-encrypt'; | |||||
| export const USER_PII_VERIFY_MIGRATION = apiPath+'/settings/migration/user-pii-verify'; | |||||
| export const AUDIT_LOG_EXPORT = apiPath+'/settings/auditLog-export'; | export const AUDIT_LOG_EXPORT = apiPath+'/settings/auditLog-export'; | ||||
| @@ -180,6 +183,7 @@ export const PAYMENT_LOAD = apiPath+'/payment/load';//GET | |||||
| export const PAYMENT_APP_LIST = apiPath+'/payment/applist';//POST | export const PAYMENT_APP_LIST = apiPath+'/payment/applist';//POST | ||||
| export const PAYMENT_CHECK = apiPath+'/payment/check-payment';//GET | export const PAYMENT_CHECK = apiPath+'/payment/check-payment';//GET | ||||
| export const PAYMENT_BIB = apiPath+'/payment/set-bib';//POST | export const PAYMENT_BIB = apiPath+'/payment/set-bib';//POST | ||||
| export const PAYMENT_MARK_AS_PAID = apiPath+'/payment/mark-as-paid';//POST | |||||
| export const PAYMENT_GFMIS_LIST = apiPath+'/payment/listGFMIS';//GET | export const PAYMENT_GFMIS_LIST = apiPath+'/payment/listGFMIS';//GET | ||||
| export const PAYMENT_LIMIT_SETTING_LIST = apiPath+'/settings/payment';//GET | export const PAYMENT_LIMIT_SETTING_LIST = apiPath+'/settings/payment';//GET | ||||