Merge remote-tracking branch 'origin/devlop' into devlop
| | |
| | | complete: "complete", |
| | | close: "close", |
| | | asnCreate: "Create By Order", |
| | | poCreate: "Create By PO", |
| | | createTask: "createTask", |
| | | recover: "recover", |
| | | createWave: "Create Wave", |
| | |
| | | }, |
| | | qlyIsptItem: { |
| | | ispectId: "主单ID", |
| | | matnrCode: "物料编号", |
| | | matnrCode: "物料编码", |
| | | maktx: "物料名称", |
| | | label: "标签", |
| | | splrName: "供应商", |
| | |
| | | spec: "规格", |
| | | model: "型号", |
| | | matnrCode: "物料编码", |
| | | anfme: "计划数", |
| | | anfme: "计划数量", |
| | | stockUnit: "单位", |
| | | isptResult: "质检结果", |
| | | purQty: "采购量", |
| | |
| | | complete: "完结", |
| | | close: "关闭", |
| | | asnCreate: "通过单据创建", |
| | | poCreate: "通过PO单创建", |
| | | orderPrint: '打印单据', |
| | | createTask: "下发任务", |
| | | createWave: "生成波次", |
New file |
| | |
| | | import { Dialog, DialogActions, DialogContent, DialogTitle, Box } from "@mui/material"; |
| | | import React, { useState, useRef, useEffect, useMemo } from "react"; |
| | | import { |
| | | List, |
| | | DatagridConfigurable, |
| | | SearchInput, |
| | | TopToolbar, |
| | | Button, |
| | | SelectColumnsButton, |
| | | EditButton, |
| | | FilterButton, |
| | | CreateButton, |
| | | ExportButton, |
| | | BulkDeleteButton, |
| | | WrapperField, |
| | | Toolbar, |
| | | useRecordContext, |
| | | useTranslate, |
| | | useNotify, |
| | | useListContext, |
| | | FunctionField, |
| | | TextField, |
| | | NumberField, |
| | | DateField, |
| | | BooleanField, |
| | | ReferenceField, |
| | | TextInput, |
| | | DateTimeInput, |
| | | DateInput, |
| | | SelectInput, |
| | | NumberInput, |
| | | ReferenceInput, |
| | | ReferenceArrayInput, |
| | | AutocompleteInput, |
| | | DeleteButton, |
| | | 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, 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 POItemModal from "./POItemModal"; |
| | | |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | | }, |
| | | '& .RaDatagrid-row': { |
| | | cursor: 'auto' |
| | | }, |
| | | '& .status': { |
| | | width: 90 |
| | | }, |
| | | })); |
| | | |
| | | const AsnCreateByPoModal = (props) => { |
| | | const { open, setOpen, record } = props; |
| | | const translate = useTranslate(); |
| | | const [params, setParams] = useState({}); |
| | | const [item, setItem] = useState({}); |
| | | const [poItemDialog, setPoItemDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const refresh = useRefresh(); |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | } |
| | | }; |
| | | // const CustomFilter = () => { |
| | | // const { filterValues, setFilters, refetch } = useListContext('deliveryItem'); |
| | | // 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 ( |
| | | // <Box sx={{ width: '100%', margin: 1, marginBottom: 8, "& .MuiDialogActions-root": { padding: 0 } }}> |
| | | // <Form> |
| | | // <Grid container rowSpacing={2} columnSpacing={2} sx={{ padding: 2 }}> |
| | | // <Stack> |
| | | // <TextInput |
| | | // source="condition" |
| | | // label="common.action.search" |
| | | // resettable |
| | | // defaultValue={params?.condition} |
| | | // onChange={handleChange} /> |
| | | // </Stack> |
| | | // </Grid> |
| | | // <DialogActions> |
| | | // <Toolbar sx={{ width: '100%', justifyContent: 'end' }} > |
| | | // <SaveButton onClick={handleSubmit} label={"toolbar.query"} /> |
| | | // </Toolbar> |
| | | // </DialogActions> |
| | | // </Form> |
| | | // </Box> |
| | | // ); |
| | | // }; |
| | | return ( |
| | | <Box> |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | aria-hidden |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="lg" |
| | | > |
| | | <DialogTitle id="form-dialog-title" sx={{ |
| | | position: 'sticky', |
| | | top: 0, |
| | | backgroundColor: 'background.paper', |
| | | zIndex: 1000 |
| | | }}> |
| | | <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 |
| | | storeKey="selectPurchase" |
| | | resource="purchase/filters" |
| | | sx={{ |
| | | flexGrow: 1, |
| | | marginTop: 8, |
| | | height: 500, |
| | | transition: (theme) => |
| | | theme.transitions.create(['all'], { |
| | | duration: theme.transitions.duration.enteringScreen, |
| | | }), |
| | | marginRight: 0, |
| | | }} |
| | | // filters={<CustomFilter />} |
| | | queryOptions={{ meta: { ...params } }} |
| | | empty={false} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | | actions={false} |
| | | perPage={DEFAULT_PAGE_SIZE} |
| | | > |
| | | <StyledDatagrid |
| | | preferenceKey='selectPurchase' |
| | | bulkActionButtons={ |
| | | <> |
| | | <ConfirmSelectButton |
| | | setOpen={setOpen} |
| | | setPoItemDialog={setPoItemDialog} |
| | | setItem={setItem} |
| | | mutationMode="pessimistic" /> |
| | | </> |
| | | } |
| | | rowClick={false} |
| | | expand={false} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy', 'channel', 'platCode', 'memo', 'channel', 'startTime', 'workQty', 'endTime']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="code" label="table.field.purchase.code" /> |
| | | <TextField source="type$" label="table.field.purchase.type" /> |
| | | <TextField source="wkType$" label="table.field.purchase.wkType" /> |
| | | <TextField source="source" label="table.field.purchase.source" /> |
| | | <NumberField source="anfme" label="table.field.purchase.anfme" /> |
| | | <NumberField source="qty" label="table.field.purchase.qty" /> |
| | | <TextField source="channel" label="table.field.purchase.channel" /> |
| | | <TextField source="platCode" label="table.field.purchase.platCode" /> |
| | | <DateField source="preArr" label="table.field.purchase.preArr" showTime /> |
| | | <DateField source="startTime" label="table.field.purchase.startTime" showTime /> |
| | | <DateField source="endTime" label="table.field.purchase.endTime" showTime /> |
| | | <TextField source="project" label="table.field.purchase.project" /> |
| | | <TextField source="memo" label="common.field.memo" sortable={false} /> |
| | | </StyledDatagrid> |
| | | </List> |
| | | </Grid> |
| | | </DialogContent> |
| | | </Grid> |
| | | </Dialog > |
| | | <POItemModal open={poItemDialog} setOpen={setPoItemDialog} record={item} /> |
| | | </Box> |
| | | ) |
| | | } |
| | | |
| | | export default AsnCreateByPoModal; |
| | | |
| | | |
| | | const ConfirmSelectButton = ({ setOpen, setPoItemDialog, setItem }) => { |
| | | const { selectedIds, onUnselectItems } = useListContext(); |
| | | const confirmSelect = async (event) => { |
| | | setItem(selectedIds[0]) |
| | | onUnselectItems(); |
| | | setPoItemDialog(true) |
| | | setOpen(false); |
| | | } |
| | | |
| | | return ( |
| | | <Button label={"toolbar.confirm"} variant="contained" color="primary" size="medium" startIcon={<SaveIcon />} onClick={confirmSelect} /> |
| | | ) |
| | | } |
| | |
| | | import ImportButton from "../../components/ImportButton"; |
| | | import PrintOutlinedIcon from '@mui/icons-material/PrintOutlined'; |
| | | import OrderPrintPreview from "./OrderPrintPreview"; |
| | | |
| | | import CreateNewFolderOutlinedIcon from '@mui/icons-material/CreateNewFolderOutlined'; |
| | | import AsnCreateByPoModal from "./AsnCreateByPoModal"; |
| | | const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({ |
| | | '& .css-1vooibu-MuiSvgIcon-root': { |
| | | height: '.9em' |
| | |
| | | const [createDialog, setCreateDialog] = useState(false); |
| | | const [drawerVal, setDrawerVal] = useState(false); |
| | | const [modalType, setmodalType] = useState(0); |
| | | const [poCreate, setPoCreate] = useState(false); |
| | | const [printOrder, setPrintOrder] = useState(false); |
| | | const [select, setSelect] = useState({}); |
| | | const invoiceRef = useRef(); |
| | |
| | | <TopToolbar> |
| | | <FilterButton /> |
| | | <MyCreateButton onClick={() => { setCreateDialog(true); setmodalType(0) }} /> |
| | | <CreateByPoButton setPoCreate={setPoCreate}/> |
| | | <SelectColumnsButton preferenceKey='asnOrder' /> |
| | | <ImportButton value={'asnOrderItem'} /> |
| | | <MyExportButton /> |
| | |
| | | <MyButton setCreateDialog={setCreateDialog} setmodalType={setmodalType} /> |
| | | <InspectionButton /> |
| | | <CompleteButton /> |
| | | <ODeleteButton /> |
| | | <PrintButton setPrintOrder={setPrintOrder} setSelect={setSelect}/> |
| | | <ODeleteButton /> |
| | | <PrintButton setPrintOrder={setPrintOrder} setSelect={setSelect} /> |
| | | {/* <CloseButton /> */} |
| | | </WrapperField> |
| | | </StyledDatagrid> |
| | |
| | | asnId={modalType} |
| | | billReload={billReload} |
| | | /> |
| | | <OrderPrintPreview |
| | | <OrderPrintPreview |
| | | open={printOrder} |
| | | setOpen={setPrintOrder} |
| | | record={select} |
| | | /> |
| | | <AsnCreateByPoModal |
| | | open={poCreate} |
| | | setOpen={setPoCreate} |
| | | /> |
| | | <PageDrawer |
| | | title='AsnOrder Detail' |
| | |
| | | } |
| | | export default AsnOrderList; |
| | | |
| | | //按PO单新建 |
| | | const CreateByPoButton = ({setPoCreate}) => { |
| | | const record = useRecordContext(); |
| | | |
| | | const createEvent = (event) => { |
| | | event.stopPropagation(); |
| | | setPoCreate(true) |
| | | } |
| | | return ( |
| | | <Button label={"toolbar.poCreate"} onClick={createEvent}> |
| | | <CreateNewFolderOutlinedIcon /> |
| | | </Button> |
| | | ) |
| | | } |
| | | |
| | | |
| | | //打印按钮 |
| | | const PrintButton = ({setPrintOrder, setSelect}) => { |
| | | const PrintButton = ({ setPrintOrder, setSelect }) => { |
| | | const record = useRecordContext(); |
| | | const printOrder = (event) => { |
| | | event.stopPropagation(); |
| | |
| | | } |
| | | |
| | | return ( |
| | | <Button label={"toolbar.print"} onClick={printOrder}> |
| | | <PrintOutlinedIcon /> |
| | | </Button> |
| | | <Button label={"toolbar.print"} onClick={printOrder}> |
| | | <PrintOutlinedIcon /> |
| | | </Button> |
| | | ) |
| | | } |
| | | |
| | |
| | | const ODeleteButton = () => { |
| | | const record = useRecordContext(); |
| | | return ( |
| | | record.exceStatus === 0 ? <DeleteButton mutationMode="pessimistic"/> : <></> |
| | | record.exceStatus === 0 ? <DeleteButton mutationMode="pessimistic" /> : <></> |
| | | ) |
| | | |
| | | } |
| | |
| | | }; |
| | | return ( |
| | | record.exceStatus === 1 || record.exceStatus === 0 ? |
| | | <Button |
| | | color="primary" |
| | | startIcon={<EditIcon />} |
| | | onClick={(btn) => handleEditClick(btn)} |
| | | sx={{ ml: 1 }} |
| | | label={'ra.action.edit'} |
| | | > |
| | | </Button> |
| | | : <></> |
| | | <Button |
| | | color="primary" |
| | | startIcon={<EditIcon />} |
| | | onClick={(btn) => handleEditClick(btn)} |
| | | sx={{ ml: 1 }} |
| | | label={'ra.action.edit'} |
| | | > |
| | | </Button> |
| | | : <></> |
| | | ) |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | return ( |
| | | <ConfirmButton label={"toolbar.inspection"} color="secondary" startIcon={<ConstructionIcon />} onConfirm={inspection} /> |
| | | <ConfirmButton label={"toolbar.inspection"} color="secondary" startIcon={<ConstructionIcon />} onConfirm={inspection} /> |
| | | ) |
| | | } |
| | | |
| | |
| | | // record.exceStatus === 1 && (record.anfme === record.qty ? <Button onClick={requestComplete} label={"toolbar.complete"} color="secondary"> |
| | | // <TaskIcon /> |
| | | // </Button> : ) |
| | | record.exceStatus === 1 ? <ConfirmButton label={"toolbar.complete"} color="secondary" startIcon={<TaskIcon />} onConfirm={requestComplete} /> : <></> |
| | | record.exceStatus === 1 ? <ConfirmButton label={"toolbar.complete"} color="secondary" startIcon={<TaskIcon />} onConfirm={requestComplete} /> : <></> |
| | | ) |
| | | |
| | | |
| | |
| | | } |
| | | |
| | | return ( |
| | | <ConfirmButton label={"toolbar.close"} color="error" startIcon={<CloseIcon />} onConfirm={requestClose} /> |
| | | <ConfirmButton label={"toolbar.close"} color="error" startIcon={<CloseIcon />} onConfirm={requestClose} /> |
| | | ) |
| | | } |
| | |
| | | const setFinally = () => { |
| | | const rows = tableRef.current.state.editRows; |
| | | for (const key in rows) { |
| | | const find = tabelData.find(item => item.matnrId === +key); |
| | | const find = tabelData.find(item => item.id === +key); |
| | | find.anfme = rows[key].anfme.value; |
| | | } |
| | | setTableData([...tabelData]); |
| | |
| | | |
| | | |
| | | const handleDeleteItem = () => { |
| | | const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.matnrId)); |
| | | const newTableData = _.filter(tabelData, (item) => !selectedRows.includes(item.id)); |
| | | setTableData(newTableData); |
| | | } |
| | | |
| | |
| | | value: selectedSupplier.id, |
| | | }); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | // flex: 1, |
| | | // editable: true, |
| | | // }, |
| | | { |
| | | field: 'purUnit', |
| | | headerName: translate('table.field.asnOrderItem.purUnit'), |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: false, |
| | | }, |
| | | |
| | | |
| | | |
| | | // { |
| | | // field: 'purUnit', |
| | | // headerName: translate('table.field.asnOrderItem.purUnit'), |
| | | // minWidth: 100, |
| | | // flex: 1, |
| | | // editable: false, |
| | | // }, |
| | | ]) |
| | | |
| | | const action = { |
| | |
| | | </IconButton> |
| | | </Tooltip> |
| | | ), |
| | | |
| | | } |
| | | |
| | | let cdata = useRef([]); |
| | |
| | | } = await request.get("/fields/enable/list"); |
| | | if (code === 200) { |
| | | const cols = data.map(el => ({ |
| | | field: el.fields, |
| | | field: el.fields, |
| | | valueGetter: (value, row) => { |
| | | if (value != null && value != undefined) { |
| | | return value; |
| | | } |
| | | if (row.extendFields == null ||row.extendFields[el.fields] == null) { |
| | | return '' |
| | | } else { |
| | | return `${row.extendFields[el.fields] == null ? '' : row.extendFields[el.fields]}`; |
| | | } |
| | | }, |
| | | headerName: el.fieldsAlise, |
| | | minWidth: 100, |
| | | flex: 1, |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | const handleDelete = (row) => { |
| | | const newData = _.filter(cdata.current, (item) => item.matnrId !== row.matnrId); |
| | | const newData = _.filter(cdata.current, (item) => item.id !== row.id); |
| | | setTableData(newData); |
| | | }; |
| | | |
| | | |
| | | const processRowUpdate = (newRow, oldRow) => { |
| | | const rows = tabelData.map((r) => |
| | | r.matnrId === newRow.matnrId ? { ...newRow } : r |
| | | r.id === newRow.id ? { ...newRow } : r |
| | | ) |
| | | setTableData(rows) |
| | | // setTableData((prevData) => |
| | |
| | | |
| | | |
| | | const handleSelectionChange = (ids) => { |
| | | console.log(ids); |
| | | |
| | | setSelectedRows(ids) |
| | | |
| | | }; |
| | |
| | | rows={tabelData} |
| | | columns={columns} |
| | | disableRowSelectionOnClick |
| | | getRowId={(row) => row.matnrId} |
| | | getRowId={(row) => row.id} |
| | | disableColumnFilter |
| | | disableColumnSelector |
| | | disableColumnSorting |
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 AsnWareModal from "./AsnWareModal"; |
| | | 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, GRID_DATE_COL_DEF, GRID_DATETIME_COL_DEF, getGridDateOperators, useGridApiContext } from '@mui/x-data-grid'; |
| | | import { LocalizationProvider, DatePicker, DateTimePicker } from '@mui/x-date-pickers'; |
| | | import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; |
| | | import DictionarySelect from "../../components/DictionarySelect"; |
| | | import DictSelect from "../../components/DictSelect"; |
| | | import "./asnOrder.css"; |
| | | import { 'zhCN' as locale } from 'date-fns/locale'; |
| | | import { format, } from 'date-fns'; |
| | | import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; |
| | | |
| | | const POItemModal = (props) => { |
| | | const { open, setOpen, billReload, record } = 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 && record !== 0) { |
| | | requestGetBody() |
| | | } |
| | | setDisabled(false) |
| | | }, [open]) |
| | | |
| | | const handleClose = (event, reason) => { |
| | | if (reason !== "backdropClick") { |
| | | setOpen(false); |
| | | refresh(); |
| | | setTableData([]) |
| | | } |
| | | }; |
| | | |
| | | |
| | | const [tabelData, setTableData] = useState([]); |
| | | |
| | | const resetData = () => { |
| | | setTableData([]) |
| | | } |
| | | |
| | | const setFinally = () => { |
| | | const rows = tableRef.current.state.editRows; |
| | | for (const key in rows) { |
| | | const find = tabelData.find(item => item.id === +key); |
| | | find.anfme = rows[key].anfme.value; |
| | | } |
| | | setTableData([...tabelData]); |
| | | } |
| | | |
| | | const handleSubmit = async () => { |
| | | setFinally() |
| | | setDisabled(true) |
| | | setOpen(false) |
| | | const parmas = { |
| | | "purchaseId": record, |
| | | "items": tabelData, |
| | | } |
| | | console.log('--------->'); |
| | | console.log(parmas); |
| | | // const res = await request.post(`/asnOrder/purchases/save`, parmas); |
| | | // if (res?.data?.code === 200) { |
| | | // setOpen(false); |
| | | // refresh(); |
| | | // resetData() |
| | | // } else { |
| | | // notify(res.data.msg); |
| | | // } |
| | | setDisabled(false) |
| | | }; |
| | | |
| | | const requestGetBody = async () => { |
| | | const res = await request.post(`/purchaseItem/page`, { purchaseId: record }); |
| | | if (res?.data?.code === 200) { |
| | | setTableData(res.data.data.records) |
| | | } else { |
| | | notify(res.data.msg); |
| | | } |
| | | } |
| | | |
| | | const [selectedRows, setSelectedRows] = useState([]); |
| | | |
| | | return ( |
| | | <> |
| | | <Dialog |
| | | open={open} |
| | | onClose={handleClose} |
| | | aria-labelledby="form-dialog-title" |
| | | aria-hidden |
| | | fullWidth |
| | | disableRestoreFocus |
| | | maxWidth="xl" // '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={{ mt: 2 }}> |
| | | <AsnOrderModalTable tabelData={tabelData} |
| | | setTableData={setTableData} |
| | | record={record} |
| | | selectedRows={selectedRows} |
| | | setSelectedRows={setSelectedRows} |
| | | tableRef={tableRef} /> |
| | | </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> |
| | | </> |
| | | ) |
| | | } |
| | | |
| | | export default POItemModal; |
| | | |
| | | 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 AsnOrderModalTable = ({ tabelData, setTableData, record, selectedRows, setSelectedRows, tableRef }) => { |
| | | const translate = useTranslate(); |
| | | const notify = useNotify(); |
| | | |
| | | const [columns, setColumns] = useState([ |
| | | { |
| | | field: 'matnrCode', |
| | | headerName: translate('table.field.asnOrderItem.matnrCode'), |
| | | width: 130, |
| | | editable: false, |
| | | }, |
| | | { |
| | | field: 'matnrName', |
| | | headerName: translate('table.field.asnOrderItem.maktx'), |
| | | width: 250, |
| | | editable: false, |
| | | }, |
| | | { |
| | | field: 'splrName', |
| | | headerName: translate('table.field.asnOrderItem.splrName') + "*", |
| | | minWidth: 150, |
| | | flex: 1, |
| | | editable: true, |
| | | renderEditCell: (params) => ( |
| | | <SelectInputSplrNameEditCell {...params} /> |
| | | ), |
| | | headerClassName: "custom", |
| | | }, |
| | | { |
| | | field: 'platItemId', |
| | | headerName: translate('table.field.asnOrderItem.platItemId') + "*", |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: true, |
| | | headerClassName: "custom", |
| | | }, |
| | | { |
| | | field: 'anfme', |
| | | headerName: translate('table.field.asnOrderItem.anfme') + "*", |
| | | type: 'number', |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: true, |
| | | valueFormatter: (val) => val < 0 ? 0 : val, |
| | | headerClassName: "custom", |
| | | }, |
| | | { |
| | | field: 'unit', |
| | | headerName: translate('table.field.asnOrderItem.stockUnit'), |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: false, |
| | | }, |
| | | ]) |
| | | |
| | | 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, |
| | | valueGetter: (value, row) => { |
| | | if (value != null && value != undefined) { |
| | | return value; |
| | | } |
| | | if (row.extendFields == null || row.extendFields[el.fields] == null) { |
| | | return '' |
| | | } else { |
| | | return `${row.extendFields[el.fields] == null ? '' : row.extendFields[el.fields]}`; |
| | | } |
| | | }, |
| | | headerName: el.fieldsAlise, |
| | | minWidth: 100, |
| | | flex: 1, |
| | | editable: true |
| | | })) |
| | | setColumns([...columns, ...cols, action]) |
| | | } else { |
| | | notify(msg); |
| | | } |
| | | } |
| | | |
| | | const handleDelete = (row) => { |
| | | const newData = _.filter(cdata.current, (item) => item.id !== row.id); |
| | | setTableData(newData); |
| | | }; |
| | | |
| | | |
| | | const processRowUpdate = (newRow, oldRow) => { |
| | | const rows = tabelData.map((r) => |
| | | r.id === newRow.id ? { ...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.id} |
| | | disableColumnFilter |
| | | disableColumnSelector |
| | | disableColumnSorting |
| | | disableMultipleColumnsSorting |
| | | processRowUpdate={processRowUpdate} |
| | | initialState={{ |
| | | pagination: { |
| | | paginationModel: { |
| | | pageSize: 25, |
| | | }, |
| | | }, |
| | | }} |
| | | pageSizeOptions={[10, 25, 50, 100]} |
| | | editMode="row" |
| | | checkboxSelection |
| | | onRowSelectionModelChange={handleSelectionChange} |
| | | selectionModel={selectedRows} |
| | | sx={{ |
| | | '& .MuiDataGrid-cell input': { |
| | | border: '1px solid #ccc' |
| | | }, |
| | | }} |
| | | /> |
| | | </div> |
| | | ); |
| | | }; |
| | | |
| | |
| | | rowClick={'edit'} |
| | | expand={false} |
| | | expandSingle={true} |
| | | omit={['id', 'createTime', 'createBy','channel', 'platCode', 'memo', 'preArr', 'channel','startTime','workQty', 'endTime']} |
| | | omit={['id', 'createTime', 'createBy','channel', 'platCode', 'memo', 'channel','startTime','workQty', 'endTime']} |
| | | > |
| | | <NumberField source="id" /> |
| | | <TextField source="code" label="table.field.purchase.code" /> |
| | | <TextField source="type$" label="table.field.purchase.type" /> |
| | | <TextField source="wkType$" label="table.field.purchase.wkType" /> |
| | | <TextField source="source" label="table.field.purchase.source" /> |
| | | <DateField source="preArr" label="table.field.purchase.preArr" showTime /> |
| | | <NumberField source="anfme" label="table.field.purchase.anfme" /> |
| | | <NumberField source="qty" label="table.field.purchase.qty" /> |
| | | {/* <NumberField source="workQty" label="table.field.purchase.workQty" /> */} |
| | | <TextField source="channel" label="table.field.purchase.channel" /> |
| | | <TextField source="platCode" label="table.field.purchase.platCode" /> |
| | | <DateField source="preArr" label="table.field.purchase.preArr" showTime /> |
| | | <DateField source="startTime" label="table.field.purchase.startTime" showTime /> |
| | | <DateField source="endTime" label="table.field.purchase.endTime" showTime /> |
| | | <TextField source="project" label="table.field.purchase.project" /> |
| | |
| | | <List |
| | | storeKey="IsptItem" |
| | | resource="qlyIsptItem/ispt/result" |
| | | filter={{ id: record?.id, type: '1' }} |
| | | filter={{ id: record?.id}} |
| | | empty={false} |
| | | filters={false} |
| | | sort={{ field: "create_time", order: "desc" }} |
| | |
| | | |
| | | const filters = [ |
| | | <SearchInput source="condition" alwaysOn />, |
| | | |
| | | <NumberInput source="areaId" label="table.field.warehouseAreasItem.areaId" />, |
| | | <TextInput source="asnCode" label="table.field.warehouseAreasItem.asnCode" />, |
| | | <TextInput source="areaName" label="table.field.warehouseAreasItem.areaName" />, |
| | | <NumberInput source="matnrId" label="table.field.warehouseAreasItem.matnrId" />, |
| | | <TextInput source="matnrName" label="table.field.warehouseAreasItem.matnrName" />, |
| | |
| | | import com.vincent.rsf.server.manager.mapper.*; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import com.vincent.rsf.server.system.constant.CodeRes; |
| | | import com.vincent.rsf.server.system.constant.GlobalConfigCode; |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | | import com.vincent.rsf.server.system.controller.param.LoginParam; |
| | | import com.vincent.rsf.server.system.controller.result.LoginResult; |
| | | import com.vincent.rsf.server.system.entity.*; |
| | | import com.vincent.rsf.server.system.mapper.FieldsMapper; |
| | | import com.vincent.rsf.server.system.mapper.TenantMapper; |
| | | import com.vincent.rsf.server.system.service.ConfigService; |
| | | import com.vincent.rsf.server.system.service.FieldsItemService; |
| | | import com.vincent.rsf.server.system.service.UserLoginService; |
| | | import com.vincent.rsf.server.system.service.UserService; |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | private LocAreaMapper locAreaMapper; |
| | | @Autowired |
| | | private DeviceSiteMapper deviceSiteMapper; |
| | | @Autowired |
| | | private ConfigService configService; |
| | | |
| | | /** |
| | | * @return |
| | |
| | | } |
| | | //TODO /**收货数量累加,1. 会出超收情况 2. 会有收货不足情况*/ |
| | | Double rcptedQty = asnOrder.getQty() + receiptQty; |
| | | asnOrder.setQty(rcptedQty).setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_EXCE_ING.val); |
| | | |
| | | asnOrder.setQty(rcptedQty).setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_EXCE_ING.val); |
| | | if (!asnOrderMapper.updateById(asnOrder)) { |
| | | throw new CoolException("已收货数量修改失败!!"); |
| | | } |
| | | |
| | | Config config = configService.getOne(new LambdaQueryWrapper<Config>().eq(Config::getFlag, GlobalConfigCode.ALLOW_OVER_CHANGE)); |
| | | |
| | | |
| | | List<Map<String, Object>> receipts1 = (List<Map<String, Object>>) params.get("receipts"); |
| | | for (Map<String, Object> rcpt : receipts1) { |
| | | if (null == rcpt || Objects.isNull(rcpt)) { |
| | |
| | | if (Objects.isNull(dto.getReceiptQty()) || Double.compare(dto.getReceiptQty(), 0.0) == 0) { |
| | | throw new CoolException("物料:" + dto.getMaktx() + "收货数量不能为零!!"); |
| | | } |
| | | |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); |
| | | try { |
| | | if (!Objects.isNull(dto.getProdTime())) { |
| | | sdf.parse(dto.getProdTime()); |
| | | } |
| | | } catch (ParseException e) { |
| | | throw new CoolException("请输入正确的时间格式!!"); |
| | | } |
| | | |
| | | Double itemRcptQty = dto.getReceiptQty() + orderItem.getQty(); |
| | | Boolean allowOver = false; |
| | | if (!Objects.isNull(config)) { |
| | | if (Boolean.parseBoolean(config.getVal())) { |
| | | allowOver = true; |
| | | } |
| | | } |
| | | if (itemRcptQty.compareTo(orderItem.getAnfme()) > 0 && !allowOver) { |
| | | throw new CoolException("收货数量不能大于计划数量!!"); |
| | | } |
| | | |
| | | orderItem.setQty(itemRcptQty) |
| | | // .setSplrBatch(dto.getSplrBatch()) |
| | | .setUpdateBy(loginUserId) |
| | |
| | | .setFieldsIndex(orderItem.getFieldsIndex()) |
| | | .setShipperId(matnr.getShipperId()); |
| | | //TODO 供应商标识未设置,标识由PO单供应商编码转换 |
| | | WarehouseAreasItem serviceOne = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>() |
| | | |
| | | LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new LambdaQueryWrapper<WarehouseAreasItem>() |
| | | // .eq(WarehouseAreasItem::getAsnItemId, item.getAsnItemId()) |
| | | .eq(WarehouseAreasItem::getMatnrCode, item.getMatnrCode()) |
| | | .eq(!Cools.isEmpty(item.getFieldsIndex()), WarehouseAreasItem::getFieldsIndex, item.getFieldsIndex()) |
| | | .eq(WarehouseAreasItem::getAsnCode, item.getAsnCode()) |
| | | .eq(!Cools.isEmpty(item.getIsptResult()), WarehouseAreasItem::getIsptResult, item.getIsptResult()) |
| | | .eq(StringUtils.isNotBlank(item.getSplrBatch()), WarehouseAreasItem::getSplrBatch, item.getSplrBatch())); |
| | | .eq(StringUtils.isNotBlank(item.getSplrBatch()), WarehouseAreasItem::getSplrBatch, item.getSplrBatch()); |
| | | if (Objects.isNull(orderItem.getIsptResult())) { |
| | | queryWrapper.isNull(WarehouseAreasItem::getIsptResult); |
| | | } else { |
| | | queryWrapper.eq(WarehouseAreasItem::getIsptResult, orderItem.getIsptResult()); |
| | | } |
| | | |
| | | WarehouseAreasItem serviceOne = warehouseAreasItemService.getOne(queryWrapper); |
| | | |
| | | if (!Objects.isNull(serviceOne)) { |
| | | item.setId(serviceOne.getId()); |
| | |
| | | @Configuration |
| | | @ConfigurationProperties(prefix = "stock") |
| | | public class SysStockProperties { |
| | | |
| | | |
| | | /** |
| | | * wms是否允许打印货物标签, 默认可打印 |
| | | */ |
| | |
| | | return asnOrderService.saveOrderAndItems(params, getLoginUserId()); |
| | | } |
| | | |
| | | @PostMapping("/asnOrder/purchases/save") |
| | | @ApiOperation("根据PO单新建收货单") |
| | | @PreAuthorize("hasAuthority('manager:asnOrder:save')") |
| | | public R orderCreateByPo(@RequestBody Map<String, Object> params) { |
| | | if (Objects.isNull(params.get("ids"))) { |
| | | return R.error("参数不能为空!!"); |
| | | } |
| | | String json = params.get("ids").toString(); |
| | | List<Long> ids = JSONArray.parseArray(params.get("ids").toString(), Long.class); |
| | | if (ids.isEmpty()) { |
| | | return R.error("参数不能为空"); |
| | | } |
| | | return asnOrderService.createByPo(ids); |
| | | } |
| | | |
| | | |
| | | @ApiOperation("单据信息修改") |
| | | @PostMapping("/asnOrder/items/update") |
| | | @PreAuthorize("hasAuthority('manager:asnOrder:update')") |
| | |
| | | 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.manager.entity.AsnOrderItem; |
| | | import com.vincent.rsf.server.manager.entity.Purchase; |
| | | import com.vincent.rsf.server.manager.entity.PurchaseItem; |
| | | import com.vincent.rsf.server.manager.enums.POExceStatus; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderItemService; |
| | | import com.vincent.rsf.server.manager.service.PurchaseItemService; |
| | | import com.vincent.rsf.server.manager.service.PurchaseService; |
| | |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('manager:purchase:list')") |
| | | @PostMapping("/purchase/filters/page") |
| | | public R filterPage(@RequestBody Map<String, Object> map) { |
| | | BaseParam baseParam = buildParam(map, BaseParam.class); |
| | | PageParam<Purchase, BaseParam> pageParam = new PageParam<>(baseParam, Purchase.class); |
| | | QueryWrapper<Purchase> wrapper = pageParam.buildWrapper(true); |
| | | wrapper.ne("exce_status", POExceStatus.PO_EXCE_STATUS_ALL_DONE.val); |
| | | return R.ok().add(purchaseService.page(pageParam, wrapper)); |
| | | } |
| | | |
| | | |
| | | @PreAuthorize("hasAuthority('manager:purchase:list')") |
| | | @PostMapping("/purchase/list") |
| | | public R list(@RequestBody Map<String, Object> map) { |
| | | return R.ok().add(purchaseService.list()); |
| | |
| | | @ApiModelProperty(value = "收货道口") |
| | | private String channel; |
| | | |
| | | @ApiModelProperty("执行状态") |
| | | private Short exceStatus; |
| | | |
| | | /** |
| | | * erp单号 |
| | | */ |
| | |
| | | |
| | | @Excel(name = "单据类型") |
| | | @ApiModelProperty(value= "单据类型") |
| | | @ExcelComment(value = "type", example = "采购入库单") |
| | | @ExcelComment(value = "type", example = "入库单") |
| | | private String type; |
| | | |
| | | |
| | | @Excel(name = "业务类型") |
| | | @ApiModelProperty(value= "业务类型") |
| | | @ExcelComment(value = "wkType", example = "外购收货") |
| | | @ExcelComment(value = "wkType", example = "采购入库单") |
| | | private String wkType; |
| | | |
| | | @Excel(name = "项目名称") |
| | |
| | | @ExcelComment(value = "splrBatch", example = "20250401") |
| | | private String splrBatch; |
| | | |
| | | |
| | | @Excel(name = "预计送达时间") |
| | | @ApiModelProperty("预计送达时间") |
| | | @ExcelComment(value = "arrTime", example = "2025-05-21") |
| | |
| | | */ |
| | | public enum AsnExceStatus { |
| | | |
| | | //质检状态 |
| | | //ASN执行状态状态 |
| | | ASN_EXCE_STATUS_UN_EXCE("0", "未执行"), |
| | | ASN_EXCE_STATUS_EXCE_ING("1", "执行中"), |
| | | ASN_EXCE_STATUS_RECEIPT_DONE("2", "收货完成"), |
| | |
| | | ASN_EXCE_STATUS_TASK_CANCEL("4", "取消"), |
| | | ASN_EXCE_STATUS_TASK_CLOSE("5", "已关闭"), |
| | | |
| | | //PO单执行状态 |
| | | PO_EXCE_STATUS_UN_EXCE("0", "未执行"), |
| | | PO_EXCE_STATUS_EXCE_ING("1", "执行中"), |
| | | PO_EXCE_STATUS_SECTION_DONE("3", "部分完成"), |
| | | PO_EXCE_STATUS_ALL_DONE("3", "已完成"), |
| | | |
| | | |
| | | OUT_STOCK_STATUS_TASK_INIT("11", "初始化"), |
| | | OUT_STOCK_STATUS_TASK_EXCE("12", "待处理"), |
New file |
| | |
| | | package com.vincent.rsf.server.manager.enums; |
| | | |
| | | |
| | | public enum POExceStatus { |
| | | PO_EXCE_STATUS_UN_EXCE("0", "未执行"), |
| | | PO_EXCE_STATUS_EXCE_ING("1", "执行中"), |
| | | PO_EXCE_STATUS_SECTION_DONE("3", "部分完成"), |
| | | PO_EXCE_STATUS_ALL_DONE("3", "已完成"), |
| | | ; |
| | | |
| | | POExceStatus(String val, String desc) { |
| | | this.val = Short.parseShort(val); |
| | | this.desc = desc; |
| | | } |
| | | |
| | | public Short val; |
| | | public String desc; |
| | | |
| | | } |
| | |
| | | import com.vincent.rsf.server.manager.controller.params.WarehouseAreaParam; |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.enums.AsnExceStatus; |
| | | import com.vincent.rsf.server.manager.enums.POExceStatus; |
| | | import com.vincent.rsf.server.manager.enums.PakinIOStatus; |
| | | import com.vincent.rsf.server.manager.enums.WarehouseAreasType; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | |
| | | .setMatnrId(matnr.getId()) |
| | | .setIsptResult(orderItem.getIsptResult()) |
| | | .setMaktx(matnr.getName()) |
| | | .setSplrBatch(orderItem.getSplrBatch()) |
| | | .setWeight(matnr.getWeight()) |
| | | .setFieldsIndex(orderItem.getFieldsIndex()) |
| | | .setShipperId(matnr.getShipperId()); |
| | | WarehouseAreasItem serviceOne = warehouseAreasItemService.getOne(new LambdaQueryWrapper<WarehouseAreasItem>() |
| | | .eq(WarehouseAreasItem::getMatnrCode, item.getMatnrCode()) |
| | | .eq(!Cools.isEmpty(item.getFieldsIndex()), WarehouseAreasItem::getFieldsIndex, item.getFieldsIndex()) |
| | | .eq(WarehouseAreasItem::getAsnCode, item.getAsnCode()) |
| | | .eq(!Cools.isEmpty(item.getIsptResult()), WarehouseAreasItem::getIsptResult, item.getIsptResult()) |
| | | .eq(StringUtils.isNotBlank(item.getSplrBatch()), WarehouseAreasItem::getSplrBatch, item.getSplrBatch())); |
| | | |
| | | LambdaQueryWrapper<WarehouseAreasItem> queryWrapper = new LambdaQueryWrapper<WarehouseAreasItem>() |
| | | .eq(WarehouseAreasItem::getMatnrCode, orderItem.getMatnrCode()) |
| | | .eq(!Cools.isEmpty(orderItem.getFieldsIndex()), WarehouseAreasItem::getFieldsIndex, orderItem.getFieldsIndex()) |
| | | .eq(WarehouseAreasItem::getAsnCode, orderItem.getAsnCode()) |
| | | .eq(StringUtils.isNotBlank(orderItem.getSplrBatch()), WarehouseAreasItem::getSplrBatch, orderItem.getSplrBatch()); |
| | | if (Objects.isNull(orderItem.getIsptResult())) { |
| | | queryWrapper.isNull(WarehouseAreasItem::getIsptResult); |
| | | } else { |
| | | queryWrapper.eq(WarehouseAreasItem::getIsptResult, orderItem.getIsptResult()); |
| | | } |
| | | WarehouseAreasItem serviceOne = warehouseAreasItemService.getOne(queryWrapper); |
| | | if (!Objects.isNull(serviceOne)) { |
| | | item.setId(serviceOne.getId()); |
| | | item.setAnfme(item.getAnfme() + serviceOne.getAnfme()); |
| | |
| | | return; |
| | | } |
| | | //获取未生成ASN单据 |
| | | List<Purchase> purchases = purchaseService.list(new LambdaQueryWrapper<Purchase>().eq(Purchase::getStatus, 0)); |
| | | List<Purchase> purchases = purchaseService.list(new LambdaQueryWrapper<Purchase>().eq(Purchase::getExceStatus, 0)); |
| | | //PO单为空,直接跳出当前任务 |
| | | if (purchases.isEmpty()) { |
| | | return; |
| | |
| | | } |
| | | |
| | | //任务执行完成,修改已完成数量和PO单执行状态 |
| | | purchase.setQty(purchase.getAnfme()).setStatus(1); |
| | | purchase.setQty(purchase.getAnfme()) |
| | | .setExceStatus(POExceStatus.PO_EXCE_STATUS_EXCE_ING.val); |
| | | |
| | | if (!purchaseService.saveOrUpdate(purchase)) { |
| | | throw new CoolException("PO单执行完成后,保存失败!!"); |
| | |
| | | |
| | | R closeOrder(Long id); |
| | | |
| | | R createByPo(List<Long> ids); |
| | | } |
| | |
| | | package com.vincent.rsf.server.manager.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.vincent.rsf.server.api.entity.dto.PoItemsDto; |
| | | import com.vincent.rsf.server.manager.entity.Purchase; |
| | | |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | public interface PurchaseService extends IService<Purchase> { |
| | | |
| | | List<PoItemsDto> poList(Set<Long> asnIds); |
| | | } |
| | |
| | | // } |
| | | //保存扩展字段 |
| | | try { |
| | | StringBuffer sb = new StringBuffer(); |
| | | if (Objects.isNull(asnOrderItem.getFieldsIndex()) || StringUtils.isBlank(asnOrderItem.getFieldsIndex())) { |
| | | StringBuffer sb = new StringBuffer(); |
| | | if (!Objects.isNull(asnOrderItem.getExtendFields()) && !asnOrderItem.getExtendFields().isEmpty()) { |
| | | Map<String, String> fields = asnOrderItem.getExtendFields(); |
| | | asnOrderItem.getExtendFields().keySet().forEach(key -> { |
| | |
| | | //获取16位uuid |
| | | String uuid16 = Cools.md5Chinese(sb.toString()); |
| | | asnOrderItem.setFieldsIndex(uuid16); |
| | | if (FieldsUtils.saveFields(params, uuid16)) { |
| | | asnOrderItem.setFieldsIndex(uuid16); |
| | | } |
| | | params.put("index", uuid16); |
| | | } |
| | | //保存或更新动态字段值 |
| | | FieldsUtils.updateFieldsValue(params); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | |
| | | import com.vincent.rsf.server.api.entity.dto.PoItemsDto; |
| | | import com.vincent.rsf.server.api.service.ReceiveMsgService; |
| | | import com.vincent.rsf.server.api.service.ReportMsgService; |
| | | import com.vincent.rsf.server.common.utils.DateUtils; |
| | | import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams; |
| | | import com.vincent.rsf.server.manager.controller.params.BatchUpdateParam; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrderItem; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrderItemLog; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrderLog; |
| | | import com.vincent.rsf.server.manager.entity.*; |
| | | import com.vincent.rsf.server.manager.enums.AsnExceStatus; |
| | | import com.vincent.rsf.server.manager.enums.POExceStatus; |
| | | import com.vincent.rsf.server.manager.mapper.AsnOrderMapper; |
| | | import com.vincent.rsf.server.manager.entity.AsnOrder; |
| | | import com.vincent.rsf.server.manager.mapper.PurchaseMapper; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderItemLogService; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderItemService; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderLogService; |
| | | import com.vincent.rsf.server.manager.service.AsnOrderService; |
| | | import com.vincent.rsf.server.manager.service.*; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.vincent.rsf.server.system.constant.SerialRuleCode; |
| | | import com.vincent.rsf.server.system.mapper.SerialRuleMapper; |
| | |
| | | private ReceiveMsgService receiveMsgService; |
| | | @Autowired |
| | | private ReportMsgService reportMsgService; |
| | | @Resource |
| | | private PurchaseMapper purchaseMapper; |
| | | |
| | | @Autowired |
| | | private AsnOrderItemService asnOrderItemService; |
| | | @Autowired |
| | |
| | | private AsnOrderItemLogService asnOrderItemLogService; |
| | | @Resource |
| | | private SerialRuleMapper serialRuleMapper; |
| | | @Autowired |
| | | private MatnrService matnrService; |
| | | @Autowired |
| | | private PurchaseService purchaseService; |
| | | @Autowired |
| | | private PurchaseItemService purchaseItemService; |
| | | |
| | | @Override |
| | | public boolean notifyInspect(List<AsnOrder> orders) { |
| | |
| | | if (asnIds.isEmpty()) { |
| | | throw new CoolException("ASN单据不能为空!!"); |
| | | } |
| | | List<PoItemsDto> items = purchaseMapper.poList(asnIds); |
| | | List<PoItemsDto> items = purchaseService.poList(asnIds); |
| | | if (items.isEmpty()) { |
| | | throw new CoolException("物料所属采购单据不存在!!"); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * @author Ryan |
| | | * @date 2025/5/13 |
| | | * @description: 根据PO单创建ASN单 |
| | | * @version 1.0 |
| | | */ |
| | | @Override |
| | | public R createByPo(List<Long> ids) { |
| | | //获取未生成ASN单据 |
| | | List<Purchase> purchases = purchaseService.list(new LambdaQueryWrapper<Purchase>().in(Purchase::getId, ids)); |
| | | //生成ASN单据 |
| | | purchases.forEach(purchase -> { |
| | | if (!Objects.isNull(purchase.getStartTime())) { |
| | | //判断起始时间是否大于当前时间 |
| | | if (DateUtils.compareDate(new Date(), purchase.getStartTime())) { |
| | | return; |
| | | } |
| | | } |
| | | List<PurchaseItem> items = purchaseItemService.list(new LambdaQueryWrapper<PurchaseItem>().eq(PurchaseItem::getPurchaseId, purchase.getId())); |
| | | if (items.isEmpty()) { |
| | | throw new CoolException("子列表数据为空,请查询PO单是否正确录入!!"); |
| | | } |
| | | AsnOrder order = new AsnOrder(); |
| | | //根据编码规则生成ASN单号 |
| | | String code = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_ASN_ORDER, purchase); |
| | | order.setAnfme(purchase.getAnfme()) |
| | | .setCode(code) |
| | | .setArrTime(purchase.getPreArr()) |
| | | .setQty(purchase.getQty()) |
| | | .setPoId(purchase.getId()) |
| | | .setPoCode(purchase.getCode()); |
| | | if (!this.save(order)) { |
| | | throw new CoolException("ASN单据保存失败!!"); |
| | | } |
| | | List<AsnOrderItem> orderItems = new ArrayList<>(); |
| | | items.forEach(item -> { |
| | | AsnOrderItem orderItem = new AsnOrderItem(); |
| | | Matnr matnr = matnrService.getOne(new LambdaQueryWrapper<Matnr>().eq(Matnr::getCode, item.getMatnrCode())); |
| | | if (Objects.isNull(matnr)) { |
| | | throw new CoolException("数据错误:当前物料不存在!!"); |
| | | } |
| | | String trackCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_LABEL_CODE, item); |
| | | if (StringUtils.isBlank(trackCode)) { |
| | | throw new CoolException("单据跟踪码生成失败:请检查「sys_asn_mantr_label」是否配置完成!!"); |
| | | } |
| | | // String barcode = code + matnr.getCode(); |
| | | orderItem.setAnfme(item.getAnfme()) |
| | | .setAsnId(order.getId()) |
| | | .setQty(item.getAnfme()) |
| | | .setSplrName(item.getSplrName()) |
| | | .setAsnCode(code) |
| | | .setSplrBatch(item.getSplrBatch()) |
| | | .setSplrCode(item.getSplrCode()) |
| | | .setPoDetlId(item.getId()) |
| | | .setPlatItemId(item.getPlatItemId()) |
| | | .setTrackCode(trackCode) |
| | | .setPoCode(purchase.getCode()) |
| | | .setPurQty(item.getAnfme()) |
| | | .setPurUnit(item.getUnit()) |
| | | .setMatnrCode(matnr.getCode()) |
| | | .setMaktx(matnr.getName()) |
| | | .setMatnrId(matnr.getId()); |
| | | orderItems.add(orderItem); |
| | | }); |
| | | if (!asnOrderItemService.saveBatch(orderItems)) { |
| | | throw new CoolException(("Asn单据明细保存失败!!")); |
| | | } |
| | | |
| | | //任务执行完成,修改已完成数量和PO单执行状态 |
| | | purchase.setQty(purchase.getAnfme()) |
| | | .setExceStatus(POExceStatus.PO_EXCE_STATUS_EXCE_ING.val); |
| | | |
| | | if (!purchaseService.saveOrUpdate(purchase)) { |
| | | throw new CoolException("PO单执行完成后,保存失败!!"); |
| | | } |
| | | }); |
| | | |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * @param |
| | | * @return |
| | | * @author Ryan |
| | |
| | | if (StringUtils.isBlank(purchaseTemplate.getMatnrCode())) { |
| | | throw new CoolException(purchaseTemplate.getPoCode() + ":物料编码不能为空!!"); |
| | | } |
| | | Matnr matnr = matnrService.getOne(new LambdaQueryWrapper<Matnr>().eq(Matnr::getCode, template.getMatnrCode())); |
| | | Matnr matnr = matnrService.getOne(new LambdaQueryWrapper<Matnr>().eq(Matnr::getCode, purchaseTemplate.getMatnrCode())); |
| | | if (Objects.isNull(matnr)) { |
| | | throw new CoolException(template.getMatnrCode() + "物料不存在!!"); |
| | | throw new CoolException(purchaseTemplate.getMatnrCode() + "物料不存在!!"); |
| | | } |
| | | item.setMatnrName(matnr.getName()) |
| | | .setMatnrCode(matnr.getCode()) |
| | | .setPlatItemId(template.getPlatItemId()) |
| | | .setAnfme(template.getAnfme()) |
| | | .setPlatItemId(purchaseTemplate.getPlatItemId()) |
| | | .setAnfme(purchaseTemplate.getAnfme()) |
| | | .setPurchaseId(purchase.getId()) |
| | | .setUnit(matnr.getUnit()) |
| | | .setNromQty(matnr.getNromNum()) |
| | | .setSplrBatch(template.getSplrBatch()) |
| | | .setSplrBatch(purchaseTemplate.getSplrBatch()) |
| | | .setCreateBy(loginUserId) |
| | | .setUpdateBy(loginUserId); |
| | | |
| | | if (StringUtils.isNotBlank(purchaseTemplate.getSplrCode())) { |
| | | Companys companys = companysService.getOne(new LambdaQueryWrapper<Companys>() |
| | | .eq(Companys::getType, CompanysType.COMPANYS_TYPE_SUPPLIER.val) |
| | | .eq(Companys::getCode, template.getSplrCode())); |
| | | .eq(Companys::getCode, purchaseTemplate.getSplrCode())); |
| | | if (!Objects.isNull(companys)) { |
| | | item.setSplrCode(companys.getCode()).setSplrName(companys.getName()); |
| | | } else { |
| | |
| | | package com.vincent.rsf.server.manager.service.impl; |
| | | |
| | | import com.vincent.rsf.server.api.entity.dto.PoItemsDto; |
| | | import com.vincent.rsf.server.manager.mapper.PurchaseMapper; |
| | | import com.vincent.rsf.server.manager.entity.Purchase; |
| | | import com.vincent.rsf.server.manager.service.PurchaseService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | @Service("purchaseService") |
| | | public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> implements PurchaseService { |
| | | |
| | | @Override |
| | | public List<PoItemsDto> poList(Set<Long> asnIds) { |
| | | return this.baseMapper.poList(asnIds); |
| | | } |
| | | } |
| | |
| | | import com.vincent.rsf.server.manager.service.QlyInspectService; |
| | | import com.vincent.rsf.server.manager.service.QlyIsptItemService; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | throw new CoolException("收货区库存信息更新失败!!"); |
| | | } |
| | | |
| | | //新建质检单,质检结果不会有质检结果 |
| | | if (Objects.isNull(orderItem.getIsptResult())) { |
| | | operateReceipt(item, orderItem); |
| | | } else { |
| | | |
| | | } |
| | | } |
| | | } |
| | |
| | | .eq(QlyInspect::getId, isptItem.stream().findFirst().get().getIspectId())); |
| | | } |
| | | |
| | | // qlyIsptItemService.pageByIsptResult(null, new QueryWrapper<QlyIsptItem>()) |
| | | return true; |
| | | } |
| | | |
| | |
| | | if (sum.compareTo(orderItem.getAnfme()) >= 0) { |
| | | //完成质检,做更新操作 |
| | | if (safeQty.compareTo(0.0) > 0) { |
| | | orderItem.setIsptQty(safeQty); |
| | | orderItem.setIsptQty(safeQty).setAnfme(safeQty); |
| | | orderItem.setIsptResult(QlyIsptResult.QLY_ISPT_RESULT_EXCELLENT.val); |
| | | if (!warehouseAreasItemService.updateById(orderItem)) { |
| | | throw new CoolException("收货区库存明细更新失败!!"); |
| | | } |
| | | } |
| | | |
| | | WarehouseAreasItem areasItem = new WarehouseAreasItem(); |
| | | BeanUtils.copyProperties(orderItem, areasItem); |
| | | if (disQty.compareTo(0.0) > 0) { |
| | | orderItem.setIsptQty(disQty) |
| | | areasItem.setIsptQty(disQty) |
| | | .setAnfme(disQty) |
| | | .setId(null) |
| | | .setIsptResult(QlyIsptResult.QLY_ISPT_RESULT_DEFECT.val); |
| | | if (!warehouseAreasItemService.saveOrUpdate(orderItem)) { |
| | | if (!warehouseAreasItemService.saveOrUpdate(areasItem)) { |
| | | throw new CoolException("收货区库存明细更新失败!!"); |
| | | } |
| | | } |
| | | } else { |
| | | orderItem.setAnfme(orderItem.getAnfme() - sum); |
| | | if (!warehouseAreasItemService.updateById(orderItem)) { |
| | | throw new CoolException("收货区库存明细更新失败!!"); |
| | | } |
| | | |
| | | WarehouseAreasItem areasItem = new WarehouseAreasItem(); |
| | | BeanUtils.copyProperties(orderItem, areasItem); |
| | | //未完成做添加操作 |
| | | if (safeQty.compareTo(0.0) > 0) { |
| | | orderItem.setIsptQty(safeQty) |
| | | areasItem.setIsptQty(safeQty) |
| | | .setAnfme(safeQty) |
| | | .setId(null) |
| | | .setIsptResult(QlyIsptResult.QLY_ISPT_RESULT_EXCELLENT.val); |
| | | if (!warehouseAreasItemService.saveOrUpdate(orderItem)) { |
| | | if (!warehouseAreasItemService.saveOrUpdate(areasItem)) { |
| | | throw new CoolException("收货区库存明细更新失败!!"); |
| | | } |
| | | } |
| | | |
| | | WarehouseAreasItem items = new WarehouseAreasItem(); |
| | | BeanUtils.copyProperties(orderItem, items); |
| | | if (disQty.compareTo(0.0) > 0) { |
| | | orderItem.setIsptQty(disQty) |
| | | items.setIsptQty(disQty) |
| | | .setAnfme(disQty) |
| | | .setId(null) |
| | | .setIsptResult(QlyIsptResult.QLY_ISPT_RESULT_DEFECT.val); |
| | | if (!warehouseAreasItemService.saveOrUpdate(orderItem)) { |
| | | if (!warehouseAreasItemService.saveOrUpdate(items)) { |
| | | throw new CoolException("收货区库存明细更新失败!!"); |
| | | } |
| | | } |
| | |
| | | */ |
| | | public class GlobalConfigCode { |
| | | |
| | | |
| | | public final static String EXECUTION = "Execution"; |
| | | |
| | | /**直接组托*/ |
| | | public final static String DIRECT_WAIT_PAKIN = "DirectWaitPakin"; |
| | | /**收货时是否允许超收*/ |
| | | public final static String ALLOW_OVER_CHANGE = "AllowOverchange"; |
| | | |
| | | } |
| | |
| | | @GetMapping("/fields/enable/list") |
| | | @ApiOperation("获取已开启扩展字段") |
| | | public R getEnableList() { |
| | | return R.ok(fieldsService.list(new LambdaQueryWrapper<Fields>().eq(Fields::getFlagEnable, 1).eq(Fields::getStatus, 1))); |
| | | return R.ok(fieldsService.list(new LambdaQueryWrapper<Fields>().eq(Fields::getFlagEnable, 1))); |
| | | } |
| | | |
| | | @PreAuthorize("hasAuthority('system:fields:list')") |
| | |
| | | #是否允许打印货物标签, 默认允许打印,也可由供应商提供标签 |
| | | flagPrinter: false |
| | | #是否自动生成ASN单(默认:是),为『否』则开启PO单手动生成ASN单功能 |
| | | flagAutoAsn: true |
| | | flagAutoAsn: false |
| | | #质检功能 是否校验上架(默认:是),是否校验收货(默认:否) |
| | | inspect: |
| | | #判断是后检验合格后,才允许上架 |