Browse Source

add payment holding check and report layout fix

master
Alex Cheung 1 year ago
parent
commit
0d1cec77bf
8 changed files with 282 additions and 188 deletions
  1. +5
    -1
      src/pages/Payment/Details_GLD/PaymentDetails.js
  2. +20
    -1
      src/pages/Payment/Details_GLD/index.js
  3. +183
    -183
      src/pages/Payment/index.js
  4. +68
    -1
      src/pages/PublicNotice/ListPanel/PendingPaymentTab.js
  5. +1
    -0
      src/translations/en.json
  6. +2
    -1
      src/translations/zh-CN.json
  7. +1
    -0
      src/translations/zh-HK.json
  8. +2
    -1
      src/utils/ApiPathConst.js

+ 5
- 1
src/pages/Payment/Details_GLD/PaymentDetails.js View File

@@ -14,7 +14,7 @@ const MainCard = Loadable(React.lazy(() => import('components/MainCard')));
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
import DownloadIcon from '@mui/icons-material/Download';
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const PaymentDetails = ({ formData,doPrint }) => {
const PaymentDetails = ({ formData,doPrint,onDownload }) => {

const [data, setData] = React.useState({});
const [onReady, setOnReady] = React.useState(false);
@@ -158,10 +158,14 @@ const PaymentDetails = ({ formData,doPrint }) => {
</FormLabel>
</Grid>
<Grid xs={6} md={5} sx={{ml:5,textAlign: "left" }}>
{onDownload?
<LoadingComponent disableText={true} alignItems="flex-start"/>
:
<Button className="printHidden" variant="contained" sx={{ mt:2 }} onClick={doPrint}>
<DownloadIcon/>
<Typography sx={{fontSize: "16px"}}>Download</Typography>
</Button>
}
</Grid>
</Grid>
</Grid>


+ 20
- 1
src/pages/Payment/Details_GLD/index.js View File

@@ -4,7 +4,7 @@ import {
Typography,
Stack,
Box,
// Button
Button
} from '@mui/material';
import * as UrlUtils from "utils/ApiPathConst";
import * as React from "react";
@@ -12,6 +12,7 @@ import * as HttpUtils from "utils/HttpUtils";
import * as DateUtils from "utils/DateUtils";
import { useParams } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import ForwardIcon from '@mui/icons-material/Forward';

import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
@@ -37,6 +38,7 @@ const Index = () => {
const [record, setRecord] = React.useState();
const [itemList, setItemList] = React.useState([]);
const [onReady, setOnReady] = React.useState(false);
const [onDownload, setOnDownload] = React.useState(false);
// const [detailsOrder, setDetailsOrder] = React.useState(2);

React.useEffect(() => {
@@ -54,8 +56,15 @@ const Index = () => {

const doPrint = () => {
// window.print();
setOnDownload(true)
HttpUtils.fileDownload({
url: UrlUtils.GEN_PAYMENT_RECEIPT+"/"+params.id,
onResponse:()=>{
setOnDownload(false)
},
onError:()=>{
setOnDownload(false)
}
});
};

@@ -98,6 +107,15 @@ const Index = () => {
</Stack>
</div>
</Grid>
<Grid item xs={12} width={{xs:"90%", sm:"90%", md:"90%", lg:"90%"}}>
<Button
aria-label={"back"}
title={"back"}
sx={{ ml: 0, mt: 2.5 }} style={{ border: '2px solid' }} variant="outlined" onClick={() => { navigate(-1) }}
>
<ForwardIcon style={{ height: 30, width: 50, transform: "rotate(180deg)" }} />
</Button>
</Grid>
{/*row 1*/}
<Grid item xs={12} md={12} sx={{textAlign: "center" }}>
<Grid container justifyContent="center" direction="column" spacing={2} sx={{ p: 2 }} alignitems="stretch" >
@@ -106,6 +124,7 @@ const Index = () => {
<PaymentDetails
formData={record}
doPrint={doPrint}
onDownload={onDownload}
style={{
display: "flex",
height: "100%",


+ 183
- 183
src/pages/Payment/index.js View File

@@ -140,29 +140,11 @@ const Index = () => {
paymentMethod = "01,PPSB,PPS";
}
if (paymentMethod != "") {
HttpUtils.post({
url: UrlUtils.PAYMENT_CREATE,
params: {
transNo: transactionData.transactionid,
payMethod: paymentMethod,
payAmount: totalAmount,
appIdList: location.state?.appIdList ?? []
},
onSuccess: function (responData) {
localStorage.removeItem("paymentId");
localStorage.setItem("paymentId", responData.id)
navigate(page, stateParams);
}
});
}

// //For testing
// if (paymentMethod != "") {
// HttpUtils.post({
// url: UrlUtils.PAYMENT_CREATE,
// params: {
// transNo: "test0001",
// transNo: transactionData.transactionid,
// payMethod: paymentMethod,
// payAmount: totalAmount,
// appIdList: location.state?.appIdList ?? []
@@ -174,181 +156,199 @@ const Index = () => {
// }
// });
// }
}
}, [afterConfirmPayment]);

const getAvailablePayment = () =>{
HttpUtils.post({
url: UrlUtils.PAYMENT_AVAILABLE_PAYMENT,
params: {
"locale": locale === 'en' ?Utils.local.en:locale === 'zh-HK' ?Utils.local.zh:Utils.local.cn,
"amount": totalAmount,
// "eserviceids": [
// "<eserviceid>", "<eserviceid>"
// ],
"preferpaymentmethods": Utils.preferpaymentmethods
},
onSuccess: (responseData) => {
let availableMethods = responseData.availablepaymentmethods;
setAvailableMethods(availableMethods);
HttpUtils.get({
url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST,
params: {},
onSuccess: (responseData) => {
// console.log(responseData)
setPaymentLimit(responseData)
//For testing
if (paymentMethod != "") {
HttpUtils.post({
url: UrlUtils.PAYMENT_CREATE,
params: {
transNo: "test0002",
payMethod: paymentMethod,
payAmount: totalAmount,
appIdList: location.state?.appIdList ?? []
},
onError: () =>{
// setOnReady(true)
onSuccess: function (responData) {
localStorage.removeItem("paymentId");
localStorage.setItem("paymentId", responData.id)
navigate(page, stateParams);
}
});
},
onError: () =>{
setOnReady(true)
}
});
// HttpUtils.get({
// url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST,
// params: {},
// onSuccess: (responseData) => {
// // console.log(responseData)
// setPaymentLimit(responseData)
}
}, [afterConfirmPayment]);

const getAvailablePayment = () =>{
// HttpUtils.post({
// url: UrlUtils.PAYMENT_AVAILABLE_PAYMENT,
// params: {
// "locale": locale === 'en' ?Utils.local.en:locale === 'zh-HK' ?Utils.local.zh:Utils.local.cn,
// "amount": totalAmount,
// // "eserviceids": [
// // "<eserviceid>", "<eserviceid>"
// // ],
// "preferpaymentmethods": Utils.preferpaymentmethods
// },
// onSuccess: (responseData) => {
// let availableMethods = responseData.availablepaymentmethods;
// setAvailableMethods(availableMethods);
// HttpUtils.get({
// url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST,
// params: {},
// onSuccess: (responseData) => {
// // console.log(responseData)
// setPaymentLimit(responseData)
// },
// onError: () =>{
// // setOnReady(true)
// }
// });
// },
// onError: () =>{
// // setOnReady(true)
// setOnReady(true)
// }
// });
HttpUtils.get({
url: UrlUtils.PAYMENT_LIMIT_SETTING_LIST,
params: {},
onSuccess: (responseData) => {
// console.log(responseData)
setPaymentLimit(responseData)

},
onError: () =>{
// setOnReady(true)
}
});

// const responseData = {
// "availablepaymentmethods": [
// {
// "active": "Y",
// "code": "04,BCFP,FPS",
// "pointstonote": [
// {
// "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
// "order": 10,
// "type": "INFO"
// },
// {
// "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
// "order": 11,
// "type": "INFO"
// }
// ],
// "subtype": "FPS"
// },
// {
// "active": "Y",
// "code": "02,BCMP,CreditCard",
// "pointstonote": [
// {
// "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
// "order": 10,
// "type": "INFO"
// },
// {
// "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
// "order": 11,
// "type": "INFO"
// },
// {
// "content": "Merchant Name is applicable to credit card payment method only.",
// "order": 40,
// "type": "INFO"
// },
// {
// "content": "Under exceptional conditions, a refund may need to be arranged. If the payment is made by Credit Card, the refund can normally be made to the Credit Card account that is used for the payment.",
// "order": 41,
// "type": "INFO"
// },
// {
// "content": "Some users may receive an error page or have to wait for several minutes before they get a response from the credit card payment gateway. If you experience such a problem, please wait a moment and retry, or change to use other available payment methods. We apologise for any inconvenience caused.",
// "order": 42,
// "type": "INFO"
// },
// {
// "content": "Different credit card issuers may have implemented different mechanisms to authenticate the cardholder's identity during online payment. Please contact your card issuer if you want to learn more about the J/Secure, MasterCard SecureCode and Verified by Visa service. ",
// "order": 43,
// "type": "INFO"
// }
// ],
// "subtype": "CreditCard",
// "supportedcard": [
// "JCB",
// "MasterCard",
// "Visa"
// ]
// },
// {
// "active": "Y",
// "code": "03,BCMP,CreditCard",
// "pointstonote": [
// {
// "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
// "order": 10,
// "type": "INFO"
// },
// {
// "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
// "order": 11,
// "type": "INFO"
// },
// {
// "content": "Merchant Name is applicable to credit card payment method only.",
// "order": 40,
// "type": "INFO"
// },
// {
// "content": "Under exceptional conditions, a refund may need to be arranged. If the payment is made by Credit Card, the refund can normally be made to the Credit Card account that is used for the payment.",
// "order": 41,
// "type": "INFO"
// },
// {
// "content": "Some users may receive an error page or have to wait for several minutes before they get a response from the credit card payment gateway. If you experience such a problem, please wait a moment and retry, or change to use other available payment methods. We apologise for any inconvenience caused.",
// "order": 42,
// "type": "INFO"
// },
// {
// "content": "Different credit card issuers may have implemented different mechanisms to authenticate the cardholder's identity during online payment. Please contact your card issuer if you want to learn more about the J/Secure, MasterCard SecureCode and Verified by Visa service. ",
// "order": 43,
// "type": "INFO"
// }
// ],
// "subtype": "CreditCard",
// "supportedcard": [
// "UnionPay"
// ]
// },
// {
// "active": "Y",
// "code": "01,PPSB,PPS",
// "pointstonote": [
// {
// "content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
// "order": 10,
// "type": "INFO"
// },
// {
// "content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
// "order": 11,
// "type": "INFO"
// },
// {
// "content": "PPS Shop&Buy (PPS) does not support payment via browsers of mobile devices (including mobile phones and tablets) at the moment. If you wish to pay by PPS, please change to use desktop computer. ",
// "order": 21,
// "type": "INFO"
// }
// ],
// "subtype": "PPS"
// }
// ]
// };
// let availableMethods = responseData.availablepaymentmethods;
// setAvailableMethods(availableMethods);
const responseData = {
"availablepaymentmethods": [
{
"active": "Y",
"code": "04,BCFP,FPS",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
"order": 11,
"type": "INFO"
}
],
"subtype": "FPS"
},
{
"active": "Y",
"code": "02,BCMP,CreditCard",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
"order": 11,
"type": "INFO"
},
{
"content": "Merchant Name is applicable to credit card payment method only.",
"order": 40,
"type": "INFO"
},
{
"content": "Under exceptional conditions, a refund may need to be arranged. If the payment is made by Credit Card, the refund can normally be made to the Credit Card account that is used for the payment.",
"order": 41,
"type": "INFO"
},
{
"content": "Some users may receive an error page or have to wait for several minutes before they get a response from the credit card payment gateway. If you experience such a problem, please wait a moment and retry, or change to use other available payment methods. We apologise for any inconvenience caused.",
"order": 42,
"type": "INFO"
},
{
"content": "Different credit card issuers may have implemented different mechanisms to authenticate the cardholder's identity during online payment. Please contact your card issuer if you want to learn more about the J/Secure, MasterCard SecureCode and Verified by Visa service. ",
"order": 43,
"type": "INFO"
}
],
"subtype": "CreditCard",
"supportedcard": [
"JCB",
"MasterCard",
"Visa"
]
},
{
"active": "Y",
"code": "03,BCMP,CreditCard",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
"order": 11,
"type": "INFO"
},
{
"content": "Merchant Name is applicable to credit card payment method only.",
"order": 40,
"type": "INFO"
},
{
"content": "Under exceptional conditions, a refund may need to be arranged. If the payment is made by Credit Card, the refund can normally be made to the Credit Card account that is used for the payment.",
"order": 41,
"type": "INFO"
},
{
"content": "Some users may receive an error page or have to wait for several minutes before they get a response from the credit card payment gateway. If you experience such a problem, please wait a moment and retry, or change to use other available payment methods. We apologise for any inconvenience caused.",
"order": 42,
"type": "INFO"
},
{
"content": "Different credit card issuers may have implemented different mechanisms to authenticate the cardholder's identity during online payment. Please contact your card issuer if you want to learn more about the J/Secure, MasterCard SecureCode and Verified by Visa service. ",
"order": 43,
"type": "INFO"
}
],
"subtype": "CreditCard",
"supportedcard": [
"UnionPay"
]
},
{
"active": "Y",
"code": "01,PPSB,PPS",
"pointstonote": [
{
"content": "Please take note of the transaction reference number or PRINT this page for making enquiry on the payment status when necessary.",
"order": 10,
"type": "INFO"
},
{
"content": "After pressing the 'Pay' button, please DO NOT leave this e-service until you receive the acknowledgement page, otherwise your transaction may not be successful.",
"order": 11,
"type": "INFO"
},
{
"content": "PPS Shop&Buy (PPS) does not support payment via browsers of mobile devices (including mobile phones and tablets) at the moment. If you wish to pay by PPS, please change to use desktop computer. ",
"order": 21,
"type": "INFO"
}
],
"subtype": "PPS"
}
]
};
let availableMethods = responseData.availablepaymentmethods;
setAvailableMethods(availableMethods);
}

useEffect(() => {


+ 68
- 1
src/pages/PublicNotice/ListPanel/PendingPaymentTab.js View File

@@ -34,6 +34,8 @@ export default function SubmittedTab({ rows }) {
const [selectedCareOf, setSelectedCareOf] = React.useState(null);
const [expiryDateErrText, setExpiryDateErrText] = React.useState("");
const [expiryDateErr, setExpiryDateErr] = React.useState(false);
const [paymentHoldedErrText, setPaymentHoldedErrText] = React.useState("");
const [paymentHoldedErr, setPaymentHoldedErr] = React.useState(false);
const theme = useTheme();
const isMdOrLg = useMediaQuery(theme.breakpoints.up('md'));
const intl = useIntl();
@@ -103,7 +105,8 @@ export default function SubmittedTab({ rows }) {
},
onSuccess: (responData) => {
if (responData.success == true) {
setIsPopUp(true);
// setIsPopUp(true);
handlePaymentCheck(appIdList)
return;
}
let str = "";
@@ -114,8 +117,45 @@ export default function SubmittedTab({ rows }) {
setExpiryDateErr(true);
}
});
};

const handlePaymentCheck = (appIdList) => {
HttpUtils.post({
url: UrlUtils.PAYMENT_CHECK,
params: {
appIds: appIdList
},
onSuccess: (responseData) => {
const latestData = {};

responseData.forEach(item => {
const { appId, timeDiff } = item;
if (latestData[appId] === undefined || timeDiff < latestData[appId].timeDiff) {
latestData[appId] = item;
}
});
const latestDataObjects = Object.values(latestData);
const filteredData = latestDataObjects.filter(item => item.timeDiff > 20 && item.status !== "APPR");
const filteredAppIds = filteredData.map(item => item.appId);
const appIdsNotInData = appIdList.filter(appId => !latestDataObjects.some(item => item.appId === appId));
const combinedAppIdsArray = [...appIdsNotInData, ...filteredAppIds];
const readyToPayment = appIdList.every(appId => combinedAppIdsArray.includes(appId));
if (readyToPayment){
setIsPopUp(true);
return;
}else{
const appIdsInData = appIdList.filter(appId => !combinedAppIdsArray.some(item => item === appId));
const HoldingApplication = latestDataObjects.filter(item => appIdsInData.includes(item.appId));
const resultString = HoldingApplication.map(item => item.appNo).join(' , ');
setPaymentHoldedErrText(resultString);
// setPaymentHoldedErrText(intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: record.appNo }));
setPaymentHoldedErr(true);
}
}
});
};

const columns = [
@@ -405,6 +445,33 @@ export default function SubmittedTab({ rows }) {
</DialogActions>
</Dialog>
</div>
<div>
<Dialog
open={paymentHoldedErr}
onClose={() => setPaymentHoldedErr(false)}
PaperProps={{
sx: {
minWidth: '40vw',
maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
}
}}
>
<DialogTitle></DialogTitle>
<Typography variant="h4" style={{ paddingLeft: '24px' }}><FormattedMessage id="MSG.actionFail" /></Typography>
<DialogContent style={{ display: 'flex', }}>
<Stack direction="column" justifyContent="space-between">
<div dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: 'MSG.paymentHolded' }, { appNo: paymentHoldedErrText }) }} />
</Stack>
</DialogContent>
<DialogActions>
<Button onClick={() => setPaymentHoldedErr(false)} aria-label={intl.formatMessage({ id: 'close' })}>
<Typography variant="h5">
<FormattedMessage id="close" />
</Typography></Button>
</DialogActions>
</Dialog>
</div>
</>
);



+ 1
- 0
src/translations/en.json View File

@@ -67,6 +67,7 @@
"MSG.proofOutOfTime": "Response out of time, please apply again.",
"MSG.plzSelectApp": "Please select application",
"MSG.actionFail": "Action failed",
"MSG.paymentHolded": "Application number {appNo} is currently in the process of payment. If the payment is unsuccessful, please try again after 20 minutes. We apologise for any inconvenience caused.",

"registerTitle1": "Become",
"registerTitle2": "Gazette Notice",


+ 2
- 1
src/translations/zh-CN.json View File

@@ -66,7 +66,8 @@
"MSG.proofOutOfTime": "回覆逾时,请重新申请。",
"MSG.plzSelectApp": "请选择公共启事。",
"MSG.actionFail": "行动失败",

"MSG.paymentHolded": "申请编号 {appNo} 已正在付款的流程中,如相关付款没有成功,请于20分钟后再尝试付款,不便之处,请见谅!",
"registerTitle1": "立即成为",
"registerTitle2": "宪报刊登公共启事",
"registerTitle3": "用户",


+ 1
- 0
src/translations/zh-HK.json View File

@@ -66,6 +66,7 @@
"MSG.proofOutOfTime": "回覆逾時,請重新申請。",
"MSG.plzSelectApp": "請選擇公共啟事。",
"MSG.actionFail": "行動失敗",
"MSG.paymentHolded": "申請編號 {appNo} 已正在付款的流程中,如相關付款沒有成功,請於20分鐘後再嘗試付款,不便之處,請見諒!",

"registerTitle1": "立即成為",
"registerTitle2": "憲報刊登公共啟事",


+ 2
- 1
src/utils/ApiPathConst.js View File

@@ -133,12 +133,13 @@ export const PROOF_CHECK_PRICE = apiPath+'/proof/check-price';//GET
export const GET_PROOF_PAY = apiPath+'/proof/pay-details';//GET
export const CANCEL_PROOF = apiPath+'/proof/cancel';//GET

//payment
export const PAYMENT_CREATE = apiPath+'/payment/create';//POST
export const PAYMENT_SAVE = apiPath+'/payment/save';//POST
export const PAYMENT_LIST = apiPath+'/payment/list';//GET
export const PAYMENT_LOAD = apiPath+'/payment/load';//GET
export const PAYMENT_APP_LIST = apiPath+'/payment/applist';//POST
export const PAYMENT_CHECK = apiPath+'/payment/check-payment';//GET

export const PAYMENT_LIMIT_SETTING_LIST = apiPath+'/settings/payment';//GET
export const PAYMENT_AVAILABLE_PAYMENT = paymentPath+'/api/payment/availability';//POST


Loading…
Cancel
Save