From 44ae31d5ea49bf686b17b670e56e5984808553a4 Mon Sep 17 00:00:00 2001 From: skyouc Date: 星期六, 02 八月 2025 17:10:42 +0800 Subject: [PATCH] 库存调整修改 --- rsf-admin/src/page/stockManage/locRevise/LocReviseList.jsx | 44 +-- rsf-admin/src/page/stockManage/locRevise/LocReviseCreate.jsx | 584 +++++++++++++++++++++++++++++++++++++++++----------- rsf-admin/src/i18n/zh.js | 2 rsf-admin/src/i18n/en.js | 2 4 files changed, 479 insertions(+), 153 deletions(-) diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js index cb9ec00..f97fa0a 100644 --- a/rsf-admin/src/i18n/en.js +++ b/rsf-admin/src/i18n/en.js @@ -910,6 +910,7 @@ exceStatus: "Exce Status", orgAreaId: "Area Id", orgAreaName: "Area Name", + exceTime: "Exce Time" }, waitPakinItem: { pakinId: "pakinId", @@ -1290,6 +1291,7 @@ complete: "complete", allComfirm: 'All Comfirm', createTransfer: 'Create Transfer Order', + createLocRevise: 'Create Stock Revise Order', verifyComfirm: 'Verify Comfirm', close: "close", asnCreate: "Create By Order", diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js index aee47ba..e36c5af 100644 --- a/rsf-admin/src/i18n/zh.js +++ b/rsf-admin/src/i18n/zh.js @@ -947,6 +947,7 @@ exceStatus: "鎵ц鐘舵��", areaId: "搴撳尯ID", areaName: "搴撳尯", + exceTime: "璋冩暣鏃堕棿", }, waitPakinItem: { pakinId: "缁勬墭Id", @@ -1303,6 +1304,7 @@ complete: "瀹岀粨", close: "鍏抽棴", createTransfer: '鍒涘缓璋冩嫈鍗�', + createLocRevise: '鍒涘缓搴撳瓨璋冩暣鍗�', asnCreate: "閫氳繃鍗曟嵁鍒涘缓", poCreate: "閫氳繃PO鍗曞垱寤�", orderPrint: '鎵撳嵃鍗曟嵁', diff --git a/rsf-admin/src/page/stockManage/locRevise/LocReviseCreate.jsx b/rsf-admin/src/page/stockManage/locRevise/LocReviseCreate.jsx index d47e380..36f977a 100644 --- a/rsf-admin/src/page/stockManage/locRevise/LocReviseCreate.jsx +++ b/rsf-admin/src/page/stockManage/locRevise/LocReviseCreate.jsx @@ -1,164 +1,494 @@ import React, { useState, useRef, useEffect, useMemo } from "react"; import { - CreateBase, useTranslate, TextInput, - NumberInput, - BooleanInput, DateInput, - SaveButton, - SelectInput, ReferenceInput, - ReferenceArrayInput, AutocompleteInput, Toolbar, required, - useDataProvider, useNotify, - Form, - useCreateController, + DeleteButton, + SaveButton, + SimpleForm, + useRefresh, + CreateBase, } from 'react-admin'; import { Dialog, DialogActions, DialogContent, DialogTitle, + TextField, + IconButton, + MenuItem, + Tooltip, + Select, + Button, Stack, Grid, Box, } from '@mui/material'; -import DialogCloseButton from "@/page/components/DialogCloseButton"; -import StatusSelectInput from "@/page/components/StatusSelectInput"; -import MemoInput from "@/page/components/MemoInput"; +import ConfirmationNumberIcon from '@mui/icons-material/ConfirmationNumber'; +import DialogCloseButton from "../../components/DialogCloseButton.jsx"; +import WarehouseSelect from "../../components/WarehouseSelect.jsx"; +import { useWatch, useFormContext } from "react-hook-form"; +import { DataGrid, useGridApiRef } from '@mui/x-data-grid'; +import ConfirmButton from "../../components/ConfirmButton"; +import { Add, Edit, Delete } from '@mui/icons-material'; +import DictSelect from "../../components/DictSelect"; +import SaveIcon from '@mui/icons-material/Save'; +import { styled } from '@mui/material/styles'; +import request from '@/utils/request'; +import _, { set } from 'lodash'; + +const StyledSimpleForm = styled(SimpleForm)(({ theme }) => ({ + '& .MuiToolbar-root-RaToolbar-root': { + '& .RaToolbar-defaultToolbar': { + justifyContent: 'flex-end', + } + } + +})); + const LocReviseCreate = (props) => { - const { open, setOpen } = props; - - const translate = useTranslate(); + const { open, setOpen, orderId } = props; + const tableRef = useRef(); const notify = useNotify(); + const refresh = useRefresh(); + const translate = useTranslate(); + const [tabelData, setTableData] = useState([]); + const [disabled, setDisabled] = useState(false); + const [selectedRows, setSelectedRows] = useState([]); + const [createDialog, setCreateDialog] = useState(false); + const [formData, setFormData] = useState({ type: '0', orgAreaId: null, tarAreaId: null, exceTime: null, code: null }); + const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_stock_revise_type')) || []; - const handleClose = (event, reason) => { - if (reason !== "backdropClick") { - setOpen(false); + const setFinally = () => { + const rows = tableRef.current.state.editRows; + for (const key in rows) { + const find = tabelData.find(item => item.matnrId === +key); + find.anfme = rows[key].anfme.value; + } + setTableData([...tabelData]); + } + + const handleSubmit = async () => { + setFinally() + setDisabled(true) + + if (orderId == null || orderId == undefined) { + const parmas = { + "revise": formData, + "items": tabelData, + } + + const res = await request.post(`/transfer/items/save`, parmas); + if (res?.data?.code === 200) { + setOpen(false); + } else { + notify(res.data.msg); + } + } else { + const parmas = { + "transfer": formData, + "items": tabelData, + } + const res = await request.post(`/transfer/items/update`, parmas); + if (res?.data?.code === 200) { + setOpen(false); + } else { + notify(res.data.msg); + } + } + setDisabled(false) + refresh(); + + }; + + const handleDeleteItem = () => { + const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId)); + setTableData(newTableData); + } + + const newAddClick = () => { + if (formData.areaId == null || formData.areaId == undefined) { + notify("搴撳尯涓嶈兘涓虹┖锛侊紒", { type: 'error' }) + return + } + setCreateDialog(true) + } + + const mutationOptions = { + onSuccess: (data) => { + notify(`鏂囩珷 "${data.title}" 鍒涘缓鎴愬姛`, { type: 'success' }); + }, + onError: (error) => { + notify(`鍒涘缓澶辫触: ${error.message}`, { type: 'error' }); } }; - const handleSuccess = async (data) => { - setOpen(false); - notify('common.response.success'); - }; - - const handleError = async (error) => { - notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); + const handleChange = (value, name) => { + setFormData((prevData) => ({ + ...prevData, + [name]: value + })); }; return ( <> - <CreateBase - record={{}} - transform={(data) => { - return data; - }} - mutationOptions={{ onSuccess: handleSuccess, onError: handleError }} - > - <Dialog - open={open} - onClose={handleClose} - aria-labelledby="form-dialog-title" - fullWidth - disableRestoreFocus - maxWidth="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' - > - <Form> - <DialogTitle id="form-dialog-title" sx={{ - position: 'sticky', - top: 0, - backgroundColor: 'background.paper', - zIndex: 1000 - }} - > - {translate('create.title')} - <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> - <DialogCloseButton onClose={handleClose} /> - </Box> - </DialogTitle> - <DialogContent sx={{ mt: 2 }}> - <Grid container rowSpacing={2} columnSpacing={2}> - <Grid item xs={6} display="flex" gap={1}> - <TextInput - label="table.field.locRevise.code" - source="code" - parse={v => v} - autoFocus - /> - </Grid> - <Grid item xs={6} display="flex" gap={1}> - <SelectInput - label="table.field.locRevise.type" - source="type" - choices={[ - { id: 0, name: ' 搴撳瓨璋冩暣' }, - { id: 2, name: ' 鐩樼偣璋冩暣' }, - ]} - /> - </Grid> - <Grid item xs={6} display="flex" gap={1}> - <NumberInput - label="table.field.locRevise.anfme" - source="anfme" - /> - </Grid> - <Grid item xs={6} display="flex" gap={1}> - <NumberInput - label="table.field.locRevise.reviseQty" - source="reviseQty" - /> - </Grid> - <Grid item xs={6} display="flex" gap={1}> - <SelectInput - label="table.field.locRevise.exceStatus" - source="exceStatus" - choices={[ - { id: 0, name: '鏈墽琛�' }, - { id: 1, name: '鎵ц涓�' }, - { id: 2, name: '鎵ц瀹屾垚' }, - ]} - /> - </Grid> - <Grid item xs={6} display="flex" gap={1}> - <NumberInput - label="table.field.locRevise.orgAreaId" - source="orgAreaId" - /> - </Grid> - <Grid item xs={6} display="flex" gap={1}> - <TextInput - label="table.field.locRevise.orgAreaName" - source="orgAreaName" - parse={v => v} - /> - </Grid> - - <Grid item xs={6} display="flex" gap={1}> - <StatusSelectInput /> - </Grid> - <Grid item xs={12} display="flex" gap={1}> - <Stack direction="column" spacing={1} width={'100%'}> - <MemoInput /> - </Stack> - </Grid> + <Box sx={{ padding: 1 }}> + <CreateBase resource="locRevise" mutationOptions={mutationOptions} > + <SimpleForm > + <Grid container spacing={2} sx={{ + '& .MuiToolbar-root-RaToolbar-root.RaToolbar-defaultToolbar': { + justifyContent: 'flex-end', + } + }}> + <Grid item md={2}> + <TextInput + source="code" + label={translate("table.field.locRevise.code")} + readOnly + /> </Grid> - </DialogContent> - <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> - <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > - <SaveButton /> - </Toolbar> - </DialogActions> - </Form> - </Dialog> - </CreateBase> + <Grid item md={2}> + <AutocompleteInput + choices={dicts} + optionText='label' + optionValue="value" + defaultValue="1" + source="type" + label={translate("table.field.transfer.type")} + /> + </Grid> + <Grid item md={2}> + <ReferenceInput source="areaId" reference="warehouseAreas"> + <AutocompleteInput + optionText='name' + optionValue="id" + label={translate("table.field.locRevise.areaName")} + /> + </ReferenceInput> + </Grid> + <Grid item md={2}> + <DateInput + source="exceTime" + label="table.field.locRevise.exceTime" + /> + </Grid> + </Grid> + </SimpleForm> + </CreateBase> + <Box sx={{ mt: 2 }}> + <Stack direction="row" spacing={2} sx={{ justifyContent: "flex-end" }}> + <Button variant="contained" onClick={newAddClick} > + {translate('common.action.newAddMats')} + </Button> + <ConfirmButton label={"toolbar.delete"} variant="outlined" color="error" onConfirm={handleDeleteItem} /> + </Stack> + </Box> + <Box sx={{ mt: 2 }}> + <TransferTableView + tabelData={tabelData} + setTableData={setTableData} + orderId={orderId} + selectedRows={selectedRows} + setSelectedRows={setSelectedRows} + tableRef={tableRef}> + </TransferTableView> + </Box> + <Toolbar sx={{ width: '100%', justifyContent: 'flex-start', bgcolor: 'white' }} > + <Button disabled={disabled} onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}> + {translate('toolbar.confirm')} + </Button> + </Toolbar> + {/* <CreateBySelectMats + data={tabelData} + queryForm={formData} + open={createDialog} + setOpen={setCreateDialog} + selectedRows={selectedRows} + setSelectedRows={setSelectedRows} + setData={setTableData} + /> */} + </Box> </> ) } +const SelectInputSplrNameEditCell = (params) => { + const [formData, setFormData] = useState([{}]) + useEffect(() => { + getOptions(); + }, []); + const getOptions = async () => { + const parmas = { + "type": "supplier" + } + const { + data: { code, data, msg }, + } = await request.post("companys/page", parmas); + if (code === 200) { + setFormData(data.records) + } else { + notify(msg); + } + } + + return ( + <Select + value={params.value} + onChange={(e) => { + params.api.setEditCellValue({ + id: params.id, + field: params.field, + value: e.target.value, + }) + // 鎵惧埌閫変腑鐨勪緵搴斿晢璁板綍 + const selectedSupplier = formData.find(supplier => supplier.name === e.target.value); + + // 濡傛灉鎵惧埌瀵瑰簲鐨勪緵搴斿晢璁板綍锛屽悓鏃舵洿鏂皊plrCode瀛楁 + if (selectedSupplier) { + params.api.setEditCellValue({ + id: params.id, + field: 'splrCode', + value: selectedSupplier.id, + }); + } + }} + fullWidth + > + {formData.map(e => { + return ( + <MenuItem value={e.name} children={e.name} key={e.id} /> + ); + + })} + + </Select> + ); +}; + +const SelectInputSplrCodeEditCell = (params) => { + const [formData, setFormData] = useState([{}]) + useEffect(() => { + getOptions(); + }, []); + const getOptions = async () => { + const parmas = { + "type": "supplier" + } + const { + data: { code, data, msg }, + } = await request.post("companys/page", parmas); + if (code === 200) { + setFormData(data.records) + } else { + notify(msg); + } + } + + return ( + <Select + value={params.value} + onChange={(e) => { + params.api.setEditCellValue({ + id: params.id, + field: params.field, + value: e.target.value, + }) + const selectedSupplier = formData.find(supplier => supplier.id === e.target.value); + + // 濡傛灉鎵惧埌瀵瑰簲鐨勪緵搴斿晢璁板綍锛屽悓鏃舵洿鏂皊plrCode瀛楁 + if (selectedSupplier) { + params.api.setEditCellValue({ + id: params.id, + field: 'splrName', + value: selectedSupplier.name, + }); + } + }} + fullWidth + + > + {formData.map(e => { + return ( + <MenuItem value={e.id} children={e.name} key={e.id} /> + ); + + })} + + </Select> + ); +}; + + + +const TransferTableView = ({ tabelData, setTableData, orderId, selectedRows, setSelectedRows, tableRef }) => { + const [extendColumns, setExtendColumns] = useState([]); + const translate = useTranslate(); + const notify = useNotify(); + const [columns, setColumns] = useState([ + { + field: 'maktx', + headerName: translate('table.field.outStockItem.maktx'), + width: 250, + editable: false, + }, + { + field: 'matnrCode', + headerName: translate('table.field.outStockItem.matnrCode'), + width: 130, + editable: false, + }, + { + field: 'anfme', + headerName: translate('table.field.outStockItem.anfme'), + type: 'number', + minWidth: 100, + flex: 1, + editable: true, + valueFormatter: (val) => val < 0 ? 0 : val, + }, + { + field: 'splrCode', + headerName: translate('table.field.outStockItem.splrCode'), + minWidth: 100, + flex: 1, + editable: true, + renderEditCell: (params) => ( + <SelectInputSplrCodeEditCell {...params} /> + ), + }, + { + field: 'splrName', + headerName: translate('table.field.outStockItem.splrName') + "*", + minWidth: 100, + flex: 1, + editable: true, + renderEditCell: (params) => ( + <SelectInputSplrNameEditCell {...params} /> + ), + }, + { + field: 'batch', + headerName: translate('table.field.outStockItem.splrBatch'), + minWidth: 100, + flex: 1, + editable: true, + }, + { + field: 'stockUnit', + headerName: translate('table.field.outStockItem.stockUnit'), + minWidth: 100, + flex: 1, + editable: true, + }, + ]) + + const action = { + field: 'action', + headerName: '鎿嶄綔', + width: 70, + lockPosition: 'left', + renderCell: (params) => ( + <Tooltip title="Delete"> + <IconButton onClick={() => handleDelete(params.row)}> + <Delete /> + </IconButton> + </Tooltip> + ), + } + + let cdata = useRef([]); + + useEffect(() => { + if (extendColumns == undefined || extendColumns.length < 1) { + getDynamicFields(); + } + }, []); + + useEffect(() => { + cdata.current = tabelData + }, [tabelData]); + + + const getDynamicFields = async () => { + const { + data: { code, data, msg }, + } = await request.get("/fields/enable/list"); + if (code === 200) { + const cols = data.map(el => ({ + field: el.fields, + headerName: el.fieldsAlise, + minWidth: 100, + flex: 1, + editable: false + })) + setColumns([...columns, ...cols, action]) + setExtendColumns(cols); + } else { + notify(msg); + } + } + + + const handleDelete = (row) => { + const newData = _.filter(cdata.current, (item) => item.matnrId !== row.matnrId); + setTableData(newData); + }; + + + const processRowUpdate = (newRow, oldRow) => { + const rows = tabelData.map((r) => + r.matnrId === newRow.matnrId ? { ...newRow } : r + ) + setTableData(rows) + return newRow; + }; + + const handleSelectionChange = (ids) => { + setSelectedRows(ids) + }; + + tableRef.current = useGridApiRef(); + + const tableIds = tabelData.map(map => map.id); + // setSelectedRows(tableIds); + // // console.log(selectedRows); + + + return ( + <Box> + <DataGrid + apiRef={tableRef} + rows={tabelData} + columns={columns} + disableRowSelectionOnClick + initialState={{ + pagination: { + paginationModel: { + pageSize: 25, + }, + }, + }} + pageSizeOptions={[15, 25, 50, 100]} + editMode="row" + checkboxSelection + rowSelectionModel={tableIds} + onRowSelectionModelChange={handleSelectionChange} + sx={{ + height: 580, + '& .MuiDataGrid-cell input': { + border: '1px solid #ccc' + }, + }} + /> + </Box> + ); +}; + + export default LocReviseCreate; diff --git a/rsf-admin/src/page/stockManage/locRevise/LocReviseList.jsx b/rsf-admin/src/page/stockManage/locRevise/LocReviseList.jsx index 18d5ca9..30a792c 100644 --- a/rsf-admin/src/page/stockManage/locRevise/LocReviseList.jsx +++ b/rsf-admin/src/page/stockManage/locRevise/LocReviseList.jsx @@ -35,6 +35,7 @@ import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; import MyCreateButton from "@/page/components/MyCreateButton"; import MyExportButton from '@/page/components/MyExportButton'; +import PageEditDrawer from "@/page/components/PageEditDrawer"; import { Box, Typography, Card, Stack } from '@mui/material'; import PageDrawer from "@/page/components/PageDrawer"; import EmptyData from "@/page/components/EmptyData"; @@ -42,7 +43,6 @@ import MyField from "@/page/components/MyField"; import { styled } from '@mui/material/styles'; import LocRevisePanel from "./LocRevisePanel"; -import * as Common from '@/utils/common'; const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ '& .css-1vooibu-MuiSvgIcon-root': { @@ -62,12 +62,11 @@ <SearchInput source="condition" alwaysOn />, <DateInput label='common.time.after' source="timeStart" alwaysOn />, <DateInput label='common.time.before' source="timeEnd" alwaysOn />, - <TextInput source="code" label="table.field.locRevise.code" />, <SelectInput source="type" label="table.field.locRevise.type" choices={[ { id: 0, name: ' 搴撳瓨璋冩暣' }, - { id: 2, name: ' 鐩樼偣璋冩暣' }, + { id: 2, name: ' 鐩樼偣璋冩暣' }, ]} />, <NumberInput source="anfme" label="table.field.locRevise.anfme" />, @@ -75,13 +74,12 @@ <SelectInput source="exceStatus" label="table.field.locRevise.exceStatus" choices={[ { id: 0, name: '鏈墽琛�' }, - { id: 1, name: '鎵ц涓�' }, - { id: 2, name: '鎵ц瀹屾垚' }, + { id: 1, name: '鎵ц涓�' }, + { id: 2, name: '鎵ц瀹屾垚' }, ]} />, <NumberInput source="orgAreaId" label="table.field.locRevise.orgAreaId" />, <TextInput source="orgAreaName" label="table.field.locRevise.orgAreaName" />, - <TextInput label="common.field.memo" source="memo" />, <SelectInput label="common.field.status" @@ -95,10 +93,9 @@ ] const LocReviseList = () => { - const translate = useTranslate(); - const [createDialog, setCreateDialog] = useState(false); const [drawerVal, setDrawerVal] = useState(false); + const translate = useTranslate(); return ( <Box display="flex"> @@ -127,9 +124,9 @@ > <StyledDatagrid preferenceKey='locRevise' - bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />} + bulkActionButtons={false} rowClick={(id, resource, record) => false} - expand={() => <LocRevisePanel />} + expand={false} expandSingle={true} omit={['id', 'createTime', 'createBy', 'memo']} > @@ -141,14 +138,9 @@ <TextField source="exceStatus$" label="table.field.locRevise.exceStatus" sortable={false} /> <NumberField source="orgAreaId" label="table.field.locRevise.orgAreaId" /> <TextField source="orgAreaName" label="table.field.locRevise.orgAreaName" /> - - <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> - <TextField source="nickname" /> - </ReferenceField> + <TextField source="updateBy$" label="common.field.updateBy" /> <DateField source="updateTime" label="common.field.updateTime" showTime /> - <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}> - <TextField source="nickname" /> - </ReferenceField> + <DateField source="createBy$" label="common.field.createBy" /> <DateField source="createTime" label="common.field.createTime" showTime /> <BooleanField source="statusBool" label="common.field.status" sortable={false} /> <TextField source="memo" label="common.field.memo" sortable={false} /> @@ -158,16 +150,16 @@ </WrapperField> </StyledDatagrid> </List> - <LocReviseCreate - open={createDialog} - setOpen={setCreateDialog} - /> - <PageDrawer - title='LocRevise Detail' - drawerVal={drawerVal} - setDrawerVal={setDrawerVal} + <PageEditDrawer + title={"toolbar.createLocRevise"} + drawerVal={createDialog} + setDrawerVal={setCreateDialog} > - </PageDrawer> + <LocReviseCreate + open={createDialog} + setOpen={setCreateDialog} + /> + </PageEditDrawer> </Box> ) } -- Gitblit v1.9.1