No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 

605 líneas
28 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 } 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 { lazy } from 'react';
  22. import { notifySaveSuccess } from 'utils/CommonFunction';
  23. import { useIntl } from "react-intl";
  24. import { PNSPS_BUTTON_THEME } from "themes/buttonConst";
  25. import { ThemeProvider } from "@emotion/react";
  26. import { makeStyles } from '@mui/styles';
  27. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  28. const useStyles = makeStyles(() => ({
  29. root: {
  30. position: "relative"
  31. },
  32. display: {
  33. position: "absolute",
  34. top: 2,
  35. left: 12,
  36. bottom: 2,
  37. background: "white",
  38. pointerEvents: "none",
  39. right: 50,
  40. display: "flex",
  41. alignItems: "center",
  42. width:"70%"
  43. },
  44. }));
  45. const OrganizationCard = ({ userData, loadDataFun, id, setEditModeFun }) => {
  46. const intl = useIntl();
  47. const [creditorConfirmPopUp, setCreditorConfirmPopUp] = React.useState(false);
  48. const [nonCreditorConfirmPopUp, setNonCreditorConfirmPopUp] = React.useState(false);
  49. const [currentUserData, setCurrentUserData] = useState({});
  50. const [editMode, setEditMode] = useState(false);
  51. const [createMode, setCreateMode] = useState(false);
  52. const [onReady, setOnReady] = useState(false);
  53. const [errorMsg, setErrorMsg] = useState("");
  54. const [minDate] = React.useState(new Date());
  55. const [fromDate, setFromDate] = React.useState("dd / mm / yyyy");
  56. const [fromDateValue, setFromDateValue] = React.useState("dd / mm / yyyy");
  57. const {register, handleSubmit, reset} = useForm()
  58. React.useEffect(() => {
  59. setFromDateValue(fromDate);
  60. }, [fromDate]);
  61. useEffect(() => {
  62. //if state data are ready and assign to different field
  63. // console.log(currentApplicationDetailData)
  64. if (Object.keys(currentUserData).length > 0) {
  65. setFromDate(currentUserData.brExpiryDate)
  66. setOnReady(true);
  67. }
  68. }, [currentUserData]);
  69. function FormDateInputComponent({ inputRef, ...props }) {
  70. const classes = useStyles();
  71. return (
  72. <>
  73. <div className={classes.display}>
  74. {DateUtils.dateStr(fromDateValue) == "Invalid Date" ?
  75. fromDateValue
  76. :
  77. DateUtils.dateStr(fromDateValue)}
  78. </div>
  79. <input
  80. // className={classes.input}
  81. ref={inputRef}
  82. {...props}
  83. // onChange={handleChange}
  84. value={fromDateValue}
  85. min={minDate}
  86. />
  87. </>
  88. );
  89. }
  90. function displayErrorMsg(errorMsg) {
  91. return <Typography variant="errorMessage1">{errorMsg}</Typography>
  92. }
  93. function getMaxErrStr(num, fieldname) {
  94. return displayErrorMsg(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: num, fieldname: fieldname ? intl.formatMessage({ id: fieldname }) + ": " : "" }));
  95. }
  96. function getRequiredErrStr(fieldname) {
  97. return displayErrorMsg(intl.formatMessage({ id: 'require' }, { fieldname: fieldname ? intl.formatMessage({ id: fieldname }) : "" }));
  98. }
  99. const formik = useFormik({
  100. enableReinitialize: true,
  101. initialValues: currentUserData,
  102. validationSchema: yup.object().shape({
  103. enCompanyName: yup.string().max(255, getMaxErrStr(255)).required(displayErrorMsg(intl.formatMessage({ id: 'userRequireEnglishName' }))),
  104. chCompanyName: yup.string().max(255, displayErrorMsg(intl.formatMessage({ id: 'userRequireChineseName' }))).nullable(),
  105. orgShortName: yup.string().max(24, getMaxErrStr(24)).required(getRequiredErrStr("Org. Short Name")),
  106. addressLine1: yup.string().max(40, getMaxErrStr(40)).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))),
  107. addressLine2: yup.string().max(40, getMaxErrStr(40)),
  108. addressLine3: yup.string().max(40, getMaxErrStr(40)),
  109. contactPerson: yup.string().max(60, getMaxErrStr(60)).required(getRequiredErrStr("contactPerson")),
  110. fax_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))).nullable(),
  111. tel_countryCode: yup.string().min(3, displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))),
  112. phoneNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requiredValidNumber' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))),
  113. faxNumber: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'require8Number' }))).nullable(),
  114. brExpiryDate: yup.string().min(8).required(displayErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertValidityDate' }))),
  115. brNo: yup.string().required(displayErrorMsg(intl.formatMessage({ id: 'pleaseFillInBusinessRegCertNumber' }))).test('checkBrNoFormat', displayErrorMsg(displayErrorMsg(intl.formatMessage({ id: 'pleaseFillInValidBusinessRegCertNumber' }))), function (value) {
  116. var brNo_pattern = /[0-9]{8}/
  117. if (value !== undefined) {
  118. if (value.match(brNo_pattern)) {
  119. return true
  120. } else {
  121. return false
  122. }
  123. }
  124. }),
  125. }),
  126. onSubmit: values => {
  127. if (values.country == null) {
  128. setErrorMsg(intl.formatMessage({ id: 'pleaseFillInCountry' }))
  129. } else {
  130. if (values.country.type == "hongKong" && values.district == null) {
  131. setErrorMsg(intl.formatMessage({ id: 'pleaseFillInDistrict' }))
  132. } else {
  133. let sentDateFrom = "";
  134. if (fromDateValue != "dd / mm / yyyy") {
  135. sentDateFrom = DateUtils.dateValue(fromDateValue)
  136. }
  137. HttpUtils.post({
  138. url: UrlUtils.POST_ORG_SAVE_PATH,
  139. params: {
  140. id: id > 0 ? id : null,
  141. enCompanyName: values.enCompanyName,
  142. chCompanyName: values.chCompanyName,
  143. orgShortName: values.creditor?values.orgShortName:"",
  144. brNo: values.brNo,
  145. // brExpiryDate: values.brExpiryDate,
  146. brExpiryDate: sentDateFrom,
  147. enCompanyNameTemp: values.enCompanyNameTemp,
  148. chCompanyNameTemp: values.chCompanyNameTemp,
  149. brExpiryDateTemp: values.brExpiryDateTemp,
  150. contactPerson: values.contactPerson,
  151. contactTel: {
  152. countryCode: values.tel_countryCode,
  153. phoneNumber: values.phoneNumber
  154. },
  155. faxNo: {
  156. countryCode: values.fax_countryCode,
  157. faxNumber: values.faxNumber
  158. },
  159. addressTemp: {
  160. country: values.country.type,
  161. district: values.district?.type,
  162. addressLine1: values.addressLine1,
  163. addressLine2: values.addressLine2,
  164. addressLine3: values.addressLine3,
  165. },
  166. creditor: values.creditor,
  167. },
  168. onSuccess: function () {
  169. notifySaveSuccess()
  170. loadDataFun();
  171. setEditMode(false);
  172. }
  173. });
  174. }
  175. }
  176. }
  177. });
  178. useEffect(() => {
  179. setEditModeFun(editMode);
  180. }, [editMode]);
  181. useEffect(() => {
  182. if (Object.keys(userData).length > 0) {
  183. setCreateMode(id <= 0);
  184. setEditMode(id <= 0);
  185. setCurrentUserData(userData);
  186. }
  187. }, [userData]);
  188. // useEffect(() => {
  189. // if (Object.keys(userData).length > 0) {
  190. // if(userData.creditor === undefined||userData.creditor === null){
  191. // userData.creditor = false
  192. // }
  193. // setCurrentUserData(userData);
  194. // }
  195. // }, []);
  196. const onEditClick = () => {
  197. setEditMode(true);
  198. };
  199. const onSubmit = (data) => {
  200. let sentOrgShortName = "";
  201. if(data.orgShortName!=null && data.orgShortName!=""){
  202. sentOrgShortName = data.orgShortName
  203. if (sentOrgShortName.length <=24){
  204. const temp = {
  205. orgShortName: sentOrgShortName,
  206. };
  207. markAsCreditor(temp);
  208. }else{
  209. alert("Organisation Short Name must not exceed 24 characters.")
  210. }
  211. }else{
  212. alert("Please enter Organisation Short Name for Demand Note.")
  213. }
  214. };
  215. function resetForm() {
  216. reset();
  217. }
  218. const markAsCreditor = (temp) => {
  219. setCreditorConfirmPopUp(false);
  220. HttpUtils.post({
  221. url: UrlUtils.GET_ORG_MARK_AS_CREDITOR + "/" + id,
  222. params: temp,
  223. onSuccess: () => {
  224. resetForm();
  225. loadDataFun();
  226. }
  227. });
  228. }
  229. const markAsNonCreditor = () => {
  230. setNonCreditorConfirmPopUp(false);
  231. HttpUtils.get({
  232. url: UrlUtils.GET_ORG_MARK_AS_NON_CREDITOR + "/" + id,
  233. onSuccess: () => {
  234. loadDataFun();
  235. }
  236. });
  237. }
  238. return (
  239. <MainCard elevation={0}
  240. border={false}
  241. content={false}
  242. >
  243. <form onSubmit={formik.handleSubmit} style={{ padding: 24 }}>
  244. {/*top*/}
  245. <Grid item s={12} md={12} lg={12} sx={{ mb: 3 }} alignItems={"start"} justifyContent="center">
  246. <Grid container maxWidth justifyContent="flex-start">
  247. {editMode ?
  248. <>
  249. {createMode ?
  250. <>
  251. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  252. <Grid item sx={{ ml: 0, mr: 3 }}>
  253. <Button
  254. variant="contained"
  255. type="submit"
  256. color="success"
  257. >
  258. Create
  259. </Button>
  260. </Grid>
  261. </ThemeProvider>
  262. </> :
  263. <>
  264. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  265. <Grid item sx={{ ml: 0, mr: 3 }}>
  266. <Button
  267. variant="contained"
  268. onClick={loadDataFun}
  269. color="cancel"
  270. >
  271. Reset & Back
  272. </Button>
  273. </Grid>
  274. <Grid item sx={{ ml: 3, mr: 3 }}>
  275. <Button
  276. variant="contained"
  277. type="submit"
  278. color="success"
  279. >
  280. Save
  281. </Button>
  282. </Grid>
  283. </ThemeProvider>
  284. </>
  285. }
  286. </>
  287. :
  288. <>
  289. <Grid item sx={{ ml: 0, mr: 3 }}>
  290. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  291. <Button
  292. variant="contained"
  293. onClick={onEditClick}
  294. color="success"
  295. >
  296. Edit
  297. </Button>
  298. </ThemeProvider>
  299. </Grid>
  300. {
  301. currentUserData.creditor ?
  302. <Grid item sx={{ ml: 3, mr: 3 }}>
  303. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  304. <Button
  305. variant="contained"
  306. color="error"
  307. onClick={() => setNonCreditorConfirmPopUp(true)}
  308. >
  309. Mark as Non-Credit Client
  310. </Button>
  311. </ThemeProvider>
  312. </Grid>
  313. :
  314. <Grid item sx={{ ml: 3, mr: 3 }}>
  315. <ThemeProvider theme={PNSPS_BUTTON_THEME}>
  316. <Button
  317. variant="contained"
  318. color="orange"
  319. onClick={() => setCreditorConfirmPopUp(true)}
  320. >
  321. Mark as Credit Client
  322. </Button>
  323. </ThemeProvider>
  324. </Grid>
  325. }
  326. </>
  327. }
  328. </Grid>
  329. </Grid>
  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. <TextField
  391. fullWidth
  392. id="brExpiryDate"
  393. type="date"
  394. name="brExpiryDate"
  395. error={Boolean(formik.errors["brExpiryDate"])}
  396. helperText={formik.errors["brExpiryDate"] ? formik.errors["brExpiryDate"] : ''}
  397. defaultValue={fromDate}
  398. InputProps={{
  399. inputComponent: FormDateInputComponent,
  400. }}
  401. onChange={(newValue) => {
  402. if (newValue.target.value>DateUtils.dateValue(minDate)){
  403. setFromDate(newValue.target.value);
  404. }else{
  405. alert("Please select a date after today.")
  406. }
  407. }}
  408. InputLabelProps={{
  409. shrink: true
  410. }}
  411. disabled={(!editMode && !createMode)}
  412. sx={{ "& .MuiInputBase-input": {display:"block", textIndent: "-9999px"} }}
  413. />
  414. </Grid>
  415. </Grid>
  416. </Grid>
  417. <Grid item xs={12} lg={4} >
  418. {FieldUtils.getTextField({
  419. label: FieldUtils.notNullFieldLabel("Contact Person:"),
  420. valueName: "contactPerson",
  421. disabled: (!editMode && !createMode),
  422. form: formik
  423. })}
  424. </Grid>
  425. <Grid item xs={12} lg={4} >
  426. {FieldUtils.getPhoneField({
  427. label: FieldUtils.notNullFieldLabel("Contact Tel:"),
  428. valueName: {
  429. code: "tel_countryCode",
  430. num: "phoneNumber"
  431. },
  432. disabled: (!editMode && !createMode),
  433. form: formik
  434. })}
  435. </Grid>
  436. <Grid item xs={12} lg={4} >
  437. {FieldUtils.getPhoneField({
  438. label: "Fax No:",
  439. valueName: {
  440. code: "fax_countryCode",
  441. num: "faxNumber"
  442. },
  443. disabled: (!editMode && !createMode),
  444. form: formik
  445. })}
  446. </Grid>
  447. <Grid item xs={12} lg={4} >
  448. {FieldUtils.getComboField({
  449. label: FieldUtils.notNullFieldLabel("Country:"),
  450. valueName: "country",
  451. disabled: (!editMode && !createMode),
  452. dataList: ComboData.country,
  453. getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
  454. form: formik
  455. })}
  456. </Grid>
  457. <Grid item xs={12} lg={4} >
  458. {FieldUtils.getComboField({
  459. label: FieldUtils.notNullFieldLabel("District:"),
  460. valueName: "district",
  461. disabled: (!editMode && !createMode),
  462. dataList: ComboData.district,
  463. getOptionLabel: (option) => option.type ? intl.formatMessage({ id: option.type }) : "",
  464. form: formik
  465. })}
  466. </Grid>
  467. {
  468. currentUserData.creditor ?
  469. <Grid item xs={12} lg={4} >
  470. {FieldUtils.getTextField({
  471. label: FieldUtils.notNullFieldLabel("Org. Short Name:"),
  472. valueName: "orgShortName",
  473. disabled: (!editMode && !createMode),
  474. form: formik
  475. })}
  476. </Grid>
  477. :
  478. null
  479. }
  480. <Grid item xs={12} lg={12} >
  481. {FieldUtils.getAddressField({
  482. label: FieldUtils.notNullFieldLabel("Address:"),
  483. valueName: ["addressLine1", "addressLine2", "addressLine3"],
  484. disabled: (!editMode && !createMode),
  485. form: formik
  486. })}
  487. </Grid>
  488. <Grid item lg={12} ></Grid>
  489. </Grid>
  490. }
  491. </form>
  492. <div>
  493. <Dialog
  494. open={creditorConfirmPopUp}
  495. onClose={() => setCreditorConfirmPopUp(false)}
  496. PaperProps={{
  497. sx: {
  498. minWidth: '40vw',
  499. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  500. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  501. }
  502. }}
  503. >
  504. <form onSubmit={handleSubmit(onSubmit)}>
  505. <DialogTitle><Typography variant="h3">Confirm</Typography></DialogTitle>
  506. <DialogContent style={{ display: 'flex', }}>
  507. <Grid container direction="column">
  508. <Grid item>
  509. <Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Credit Client?</Typography>
  510. </Grid>
  511. <Grid item>
  512. <Typography variant="h6" style={{ padding: '16px' }}>Please Enter Organisation Short Name for Credit Client (Used for Demand Note)</Typography>
  513. </Grid>
  514. <Grid item sx={{padding: '16px'}}>
  515. <TextField
  516. fullWidth
  517. {...register("orgShortName")}
  518. id='orgShortName'
  519. label="Organisation Short Name"
  520. defaultValue={currentUserData.orgShortName}
  521. InputLabelProps={{
  522. shrink: true
  523. }}
  524. />
  525. </Grid>
  526. </Grid>
  527. </DialogContent>
  528. <DialogActions>
  529. <Button onClick={() => setCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
  530. <Button type="submit"><Typography variant="h5">Confirm</Typography></Button>
  531. {/* <Button onClick={() => markAsCreditor()}><Typography variant="h5">Confirm</Typography></Button> */}
  532. </DialogActions>
  533. </form>
  534. </Dialog>
  535. </div>
  536. <div>
  537. <Dialog
  538. open={nonCreditorConfirmPopUp}
  539. onClose={() => setNonCreditorConfirmPopUp(false)}
  540. PaperProps={{
  541. sx: {
  542. minWidth: '40vw',
  543. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  544. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  545. }
  546. }}
  547. >
  548. <DialogTitle><Typography variant="h3">Confirm</Typography></DialogTitle>
  549. <DialogContent style={{ display: 'flex', }}>
  550. <Typography variant="h4" style={{ padding: '16px' }}>Are you sure mark as Non-Credit Client?</Typography>
  551. </DialogContent>
  552. <DialogActions>
  553. <Button onClick={() => setNonCreditorConfirmPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
  554. <Button onClick={() => markAsNonCreditor()}><Typography variant="h5">Confirm</Typography></Button>
  555. </DialogActions>
  556. </Dialog>
  557. </div>
  558. </MainCard>
  559. );
  560. };
  561. export default OrganizationCard;