| | |
| | | ntyStatus: "Notify", |
| | | exceStatus: 'bill status' |
| | | }, |
| | | checkOrder: { |
| | | code: "Check Code", |
| | | poCode: "Po Code", |
| | | poId: "Po Id", |
| | | type: "Type", |
| | | wkType: "Work Type", |
| | | anfme: "Anfme", |
| | | workQty: 'Work Qty', |
| | | qty: "Qty", |
| | | logisNo: "Logis No", |
| | | arrTime: "arrived Time", |
| | | rleStatus: "释放状态", |
| | | ntyStatus: "上报状态", |
| | | exceStatus: '单据状态' |
| | | }, |
| | | outStockItem: { |
| | | asnId: "ID", |
| | | asnCode: "Out Code", |
| | |
| | | checkOutBound: '盘点出库', |
| | | stockTransfer: '库位转移', |
| | | waveRule: '波次策略', |
| | | |
| | | checkOrder: '盘点单', |
| | | }, |
| | | table: { |
| | | field: { |
| | |
| | | ntyStatus: "上报状态", |
| | | exceStatus: '单据状态' |
| | | }, |
| | | checkOrder: { |
| | | code: "盘点单号", |
| | | poCode: "DO单号", |
| | | poId: "DO标识", |
| | | type: "类型", |
| | | wkType: "业务类型", |
| | | anfme: "数量", |
| | | workQty: '执行数', |
| | | qty: "完成数", |
| | | logisNo: "物流单号", |
| | | arrTime: "预计到达时间", |
| | | rleStatus: "释放状态", |
| | | ntyStatus: "上报状态", |
| | | exceStatus: '单据状态' |
| | | }, |
| | | asnOrderItem: { |
| | | asnId: "主单标识", |
| | | asnCode: "单号", |
| | |
| | | import checkOutBound from "./work/checkOutBound"; |
| | | import stockTransfer from "./work/stockTransfer"; |
| | | import waveRule from './waveRule'; |
| | | import check from './orders/check'; |
| | | |
| | | const ResourceContent = (node) => { |
| | | switch (node.component) { |
| | |
| | | return stockTransfer; |
| | | case 'waveRule': |
| | | return waveRule; |
| | | case 'check': |
| | | return check; |
| | | default: |
| | | return { |
| | | list: ListGuesser, |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | CreateBase, |
| | | useTranslate, |
| | | TextInput, |
| | | NumberInput, |
| | | BooleanInput, |
| | | TextField, |
| | | WrapperField, |
| | | NumberField, |
| | | DateInput, |
| | | TopToolbar, |
| | | SelectColumnsButton, |
| | | DatagridConfigurable, |
| | | SaveButton, |
| | | SelectInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | Toolbar, |
| | | required, |
| | | useDataProvider, |
| | | useNotify, |
| | | Form, |
| | | useCreateController, |
| | | useGetList, |
| | | useList, |
| | | ListContextProvider, |
| | | useListContext, |
| | | Button, |
| | | useRecordContext, |
| | | } from 'react-admin'; |
| | | import { |
| | | Dialog, |
| | | DialogActions, |
| | | DialogContent, |
| | | DialogTitle, |
| | | Stack, |
| | | Grid, |
| | | Box, |
| | | } from '@mui/material'; |
| | | import DialogCloseButton from "../../components/DialogCloseButton"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import { styled } from '@mui/material/styles'; |
| | | import StatusSelectInput from "../../components/StatusSelectInput"; |
| | | import OutOrderItemList from "./OutOrderItemList"; |
| | | import MemoInput from "../../components/MemoInput"; |
| | | import AddIcon from '@mui/icons-material/Add'; |
| | | import SelectMatnrModal from "./SelectMatnrModal"; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | }, |
| | | })); |
| | | |
| | | |
| | | const OutOrderCreate = (props) => { |
| | | const { open, setOpen, record } = props; |
| | | const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || []; |
| | | const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || []; |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const [matCreate, setMatCreate] = useState(false); |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | |
| | | 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 { data, total, isPending, error, refetch, meta } = useGetList('/wave/locs/preview', { filter: { waveId: record?.id } }); |
| | | const listContext = useList({ data, isPending }); |
| | | |
| | | 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="xl" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
| | | > |
| | | <Form |
| | | resource="outStock" |
| | | > |
| | | <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> |
| | | <Grid item xs={12} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.asnOrder.poCode" |
| | | source="poCode" |
| | | parse={v => v} |
| | | /> |
| | | <NumberInput |
| | | label="table.field.asnOrder.poId" |
| | | source="poId" |
| | | /> |
| | | {/* <AutocompleteInput |
| | | choices={dicts} |
| | | optionText="label" |
| | | label="table.field.asnOrder.type" |
| | | source="type" |
| | | optionValue="value" |
| | | validate={required()} |
| | | parse={v => v} |
| | | /> */} |
| | | <AutocompleteInput |
| | | choices={business} |
| | | optionText="label" |
| | | label="table.field.asnOrder.wkType" |
| | | source="wkType" |
| | | optionValue="value" |
| | | validate={required()} |
| | | parse={v => v} |
| | | /> |
| | | <NumberInput |
| | | label="table.field.asnOrder.anfme" |
| | | source="anfme" |
| | | validate={required()} |
| | | /> |
| | | |
| | | </Grid> |
| | | <Grid item xs={12} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.asnOrder.qty" |
| | | source="qty" |
| | | /> |
| | | <TextInput |
| | | label="table.field.asnOrder.logisNo" |
| | | source="logisNo" |
| | | parse={v => v} |
| | | /> |
| | | <DateInput |
| | | label="table.field.asnOrder.arrTime" |
| | | source="arrTime" |
| | | /> |
| | | <SelectInput |
| | | label="table.field.asnOrder.rleStatus" |
| | | source="rleStatus" |
| | | choices={[ |
| | | { id: 0, name: ' 正常' }, |
| | | { id: 1, name: ' 已释放' }, |
| | | ]} |
| | | /> |
| | | </Grid> |
| | | </Grid> |
| | | <SelectMatnrModal open={matCreate} setOpen={setMatCreate} /> |
| | | <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> |
| | | <Toolbar sx={{ width: '100%', justifyContent: 'end' }} > |
| | | <AddOutOrderButton setMatCreate={setMatCreate} /> |
| | | <SaveButton /> |
| | | </Toolbar> |
| | | </DialogActions> |
| | | <Box> |
| | | |
| | | </Box> |
| | | </> |
| | | </DialogContent> |
| | | </Form> |
| | | </Dialog> |
| | | </CreateBase> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default OutOrderCreate; |
| | | |
| | | |
| | | const AddOutOrderButton = (setMatCreate) => { |
| | | const record = useRecordContext(); |
| | | const addMats = (event) => { |
| | | event.stopPropagation(); |
| | | setMatCreate(true) |
| | | } |
| | | |
| | | return ( |
| | | <Button label={"common.action.newAddMats"} onClick={addMats} variant="contained" sx={{ padding: '0.6em', marginRight: '1em' }}> |
| | | <AddIcon /> |
| | | </Button> |
| | | ); |
| | | } |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | Edit, |
| | | SimpleForm, |
| | | useTranslate, |
| | | TextInput, |
| | | DateInput, |
| | | SelectInput, |
| | | AutocompleteInput, |
| | | SaveButton, |
| | | Toolbar, |
| | | required, |
| | | DeleteButton, |
| | | } from 'react-admin'; |
| | | import { Stack, Grid, Box, Typography } from '@mui/material'; |
| | | import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting'; |
| | | import EditBaseAside from "../../components/EditBaseAside"; |
| | | import CustomerTopToolBar from "../../components/EditTopToolBar"; |
| | | import CheckOrderItemList from "./CheckOrderItemList"; |
| | | |
| | | |
| | | const CheckOrderEdit = () => { |
| | | const translate = useTranslate(); |
| | | const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_order_type')) || []; |
| | | const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || []; |
| | | |
| | | return ( |
| | | <> |
| | | <Edit |
| | | redirect="list" |
| | | mutationMode={EDIT_MODE} |
| | | actions={<CustomerTopToolBar />} |
| | | aside={<EditBaseAside />} |
| | | > |
| | | <SimpleForm |
| | | shouldUnregister |
| | | warnWhenUnsavedChanges |
| | | toolbar={false} |
| | | mode="onTouched" |
| | | defaultValues={{}} |
| | | > |
| | | <Grid container width={{ xs: '100%', xl: '100%' }} rowSpacing={3} columnSpacing={3} |
| | | sx={{ |
| | | "& .MuiFormLabel-root.MuiInputLabel-root.Mui-disabled": { |
| | | bgcolor: 'white', |
| | | WebkitTextFillColor: "rgba(0, 0, 0)" |
| | | }, |
| | | |
| | | "& .MuiInputBase-input.MuiFilledInput-input.Mui-disabled": { |
| | | bgcolor: 'white', |
| | | WebkitTextFillColor: "rgba(0, 0, 0)" |
| | | }, |
| | | "& .MuiFilledInput-root.MuiInputBase-sizeSmall": { |
| | | bgcolor: 'white', |
| | | } |
| | | }} |
| | | > |
| | | <Grid item xs={24} md={12} > |
| | | <Typography variant="h6" gutterBottom> |
| | | {translate('common.edit.title.main')} |
| | | </Typography> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.outStock.code" |
| | | source="code" |
| | | readOnly |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStock.poCode" |
| | | source="poCode" |
| | | readOnly |
| | | parse={v => v} |
| | | /> |
| | | <AutocompleteInput |
| | | choices={dicts} |
| | | optionText="label" |
| | | label="table.field.outStock.type" |
| | | source="type" |
| | | optionValue="value" |
| | | parse={v => v} |
| | | readOnly |
| | | /> |
| | | <AutocompleteInput |
| | | choices={business} |
| | | optionText="label" |
| | | label="table.field.outStock.wkType" |
| | | source="wkType" |
| | | optionValue="value" |
| | | parse={v => v} |
| | | readOnly |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <TextInput |
| | | label="table.field.outStock.logisNo" |
| | | source="logisNo" |
| | | readOnly |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStock.anfme" |
| | | source="anfme" |
| | | readOnly |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStock.qty" |
| | | source="qty" |
| | | readOnly |
| | | parse={v => v} |
| | | /> |
| | | <DateInput |
| | | label="table.field.outStock.arrTime" |
| | | source="arrTime" |
| | | readOnly |
| | | /> |
| | | <SelectInput |
| | | label="table.field.outStock.rleStatus" |
| | | source="rleStatus" |
| | | readOnly |
| | | choices={[ |
| | | { id: 0, name: ' 正常' }, |
| | | { id: 1, name: ' 已释放' }, |
| | | ]} |
| | | validate={required()} |
| | | /> |
| | | </Stack> |
| | | </Grid> |
| | | </Grid> |
| | | </SimpleForm> |
| | | </Edit > |
| | | <CheckOrderItemList /> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default CheckOrderEdit; |
New file |
| | |
| | | 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, |
| | | } from 'react-admin'; |
| | | import { |
| | | Dialog, |
| | | DialogActions, |
| | | DialogContent, |
| | | DialogTitle, |
| | | Stack, |
| | | Grid, |
| | | Box, |
| | | } from '@mui/material'; |
| | | import DialogCloseButton from "../../components/DialogCloseButton"; |
| | | import StatusSelectInput from "../../components/StatusSelectInput"; |
| | | import MemoInput from "../../components/MemoInput"; |
| | | |
| | | |
| | | |
| | | const CheckOrderItemCreate = (props) => { |
| | | const { open, setOpen, record } = props; |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | |
| | | 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 } }); |
| | | }; |
| | | |
| | | return ( |
| | | <> |
| | | <CreateBase |
| | | resource="outStockItem" |
| | | 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> |
| | | <Grid item xs={6} display="flex" gap={2}> |
| | | <NumberInput |
| | | label="table.field.outStockItem.asnId" |
| | | source="asnId" |
| | | readOnly |
| | | hidden |
| | | defaultValue={record?.id} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.asnCode" |
| | | source="asnCode" |
| | | readOnly |
| | | defaultValue={record?.code} |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.poDetlId" |
| | | source="poDetlId" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.outStockItem.matnrId" |
| | | source="matnrId" |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.maktx" |
| | | source="maktx" |
| | | parse={v => v} |
| | | /> |
| | | <NumberInput |
| | | label="table.field.outStockItem.anfme" |
| | | source="anfme" |
| | | validate={required()} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.outStockItem.stockUnit" |
| | | source="stockUnit" |
| | | parse={v => v} |
| | | /> |
| | | <NumberInput |
| | | label="table.field.outStockItem.purQty" |
| | | source="purQty" |
| | | validate={required()} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.purUnit" |
| | | source="purUnit" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <NumberInput |
| | | label="table.field.outStockItem.qty" |
| | | source="qty" |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.splrCode" |
| | | source="splrCode" |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.splrName" |
| | | source="splrName" |
| | | parse={v => v} |
| | | /> |
| | | |
| | | </Grid> |
| | | <Grid item xs={6} display="flex" gap={1}> |
| | | <TextInput |
| | | label="table.field.outStockItem.qrcode" |
| | | source="qrcode" |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.barcode" |
| | | source="barcode" |
| | | parse={v => v} |
| | | /> |
| | | <TextInput |
| | | label="table.field.outStockItem.packName" |
| | | source="packName" |
| | | parse={v => v} |
| | | /> |
| | | </Grid> |
| | | |
| | | <Grid item xs={4} display="flex" gap={1}> |
| | | <StatusSelectInput /> |
| | | </Grid> |
| | | <Grid item xs={4} display="flex" gap={1}> |
| | | <Stack direction="column" spacing={1}> |
| | | <MemoInput /> |
| | | </Stack> |
| | | </Grid> |
| | | </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> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default CheckOrderItemCreate; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo, useCallback } from "react"; |
| | | import { useNavigate, useLocation } from 'react-router-dom'; |
| | | import { |
| | | List, |
| | | DatagridConfigurable, |
| | | SearchInput, |
| | | TopToolbar, |
| | | SelectColumnsButton, |
| | | EditButton, |
| | | FilterButton, |
| | | CreateButton, |
| | | ExportButton, |
| | | BulkDeleteButton, |
| | | WrapperField, |
| | | useRecordContext, |
| | | useTranslate, |
| | | useNotify, |
| | | useListContext, |
| | | FunctionField, |
| | | TextField, |
| | | NumberField, |
| | | DateField, |
| | | BooleanField, |
| | | ReferenceField, |
| | | TextInput, |
| | | DateTimeInput, |
| | | DateInput, |
| | | SelectInput, |
| | | NumberInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | DeleteButton, |
| | | Button, |
| | | useEditContext, |
| | | useGetRecordId, |
| | | useGetOne |
| | | } from 'react-admin'; |
| | | import { Box, Typography, Card, Stack, Dialog, DialogActions, DialogTitle } from '@mui/material'; |
| | | import { styled } from '@mui/material/styles'; |
| | | import PageDrawer from "../../components/PageDrawer"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting'; |
| | | |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em', |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 200 |
| | | }, |
| | | })); |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <NumberInput source="asnId" label="table.field.outStockItem.asnId" />, |
| | | <TextInput source="asnCode" label="table.field.outStockItem.asnCode" alwaysOn />, |
| | | <TextInput source="poDetlId" label="table.field.outStockItem.poDetlId" />, |
| | | <TextInput source="matnrId" label="table.field.outStockItem.matnrId" />, |
| | | <TextInput source="maktx" label="table.field.outStockItem.maktx" alwaysOn />, |
| | | <TextInput source="matnrCode" label="table.field.outStockItem.matnrCode" alwaysOn />, |
| | | <NumberInput source="anfme" label="table.field.outStockItem.anfme" />, |
| | | <TextInput source="stockUnit" label="table.field.outStockItem.stockUnit" />, |
| | | <NumberInput source="purQty" label="table.field.outStockItem.purQty" />, |
| | | <TextInput source="purUnit" label="table.field.outStockItem.purUnit" />, |
| | | <NumberInput source="qty" label="table.field.outStockItem.qty" />, |
| | | <TextInput source="splrCode" label="table.field.outStockItem.splrCode" />, |
| | | <TextInput source="splrName" label="table.field.outStockItem.splrName" />, |
| | | <TextInput source="qrcode" label="table.field.outStockItem.qrcode" />, |
| | | <TextInput source="trackCode" label="table.field.outStockItem.barcode" />, |
| | | <TextInput source="packName" label="table.field.outStockItem.packName" />, |
| | | <TextInput label="common.field.memo" source="memo" />, |
| | | <SelectInput |
| | | label="common.field.status" |
| | | source="status" |
| | | choices={[ |
| | | { id: '1', name: 'common.enums.statusTrue' }, |
| | | { id: '0', name: 'common.enums.statusFalse' }, |
| | | ]} |
| | | resettable |
| | | />, |
| | | ] |
| | | |
| | | const OutOrderItemList = () => { |
| | | const translate = useTranslate(); |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [editDialog, setEditDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const [select, setSelect] = useState({}); |
| | | const asnId = useGetRecordId(); |
| | | const { data: dicts, isPending, error } = useGetOne('outStock', { id: asnId }); |
| | | |
| | | return ( |
| | | <> |
| | | <Box display="flex"> |
| | | <List |
| | | resource="outStockItem" |
| | | storeKey='outStockItem' |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, |
| | | }} |
| | | title={"menu.outStockItem"} |
| | | empty={false} |
| | | filter={{ asnId: asnId, deleted: 0 }} |
| | | filters={filters} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <SelectColumnsButton preferenceKey='outStockItem' /> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_ITEM_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='outStockItem' |
| | | bulkActionButtons={false} |
| | | rowClick={false} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'poDetlId', 'purQty', 'purUnit', 'trackCode', 'packName', 'qrcode', 'splrName', 'matnrId', 'asnId']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <NumberField source="asnId" label="table.field.outStockItem.asnId" /> |
| | | <TextField source="asnCode" label="table.field.outStockItem.asnCode" /> |
| | | <TextField source="poCode" label="table.field.outStockItem.poCode" /> |
| | | <TextField source="poDetlId" label="table.field.outStockItem.poDetlId" /> |
| | | <TextField source="matnrId" label="table.field.outStockItem.matnrId" /> |
| | | <TextField source="matnrCode" label="table.field.outStockItem.matnrCode" /> |
| | | <TextField source="maktx" label="table.field.outStockItem.maktx" /> |
| | | <TextField source="platOrderCode" label="table.field.outStockItem.platOrderCode" /> |
| | | <NumberField source="anfme" label="table.field.outStockItem.anfme" /> |
| | | <NumberField source="purQty" label="table.field.outStockItem.purQty" /> |
| | | <NumberField source="workQty" label="table.field.outStockItem.workQty" /> |
| | | <NumberField source="qty" label="table.field.outStockItem.qty" /> |
| | | <TextField source="stockUnit" label="table.field.outStockItem.stockUnit" /> |
| | | <TextField source="splrBatch" label="table.field.outStockItem.splrBatch" /> |
| | | <TextField source="purUnit" label="table.field.outStockItem.purUnit" /> |
| | | <TextField source="splrCode" label="table.field.outStockItem.splrCode" /> |
| | | <TextField source="splrName" label="table.field.outStockItem.splrName" /> |
| | | <TextField source="qrcode" label="table.field.outStockItem.qrcode" /> |
| | | <TextField source="trackCode" label="table.field.outStockItem.barcode" /> |
| | | <TextField source="packName" label="table.field.outStockItem.packName" /> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime /> |
| | | <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField>, |
| | | <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField>, |
| | | <DateField source="createTime" label="common.field.createTime" showTime /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} /> |
| | | </StyledDatagrid> |
| | | </List> |
| | | {/* <OutOrderItemCreate |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | record={dicts} |
| | | /> |
| | | <OutOrderItemEdit |
| | | open={editDialog} |
| | | setOpen={setEditDialog} |
| | | record={select} |
| | | /> */} |
| | | <PageDrawer |
| | | title='OutStockItem Detail' |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | </PageDrawer> |
| | | </Box> |
| | | </> |
| | | ) |
| | | } |
| | | OutOrderItemList.Context = React.createContext() |
| | | |
| | | export default OutOrderItemList; |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo, useCallback } from "react"; |
| | | import { useLocation, useNavigate } from 'react-router-dom'; |
| | | import { |
| | | List, |
| | | DatagridConfigurable, |
| | | SearchInput, |
| | | TopToolbar, |
| | | Toolbar, |
| | | SelectColumnsButton, |
| | | EditButton, |
| | | FilterButton, |
| | | CreateButton, |
| | | ExportButton, |
| | | BulkDeleteButton, |
| | | useDataProvider, |
| | | WrapperField, |
| | | useRecordContext, |
| | | useTranslate, |
| | | useNotify, |
| | | useRefresh, |
| | | useListContext, |
| | | FunctionField, |
| | | TextField, |
| | | NumberField, |
| | | DateField, |
| | | BooleanField, |
| | | ReferenceField, |
| | | TextInput, |
| | | DateTimeInput, |
| | | DateInput, |
| | | SelectInput, |
| | | NumberInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | DeleteButton, |
| | | Button, |
| | | useRedirect, |
| | | useUnselectAll, |
| | | useRecordSelection, |
| | | } from 'react-admin'; |
| | | import { styled } from '@mui/material/styles'; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined'; |
| | | import { Box, Typography, Card, Stack, Drawer } from '@mui/material'; |
| | | import DictionarySelect from "../../components/DictionarySelect"; |
| | | import BillStatusField from '../../components/BillStatusField'; |
| | | import MyCreateButton from "../../components/MyCreateButton"; |
| | | import ConfirmButton from '../../components/ConfirmButton'; |
| | | import ImportButton from "../../components/ImportButton"; |
| | | import DetailsIcon from '@mui/icons-material/Details'; |
| | | import AddTaskIcon from '@mui/icons-material/AddTask'; |
| | | import PublicIcon from '@mui/icons-material/Public'; |
| | | import EditIcon from '@mui/icons-material/Edit'; |
| | | import AddIcon from '@mui/icons-material/Add'; |
| | | import request from '@/utils/request'; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | '& .opt': { |
| | | width: 220 |
| | | }, |
| | | '& .wkType': { |
| | | width: 110 |
| | | }, |
| | | '& .status': { |
| | | width: 90 |
| | | }, |
| | | })); |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <TextInput source="code" label="table.field.outStock.code" alwaysOn />, |
| | | <TextInput source="poCode" label="table.field.outStock.poCode" />, |
| | | <NumberInput source="poId" label="table.field.outStock.poId" />, |
| | | <ReferenceInput source="type" reference="dictData" filter={{ dictTypeCode: 'sys_order_type', group: '2' }} label="table.field.outStock.type" alwaysOn> |
| | | <AutocompleteInput label="table.field.outStock.type" optionValue="value" /> |
| | | </ReferenceInput>, |
| | | <ReferenceInput source="wkType" reference="dictData" filter={{ dictTypeCode: 'sys_business_type', group: '2' }} label="table.field.outStock.wkType" alwaysOn> |
| | | <AutocompleteInput label="table.field.outStock.wkType" optionValue="value" /> |
| | | </ReferenceInput>, |
| | | <NumberInput source="anfme" label="table.field.outStock.anfme" />, |
| | | <NumberInput source="qty" label="table.field.outStock.qty" />, |
| | | <TextInput source="logisNo" label="table.field.outStock.logisNo" />, |
| | | <DateInput source="arrTime" label="table.field.outStock.arrTime" />, |
| | | <SelectInput source="rleStatus" label="table.field.outStock.rleStatus" |
| | | choices={[ |
| | | { id: 0, name: ' 正常' }, |
| | | { id: 1, name: ' 已释放' }, |
| | | ]} |
| | | />, |
| | | |
| | | <TextInput label="common.field.memo" source="memo" />, |
| | | <DictionarySelect |
| | | label='table.field.outStock.exceStatus' |
| | | name="exceStatus" |
| | | dictTypeCode="sys_asn_exce_status" |
| | | alwaysOn |
| | | />, |
| | | ] |
| | | |
| | | const CheckOrderList = (props) => { |
| | | const translate = useTranslate(); |
| | | const refresh = useRefresh(); |
| | | const notify = useNotify(); |
| | | |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [manualDialog, setManualDialog] = useState(false); |
| | | const [selectIds, setSelectIds] = useState([]); |
| | | const [preview, setPreview] = useState(false); |
| | | const [waveRule, setWaveRule] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const [modalType, setmodalType] = useState(0); |
| | | const [select, setSelect] = useState(0); |
| | | const billReload = useRef(); |
| | | const dicts = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type')) || []; |
| | | |
| | | //获取波次规则 |
| | | // const closeDialog = async (value) => { |
| | | // setWaveRule(false) |
| | | // const res = await request.post(`/outStock/generate/wave`, { ids: selectIds, waveRuleId: value.id }); |
| | | // if (res?.data?.code === 200) { |
| | | // notify(res.data.msg); |
| | | // } else { |
| | | // notify(res.data.msg); |
| | | // } |
| | | // refresh() |
| | | // } |
| | | |
| | | return ( |
| | | <Box display="flex"> |
| | | <List |
| | | resource="check" |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | }} |
| | | title={"menu.checkOrder"} |
| | | empty={false} |
| | | filters={filters} |
| | | filter={{ deleted: 0, type: 'check' }} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={( |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <CreateByOrderButton setCreateDialog={setCreateDialog} /> |
| | | <MyCreateButton onClick={() => { setManualDialog(true); setmodalType(0) }} /> |
| | | <SelectColumnsButton preferenceKey='check' /> |
| | | <ImportButton value={'outStockItem'} /> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='check' |
| | | bulkActionButtons={<PublicTaskButton setWaveRule={setWaveRule} setSelectIds={setSelectIds} />} |
| | | rowClick={false} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'rleStatus$']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="code" label="table.field.checkOrder.code" /> |
| | | <TextField source="poCode" label="table.field.checkOrder.poCode" /> |
| | | <TextField source="type$" label="table.field.checkOrder.type" /> |
| | | <TextField cellClassName="wkType" source="wkType$" label="table.field.checkOrder.wkType" /> |
| | | <NumberField source="anfme" label="table.field.checkOrder.anfme" /> |
| | | <NumberField source="workQty" label="table.field.checkOrder.workQty" /> |
| | | <NumberField source="qty" label="table.field.checkOrder.qty" /> |
| | | <TextField source="logisNo" label="table.field.checkOrder.logisNo" /> |
| | | <TextField source="rleStatus$" label="table.field.checkOrder.rleStatus" sortable={false} /> |
| | | <TextField source="updateBy$" label="common.field.updateBy" /> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime /> |
| | | <TextField source="createBy$" label="common.field.createBy" /> |
| | | <DateField source="createTime" label="common.field.createTime" showTime /> |
| | | <BillStatusField cellClassName="status" source="exceStatus" label="table.field.checkOrder.exceStatus" /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} /> |
| | | <WrapperField cellClassName="opt" label="common.field.opt" > |
| | | <MyButton setCreateDialog={setManualDialog} setmodalType={setmodalType} /> |
| | | <EditButton label="toolbar.detail" icon={(<DetailsIcon />)}></EditButton> |
| | | <CancelButton /> |
| | | <PublicButton setDrawerVal={setDrawerVal} drawerVal={drawerVal} setSelect={setSelect} /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | | </List> |
| | | {/* <OutOrderCreate |
| | | open={manualDialog} |
| | | setOpen={setManualDialog} |
| | | /> */} |
| | | {/* <SelectMatnrModal |
| | | asnId={modalType} |
| | | billReload={billReload} |
| | | open={manualDialog} |
| | | setOpen={setManualDialog} |
| | | /> |
| | | <OutOrderModal |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | preview={preview} |
| | | setPreview={setPreview} |
| | | /> |
| | | <OutStockWaveDialog open={waveRule} setOpen={setWaveRule} onClose={closeDialog} /> |
| | | <OutOrderPreview open={preview} setOpen={setPreview} /> |
| | | <PageEditDrawer |
| | | title={"toolbar.publicWorking"} |
| | | drawerVal={drawerVal} |
| | | setDrawerVal={setDrawerVal} |
| | | > |
| | | <OutStockPublic record={select} open={drawerVal} setOpen={setDrawerVal} /> |
| | | </PageEditDrawer> */} |
| | | </Box > |
| | | ) |
| | | } |
| | | export default CheckOrderList; |
| | | |
| | | |
| | | const PublicTaskButton = ({ setWaveRule, setSelectIds }) => { |
| | | const record = useRecordContext(); |
| | | const { selectedIds, onUnselectItems } = useListContext(); |
| | | const notify = useNotify(); |
| | | const redirect = useRedirect(); |
| | | |
| | | const pubClick = async () => { |
| | | onUnselectItems(); |
| | | setWaveRule(true); |
| | | setSelectIds(selectedIds) |
| | | } |
| | | |
| | | return ( |
| | | <Button |
| | | onClick={pubClick} |
| | | label={"toolbar.createWave"} |
| | | startIcon={<PublicIcon />} |
| | | /> |
| | | ); |
| | | } |
| | | |
| | | const MyButton = ({ setCreateDialog, setmodalType }) => { |
| | | const record = useRecordContext(); |
| | | const handleEditClick = (btn) => { |
| | | btn.stopPropagation(); |
| | | const id = record.id; |
| | | setmodalType(id); |
| | | setCreateDialog(true); |
| | | }; |
| | | return ( |
| | | <Button |
| | | color="primary" |
| | | startIcon={<EditIcon />} |
| | | onClick={(btn) => handleEditClick(btn)} |
| | | sx={{ ml: 1 }} |
| | | label={'ra.action.edit'} |
| | | > |
| | | </Button> |
| | | ) |
| | | } |
| | | |
| | | const CreateByOrderButton = ({ setCreateDialog }) => { |
| | | const record = useRecordContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const createByOrder = async (event) => { |
| | | event.stopPropagation(); |
| | | setCreateDialog(true); |
| | | } |
| | | |
| | | return ( |
| | | <Button onClick={createByOrder} label={'toolbar.asnCreate'}> <AddIcon /> </Button> |
| | | ) |
| | | } |
| | | |
| | | const CancelButton = () => { |
| | | const record = useRecordContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const cancelOrder = async () => { |
| | | const { data: { code, data, msg } } = await request.get(`/outStock/cancel/${record?.id}`); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | refresh() |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | record?.exceStatus == 10 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />} onConfirm={cancelOrder} size={"small"} /> : <></> |
| | | ) |
| | | } |
| | | |
| | | //下发执行 |
| | | const PublicButton = ({ setDrawerVal, setSelect }) => { |
| | | const record = useRecordContext(); |
| | | const refresh = useRefresh(); |
| | | const taskEvent = () => { |
| | | setDrawerVal(true) |
| | | setSelect(record) |
| | | refresh(); |
| | | } |
| | | |
| | | return ( |
| | | record.workQty < record.anfme ? <Button label={"toolbar.publicWorking"} startIcon={<AddTaskIcon />} onClick={taskEvent} size={"small"} /> : <></> |
| | | ) |
| | | } |
New file |
| | |
| | | import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress } from "@mui/material"; |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | List, |
| | | DatagridConfigurable, |
| | | SearchInput, |
| | | TopToolbar, |
| | | Toolbar, |
| | | Button, |
| | | SelectColumnsButton, |
| | | EditButton, |
| | | FilterButton, |
| | | CreateButton, |
| | | ExportButton, |
| | | BulkDeleteButton, |
| | | WrapperField, |
| | | useRecordContext, |
| | | useTranslate, |
| | | useNotify, |
| | | useListContext, |
| | | FunctionField, |
| | | TextField, |
| | | NumberField, |
| | | DateField, |
| | | BooleanField, |
| | | ReferenceField, |
| | | TextInput, |
| | | DateTimeInput, |
| | | DateInput, |
| | | SelectInput, |
| | | NumberInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | DeleteButton, |
| | | SimpleForm, |
| | | Form, |
| | | SaveButton, |
| | | useRefresh, |
| | | useGetList, |
| | | } from 'react-admin'; |
| | | import DialogCloseButton from "../../components/DialogCloseButton"; |
| | | import { styled } from '@mui/material/styles'; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import { Grid, margin, Stack, width } from "@mui/system"; |
| | | import request from '@/utils/request'; |
| | | import SaveIcon from '@mui/icons-material/Save'; |
| | | import CheckCircleIcon from '@mui/icons-material/CheckCircle'; |
| | | import EditableTextField from "../../components/EditableTextField"; |
| | | import OutOrderPreview from "./OutOrderPreview"; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .status': { |
| | | width: 90 |
| | | }, |
| | | })); |
| | | |
| | | const StyledForm = styled(Form)(({ theme }) => ({ |
| | | width: '100%', |
| | | marginBottom: '45px', |
| | | |
| | | '& .MuiGrid-root': { |
| | | margin: '0 10px' |
| | | } |
| | | })); |
| | | |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | <DateInput label='common.time.after' source="timeStart" />, |
| | | <DateInput label='common.time.before' source="timeEnd" />, |
| | | <TextInput source="code" label="table.field.delivery.code" />, |
| | | <TextInput source="platId" label="table.field.delivery.platId" />, |
| | | <TextInput source="type" label="table.field.delivery.type" />, |
| | | <TextInput source="wkType" label="table.field.delivery.wkType" />, |
| | | <TextInput source="source" label="table.field.delivery.source" />, |
| | | <SelectInput |
| | | label="common.field.status" |
| | | source="status" |
| | | choices={[ |
| | | { id: '1', name: 'common.enums.statusTrue' }, |
| | | { id: '0', name: 'common.enums.statusFalse' }, |
| | | ]} |
| | | resettable |
| | | />, |
| | | ] |
| | | |
| | | const OutOrderModal = (props) => { |
| | | const { open, setOpen, preview, setPreview, record } = props; |
| | | const translate = useTranslate(); |
| | | const [params, setParams] = useState({}); |
| | | const [select, setSelect] = useState([]); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const refresh = useRefresh(); |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | const CustomFilter = () => { |
| | | const { filterValues, setFilters, refetch } = useListContext(); |
| | | const [formValues, setFormValues] = useState(filterValues); |
| | | const handleChange = (event) => { |
| | | if (event.target == undefined || event.target == null) { return } |
| | | setFormValues(formValues => ({ |
| | | ...formValues, |
| | | [event.target.name]: event.target.value, |
| | | })); |
| | | }; |
| | | |
| | | const handleSubmit = (event) => { |
| | | setParams(formValues) |
| | | }; |
| | | |
| | | return ( |
| | | <StyledForm> |
| | | <Grid container rowSpacing={3} columnSpacing={3} > |
| | | <Stack> |
| | | <TextInput |
| | | source="condition" |
| | | label="common.action.search" |
| | | resettable |
| | | defaultValue={params?.condition} |
| | | onChange={handleChange} /> |
| | | </Stack> |
| | | <Stack> |
| | | <TextInput |
| | | source="deliveryCode" |
| | | label="table.field.deliveryItem.deliveryCode" |
| | | defaultValue={params?.deliveryCode} |
| | | onChange={handleChange} |
| | | resettable |
| | | /> |
| | | </Stack> |
| | | <Stack> |
| | | <TextInput |
| | | source="maktx" |
| | | label="table.field.deliveryItem.matnrName" |
| | | defaultValue={params?.maktx} |
| | | onChange={handleChange} |
| | | resettable |
| | | /> |
| | | </Stack> |
| | | <Stack> |
| | | <TextInput |
| | | source="matnrCode" |
| | | label="table.field.deliveryItem.matnrCode" |
| | | defaultValue={params?.matnrCode} |
| | | resettable |
| | | onChange={handleChange} /> |
| | | </Stack> |
| | | <Stack> |
| | | <TextInput |
| | | source="splrName" |
| | | label="table.field.deliveryItem.splrName" |
| | | defaultValue={params?.splrName} |
| | | resettable |
| | | onChange={handleChange} /> |
| | | </Stack> |
| | | </Grid> |
| | | <DialogActions> |
| | | <Toolbar sx={{ width: '100%', justifyContent: 'end' }} > |
| | | <SaveButton onClick={handleSubmit} label={"toolbar.query"} /> |
| | | </Toolbar> |
| | | </DialogActions> |
| | | </StyledForm> |
| | | ); |
| | | }; |
| | | return ( |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | aria-hidden |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="xl" |
| | | > |
| | | <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> |
| | | <Grid container rowSpacing={2} columnSpacing={2}> |
| | | <DialogContent> |
| | | <Grid item sx={24}> |
| | | <List |
| | | resource="/deliveryItem/filters" |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, |
| | | }} |
| | | filters={<CustomFilter />} |
| | | queryOptions={{ meta: { ...params } }} |
| | | empty={false} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={( |
| | | <TopToolbar> |
| | | <></> |
| | | </TopToolbar> |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <Box sx={{ position: 'relative', minHeight: "60vh", }}> |
| | | <LinearProgress |
| | | sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} |
| | | /> |
| | | <StyledDatagrid |
| | | preferenceKey='deliveryItem' |
| | | bulkActionButtons={<AddOutStockButton setOpen={setOpen} setPreview={setPreview} setSelect={setSelect} />} |
| | | rowClick={(id, resource, record) => false} |
| | | expand={false} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'memo', 'startTime', 'endTime', 'updateBy', 'createTime']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="deliveryCode" label="table.field.deliveryItem.deliveryCode" /> |
| | | <TextField source="matnrCode" label="table.field.deliveryItem.matnrCode" /> |
| | | <TextField source="maktx" label="table.field.deliveryItem.matnrName" /> |
| | | <TextField source="unit" label="table.field.deliveryItem.unit" /> |
| | | <NumberField source="anfme" label="table.field.deliveryItem.anfme" /> |
| | | <NumberField source="workQty" label="table.field.outStockItem.workQty" /> |
| | | <TextField source="splrName" label="table.field.deliveryItem.splrName" /> |
| | | <TextField source="splrBatch" label="table.field.deliveryItem.splrBatch" /> |
| | | <TextField source="updateBy$" label="common.field.updateBy" /> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime /> |
| | | <TextField 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} /> |
| | | </StyledDatagrid> |
| | | </Box> |
| | | </List> |
| | | </Grid> |
| | | </DialogContent> |
| | | </Grid> |
| | | <Grid> |
| | | <OutOrderPreview open={preview} setOpen={setPreview} selectedIds={select} setCloseParent={setOpen} /> |
| | | </Grid> |
| | | </Dialog > |
| | | ) |
| | | } |
| | | |
| | | export default OutOrderModal; |
| | | |
| | | const AddOutStockButton = (props) => { |
| | | const { setOpen, setPreview, setSelect } = props; |
| | | const { selectedIds, onUnselectItems } = useListContext(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const confirm = async (event) => { |
| | | setPreview(true) |
| | | setSelect(selectedIds); |
| | | onUnselectItems(); |
| | | // refresh(); |
| | | } |
| | | |
| | | return ( |
| | | <Button label={"toolbar.confirmSelect"} onClick={confirm}> |
| | | <CheckCircleIcon /> |
| | | </Button> |
| | | ) |
| | | } |
New file |
| | |
| | | import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress, Grid, } from "@mui/material"; |
| | | import React, { useState, useRef, useEffect, useMemo, memo } from "react"; |
| | | import { |
| | | Toolbar, |
| | | Button, |
| | | useTranslate, |
| | | useNotify, |
| | | useRefresh, |
| | | useGetList, |
| | | } from 'react-admin'; |
| | | import request from '@/utils/request'; |
| | | import { styled } from '@mui/material/styles'; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid'; |
| | | import DialogCloseButton from "../../components/DialogCloseButton"; |
| | | |
| | | |
| | | const OutOrderPreview = (props) => { |
| | | const { open, setOpen, record, selectedIds, setCloseParent } = props; |
| | | const translate = useTranslate(); |
| | | const gridRef = useGridApiRef(); |
| | | const [rows, setRows] = useState([]); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const handleClose = async (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | // const res = await request.get(`/outStock/items/cancel/` + selectedIds); |
| | | setOpen(false); |
| | | setCloseParent(false) |
| | | } |
| | | }; |
| | | |
| | | if (!selectedIds) { return } |
| | | |
| | | const { data, isLoading, error } = useGetList('/deliveryItem/edit', { |
| | | pagination: { page: 1, perPage: 1000 }, |
| | | filter: { deleted: 0, ids: selectedIds } |
| | | }); |
| | | |
| | | return ( |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | aria-hidden |
| | | fullWidth |
| | | maxWidth="lg" |
| | | > |
| | | <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> |
| | | <Grid container xl={12}> |
| | | <Grid item xl={12}> |
| | | <Box display="flex" sx={{ height: 400, width: '100%', '& .RaConfigurable-root': { width: '100%' } }}> |
| | | <LinearProgress sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} /> |
| | | <OrderPreview rows={data} gridRef={gridRef} /> |
| | | </Box > |
| | | </Grid> |
| | | </Grid> |
| | | <Toolbar sx={{ justifyContent: 'end' }}> |
| | | <ConfirmButton label="toolbar.confirm" variant="contained" size="large" gridRef={gridRef} setOpen={setOpen} setCloseParent={setCloseParent}/> |
| | | </Toolbar> |
| | | </DialogContent> |
| | | </Dialog> |
| | | ) |
| | | } |
| | | |
| | | export default OutOrderPreview; |
| | | |
| | | const ConfirmButton = ({ gridRef, setOpen, setCloseParent }) => { |
| | | const refresh = useRefresh(); |
| | | const notify = useNotify(); |
| | | const confirm = async () => { |
| | | const items = gridRef.current?.getSortedRows(); |
| | | const { data: { code, msg } } = await request.post(`/outStock/generate/orders`, { ids: items }); |
| | | if (code === 200) { |
| | | notify(msg); |
| | | refresh() |
| | | setOpen(false) |
| | | setCloseParent(false) |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | return ( |
| | | <Button label="toolbar.confirm" variant="contained" size="large" onClick={confirm} /> |
| | | ) |
| | | } |
| | | |
| | | const OrderPreview = ({ rows, gridRef }) => { |
| | | gridRef.current = useGridApiRef(); |
| | | |
| | | const columns = [ |
| | | { field: 'matnrCode', headerName: '物料编码', width: 110 }, |
| | | { field: 'maktx', headerName: '物料名称', width: 190 }, |
| | | { |
| | | field: 'anfme', headerName: '出库数量', width: 110, type: 'number', editable: true, |
| | | valueGetter: (value, row) => { |
| | | return row.anfme - row.workQty - row.qty; |
| | | }, |
| | | }, |
| | | { |
| | | field: 'workQty', headerName: '剩余数量', width: 110, type: 'number', |
| | | valueGetter: (value, row) => { |
| | | return row.anfme - row.workQty - row.qty; |
| | | }, |
| | | }, |
| | | { field: 'unit', headerName: '单位', width: 110 }, |
| | | { field: 'splrBatch', headerName: '批次', width: 110 }, |
| | | { field: 'splrName', headerName: '供应商', width: 110 }, |
| | | { field: 'updateTime', headerName: '更新时间', width: 110 }, |
| | | { field: 'updateBy$', headerName: '更新人员', width: 110 }, |
| | | ] |
| | | |
| | | return ( |
| | | <DataGrid |
| | | storeKey={"outOrderItemPreview"} |
| | | rows={rows} |
| | | columns={columns} |
| | | apiRef={gridRef} |
| | | disableRowSelectionOnClick |
| | | hideFooterPagination={true} // 隐藏分页控件 |
| | | hideFooter={true} |
| | | onRowSelectionModelChange={(ids) => { |
| | | setSelectedIds(ids) |
| | | }} |
| | | /> |
| | | ) |
| | | } |
| | | |
| | | |
New file |
| | |
| | | import { Box, Card, Grid, LinearProgress, Select, MenuItem, ListItemText } from "@mui/material"; |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | List, |
| | | DatagridConfigurable, |
| | | SearchInput, |
| | | TopToolbar, |
| | | Button, |
| | | SelectColumnsButton, |
| | | EditButton, |
| | | FilterButton, |
| | | CreateButton, |
| | | ExportButton, |
| | | BulkDeleteButton, |
| | | WrapperField, |
| | | useRecordContext, |
| | | useTranslate, |
| | | useNotify, |
| | | useListContext, |
| | | FunctionField, |
| | | TextField, |
| | | NumberField, |
| | | DateField, |
| | | BooleanField, |
| | | ReferenceField, |
| | | TextInput, |
| | | DateTimeInput, |
| | | DateInput, |
| | | SelectInput, |
| | | NumberInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | DeleteButton, |
| | | SimpleForm, |
| | | required, |
| | | Form, |
| | | useRefresh, |
| | | useRedirect, |
| | | } from 'react-admin'; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_TYPE } from '@/config/setting'; |
| | | import { styled } from '@mui/material/styles'; |
| | | import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid'; |
| | | import request from '@/utils/request'; |
| | | import ConfirmationNumberOutlinedIcon from '@mui/icons-material/ConfirmationNumberOutlined'; |
| | | import CloseSharpIcon from '@mui/icons-material/CloseSharp'; |
| | | import ConfirmButton from '../../components/ConfirmButton'; |
| | | import { Delete, Edit, Add } from '@mui/icons-material'; |
| | | import OutStockSiteDialog from "./OutStockSiteDialog"; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-maktx': { |
| | | width: 200 |
| | | }, |
| | | |
| | | mt: '60px' |
| | | // '& .RaBulkActionsToolbar-toolbar': { |
| | | // display: 'none' |
| | | // } |
| | | |
| | | })); |
| | | |
| | | const OutStockPublic = (props) => { |
| | | const { record, open, setOpen, setManualDialog } = props; |
| | | const notify = useNotify(); |
| | | const gridRef = useGridApiRef(); |
| | | const [rows, setRows] = useState([]); |
| | | const [fetchRows, setFetchRows] = useState([]); |
| | | const translate = useTranslate(); |
| | | const [rowSelectedIds, setRowSelectedIds] = useState([]); |
| | | const [selectedMatnr, setSelectedMatnr] = useState([]); |
| | | const [selectedIds, setSelectedIds] = useState([]); |
| | | const [formData, setFormData] = useState({ orderId: record?.id, waveId: DEFAULT_TYPE }); |
| | | const [dialog, setDialog] = useState(false); |
| | | const [selectedValue, setSelectedValue] = useState({}); |
| | | |
| | | useEffect(() => { |
| | | if (selectedMatnr.length < 1) { |
| | | setRows(fetchRows) |
| | | } else { |
| | | const mas = fetchRows.filter(item => selectedMatnr.includes(item.matnrCode)); |
| | | setRows(mas) |
| | | } |
| | | }, [selectedMatnr]) |
| | | |
| | | |
| | | const ComfirmButton = () => { |
| | | const { selectedIds, data } = useListContext(); |
| | | const handleRowClick = () => { |
| | | const ids = data.filter(item => selectedIds.includes(item.id)).map(item => item.id); |
| | | setRowSelectedIds(ids); |
| | | const mas = data.filter(item => selectedIds.includes(item.id)).map(item => item.matnrCode); |
| | | //设置库位信息筛选条件 |
| | | setSelectedMatnr(mas); |
| | | } |
| | | |
| | | return ( |
| | | <Button label="toolbar.confirm" size="medium" onClick={handleRowClick} /> |
| | | ) |
| | | }; |
| | | |
| | | const handleClickOpen = () => { |
| | | setDialog(true); |
| | | }; |
| | | |
| | | const handleClose = (value) => { |
| | | setDialog(false); |
| | | setSelectedValue(value); |
| | | if (selectedIds.length == 0) { |
| | | const newRows = rows.map(item => { |
| | | return { |
| | | ...item, |
| | | siteNo: value?.site |
| | | } |
| | | }) |
| | | setRows(newRows); |
| | | } else { |
| | | const newRows = rows.map(item => { |
| | | return selectedIds.includes(item?.id) ? { |
| | | ...item, |
| | | siteNo: value?.site |
| | | } : item |
| | | }) |
| | | setRows(newRows); |
| | | } |
| | | }; |
| | | |
| | | useEffect(() => { |
| | | getWaveRule() |
| | | }, [open]) |
| | | |
| | | const getWaveRule = async () => { |
| | | if (formData.waveId == null && formData.waveId == undefined) { |
| | | return |
| | | } |
| | | const { data: { code, data, msg } } = await request.post('/outStock/order/getOutTaskItems', { ...formData }); |
| | | if (code === 200) { |
| | | // setRows(data) |
| | | setFetchRows(data) |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | const handleChange = (value, name) => { |
| | | setFormData((prevData) => ({ |
| | | ...prevData, |
| | | [name]: value |
| | | })); |
| | | }; |
| | | |
| | | |
| | | return ( |
| | | <> |
| | | <Box> |
| | | <Grid sx={{ display: "flex" }} container rowSpacing={2} columnSpacing={2}> |
| | | <Grid item xl={5.7} gap={2} > |
| | | <Card> |
| | | <Form> |
| | | <ReferenceInput |
| | | source="type" |
| | | reference="waveRule" |
| | | > |
| | | <AutocompleteInput |
| | | label="table.field.waveRule.type" |
| | | onChange={(e) => handleChange(e, 'waveId')} |
| | | defaultValue={15} |
| | | value={formData.type} |
| | | validate={required()} |
| | | /> |
| | | </ReferenceInput> |
| | | </Form> |
| | | <List |
| | | resource="outStockItem" |
| | | storeKey='outStockItem' |
| | | sx={{ |
| | | flexGrow: 1, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | }} |
| | | title={"menu.outStockItem"} |
| | | empty={false} |
| | | filter={{ asnId: record?.id, deleted: 0 }} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={false} |
| | | pagination={false} |
| | | perPage={DEFAULT_ITEM_PAGE_SIZE} |
| | | > |
| | | <LinearProgress |
| | | sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }} |
| | | /> |
| | | <StyledDatagrid |
| | | storeKey={"outStockPublic"} |
| | | preferenceKey='outStockItem' |
| | | bulkActionButtons={<> |
| | | <ComfirmButton /> |
| | | </>} |
| | | omit={['id', 'splrName', 'qty', 'poCode',]} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="asnCode" label="table.field.outStockItem.asnCode" /> |
| | | <TextField source="poCode" label="table.field.outStockItem.poCode" /> |
| | | <TextField source="matnrCode" label="table.field.outStockItem.matnrCode" /> |
| | | <TextField source="maktx" label="table.field.outStockItem.maktx" /> |
| | | <NumberField source="anfme" label="table.field.outStockItem.anfme" /> |
| | | <NumberField source="workQty" label="table.field.outStockItem.workQty" /> |
| | | <NumberField source="qty" label="table.field.outStockItem.qty" /> |
| | | <TextField source="stockUnit" label="table.field.outStockItem.stockUnit" /> |
| | | <TextField source="splrName" label="table.field.outStockItem.splrName" /> |
| | | </StyledDatagrid> |
| | | </List> |
| | | </Card> |
| | | </Grid> |
| | | <Grid item xl={6.3} gap={2}> |
| | | <Card sx={{ minHeight: 1050, height: 'calc(100% - 10px)', width: '100%' }}> |
| | | <Box> |
| | | <PreviewTable |
| | | rows={rows} |
| | | gridRef={gridRef} |
| | | setRows={setRows} |
| | | record={record} |
| | | formData={formData} |
| | | selectedIds={selectedIds} |
| | | setDialog={setDialog} |
| | | setSelectedIds={setSelectedIds} |
| | | /> |
| | | </Box> |
| | | <Box sx={{ textAlign: 'center' }}> |
| | | <CloseButton setOpen={setOpen} /> |
| | | <SubmitButton selectedIds={selectedIds} setSelectedIds={setSelectedIds} gridRef={gridRef} record={record} /> |
| | | </Box> |
| | | </Card> |
| | | </Grid> |
| | | </Grid> |
| | | <Grid> |
| | | <OutStockSiteDialog |
| | | selectedValue={selectedValue} |
| | | open={dialog} |
| | | onClose={handleClose} |
| | | /> |
| | | </Grid> |
| | | </Box> |
| | | </> |
| | | ); |
| | | } |
| | | |
| | | const PreviewTable = ({ rows, gridRef, setRows, record, selectedIds, setSelectedIds, setDialog, formData }) => { |
| | | gridRef.current = useGridApiRef(); |
| | | const translate = useTranslate(); |
| | | |
| | | useEffect(() => { |
| | | if (selectedIds.length > 0) { |
| | | console.log(selectedIds); |
| | | } |
| | | }, [selectedIds]) |
| | | |
| | | const baseColumns = [ |
| | | // { field: 'id', headerName: 'ID', width: 40 }, |
| | | { field: 'locCode', headerName: '库位', width: 110 }, |
| | | { field: 'barcode', headerName: '容器', width: 120 }, |
| | | { field: 'matnrCode', headerName: '物料编码', width: 120 }, |
| | | { field: 'batch', headerName: '批次', width: 90 }, |
| | | { field: 'unit', headerName: '单位', width: 60 }, |
| | | { field: 'outQty', headerName: '出库数量', width: 110, }, |
| | | { |
| | | field: 'anfme', headerName: '库存数量', width: 110, |
| | | renderCell: (params) => ( |
| | | <OutStockAnfme value={params.value} /> |
| | | ) |
| | | }, |
| | | { |
| | | field: 'siteNo', |
| | | headerName: '出库口', |
| | | width: 90, |
| | | type: 'singleSelect', |
| | | editable: true, |
| | | renderCell: (params) => ( |
| | | <OutStockSiteNo value={params.value} /> |
| | | ), |
| | | renderEditCell: (params) => ( |
| | | <OutStockSite {...params} /> |
| | | ), |
| | | }, |
| | | ] |
| | | |
| | | const optAction = { |
| | | field: 'actions', |
| | | type: 'actions', |
| | | headerName: translate('common.field.opt'), |
| | | with: 120, |
| | | getActions: (params) => [ |
| | | <GridActionsCellItem |
| | | icon={<Delete />} |
| | | label="Delete" |
| | | onClick={() => handleDelete(params.row, rows, setRows)} |
| | | />, |
| | | ] |
| | | } |
| | | |
| | | const columns = (formData.waveId == 15 || formData.waveId == 16) ? [...baseColumns] : [...baseColumns, optAction]; |
| | | |
| | | /** |
| | | * 删除事件 |
| | | * @param {*} params |
| | | */ |
| | | const handleDelete = (params, rows, setRows) => { |
| | | const outRows = rows.filter(row => { |
| | | return row.id !== params.id |
| | | }) |
| | | setRows(outRows) |
| | | } |
| | | |
| | | const OutStockAnfme = React.memo(function OutStockAnfme(props) { |
| | | const { value } = props; |
| | | return ( |
| | | value > 0 ? |
| | | <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
| | | <span>{value}</span> |
| | | </Box> |
| | | : |
| | | <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
| | | <span style={{ color: 'red' }}>{translate('common.edit.title.insuffInventory')}</span> |
| | | </Box> |
| | | ); |
| | | }); |
| | | |
| | | const OutStockSiteNo = React.memo(function OutStockSiteNo(props) { |
| | | const { value } = props; |
| | | if (!value) { |
| | | return null; |
| | | } |
| | | return ( |
| | | <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
| | | <span>{value}</span> |
| | | </Box> |
| | | ); |
| | | }); |
| | | |
| | | const CustomToolBar = () => { |
| | | const selectSiteNo = () => { |
| | | setDialog(true) |
| | | } |
| | | return ( |
| | | <Box sx={{ |
| | | p: 1, |
| | | display: 'flex', |
| | | justifyContent: 'flex-end', |
| | | borderTop: '1px solid rgba(224, 224, 224, 1)' |
| | | }}> |
| | | <Button |
| | | onClick={selectSiteNo} |
| | | variant="outlined" |
| | | label="toolbar.modiftySite" |
| | | size="medium" |
| | | sx={{ mr: 1 }} /> |
| | | </Box> |
| | | ); |
| | | } |
| | | |
| | | const OutStockSite = (params) => { |
| | | const { id, field, siteNo, row: { staNos } } = params; |
| | | const apiRef = useGridApiContext(); |
| | | const handleChange = async (event) => { |
| | | await apiRef.current.setEditCellValue( |
| | | { id, field, value: event.target.value }, |
| | | event, |
| | | ); |
| | | apiRef.current.stopCellEditMode({ id, field }); |
| | | }; |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason === 'backdropClick') { |
| | | apiRef.current.stopCellEditMode({ id, field }); |
| | | } |
| | | }; |
| | | |
| | | return ( |
| | | <Select |
| | | value={siteNo} |
| | | onChange={handleChange} |
| | | MenuProps={{ |
| | | onClose: handleClose, |
| | | }} |
| | | sx={{ |
| | | height: '100%', |
| | | '& .MuiSelect-select': { |
| | | display: 'flex', |
| | | alignItems: 'center', |
| | | pl: 1, |
| | | }, |
| | | }} |
| | | autoFocus |
| | | fullWidth |
| | | open |
| | | > |
| | | {staNos.map((option) => { |
| | | return ( |
| | | <MenuItem |
| | | key={option} |
| | | value={option.staNo} |
| | | > |
| | | <ListItemText sx={{ overflow: 'hidden' }} primary={option.staNo} /> |
| | | </MenuItem> |
| | | ); |
| | | })} |
| | | </Select > |
| | | ) |
| | | } |
| | | |
| | | return ( |
| | | <DataGrid |
| | | storeKey={"locItemPreview"} |
| | | rows={rows} |
| | | columns={columns} |
| | | slots={{ toolbar: CustomToolBar }} |
| | | apiRef={gridRef} |
| | | checkboxSelection |
| | | disableRowSelectionOnClick |
| | | hideFooterPagination={true} // 隐藏分页控件 |
| | | hideFooter={false} |
| | | onRowSelectionModelChange={(ids) => { |
| | | setSelectedIds(ids) |
| | | }} |
| | | /> |
| | | ) |
| | | } |
| | | |
| | | |
| | | //提交按钮 |
| | | const SubmitButton = ({ selectedIds, setSelectedIds, gridRef, record }) => { |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const redirect = useRedirect(); |
| | | const submit = async () => { |
| | | const items = gridRef.current?.getSortedRows(); |
| | | const { data: { code, data, msg } } = await request.post('/outStock/generate/tasks', { items, outId: record?.id }); |
| | | if (code == 200) { |
| | | refresh(); |
| | | redirect("/task") |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | return ( |
| | | <ConfirmButton |
| | | label="toolbar.allComfirm" |
| | | variant="contained" |
| | | size="medium" |
| | | onConfirm={submit} |
| | | /> |
| | | ) |
| | | } |
| | | |
| | | //关闭按钮 |
| | | const CloseButton = ({ setOpen }) => { |
| | | const close = () => { |
| | | setOpen(false) |
| | | } |
| | | return ( |
| | | <Button |
| | | label="toolbar.close" |
| | | variant="outlined" |
| | | size="medium" |
| | | onClick={close} |
| | | startIcon={<CloseSharpIcon />} |
| | | sx={{ margin: '3.5em' }} /> |
| | | ) |
| | | } |
| | | |
| | | export default OutStockPublic; |
| | | |
| | | |
New file |
| | |
| | | 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, |
| | | useListContext, |
| | | useRefresh, |
| | | } from 'react-admin'; |
| | | import { |
| | | Dialog, |
| | | DialogActions, |
| | | DialogContent, |
| | | DialogTitle, |
| | | Stack, |
| | | Grid, |
| | | TextField, |
| | | Box, |
| | | Button, |
| | | Paper, |
| | | TableContainer, |
| | | Table, |
| | | TableHead, |
| | | TableBody, |
| | | TableRow, |
| | | TableCell, |
| | | Tooltip, |
| | | IconButton, |
| | | styled, |
| | | Select, |
| | | MenuItem |
| | | } from '@mui/material'; |
| | | import DialogCloseButton from "../../components/DialogCloseButton"; |
| | | import StatusSelectInput from "../../components/StatusSelectInput"; |
| | | import ConfirmButton from "../../components/ConfirmButton"; |
| | | import MatnrInfoModal from "./MatnrInfoModal"; |
| | | import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; |
| | | import SaveIcon from '@mui/icons-material/Save'; |
| | | import request from '@/utils/request'; |
| | | import { Add, Edit, Delete } from '@mui/icons-material'; |
| | | import _, { set } from 'lodash'; |
| | | import { DataGrid, useGridApiRef } from '@mui/x-data-grid'; |
| | | import DictionarySelect from "../../components/DictionarySelect"; |
| | | import DictSelect from "../../components/DictSelect"; |
| | | import "./asnOrder.css"; |
| | | |
| | | const SelectMatnrModal = (props) => { |
| | | const { open, setOpen, asnId, billReload } = props; |
| | | |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | const refresh = useRefresh(); |
| | | const [disabled, setDisabled] = useState(false) |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | |
| | | const tableRef = useRef(); |
| | | |
| | | useEffect(() => { |
| | | if (open && asnId !== 0) { |
| | | requestGetHead() |
| | | requestGetBody() |
| | | } |
| | | setDisabled(false) |
| | | }, [open]) |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | refresh(); |
| | | setFormData({ type: '', wkType: '' }) |
| | | setTableData([]) |
| | | } |
| | | }; |
| | | |
| | | const [formData, setFormData] = useState({ |
| | | type: '', |
| | | wkType: '', |
| | | poCode: '', |
| | | logisNo: '', |
| | | arrTime: '' |
| | | }); |
| | | |
| | | const [tabelData, setTableData] = useState([]); |
| | | |
| | | const handleChange = (value, name) => { |
| | | setFormData((prevData) => ({ |
| | | ...prevData, |
| | | [name]: value |
| | | })); |
| | | }; |
| | | |
| | | const resetData = () => { |
| | | setFormData({ |
| | | type: '', |
| | | wkType: '', |
| | | poCode: '', |
| | | logisNo: '', |
| | | arrTime: '' |
| | | }) |
| | | setTableData([]) |
| | | } |
| | | |
| | | 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 (asnId === 0) { |
| | | const parmas = { |
| | | "orders": formData, |
| | | "items": tabelData, |
| | | } |
| | | const res = await request.post(`/outStock/items/save`, parmas); |
| | | if (res?.data?.code === 200) { |
| | | setOpen(false); |
| | | refresh(); |
| | | resetData() |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | } else { |
| | | const parmas = { |
| | | "orders": formData, |
| | | "items": tabelData, |
| | | } |
| | | const res = await request.post(`/outStock/items/update`, parmas); |
| | | if (res?.data?.code === 200) { |
| | | setOpen(false); |
| | | refresh(); |
| | | resetData() |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | } |
| | | setDisabled(false) |
| | | |
| | | }; |
| | | |
| | | |
| | | const handleDelete = async () => { |
| | | const res = await request.post(`/outStock/remove/${asnId}`); |
| | | if (res?.data?.code === 200) { |
| | | setOpen(false); |
| | | refresh(); |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | }; |
| | | |
| | | const requestGetHead = async () => { |
| | | const res = await request.get(`/outStock/${asnId}`); |
| | | if (res?.data?.code === 200) { |
| | | setFormData(res.data.data) |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | } |
| | | |
| | | const requestGetBody = async () => { |
| | | const res = await request.post(`/outStockItem/page`, { asnId }); |
| | | if (res?.data?.code === 200) { |
| | | setTableData(res.data.data.records) |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | } |
| | | |
| | | const [selectedRows, setSelectedRows] = useState([]); |
| | | |
| | | const handleDeleteItem = () => { |
| | | const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId)); |
| | | setTableData(newTableData); |
| | | } |
| | | |
| | | return ( |
| | | <> |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | aria-hidden |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="lg" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
| | | > |
| | | <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 }}> |
| | | <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}> |
| | | <Form defaultValues={formData}> |
| | | <Grid container spacing={2}> |
| | | {/* <Grid item md={2}> |
| | | <DictSelect |
| | | label={translate("table.field.asnOrder.type")} |
| | | value={formData.type} |
| | | onChange={(e) => handleChange(e.target.value, 'type')} |
| | | dictTypeCode="sys_order_type" |
| | | required |
| | | /> |
| | | </Grid> */} |
| | | <Grid item md={2}> |
| | | <DictSelect |
| | | label={translate("table.field.outStock.wkType")} |
| | | value={formData.wkType} |
| | | variant="filled" |
| | | group='2' |
| | | onChange={(e) => handleChange(e.target.value, 'wkType')} |
| | | dictTypeCode="sys_business_type" |
| | | required |
| | | /> |
| | | </Grid> |
| | | <Grid item md={2}> |
| | | <TextField |
| | | label={translate("table.field.outStock.poCode")} |
| | | value={formData.poCode} |
| | | variant="filled" |
| | | size='small' |
| | | onChange={(e) => handleChange(e.target.value, 'poCode')} |
| | | /> |
| | | </Grid> |
| | | <Grid item md={2}> |
| | | <TextField |
| | | label={translate("table.field.outStock.logisNo")} |
| | | value={formData.logisNo} |
| | | variant="filled" |
| | | size='small' |
| | | onChange={(e) => handleChange(e.target.value, 'logisNo')} |
| | | /> |
| | | </Grid> |
| | | <Grid item md={2}> |
| | | <DateInput |
| | | source="arrTime" |
| | | label="table.field.outStock.arrTime" |
| | | size='small' |
| | | variant="filled" |
| | | value={formData.arrTime} |
| | | onChange={(e) => handleChange(e.target.value, 'arrTime')} |
| | | /> |
| | | </Grid> |
| | | </Grid> |
| | | </Form> |
| | | </Box> |
| | | |
| | | <Box sx={{ mt: 2 }}> |
| | | <Stack direction="row" spacing={2}> |
| | | <Button variant="contained" onClick={() => setCreateDialog(true)}>新增物料</Button> |
| | | {/* {asnId !== '' && <ConfirmButton label={'删除'} variant="outlined" color="error" onConfirm={handleDelete} />} */} |
| | | <ConfirmButton label={'删除'} variant="outlined" color="error" onConfirm={handleDeleteItem} /> |
| | | </Stack> |
| | | </Box> |
| | | <Box sx={{ mt: 2 }}> |
| | | <AsnOrderModalTable tabelData={tabelData} setTableData={setTableData} asnId={asnId} selectedRows={selectedRows} setSelectedRows={setSelectedRows} tableRef={tableRef}></AsnOrderModalTable> |
| | | </Box> |
| | | </DialogContent> |
| | | <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> |
| | | <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }} > |
| | | <Button disabled={disabled} onClick={handleSubmit} variant="contained" startIcon={<SaveIcon />}> |
| | | {translate('toolbar.confirm')} |
| | | </Button> |
| | | </Toolbar> |
| | | </DialogActions> |
| | | </Dialog> |
| | | <MatnrInfoModal |
| | | open={createDialog} |
| | | setOpen={setCreateDialog} |
| | | data={tabelData} |
| | | setData={setTableData} |
| | | /> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default SelectMatnrModal; |
| | | |
| | | 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); |
| | | |
| | | // 如果找到对应的供应商记录,同时更新splrCode字段 |
| | | 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); |
| | | |
| | | // 如果找到对应的供应商记录,同时更新splrCode字段 |
| | | 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 AsnOrderModalTable = ({ tabelData, setTableData, asnId, selectedRows, setSelectedRows, tableRef }) => { |
| | | 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, |
| | | headerClassName: "custom", |
| | | }, |
| | | { |
| | | field: 'splrCode', |
| | | headerName: translate('table.field.outStockItem.splrCode') + "*", |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: true, |
| | | renderEditCell: (params) => ( |
| | | <SelectInputSplrCodeEditCell {...params} /> |
| | | ), |
| | | headerClassName: "custom", |
| | | }, |
| | | { |
| | | field: 'splrName', |
| | | headerName: translate('table.field.outStockItem.splrName') + "*", |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: true, |
| | | renderEditCell: (params) => ( |
| | | <SelectInputSplrNameEditCell {...params} /> |
| | | ), |
| | | headerClassName: "custom", |
| | | }, |
| | | { |
| | | field: 'splrBatch', |
| | | headerName: translate('table.field.outStockItem.splrBatch'), |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: true, |
| | | }, |
| | | { |
| | | field: 'poCode', |
| | | headerName: translate('table.field.outStockItem.poDetlCode'), |
| | | 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(() => { |
| | | 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]) |
| | | } 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(); |
| | | |
| | | return ( |
| | | <div style={{ height: 400, width: '100%' }}> |
| | | <DataGrid |
| | | apiRef={tableRef} |
| | | rows={tabelData} |
| | | columns={columns} |
| | | disableRowSelectionOnClick |
| | | getRowId={(row) => row.matnrId ? row.matnrId : row.id} |
| | | disableColumnFilter |
| | | disableColumnSelector |
| | | disableColumnSorting |
| | | disableMultipleColumnsSorting |
| | | processRowUpdate={processRowUpdate} |
| | | initialState={{ |
| | | pagination: { |
| | | paginationModel: { |
| | | pageSize: 25, |
| | | }, |
| | | }, |
| | | }} |
| | | pageSizeOptions={[15, 25, 50, 100]} |
| | | editMode="row" |
| | | checkboxSelection |
| | | onRowSelectionModelChange={handleSelectionChange} |
| | | selectionModel={selectedRows} |
| | | sx={{ |
| | | '& .MuiDataGrid-cell input': { |
| | | border: '1px solid #ccc' |
| | | }, |
| | | }} |
| | | /> |
| | | </div> |
| | | ); |
| | | }; |
| | | |
New file |
| | |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | ListGuesser, |
| | | EditGuesser, |
| | | ShowGuesser, |
| | | } from "react-admin"; |
| | | |
| | | import CheckOrderList from "./CheckOrderList"; |
| | | import CheckOrderEdit from "./CheckOrderEdit"; |
| | | |
| | | export default { |
| | | list: CheckOrderList, |
| | | edit: CheckOrderEdit, |
| | | show: ShowGuesser, |
| | | recordRepresentation: (record) => { |
| | | return `${record.name}` |
| | | } |
| | | }; |
| | |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | DeleteButton, |
| | | Datagrid, |
| | | useRefresh, |
| | | Button |
| | | } from 'react-admin'; |
| | |
| | | import PageDrawer from "../components/PageDrawer"; |
| | | import BatchModal from "./BatchModal"; |
| | | import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting'; |
| | | import * as Common from '@/utils/common'; |
| | | import EditIcon from '@mui/icons-material/Edit'; |
| | | import { minWidth } from "@mui/system"; |
| | | |
| | | |
| | | const ScrollableDatagrid = styled(Datagrid)(({ theme }) => ({ |
| | | '& .MuiTable-root': { |
| | | minWidth: '100%', // 确保表格宽度足够 |
| | | tableLayout: 'fixed', // 固定表格布局 |
| | | }, |
| | | '& .RaDatagrid-rowCell': { |
| | | textAlign: 'center', |
| | | whiteSpace: 'nowrap', |
| | | textOverflow: 'ellipsis', |
| | | }, |
| | | |
| | | '& .RaDatagrid-headerCell': { |
| | | whiteSpace: 'nowrap', |
| | | overflowX: 'auto', |
| | | }, |
| | | |
| | | '& .opt': { |
| | | width: 200, |
| | | position: 'sticky', |
| | | zIndex: 3, |
| | | right: 0, |
| | | |
| | | }, |
| | | })); |
| | | |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .column-name': { |
| | | }, |
| | | // height: '.9em' |
| | | // }, |
| | | // '& .RaDatagrid-row': { |
| | | // cursor: 'auto' |
| | | // }, |
| | | '& .opt': { |
| | | width: 200 |
| | | width: 200, |
| | | position: 'sticky', |
| | | right: 0, |
| | | }, |
| | | |
| | | '& .MuiTableContainer-root': { |
| | | overflowX: 'auto', |
| | | '&::-webkit-scrollbar': { |
| | | height: '8px', |
| | | }, |
| | | '&::-webkit-scrollbar-thumb': { |
| | | backgroundColor: theme.palette.action.hover, |
| | | borderRadius: '4px', |
| | | }, |
| | | }, |
| | | // '& .MuiTable-root': { |
| | | // minWidth: '100%', // 确保表格宽度足够 |
| | | // tableLayout: 'fixed', // 固定表格布局 |
| | | // }, |
| | | // '& .MuiTableCell-root': { |
| | | // whiteSpace: 'nowrap', |
| | | // overflow: 'hidden', |
| | | // textOverflow: 'ellipsis', |
| | | // position: 'relative', // 为固定列提供定位上下文 |
| | | // }, |
| | | // '& .MuiTableCell-actions': { |
| | | // position: 'sticky', |
| | | // right: 0, |
| | | // background: theme.palette.background.paper, |
| | | // zIndex: 2, |
| | | // width: '150px', |
| | | // minWidth: '150px', |
| | | // boxShadow: '-2px 0 4px rgba(0,0,0,0.1)', |
| | | // '& button': { |
| | | // marginLeft: theme.spacing(1), |
| | | // } |
| | | // }, |
| | | // '& .MuiTableHead-root .MuiTableCell-actions': { |
| | | // zIndex: 3, // 表头比内容高一层 |
| | | // } |
| | | |
| | | })); |
| | | |
| | | const filters = [ |
| | |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0, |
| | | '& .RaList-content': { |
| | | position: 'sticky', |
| | | overflow: 'auto', |
| | | width: 'auto', |
| | | righ: '0px', |
| | | minWidth: '100%' |
| | | } |
| | | }} |
| | | title={"menu.warehouseAreas"} |
| | | empty={<EmptyData onClick={() => { setCreateDialog(true) }} />} |
| | |
| | | )} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | <ScrollableDatagrid |
| | | preferenceKey='warehouseAreas' |
| | | bulkActionButtons={ |
| | | <> |
| | |
| | | > |
| | | <NumberField source="id" /> |
| | | {/* <TextField source="uuid" label="table.field.warehouseAreas.uuid" /> */} |
| | | <TextField source="name" label="table.field.warehouseAreas.name" /> |
| | | <TextField source="code" label="table.field.warehouseAreas.code" /> |
| | | <TextField source="type$" label="table.field.warehouseAreas.type"/> |
| | | <TextField source="name" label="table.field.warehouseAreas.name" width="10%" /> |
| | | <TextField source="code" label="table.field.warehouseAreas.code" width="10%" /> |
| | | <TextField source="type$" label="table.field.warehouseAreas.type" width="10%" /> |
| | | {/* <ReferenceField source="shipperId" label="table.field.warehouseAreas.shipperId" reference="shipper" link={false} sortable={false}> |
| | | <TextField source="name" /> |
| | | </ReferenceField> */} |
| | | <TextField source="warehouseId$" label="table.field.warehouseAreas.wareId" /> |
| | | <TextField source="shipperId$" label="table.field.warehouseAreas.shipperId" /> |
| | | <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" /> |
| | | <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} /> |
| | | <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} /> |
| | | <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} /> |
| | | <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}> |
| | | <TextField source="warehouseId$" label="table.field.warehouseAreas.wareId" width="10%" /> |
| | | <TextField source="shipperId$" label="table.field.warehouseAreas.shipperId" width="10%" /> |
| | | <NumberField source="supplierId" label="table.field.warehouseAreas.supplierId" width="10%" /> |
| | | <TextField source="flagMinus$" label="table.field.warehouseAreas.flagMinus" sortable={false} width="10%" /> |
| | | <TextField source="flagLabelMange$" label="table.field.warehouseAreas.flagLabelMange" sortable={false} width="10%" /> |
| | | <TextField source="flagMix$" label="table.field.warehouseAreas.flagMix" sortable={false} width="10%" /> |
| | | <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false} width="10%"> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime /> |
| | | <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}> |
| | | <DateField source="updateTime" label="common.field.updateTime" showTime width="10%" /> |
| | | <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false} width="10%"> |
| | | <TextField source="nickname" /> |
| | | </ReferenceField> |
| | | <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} /> |
| | | <WrapperField cellClassName="opt" label="common.field.opt"> |
| | | <DateField source="createTime" label="common.field.createTime" showTime width="10%" /> |
| | | <BooleanField source="statusBool" label="common.field.status" sortable={false} width="10%" /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} width="10%" /> |
| | | <WrapperField source="opt" cellClassName="opt" label="common.field.opt"> |
| | | <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} /> |
| | | <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | | </ScrollableDatagrid> |
| | | </List> |
| | | <WarehouseAreasCreate |
| | | open={createDialog} |
New file |
| | |
| | | package com.vincent.rsf.server.manager.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.vincent.rsf.framework.common.Cools; |
| | | import com.vincent.rsf.framework.common.R; |
| | | import com.vincent.rsf.server.common.annotation.OperationLog; |
| | | import com.vincent.rsf.server.common.domain.BaseParam; |
| | | import com.vincent.rsf.server.common.domain.KeyValVo; |
| | | import com.vincent.rsf.server.common.domain.PageParam; |
| | | import com.vincent.rsf.server.common.utils.ExcelUtil; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrder; |
| | | import com.vincent.rsf.server.manager.enums.OrderType; |
| | | import com.vincent.rsf.server.manager.service.CheckOrderService; |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | | import com.vincent.rsf.server.system.controller.BaseController; |
| | | import com.vincent.rsf.server.system.utils.SerialRuleUtils; |
| | | import io.swagger.annotations.Api; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.*; |
| | | |
| | | @Api("盘点") |
| | | @RestController |
| | | public class CheckOrderController extends BaseController { |
| | | |
| | | @Autowired |
| | | private CheckOrderService checkOrderService; |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:list')") |
| | | @PostMapping("/check/page") |
| | | public R page(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<AsnOrder, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrder.class); |
| | | QueryWrapper<AsnOrder> wrapper = pageParam.buildWrapper(true); |
| | | wrapper.eq("type", OrderType.ORDER_CHECK.type); |
| | | return R.ok().add(checkOrderService.page(pageParam, wrapper)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:list')") |
| | | @PostMapping("/check/list") |
| | | public R list(@RequestBody Map<String, Object> map) { |
| | | return R.ok().add(checkOrderService.list()); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:list')") |
| | | @PostMapping({"/check/many/{ids}", "/check/many/{ids}"}) |
| | | public R many(@PathVariable Long[] ids) { |
| | | return R.ok().add(checkOrderService.listByIds(Arrays.asList(ids))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:list')") |
| | | @GetMapping("/check/{id}") |
| | | public R get(@PathVariable("id") Long id) { |
| | | return R.ok().add(checkOrderService.getById(id)); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:save')") |
| | | @OperationLog("Create 字典数据集") |
| | | @PostMapping("/check/save") |
| | | public R save(@RequestBody AsnOrder order) { |
| | | order.setType(OrderType.ORDER_CHECK.type); |
| | | String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_CHECK_RULE_CODE, order); |
| | | if (Objects.isNull(ruleCode)) { |
| | | throw new RuntimeException("盘点单号生成失败!!"); |
| | | } |
| | | if (!checkOrderService.save(order)) { |
| | | return R.error("Save Fail"); |
| | | } |
| | | return R.ok("Save Success").add(order); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:update')") |
| | | @OperationLog("Update 字典数据集") |
| | | @PostMapping("/check/update") |
| | | public R update(@RequestBody AsnOrder order) { |
| | | order.setUpdateTime(null); |
| | | order.setUpdateBy(getLoginUserId()); |
| | | if (!checkOrderService.updateById(order)) { |
| | | return R.error("Update Fail"); |
| | | } |
| | | return R.ok("Update Success").add(order); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:remove')") |
| | | @OperationLog("Delete 字典数据集") |
| | | @PostMapping("/check/remove/{ids}") |
| | | public R remove(@PathVariable Long[] ids) { |
| | | if (!checkOrderService.removeByIds(Arrays.asList(ids))) { |
| | | return R.error("Delete Fail"); |
| | | } |
| | | return R.ok("Delete Success").add(ids); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:list')") |
| | | @PostMapping("/check/query") |
| | | public R query(@RequestParam(required = false) String condition) { |
| | | List<KeyValVo> vos = new ArrayList<>(); |
| | | LambdaQueryWrapper<AsnOrder> wrapper = new LambdaQueryWrapper<>(); |
| | | if (!Cools.isEmpty(condition)) { |
| | | wrapper.like(AsnOrder::getCode, condition); |
| | | } |
| | | checkOrderService.page(new Page<>(1, 30), wrapper).getRecords().forEach( |
| | | item -> vos.add(new KeyValVo(item.getId(), item.getCode())) |
| | | ); |
| | | return R.ok().add(vos); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:check:list')") |
| | | @PostMapping("/check/export") |
| | | public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception { |
| | | List<AsnOrder> orders = new ArrayList<>(); |
| | | if (!Objects.isNull(map.get("ids"))) { |
| | | orders = checkOrderService.list(new LambdaQueryWrapper<AsnOrder>().in(AsnOrder::getId, map.get("ids"))); |
| | | } else { |
| | | orders = checkOrderService.list(); |
| | | } |
| | | ExcelUtil.build(ExcelUtil.create(orders, AsnOrder.class), response); |
| | | } |
| | | |
| | | } |
| | |
| | | //订单类型 |
| | | ORDER_OUT("out", "出库单"), |
| | | ORDER_IN("in", "入库单"), |
| | | ORDER_CHECK("check", "盘点单"); |
| | | ; |
| | | |
| | | OrderType(String type, String desc) { |
New file |
| | |
| | | package com.vincent.rsf.server.manager.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrder; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface CheckOrderMapper extends BaseMapper<AsnOrder> { |
| | | |
| | | } |
| | |
| | | |
| | | /** |
| | | * 任务自动下发 |
| | | * |
| | | * @throws Exception |
| | | */ |
| | | @Scheduled(cron = "0/5 * * * * ? ") |
| | |
| | | Long loginUserId = SystemAuthUtils.getLoginUserId(); |
| | | List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_IN.type, TaskType.TASK_TYPE_OUT.type); |
| | | List<Integer> integers = Arrays.asList(TaskStsType.GENERATE_IN.id, TaskStsType.GENERATE_OUT.id); |
| | | List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>().in(Task::getTaskType, list) |
| | | .in(Task::getTaskStatus, integers) |
| | | List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>() |
| | | .in(Task::getTaskType, list) |
| | | .in(Task::getTaskStatus, integers) |
| | | .orderByDesc(Task::getSort)); |
| | | for (Task task : tasks) { |
| | | Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, task.getBarcode())); |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrder; |
| | | |
| | | public interface CheckOrderService extends IService<AsnOrder> { |
| | | |
| | | } |
New file |
| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrder; |
| | | import com.vincent.rsf.server.manager.mapper.CheckOrderMapper; |
| | | import com.vincent.rsf.server.manager.service.CheckOrderService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | @Service("checkOrderService") |
| | | public class CheckOrderServiceImpl extends ServiceImpl<CheckOrderMapper, AsnOrder> implements CheckOrderService { |
| | | |
| | | } |
| | |
| | | */ |
| | | public final static String SYS_WAVE_RULE_CODE = "sys_wave_type"; |
| | | |
| | | /**盘点单号*/ |
| | | public final static String SYS_CHECK_RULE_CODE = "sys_check_rule_code"; |
| | | |
| | | |
| | | } |
| | |
| | | datasource: |
| | | driver-class-name: com.mysql.jdbc.Driver |
| | | # url: jdbc:mysql://47.76.147.249:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai |
| | | # username: rsf |
| | | username: root |
| | | url: jdbc:mysql://127.0.0.1:3306/rsf?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai |
| | | # username: rsf |
| | | password: 34821015 |
| | | type: com.alibaba.druid.pool.DruidDataSource |
| | | druid: |