您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

637 行
32 KiB

  1. // material-ui
  2. import {
  3. Grid, Button, Checkbox, FormControlLabel, Typography,
  4. Dialog, DialogTitle, DialogContent, DialogActions,
  5. FormHelperText, TextField,
  6. } from '@mui/material';
  7. // import { FormControlLabel } from '@material-ui/core';
  8. import MainCard from "components/MainCard";
  9. import * as React from "react";
  10. import { useFormik } from 'formik';
  11. import { useForm } from "react-hook-form";
  12. import * as yup from 'yup';
  13. import { useEffect, useState, lazy } from "react";
  14. import * as DateUtils from 'utils/DateUtils';
  15. import * as HttpUtils from 'utils/HttpUtils';
  16. import * as UrlUtils from "utils/ApiPathConst";
  17. import * as FieldUtils from "utils/FieldUtils";
  18. import * as ComboData from "utils/ComboData";
  19. const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
  20. import Loadable from 'components/Loadable';
  21. import { notifySaveSuccess } from 'utils/CommonFunction';
  22. import { useIntl } from "react-intl";
  23. import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
  24. import { ThemeProvider } from "@emotion/react";
  25. import { isGrantedAny } from "auth/utils";
  26. import { DatePicker } from "@mui/x-date-pickers/DatePicker";
  27. import dayjs from "dayjs";
  28. import { DemoItem } from "@mui/x-date-pickers/internals/demo";
  29. import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
  30. import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
  31. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  32. const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
  33. const intl = useIntl();
  34. const [creditorConfirmPopUp, setCreditorConfirmPopUp] = React.useState(false);
  35. const [nonCreditorConfirmPopUp, setNonCreditorConfirmPopUp] = React.useState(false);
  36. const [currentUserData, setCurrentUserData] = useState({});
  37. const [editMode, setEditMode] = useState(false);
  38. const [createMode, setCreateMode] = useState(false);
  39. const [onReady, setOnReady] = useState(false);
  40. const [errorMsg, setErrorMsg] = useState("");
  41. const [minDate] = React.useState(new Date().setDate(new Date().getDate() + 1));
  42. const [fromDate, setFromDate] = React.useState(null);
  43. const [currentFromDate, setCurrentFromDate] = React.useState(null);
  44. const [fromDateValue, setFromDateValue] = React.useState(null);
  45. const { register, handleSubmit, reset } = useForm()
  46. React.useEffect(() => {
  47. setFromDateValue(fromDate);
  48. }, [fromDate]);
  49. useEffect(() => {
  50. //if state data are ready and assign to different field
  51. // console.log(currentApplicationDetailData)
  52. if (Object.keys(currentUserData).length > 0) {
  53. console.log(currentUserData)
  54. if (DateUtils.dateValue(currentUserData.brExpiryDate) > DateUtils.dateValue(minDate)) {
  55. setFromDate(currentUserData.brExpiryDate);
  56. } else {
  57. setCurrentFromDate(currentUserData.brExpiryDate);
  58. // setErrorMsg("Please select a date after today.")
  59. }
  60. setOnReady(true);
  61. }
  62. }, [currentUserData]);
  63. function displayErrorMsg(errorMsg) {
  64. return <Typography variant="errorMessage1">{errorMsg}</Typography>
  65. }
  66. function getMaxErrStr(num, fieldname) {
  67. return displayErrorMsg(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: num, fieldname: fieldname ? intl.formatMessage({ id: fieldname }) + ": " : "" }));
  68. }
  69. function getRequiredErrStr(fieldname) {
  70. return displayErrorMsg(intl.formatMessage({ id: 'require' }, { fieldname: fieldname ? intl.formatMessage({ id: fieldname }) : "" }));
  71. }
  72. const formik = useFormik({
  73. enableReinitialize: true,
  74. initialValues: currentUserData,
  75. validationSchema: yup.object().shape({
  76. enCompanyName: yup.string().max(255, getMaxErrStr(255)).required(displayErrorMsg(intl.formatMessage({ id: 'userRequireEnglishName' }))),
  77. chCompanyName: yup.string().max(255, displayErrorMsg(intl.formatMessage({ id: 'userRequireChineseName' }))).nullable(),
  78. orgShortName: yup.string().max(24, getMaxErrStr(24)).required(getRequiredErrStr("orgShortName")),
  79. addressLine1: yup.string().max(40, getMaxErrStr(40)).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))),
  80. addressLine2: yup.string().max(40, getMaxErrStr(40)),
  81. addressLine3: yup.string().max(40, getMaxErrStr(40)),
  82. contactPerson: yup.string().max(60, getMaxErrStr(60)).required(getRequiredErrStr("contactPerson")),
  83. fax_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))).nullable(),
  84. tel_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))),
  85. phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requiredValidNumber' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))),
  86. faxNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'require8Number' }))).nullable(),
  87. brExpiryDate: yup.string().min(8).required(displayErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' }))),
  88. brNo: yup.string().required(displayErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertNumber' }))).test('checkBrNoFormat', displayErrorMsg(displayErrorMsg(intl.formatMessage({ id: 'pleaseFillInValidBusinessRegCertNumber' }))), function (value) {
  89. var brNo_pattern = /[0-9]{8}/
  90. if (value !== undefined) {
  91. if (value.match(brNo_pattern)) {
  92. return true
  93. } else {
  94. return false
  95. }
  96. }
  97. }),
  98. }),
  99. onSubmit: (values) => {
  100. if (values.country == null) {
  101. setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' }))
  102. } else {
  103. if (values.country.type == "hongKong" && values.district == null) {
  104. setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' }))
  105. } else {
  106. let sentDateFrom = "";
  107. if (fromDateValue == null) {
  108. setErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' }))
  109. } else {
  110. sentDateFrom = DateUtils.dateValue(fromDateValue)
  111. HttpUtils.post({
  112. url: UrlUtils.POST_ORG_SAVE_PATH,
  113. params: {
  114. id: id > 0 ? id : null,
  115. enCompanyName: values.enCompanyName,
  116. chCompanyName: values.chCompanyName,
  117. orgShortName: values.orgShortName === "N/A" ? "" : values.orgShortName,
  118. brNo: values.brNo,
  119. // brExpiryDate: values.brExpiryDate,
  120. brExpiryDate: sentDateFrom,
  121. enCompanyNameTemp: values.enCompanyNameTemp,
  122. chCompanyNameTemp: values.chCompanyNameTemp,
  123. brExpiryDateTemp: values.brExpiryDateTemp,
  124. contactPerson: values.contactPerson,
  125. contactTel: {
  126. countryCode: values.tel_countryCode,
  127. phoneNumber: values.phoneNumber
  128. },
  129. faxNo: {
  130. countryCode: values.fax_countryCode,
  131. faxNumber: values.faxNumber
  132. },
  133. addressTemp: {
  134. country: values.country.type,
  135. district: values.district?.type,
  136. addressLine1: values.addressLine1,
  137. addressLine2: values.addressLine2,
  138. addressLine3: values.addressLine3,
  139. },
  140. creditor: values.creditor,
  141. },
  142. onSuccess: function () {
  143. notifySaveSuccess()
  144. loadDataFun();
  145. setEditMode(false);
  146. }
  147. });
  148. }
  149. }
  150. }
  151. }
  152. });
  153. useEffect(() => {
  154. setEditModeFun(editMode);
  155. }, [editMode]);
  156. useEffect(() => {
  157. if (Object.keys(userData).length > 0) {
  158. setCreateMode(id <= 0);
  159. setEditMode(id <= 0);
  160. setCurrentUserData(userData);
  161. }
  162. }, [userData]);
  163. // useEffect(() => {
  164. // if (Object.keys(userData).length > 0) {
  165. // if(userData.creditor === undefined||userData.creditor === null){
  166. // userData.creditor = false
  167. // }
  168. // setCurrentUserData(userData);
  169. // }
  170. // }, []);
  171. const onEditClick = () => {
  172. setEditMode(true);
  173. };
  174. const onSubmit = (data) => {
  175. let sentOrgShortName = "";
  176. if (data.orgShortName != null && data.orgShortName != "" && data.orgShortName != "N/A") {
  177. sentOrgShortName = data.orgShortName
  178. if (sentOrgShortName.length <= 24) {
  179. const temp = {
  180. orgShortName: sentOrgShortName,
  181. };
  182. markAsCreditor(temp);
  183. } else {
  184. alert("Organisation Short Name must not exceed 24 characters.")
  185. }
  186. } else {
  187. alert("Please enter Organisation Short Name for Demand Note.")
  188. }
  189. };
  190. function resetForm() {
  191. reset();
  192. }
  193. const markAsCreditor = (temp) => {
  194. setCreditorConfirmPopUp(false);
  195. HttpUtils.post({
  196. url: UrlUtils.GET_ORG_MARK_AS_CREDITOR + "/" + id,
  197. params: temp,
  198. onSuccess: () => {
  199. resetForm();
  200. loadDataFun();
  201. }
  202. });
  203. }
  204. const markAsNonCreditor = () => {
  205. setNonCreditorConfirmPopUp(false);
  206. HttpUtils.get({
  207. url: UrlUtils.GET_ORG_MARK_AS_NON_CREDITOR + "/" + id,
  208. onSuccess: () => {
  209. loadDataFun();
  210. }
  211. });
  212. }
  213. const sendDn_terminationOfCredit = () => {
  214. setNonCreditorConfirmPopUp(false);
  215. HttpUtils.get({
  216. url: UrlUtils.GET_SEND_TERMINATION_OF_CREDIT + "/" + id,
  217. onSuccess: () => {
  218. loadDataFun();
  219. }
  220. });
  221. }
  222. return (
  223. <MainCard elevation={0}
  224. border={false}
  225. content={false}
  226. >
  227. <form onSubmit={formik.handleSubmit} style={{ padding: 24 }}>
  228. {/*top*/}
  229. {isGrantedAny("MAINTAIN_ORG") ?
  230. <Grid item s={12} md={12} lg={12} sx={{ mb: 3 }} alignItems={"start"} justifyContent="center">
  231. <Grid container maxWidth justifyContent="flex-start">
  232. {editMode ?
  233. <>
  234. {createMode ?
  235. <>
  236. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  237. <Grid item sx={{ ml: 0, mr: 3 }}>
  238. <Button
  239. variant="contained"
  240. type="submit"
  241. color="success"
  242. >
  243. Create
  244. </Button>
  245. </Grid>
  246. </ThemeProvider>
  247. </> :
  248. <>
  249. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  250. <Grid item sx={{ ml: 0, mr: 3 }}>
  251. <Button
  252. variant="contained"
  253. onClick={loadDataFun}
  254. color="cancel"
  255. >
  256. Reset & Back
  257. </Button>
  258. </Grid>
  259. <Grid item sx={{ ml: 3, mr: 3 }}>
  260. <Button
  261. variant="contained"
  262. type="submit"
  263. color="success"
  264. >
  265. Save
  266. </Button>
  267. </Grid>
  268. </ThemeProvider>
  269. </>
  270. }
  271. </>
  272. :
  273. <>
  274. <Grid item sx={{ ml: 0, mr: 3 }}>
  275. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  276. <Button
  277. variant="contained"
  278. onClick={onEditClick}
  279. color="success"
  280. >
  281. Edit
  282. </Button>
  283. </ThemeProvider>
  284. </Grid>
  285. {
  286. currentUserData.creditor ?
  287. <Grid item sx={{ ml: 3, mr: 3 }}>
  288. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  289. <Button
  290. variant="contained"
  291. color="error"
  292. onClick={() => setNonCreditorConfirmPopUp(true)}
  293. >
  294. Mark as Non-Credit Client
  295. </Button>
  296. </ThemeProvider>
  297. </Grid>
  298. :
  299. <>
  300. <Grid item sx={{ ml: 3, mr: 3 }}>
  301. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  302. <Button
  303. variant="contained"
  304. color="orange"
  305. onClick={() => setCreditorConfirmPopUp(true)}
  306. >
  307. Mark as Credit Client
  308. </Button>
  309. </ThemeProvider>
  310. </Grid>
  311. <Grid item sx={{ ml: 3, mr: 3 }}>
  312. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  313. <Button
  314. variant="contained"
  315. color="primary"
  316. onClick={() => sendDn_terminationOfCredit(true)}
  317. >
  318. Send &quot;Termination of Credit&quot; Email
  319. </Button>
  320. </ThemeProvider>
  321. </Grid>
  322. </>
  323. }
  324. </>
  325. }
  326. </Grid>
  327. </Grid>
  328. : <></>
  329. }
  330. {/*top*/}
  331. {!onReady ?
  332. <LoadingComponent />
  333. :
  334. <Grid container spacing={1}>
  335. <Grid item xs={12}>
  336. <Typography variant="h4" sx={{ mb: 2, mr: 3, borderBottom: "1px solid black" }}>
  337. Organisation Details
  338. </Typography>
  339. </Grid>
  340. <Grid item xs={12}>
  341. <FormHelperText error id="helper-text-address1-signup">
  342. <Typography variant="errorMessage1">
  343. {errorMsg}
  344. </Typography>
  345. </FormHelperText>
  346. </Grid>
  347. <Grid item xs={12} lg={4} >
  348. {FieldUtils.getTextField({
  349. label: FieldUtils.notNullFieldLabel("BR No.:"),
  350. valueName: "brNo",
  351. disabled: (!editMode && !createMode),
  352. form: formik
  353. })}
  354. </Grid>
  355. <Grid item xs={12} lg={4} >
  356. <FormControlLabel
  357. control={<Checkbox checked={formik.values.creditor} />}
  358. label="is Credit Client"
  359. name="creditor"
  360. onChange={() => {
  361. formik.setFieldValue("creditor", !formik.values.creditor);
  362. }}
  363. disabled={true}
  364. //disabled={!editMode && !createMode}
  365. />
  366. </Grid>
  367. <Grid item xs={12} lg={4} ></Grid>
  368. <Grid item xs={12} lg={4} >
  369. {FieldUtils.getTextField({
  370. label: FieldUtils.notNullFieldLabel("Name (Eng):"),
  371. valueName: "enCompanyName",
  372. disabled: (!editMode && !createMode),
  373. form: formik
  374. })}
  375. </Grid>
  376. <Grid item xs={12} lg={4} >
  377. {FieldUtils.getTextField({
  378. label: "Name (Ch):",
  379. valueName: "chCompanyName",
  380. disabled: (!editMode && !createMode),
  381. form: formik
  382. })}
  383. </Grid>
  384. <Grid item xs={12} lg={4} >
  385. <Grid container alignItems={"center"}>
  386. <Grid item xs={12} md={3} lg={3} sx={{ display: 'flex', alignItems: 'center' }}>
  387. <Typography variant="pnspsFormParagraphBold">{FieldUtils.notNullFieldLabel("Expiry Date:")}</Typography>
  388. </Grid>
  389. <Grid item xs={12} md={6} lg={6}>
  390. {(!editMode && !createMode) ?
  391. <TextField
  392. fullWidth
  393. id="currentExDate"
  394. // error={(fromDate===null)}
  395. // type="date"
  396. name="currentExDate"
  397. value={fromDate != null ? DateUtils.dateStr(fromDate) : DateUtils.dateStr(currentFromDate)}
  398. disabled={true}
  399. /> :
  400. <LocalizationProvider dateAdapter={AdapterDayjs}>
  401. <DemoItem components={['DatePicker']}>
  402. <DatePicker
  403. id="brExpiryDate"
  404. name="brExpiryDate"
  405. // error={fromDate===null}
  406. slotProps={{
  407. field: { readOnly: true, },
  408. // textField: {
  409. // helperText:fromDate == null ? intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' }):""
  410. // },
  411. }}
  412. format="DD/MM/YYYY"
  413. // label={"Submit Date (From)"}
  414. value={fromDate == null ? null : dayjs(fromDate)}
  415. minDate={minDate == null ? null : dayjs(minDate)}
  416. disabled={(!editMode && !createMode)}
  417. onChange={(newValue) => {
  418. // console.log(newValue)
  419. // setErrorMsg("")
  420. if (DateUtils.dateValue(newValue) > DateUtils.dateValue(new Date())) {
  421. setFromDate(newValue);
  422. } else {
  423. // setErrorMsg("Please select a date after today.")
  424. }
  425. }}
  426. />
  427. </DemoItem >
  428. </LocalizationProvider>
  429. }
  430. </Grid>
  431. {
  432. fromDate == null ?
  433. (!editMode && !createMode) ?
  434. // <FormHelperText error id="helper-text-date">
  435. // Please select a date after today.
  436. // </FormHelperText>
  437. null
  438. :
  439. <FormHelperText error id="helper-text-date">
  440. {intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' })}
  441. </FormHelperText>
  442. :
  443. null
  444. }
  445. </Grid>
  446. </Grid>
  447. <Grid item xs={12} lg={4} >
  448. {FieldUtils.getTextField({
  449. label: FieldUtils.notNullFieldLabel("Contact Person:"),
  450. valueName: "contactPerson",
  451. disabled: (!editMode && !createMode),
  452. form: formik
  453. })}
  454. </Grid>
  455. <Grid item xs={12} lg={4} >
  456. {FieldUtils.getPhoneField({
  457. label: FieldUtils.notNullFieldLabel("Contact Tel:"),
  458. valueName: {
  459. code: "tel_countryCode",
  460. num: "phoneNumber"
  461. },
  462. disabled: (!editMode && !createMode),
  463. form: formik
  464. })}
  465. </Grid>
  466. <Grid item xs={12} lg={4} >
  467. {FieldUtils.getPhoneField({
  468. label: "Fax No:",
  469. valueName: {
  470. code: "fax_countryCode",
  471. num: "faxNumber"
  472. },
  473. disabled: (!editMode && !createMode),
  474. form: formik
  475. })}
  476. </Grid>
  477. <Grid item xs={12} lg={4} >
  478. {FieldUtils.getComboField({
  479. label: FieldUtils.notNullFieldLabel("Country:"),
  480. valueName: "country",
  481. disabled: (!editMode && !createMode),
  482. dataList: ComboData.country,
  483. getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
  484. form: formik
  485. })}
  486. </Grid>
  487. <Grid item xs={12} lg={4} >
  488. {FieldUtils.getComboField({
  489. label: FieldUtils.notNullFieldLabel("District:"),
  490. valueName: "district",
  491. disabled: (!editMode && !createMode),
  492. dataList: ComboData.district,
  493. getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
  494. form: formik
  495. })}
  496. </Grid>
  497. {
  498. currentUserData.creditor ?
  499. <Grid item xs={12} lg={4} >
  500. {FieldUtils.getTextField({
  501. label: FieldUtils.notNullFieldLabel("Org. Short Name:"),
  502. valueName: "orgShortName",
  503. disabled: (!editMode && !createMode),
  504. form: formik
  505. })}
  506. </Grid>
  507. :
  508. null
  509. }
  510. <Grid item xs={12} lg={12} >
  511. {FieldUtils.getAddressField({
  512. label: FieldUtils.notNullFieldLabel("Address:"),
  513. valueName: ["addressLine1", "addressLine2", "addressLine3"],
  514. disabled: (!editMode && !createMode),
  515. form: formik
  516. })}
  517. </Grid>
  518. <Grid item lg={12} ></Grid>
  519. </Grid>
  520. }
  521. </form>
  522. <div>
  523. <Dialog
  524. open={creditorConfirmPopUp}
  525. onClose={() => setCreditorConfirmPopUp(false)}
  526. PaperProps={{
  527. sx: {
  528. minWidth: '40vw',
  529. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  530. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  531. }
  532. }}
  533. >
  534. <form onSubmit={handleSubmit(onSubmit)}>
  535. <DialogTitle><Typography variant="h3">Confirm</Typography></DialogTitle>
  536. <DialogContent style={{ display: 'flex', }}>
  537. <Grid container direction="column">
  538. <Grid item>
  539. <Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Credit Client?</Typography>
  540. </Grid>
  541. <Grid item>
  542. <Typography variant="h6" style={{ padding: '16px' }}>Please Enter Organisation Short Name for Credit Client (Used for Demand Note)</Typography>
  543. </Grid>
  544. <Grid item sx={{ padding: '16px' }}>
  545. <TextField
  546. fullWidth
  547. {...register("orgShortName")}
  548. id='orgShortName'
  549. label="Organisation Short Name"
  550. defaultValue={currentUserData.orgShortName != "N/A" ? currentUserData.orgShortName : ""}
  551. InputLabelProps={{
  552. shrink: true
  553. }}
  554. />
  555. </Grid>
  556. </Grid>
  557. </DialogContent>
  558. <DialogActions>
  559. <Button onClick={() => setCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
  560. <Button type="submit"><Typography variant="h5">Confirm</Typography></Button>
  561. {/* <Button onClick={() => markAsCreditor()}><Typography variant="h5">Confirm</Typography></Button> */}
  562. </DialogActions>
  563. </form>
  564. </Dialog>
  565. </div>
  566. <div>
  567. <Dialog
  568. open={nonCreditorConfirmPopUp}
  569. onClose={() => setNonCreditorConfirmPopUp(false)}
  570. PaperProps={{
  571. sx: {
  572. minWidth: '40vw',
  573. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  574. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  575. }
  576. }}
  577. >
  578. <DialogTitle><Typography variant="h3">Confirm</Typography></DialogTitle>
  579. <DialogContent style={{ display: 'flex', }}>
  580. <Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Non-Credit Client?</Typography>
  581. </DialogContent>
  582. <DialogActions>
  583. <Button onClick={() => setNonCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
  584. <Button onClick={() => markAsNonCreditor()}><Typography variant="h5">Confirm</Typography></Button>
  585. </DialogActions>
  586. </Dialog>
  587. </div>
  588. </MainCard>
  589. );
  590. };
  591. export default OrganizationCard;