Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

312 строки
12 KiB

  1. // material-ui
  2. import {
  3. Grid,
  4. Typography,
  5. Stack,
  6. Button,
  7. Dialog, DialogTitle, DialogContent, DialogActions,
  8. } from '@mui/material';
  9. import MainCard from "components/MainCard";
  10. import {GEN_GFMIS_XML} from "utils/ApiPathConst";
  11. import * as React from "react";
  12. import * as HttpUtils from "utils/HttpUtils";
  13. import * as DateUtils from "utils/DateUtils";
  14. import {DatePicker} from "@mui/x-date-pickers/DatePicker";
  15. import dayjs from "dayjs";
  16. import {DemoItem} from "@mui/x-date-pickers/internals/demo";
  17. import {LocalizationProvider} from "@mui/x-date-pickers/LocalizationProvider";
  18. import {AdapterDayjs} from "@mui/x-date-pickers/AdapterDayjs";
  19. import Loadable from 'components/Loadable';
  20. const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
  21. const SearchForm = Loadable(React.lazy(() => import('./SearchForm')));
  22. const EventTable = Loadable(React.lazy(() => import('./DataGrid')));
  23. const TransactionTable = Loadable(React.lazy(() => import('./TransactionDataGrid')));
  24. import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
  25. const BackgroundHead = {
  26. backgroundImage: `url(${titleBackgroundImg})`,
  27. width: '100%',
  28. height: '100%',
  29. backgroundSize:'contain',
  30. backgroundRepeat: 'no-repeat',
  31. backgroundColor: '#0C489E',
  32. backgroundPosition: 'right'
  33. }
  34. // ==============================|| DASHBOARD - DEFAULT ||============================== //
  35. const Index = () => {
  36. const [isTxLoading, setIsTxLoading] = React.useState(false);
  37. const [autoPreviewPending, setAutoPreviewPending] = React.useState(false);
  38. const [searchCriteria, setSearchCriteria] = React.useState({
  39. dateTo: DateUtils.dateValue(new Date()),
  40. dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
  41. });
  42. const [previewSearchCriteria, setPreviewSearchCriteria] = React.useState({
  43. dateTo: DateUtils.dateValue(new Date()),
  44. dateFrom: DateUtils.dateValue(new Date().setDate(new Date().getDate()-14)),
  45. });
  46. const [onReady, setOnReady] = React.useState(false);
  47. const [onGridReady, setGridOnReady] = React.useState(false);
  48. const [isPreviewLoading, setIsPreviewLoading] = React.useState(false);
  49. const [isPopUp, setIsPopUp] = React.useState(false);
  50. const [downloadInput, setDownloadInput] = React.useState();
  51. const [selectedIds, setSelectedIds] = React.useState([]);
  52. const [inputDate, setInputDate] = React.useState(searchCriteria.dateTo);
  53. const [inputDateValue, setInputDateValue] = React.useState("dd / mm / yyyy");
  54. const [previewToken, setPreviewToken] = React.useState(0);
  55. React.useEffect(() => {
  56. setInputDateValue(inputDate);
  57. }, [inputDate]);
  58. React.useEffect(() => {
  59. setOnReady(true);
  60. }, [searchCriteria]);
  61. React.useEffect(() => {
  62. if (!autoPreviewPending) return;
  63. // wait for tx grid load complete, and for auto-selection to happen
  64. if (isTxLoading) return;
  65. if (!selectedIds || selectedIds.length === 0) return;
  66. // trigger preview exactly once
  67. const withToken = { ...searchCriteria, __ts: Date.now() };
  68. setPreviewSearchCriteria(withToken);
  69. setPreviewToken(t => t + 1);
  70. setAutoPreviewPending(false);
  71. }, [autoPreviewPending, isTxLoading, selectedIds, searchCriteria]);
  72. React.useEffect(() => {
  73. if (selectedIds.length === 0) {
  74. setPreviewSearchCriteria({});
  75. setPreviewToken(t => t + 1); // forces preview grid remount -> clears rows
  76. }
  77. }, [selectedIds]);
  78. function downloadXML() {
  79. console.log(selectedIds.join(','))
  80. setIsPopUp(false)
  81. let sentDateFrom = "";
  82. if (inputDateValue != "dd / mm / yyyy") {
  83. sentDateFrom = DateUtils.dateValue(inputDateValue)
  84. }
  85. HttpUtils.get({
  86. url: GEN_GFMIS_XML + "/today",
  87. params:{
  88. dateTo: downloadInput.dateTo,
  89. dateFrom: downloadInput.dateFrom,
  90. inputDate: sentDateFrom,
  91. paymentId: selectedIds.join(',')
  92. },
  93. onSuccess: (responseData) => {
  94. // console.log(responseData)
  95. const parser = new DOMParser();
  96. const xmlDoc = parser.parseFromString(responseData, 'application/xml');
  97. // Get the DCBHeader element
  98. const dcbHeader = xmlDoc.querySelector("DCBHeader");
  99. // Get the Receipt and Allocation elements
  100. const receiptElement = dcbHeader.querySelector("Receipt");
  101. const allocationElement = dcbHeader.querySelector("Allocation");
  102. const paymentMethodElements = Array.from(dcbHeader.querySelectorAll("PaymentMethod"));
  103. // Remove existing elements from DCBHeader
  104. dcbHeader.innerHTML = "";
  105. dcbHeader.appendChild(receiptElement);
  106. dcbHeader.appendChild(allocationElement);
  107. if (paymentMethodElements) {
  108. paymentMethodElements.forEach((paymentMethodElement) => {
  109. dcbHeader.appendChild(paymentMethodElement);
  110. });
  111. }
  112. const updatedXmlString = new XMLSerializer().serializeToString(xmlDoc);
  113. const filename = xmlDoc.querySelector('FileHeader').getAttribute('H_Filename');
  114. // console.log(updatedXmlString)
  115. const blob = new Blob([updatedXmlString], { type: 'application/xml' });
  116. // Create a download link
  117. const link = document.createElement('a');
  118. link.href = URL.createObjectURL(blob);
  119. link.download = filename+'.xml';
  120. // Append the link to the document body
  121. document.body.appendChild(link);
  122. // Programmatically click the link to trigger the download
  123. link.click();
  124. // Clean up the link
  125. document.body.removeChild(link);
  126. }
  127. });
  128. // open(UrlUtils.GEN_GFMIS_XML + "/today?online=true")
  129. }
  130. function applySearch(input) {
  131. setAutoPreviewPending(true); // NEW: ask for auto-preview after grid loads
  132. setGridOnReady(true);
  133. setSelectedIds([]);
  134. setPreviewSearchCriteria({});
  135. setSearchCriteria(input);
  136. setInputDate(input.dateFrom);
  137. }
  138. function previewSearch() {
  139. if (selectedIds.length === 0) return;
  140. setIsPopUp(false);
  141. setIsPreviewLoading(true);
  142. const withToken = { ...searchCriteria, __ts: Date.now() };
  143. setPreviewSearchCriteria(withToken);
  144. setPreviewToken(t => t + 1);
  145. }
  146. function onPreviewGridOnReady(isLoading) {
  147. // FiDataGrid calls this with true/false
  148. setIsPreviewLoading(isLoading);
  149. }
  150. function applyGridOnReady(isLoading) {
  151. setGridOnReady(isLoading); // keep existing behavior for disabling Search
  152. setIsTxLoading(isLoading); // NEW: remember tx grid loading
  153. }
  154. function generateXML(input) {
  155. setDownloadInput(input);
  156. setIsPopUp(true)
  157. }
  158. return (
  159. !onReady ?
  160. <LoadingComponent/>
  161. :
  162. <Grid container sx={{minHeight: '87vh', backgroundColor: 'backgroundColor.default'}} direction="column">
  163. <Grid item xs={12}>
  164. <div style={BackgroundHead}>
  165. <Stack direction="row" height='70px' justifyContent="flex-start" alignItems="center">
  166. <Typography ml={15} color='#FFF' variant="h4" sx={{ "textShadow": "0px 0px 25px #0C489E" }}>
  167. GFMIS Generate XML
  168. </Typography>
  169. </Stack>
  170. </div>
  171. </Grid>
  172. {/*row 1*/}
  173. <Grid item xs={12} md={12} lg={12} sx={{mb:-1}}>
  174. <SearchForm
  175. applySearch={applySearch}
  176. generateXML={generateXML}
  177. searchCriteria={searchCriteria}
  178. onGridReady={onGridReady}
  179. selectedIds={selectedIds}
  180. />
  181. </Grid>
  182. {/*row 2*/}
  183. <Grid item xs={12} md={12} lg={12}>
  184. <MainCard elevation={0}
  185. border={false}
  186. content={false}
  187. sx={{width: "-webkit-fill-available"}}
  188. >
  189. <TransactionTable
  190. searchCriteria={searchCriteria}
  191. applyGridOnReady={applyGridOnReady}
  192. applySearch={applySearch}
  193. selectedIds={selectedIds}
  194. onSelectionChange={setSelectedIds}
  195. />
  196. </MainCard>
  197. </Grid>
  198. <Grid item xs={12} md={12} lg={12} sx={{ml:2}}>
  199. <Button
  200. variant="contained"
  201. onClick={previewSearch}
  202. disabled={isPreviewLoading || selectedIds.length === 0}
  203. >
  204. Preview
  205. </Button>
  206. </Grid>
  207. <Grid item xs={12} md={12} lg={12}>
  208. <MainCard elevation={0}
  209. border={false}
  210. content={false}
  211. sx={{width: "-webkit-fill-available"}}
  212. >
  213. <EventTable
  214. previewSearchCriteria={previewSearchCriteria}
  215. onPreviewGridOnReady={onPreviewGridOnReady}
  216. selectedIds={selectedIds}
  217. previewToken={previewToken}
  218. />
  219. </MainCard>
  220. </Grid>
  221. <Dialog
  222. open={isPopUp}
  223. onClose={() => setIsPopUp(false)}
  224. PaperProps={{
  225. sx: {
  226. minWidth: '40vw',
  227. maxWidth: { xs: '90vw', s: '90vw', m: '70vw', lg: '70vw' },
  228. maxHeight: { xs: '90vh', s: '70vh', m: '70vh', lg: '60vh' }
  229. }
  230. }}
  231. >
  232. <DialogTitle> Bank Statement Collection Date </DialogTitle>
  233. <DialogContent style={{ display: 'flex', }}>
  234. <LocalizationProvider dateAdapter={AdapterDayjs}>
  235. <DemoItem components={['DatePicker']}>
  236. <DatePicker
  237. id="dateFrom"
  238. // onError={(newError) => setReceiptFromError(newError)}
  239. slotProps={{
  240. field: { readOnly: true, },
  241. // textField: {
  242. // helperText: receiptFromErrorMessage,
  243. // },
  244. }}
  245. format="DD/MM/YYYY"
  246. // label="Credit Date"
  247. value={inputDate === null ? null : dayjs(inputDate)}
  248. minDate={searchCriteria.dateFrom === null ? null : dayjs(searchCriteria.dateFrom)}
  249. onChange={(newValue) => {
  250. // console.log(newValue)
  251. if(newValue!=null){
  252. setInputDate(newValue);
  253. }
  254. }}
  255. />
  256. </DemoItem >
  257. </LocalizationProvider>
  258. </DialogContent>
  259. <DialogActions>
  260. <Button onClick={() => setIsPopUp(false)}><Typography variant="h5">Cancel</Typography></Button>
  261. <Button onClick={() => downloadXML()}><Typography variant="h5">Confirm</Typography></Button>
  262. </DialogActions>
  263. </Dialog>
  264. </Grid>
  265. );
  266. };
  267. export default Index;