5074c51d978a490a1d0e9dc116a874d33ddeb16c..b011b1368c2f8813ef2684a4a63914e6e59b5e15
2025-06-05 skyouc
DO单优化 出库单优化
b011b1 对比 | 目录
2025-06-05 skyouc
出库单取消功能优化
b0409a 对比 | 目录
2025-06-05 skyouc
任务列表优化 DO单功能优化 出库单功能优化
e4e3f7 对比 | 目录
24个文件已修改
1个文件已添加
582 ■■■■ 已修改文件
rsf-admin/src/i18n/en.js 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/components/BillStatusField.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/delivery/DeliveryEdit.jsx 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/delivery/DeliveryItemList.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/delivery/DeliveryList.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderEdit.jsx 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderItemList.jsx 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderList.jsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeliveryController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeliveryItemController.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeliveryItem.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/OutStockTemplate.java 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/POExceStatus.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/DeliveryService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeliveryServiceImpl.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/AsnOrderItemMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -607,7 +607,9 @@
                poDetlCode: "DO Detl Code",
                matnrId: "matnrId",
                maktx: "maktx",
                workQty: 'Work Qty',
                anfme: "anfme",
                platOrderCode: 'Customer Code',
                stockUnit: "stockUnit",
                purQty: "purQty",
                purUnit: "purUnit",
@@ -726,7 +728,8 @@
                fieldsIndex: "fieldsIndex",
                unit: "unit",
                anfme: "anfme",
                qty: "qty",
                workQty: 'Work Qty',
                qty: "Qty",
                nromQty: "nromQty",
                printQty: "printQty",
                splrName: "splrName",
rsf-admin/src/i18n/zh.js
@@ -618,7 +618,8 @@
                type: "类型",
                wkType: "业务类型",
                anfme: "数量",
                qty: "已出库数量",
                workQty: '执行数',
                qty: "完成数",
                logisNo: "物流单号",
                arrTime: "预计到达时间",
                rleStatus: "释放状态",
@@ -666,8 +667,10 @@
                matnrId: "物料标识",
                maktx: "物料名称",
                matnrCode: "物料编码",
                platOrderCode: '客单号',
                anfme: "计划出库数",
                stockUnit: "库存单位",
                workQty: '执行数',
                purQty: "下单数量",
                purUnit: "单位",
                qty: "完成数量",
@@ -755,8 +758,9 @@
                fieldsIndex: "字段索引",
                unit: "单位",
                anfme: "数量",
                qty: "完成数量",
                nromQty: "nromQty",
                workQty: '执行数',
                qty: "完成数",
                nromQty: "标包数",
                printQty: "打印数量",
                splrName: "供应商名称",
                splrCode: "供应商编码",
rsf-admin/src/page/components/BillStatusField.jsx
@@ -15,6 +15,11 @@
        2: '#52C41A',
        3: '#595959',
        4: '#FF4D4F',
        10: '#BFBFBF',
        11: '#FFC53D',
        12: '#52C41A',
        13: '#595959',
        14: '#FF4D4F',
    }
    return (
        <Typography
rsf-admin/src/page/orders/asnOrder/AsnOrderList.jsx
@@ -138,12 +138,13 @@
        title={"menu.asnOrder"}
        empty={false}
        filters={filters}
        filter={{ deleted: 0, type: 'in' }}
        sort={{ field: "create_time", order: "desc" }}
        actions={(
          <TopToolbar>
            <FilterButton />
            <MyCreateButton onClick={() => { setCreateDialog(true); setmodalType(0) }} />
            <CreateByPoButton setPoCreate={setPoCreate}/>
            <CreateByPoButton setPoCreate={setPoCreate} />
            <SelectColumnsButton preferenceKey='asnOrder' />
            <ImportButton value={'asnOrderItem'} />
            <MyExportButton />
@@ -175,7 +176,6 @@
          <DateField source="arrTime" label="table.field.asnOrder.arrTime" showTime />
          <TextField source="rleStatus$" label="table.field.asnOrder.rleStatus" sortable={false} />
          <TextField source="logisNo" label="table.field.asnOrder.logisNo" />
          {/* <TextField source="ntyStatus$" label="table.field.asnOrder.ntyStatus" /> */}
          <TextField source="updateBy$" label="common.field.updateBy" />
          <DateField source="updateTime" label="common.field.updateTime" showTime />
          <TextField source="createBy$" label="common.field.createBy" />
@@ -220,7 +220,7 @@
export default AsnOrderList;
//按PO单新建
const CreateByPoButton = ({setPoCreate}) => {
const CreateByPoButton = ({ setPoCreate }) => {
  const record = useRecordContext();
  const createEvent = (event) => {
rsf-admin/src/page/orders/delivery/DeliveryEdit.jsx
@@ -44,7 +44,7 @@
const DeliveryEdit = () => {
    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')) || [];
    const business = JSON.parse(localStorage.getItem('sys_dicts'))?.filter(dict => (dict.dictTypeCode == 'sys_business_type' && dict.group == 2)) || [];
    return (
        <>
@@ -73,11 +73,6 @@
                                    parse={v => v}
                                    autoFocus
                                />
                                <TextInput
                                    label="table.field.delivery.platId"
                                    source="platId"
                                    parse={v => v}
                                />
                                <AutocompleteInput
                                    choices={dicts}
                                    optionText="label"
@@ -95,14 +90,14 @@
                                    optionValue="value"
                                    parse={v => v}
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <TextInput
                                    label="table.field.delivery.source"
                                    source="source"
                                    parse={v => v}
                                    validate={required()}
                                />
                            </Stack>
                            <Stack direction='row' gap={2}>
                                <NumberInput
                                    label="table.field.delivery.anfme"
                                    source="anfme"
@@ -117,6 +112,11 @@
                                    source="workQty"
                                />
                                <TextInput
                                    label="table.field.delivery.platId"
                                    source="platId"
                                    parse={v => v}
                                />
                                <TextInput
                                    label="table.field.delivery.platCode"
                                    source="platCode"
                                    parse={v => v}
rsf-admin/src/page/orders/delivery/DeliveryItemList.jsx
@@ -121,19 +121,19 @@
                    }}
                    expand={false}
                    expandSingle={true}
                    omit={['id', 'createTime', 'deliveryId', 'fieldsIndex', 'qty', 'printQty', 'nromQty', 'createBy', 'memo']}
                    omit={['id', 'createTime', 'deliveryId', 'fieldsIndex', 'printQty', 'nromQty', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="deliveryId" label="table.field.deliveryItem.deliveryId" />
                    <TextField source="platItemId" label="table.field.deliveryItem.platItemId" />
                    <TextField source="matnrCode" label="table.field.deliveryItem.matnrCode" />
                    <TextField source="matnrName" label="table.field.deliveryItem.matnrName" />
                    <TextField source="maktx" label="table.field.deliveryItem.matnrName" />
                    <TextField source="fieldsIndex" label="table.field.deliveryItem.fieldsIndex" />
                    <TextField source="unit" label="table.field.deliveryItem.unit" />
                    <NumberField source="anfme" label="table.field.deliveryItem.anfme" />
                    <NumberField source="workQty" label="table.field.deliveryItem.workQty" />
                    <NumberField source="qty" label="table.field.deliveryItem.qty" />
                    <NumberField source="nromQty" label="table.field.deliveryItem.nromQty" />
                    <NumberField source="printQty" label="table.field.deliveryItem.printQty" />
                    <TextField source="unit" label="table.field.deliveryItem.unit" />
                    <TextField source="splrName" label="table.field.deliveryItem.splrName" />
                    <TextField source="splrCode" label="table.field.deliveryItem.splrCode" />
                    <TextField source="splrBatch" label="table.field.deliveryItem.splrBatch" />
rsf-admin/src/page/orders/delivery/DeliveryList.jsx
@@ -110,10 +110,8 @@
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        {/* <MyCreateButton onClick={() => { setCreateDialog(true) }} /> */}
                        <SelectColumnsButton preferenceKey='delivery' />
                        <ImportButton value={'delivery'} />
                        {/* <MyExportButton /> */}
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
@@ -124,7 +122,7 @@
                    rowClick={(id, resource, record) => false}
                    expand={false}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'platId', 'memo', 'workQty', 'startTime', 'endTime', 'updateBy', 'createTime']}
                    omit={['id', 'createTime', 'createBy', 'platId', 'platCode', 'memo', 'startTime', 'endTime', 'updateBy', 'createTime']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.delivery.code" />
@@ -133,8 +131,8 @@
                    <TextField source="wkType$" label="table.field.delivery.wkType" />
                    <TextField source="source" label="table.field.delivery.source" />
                    <NumberField source="anfme" label="table.field.delivery.anfme" />
                    <NumberField source="qty" label="table.field.delivery.qty" />
                    <NumberField source="workQty" label="table.field.delivery.workQty" />
                    <NumberField source="qty" label="table.field.delivery.qty" />
                    <TextField source="platCode" label="table.field.delivery.platCode" />
                    <DateField source="startTime" label="table.field.delivery.startTime" showTime />
                    <DateField source="endTime" label="table.field.delivery.endTime" showTime />
@@ -143,11 +141,10 @@
                    <TextField source="createBy$" label="common.field.createBy" />
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BillStatusField cellClassName="status" source="exceStatus" label="table.field.asnOrder.exceStatus" />
                    {/* <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">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                        <CustomDelteButton />
                    </WrapperField>
                </StyledDatagrid>
            </List>
@@ -165,4 +162,13 @@
    )
}
const CustomDelteButton = () => {
    const record = useRecordContext();
    return (
        record?.exceStatus == 0 ? <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} /> : <></>
    )
}
export default DeliveryList;
rsf-admin/src/page/orders/outStock/OutOrderEdit.jsx
@@ -19,17 +19,6 @@
import CustomerTopToolBar from "../../components/EditTopToolBar";
import OutOrderItemList from "./OutOrderItemList";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'end' }}>
            <></>
            {/* <SaveButton />
            <DeleteButton mutationMode="optimistic" /> */}
        </Toolbar>
    )
}
const OutOrderEdit = () => {
    const translate = useTranslate();
@@ -47,7 +36,7 @@
                <SimpleForm
                    shouldUnregister
                    warnWhenUnsavedChanges
                    toolbar={<FormToolbar />}
                    toolbar={false}
                    mode="onTouched"
                    defaultValues={{}}
                >
rsf-admin/src/page/orders/outStock/OutOrderItemList.jsx
@@ -64,11 +64,11 @@
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="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/>,
  <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" />,
@@ -136,7 +136,7 @@
              setSelect(record)
              setEditDialog(true)
            }}
             omit={['id', 'createTime', 'createBy', 'memo', 'poDetlId', 'purQty','purUnit','trackCode','packName','splrName','matnrId', 'asnId']}
            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" />
@@ -145,11 +145,13 @@
            <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" />
            <TextField source="stockUnit" label="table.field.outStockItem.stockUnit" />
            <NumberField source="purQty" label="table.field.outStockItem.purQty" />
            <TextField source="purUnit" label="table.field.outStockItem.purUnit" />
            <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="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" />
rsf-admin/src/page/orders/outStock/OutOrderList.jsx
@@ -86,7 +86,7 @@
  <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>
  <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" />,
@@ -142,7 +142,7 @@
            <CreateByOrderButton setCreateDialog={setCreateDialog} />
            <MyCreateButton onClick={() => { setManualDialog(true); setmodalType(0) }} />
            <SelectColumnsButton preferenceKey='outStock' />
            <ImportButton value={'asnOrderItem'} />
            <ImportButton value={'outStock'} />
            {/* <MyExportButton /> */}
          </TopToolbar>
        )}
@@ -164,6 +164,7 @@
          <TextField source="type$" label="table.field.outStock.type" />
          <TextField cellClassName="wkType" source="wkType$" label="table.field.outStock.wkType" />
          <NumberField source="anfme" label="table.field.outStock.anfme" />
          <NumberField source="workQty" label="table.field.outStock.workQty" />
          <NumberField source="qty" label="table.field.outStock.qty" />
          <TextField source="logisNo" label="table.field.outStock.logisNo" />
          <TextField source="rleStatus$" label="table.field.outStock.rleStatus" sortable={false} />
@@ -283,6 +284,6 @@
  }
  return (
     record?.exceStatus == 0 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />  } onConfirm={cancelOrder} /> : <></>
    record?.exceStatus == 10 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />} onConfirm={cancelOrder} /> : <></>
  )
}
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx
@@ -1,4 +1,4 @@
import { Dialog, DialogActions, DialogContent, DialogTitle, Box } from "@mui/material";
import { Dialog, DialogActions, DialogContent, DialogTitle, Box, LinearProgress } from "@mui/material";
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    List,
@@ -33,6 +33,7 @@
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
    SimpleForm,
    Form,
    SaveButton,
    useRefresh,
@@ -41,7 +42,7 @@
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 { Grid, margin, Stack, width } from "@mui/system";
import request from '@/utils/request';
import SaveIcon from '@mui/icons-material/Save';
import debounce from "lodash/debounce";
@@ -58,6 +59,17 @@
        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" />,
@@ -85,6 +97,7 @@
    const [drawerVal, setDrawerVal] = useState(false);
    const refresh = useRefresh();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
@@ -94,20 +107,22 @@
        const { filterValues, setFilters, refetch } = useListContext('deliveryItem');
        const [formValues, setFormValues] = useState(filterValues);
        const handleChange = (event) => {
            if (event.target == undefined || event.target == null) {return}
            if (event.target == undefined || event.target == null) { return }
            setFormValues(formValues => ({
                ...formValues,
              [event.target.name]: event.target.value
                [event.target.name]: event.target.value
            }));
        };
        const handleSubmit = (event) => {
            setParams(formValues)
        };
        return (
            <Form>
                <Grid container rowSpacing={2} columnSpacing={2} >
            <StyledForm>
                <Grid container rowSpacing={3} columnSpacing={3} >
                    <Stack>
                        <TextInput
                            source="condition"
@@ -158,7 +173,7 @@
                        <SaveButton onClick={handleSubmit} label={"toolbar.query"} />
                    </Toolbar>
                </DialogActions>
            </Form>
            </StyledForm>
        );
    };
    return (
@@ -206,30 +221,40 @@
                            )}
                            perPage={DEFAULT_PAGE_SIZE}
                        >
                            <StyledDatagrid
                                sx={{ height: '400' }}
                                preferenceKey='deliveryItem'
                                bulkActionButtons={<AddOutStockButton setOpen={setOpen} />}
                                rowClick={(id, resource, record) => false}
                                expand={false}
                                expandSingle={true}
                                omit={['id', 'createTime', 'createBy', 'memo', 'workQty', '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="matnrName" label="table.field.deliveryItem.matnrName" />
                                <TextField source="unit" label="table.field.deliveryItem.unit" />
                                <NumberField source="anfme" label="table.field.deliveryItem.anfme" />
                                <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 sx={{ position: 'relative', minHeight: "60vh", }}>
                                <LinearProgress
                                    sx={{
                                        height: "2px",
                                        position: 'absolute',
                                        top: 0,
                                        left: 0,
                                        right: 0,
                                    }}
                                />
                                <StyledDatagrid
                                    preferenceKey='deliveryItem'
                                    bulkActionButtons={<AddOutStockButton setOpen={setOpen} />}
                                    rowClick={(id, resource, record) => false}
                                    expand={false}
                                    expandSingle={true}
                                    omit={['id', 'createTime', 'createBy', 'memo', 'workQty', '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="matnrName" label="table.field.deliveryItem.matnrName" />
                                    <TextField source="unit" label="table.field.deliveryItem.unit" />
                                    <NumberField source="anfme" label="table.field.deliveryItem.anfme" />
                                    <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>
@@ -244,6 +269,7 @@
    const { setOpen } = props;
    const { selectedIds, onUnselectItems } = useListContext();
    const notify = useNotify();
    const refresh = useRefresh();
    const confirm = async (event) => {
        const res = await request.post(`/outStock/generate/orders`, { ids: selectedIds });
        if (res?.data?.code === 200) {
@@ -251,6 +277,7 @@
        } else {
            notify(res.data.msg);
        }
        refresh();
        onUnselectItems();
        setOpen(false);
    }
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java
@@ -61,8 +61,8 @@
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<AsnOrder, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrder.class);
        QueryWrapper<AsnOrder> queryWrapper = pageParam.buildWrapper(true);
        List<String> asList = Arrays.asList(OrderType.ORDER_OUT.type);
        queryWrapper.notIn("type", asList);
        List<String> asList = Arrays.asList(OrderType.ORDER_IN.type);
        queryWrapper.in("type", asList);
        return R.ok().add(asnOrderService.page(pageParam, queryWrapper));
    }
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeliveryController.java
@@ -7,6 +7,7 @@
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.exception.BusinessException;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
@@ -15,6 +16,7 @@
import com.vincent.rsf.server.manager.entity.Delivery;
import com.vincent.rsf.server.manager.entity.DeliveryItem;
import com.vincent.rsf.server.manager.entity.excel.DeliveryTemplate;
import com.vincent.rsf.server.manager.enums.AsnExceStatus;
import com.vincent.rsf.server.manager.enums.OrderType;
import com.vincent.rsf.server.manager.enums.OrderWorkType;
import com.vincent.rsf.server.manager.service.CompanysService;
@@ -110,10 +112,11 @@
    @OperationLog("Delete 综合单据明细")
    @PostMapping("/delivery/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!deliveryService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        List<Long> list = Arrays.asList(ids);
        if (list.isEmpty()) {
            return R.error("参数不能为空!!");
        }
        return R.ok("Delete Success").add(ids);
        return R.ok("操作成功").add(deliveryService.removeDo(list));
    }
    @PreAuthorize("hasAuthority('manager:delivery:list')")
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeliveryItemController.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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;
@@ -47,7 +48,9 @@
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<DeliveryItem, BaseParam> pageParam = new PageParam<>(baseParam, DeliveryItem.class);
        return R.ok().add(deliveryItemService.page(pageParam, pageParam.buildWrapper(true)));
        QueryWrapper<DeliveryItem> wrapper = pageParam.buildWrapper(true);
        wrapper.apply("anfme > work_qty + qty ");
        return R.ok().add(deliveryItemService.page(pageParam, wrapper));
    }
    @PreAuthorize("hasAuthority('manager:deliveryItem:list')")
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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;
@@ -47,7 +48,10 @@
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<AsnOrder, BaseParam> pageParam = new PageParam<>(baseParam, AsnOrder.class);
        return R.ok().add(outStockService.page(pageParam, pageParam.buildWrapper(true)));
        QueryWrapper<AsnOrder> queryWrapper = pageParam.buildWrapper(true);
        List<String> list = Arrays.asList(OrderType.ORDER_OUT.type);
        queryWrapper.in("type", list);
        return R.ok().add(outStockService.page(pageParam, queryWrapper));
    }
    @PreAuthorize("hasAuthority('manager:outStock:list')")
@@ -194,7 +198,7 @@
            return R.error("参数不能为空!!");
        }
        List<Long> ids = (List<Long>) params.get("ids");
        return outStockService.genOutStock(ids);
        return outStockService.genOutStock(ids, getLoginUserId());
    }
    @PreAuthorize("hasAuthority('manager:outStock:update')")
@@ -227,8 +231,4 @@
        }
        return outStockService.updateOrderItem(params, getLoginUserId());
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/DeliveryItem.java
@@ -44,8 +44,18 @@
    @ApiModelProperty(value= "主单标识")
    private Long deliveryId;
    @ApiModelProperty("主单编码")
    private String deliveryCode;
    @ApiModelProperty("客户订单号")
    private String platOrderCode;
    @ApiModelProperty("工单号")
    private String platWorkCode;
    @ApiModelProperty("项目号")
    private String projectCode;
    /**
     * erp明细标识
@@ -90,6 +100,12 @@
    private Double anfme;
    /**
     * 执行数量
     */
    @ApiModelProperty(value= "执行数量")
    private Double workQty;
    /**
     * 已出数量
     */
    @ApiModelProperty(value= "已出数量")
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/OutStockTemplate.java
New file
@@ -0,0 +1,195 @@
package com.vincent.rsf.server.manager.entity.excel;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.vincent.rsf.server.manager.entity.excel.annotation.ExcelAutoColumnSize;
import com.vincent.rsf.server.manager.entity.excel.annotation.ExcelComment;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
 * @author Ryan
 * @version 1.0
 * @title AsnOrderTemplate
 * @description
 * @create 2025/3/12 13:49
 */
@Data
@ExcelAutoColumnSize
@Accessors(chain = true)
public class OutStockTemplate {
    /**
     * 编号
     */
    @Excel(name = "*出库单号")
    @ApiModelProperty(value = "*出库单号")
    @ExcelComment(value = "code", example = "OS5945272236")
    private String code;
    /**
     * PO单号
     */
    @Excel(name = "DO单号")
    @ApiModelProperty(value = "DO单号")
    @ExcelComment(value = "poCode", example = "DO59755695")
    private String poCode;
//    /**
//     * PO单据标识
//     */
//    @Excel(name = "PO单据标识")
//    @ApiModelProperty(value= "PO单据标识")
//    @ExcelComment(value = "poId", example = "123456698")
//    private String poId;
    @Excel(name = "行号")
    @ApiModelProperty("行号")
    @ExcelComment(value = "platItemId", example = "1357564255478")
    private String platItemId;
    @Excel(name = "客户订单号")
    @ApiModelProperty("客户订单号")
    @ExcelComment(value = "platOrderCode", example = "PT202564713301")
    private String platOrderCode;
    @Excel(name = "工单号")
    @ApiModelProperty("工单号")
    @ExcelComment(value = "platWorkCode", example = "PWC2354894211")
    private String platWorkCode;
    @Excel(name = "项目号")
    @ApiModelProperty("项目号")
    @ExcelComment(value = "projectCode", example = "PC2365845636001")
    private String projectCode;
    /**
     * 单据类型
     */
    @Excel(name = "*单据类型")
    @ApiModelProperty(value = "*单据类型")
    @ExcelComment(value = "type", example = "入库单")
    private String type;
    /**
     * 业务类型
     */
    @Excel(name = "*业务类型")
    @ApiModelProperty(value = "*业务类型")
    @ExcelComment(value = "wkType", example = "采购入库单")
    private String wkType;
//    @Excel(name = "执行状态")
//    @ApiModelProperty(value= "执行状态")
//    @ExcelComment(value = "exceStatus", example = "0")
//    private String exceStatus;
    @Excel(name = "*物料编码")
    @ApiModelProperty("*物料编码")
    @ExcelComment(value = "matnrCode", example = "102010101545")
    private String matnrCode;
    @Excel(name = "物料名称")
    @ApiModelProperty("物料名称")
    @ExcelComment(value = "maktx", example = "天瑞019-大A型支架-55飞机轮黑色,三角轮盖喷漆银色 (带攻丝钉)右")
    private String maktx;
    //    @Excel(name = "物料规格")
//    @ApiModelProperty("物料规格")
//    @ExcelComment(value = "maktx",example = "2*3*6")
//    private String spec;
//
//
//    @Excel(name = "物料型号")
//    @ApiModelProperty("物料型号")
//    @ExcelComment(value = "maktx",example = "abc")
//    private String model;
    @Excel(name = "供应商编码")
    @ApiModelProperty("供应商编码")
    @ExcelComment(value = "splrCode", example = "685947")
    private String splrCode;
    @Excel(name = "供应商名称")
    @ApiModelProperty("供应商名称")
    @ExcelComment(value = "splrName", example = "浙江中扬立库技术有限公司")
    private String splrName;
//    @Excel(name = "库存单位")
//    @ApiModelProperty("库存单位")
//    @ExcelComment(value = "stockUnit", example = "个")
//    private String stockUnit;
//    @Excel(name = "采购数量")
//    @ApiModelProperty("采购数量")
//    @ExcelComment(value = "purQty", example = "0")
//    private String purQty;
//
//    @Excel(name = "采购单位")
//    @ApiModelProperty("采购单位")
//    @ExcelComment(value = "purUnit", example = "个")
//    private String purUnit;
//    @Excel(name = "已完成数量")
//    @ApiModelProperty("已完成数量")
//    @ExcelComment(value = "qty", example = "0")
//    private String qty;
    @Excel(name = "供应商批次")
    @ApiModelProperty("供应商批次")
    @ExcelComment(value = "splrBatch", example = "25251212")
    private String splrBatch;
    @Excel(name = "*数量")
    @ApiModelProperty("*数量")
    @ExcelComment(value = "anfme", example = "75")
    private String anfme;
//    @Excel(name = "二维码")
//    @ApiModelProperty("二维码")
//    @ExcelComment(value = "qrcode",example = "")
//    private String qrcode;
    //    @Excel(name = "条形码")
//    @ApiModelProperty("条形码")
//    @ExcelComment(value = "barcode", example = "")
//    private String barcode;
//
//    @Excel(name = "跟踪码")
//    @ApiModelProperty("跟踪码")
//    @ExcelComment(value = "trackCode", example = "")
//    private String trackCode;
    @Excel(name = "物流单号")
    @ApiModelProperty("物流单号")
    @ExcelComment(value = "logicNo", example = "SF100064851")
    private String logicNo;
    @Excel(name = "质检状态")
    @ApiModelProperty("质检状态")
    @ExcelComment(value = "isptResult", example = "合格")
    private String isptResult;
    @Excel(name = "预计送达时间")
    @ApiModelProperty("预计送达时间")
    @ExcelComment(value = "arrTime", example = "2025-05-21")
    private String arrTime;
//    @Excel(name = "包装名称")
//    @ApiModelProperty("包装名称")
//    @ExcelComment(value = "packName", example = "箱")
//    private String packName;
    @Excel(name = "备注")
    @ApiModelProperty("备注")
    @ExcelComment(value = "memo", example = "注:易碎品,轻拿放")
    private String memo;
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/AsnExceStatus.java
@@ -24,10 +24,10 @@
//    PO_EXCE_STATUS_ALL_DONE("3", "已完成"),
    OUT_STOCK_STATUS_TASK_INIT("11", "初始化"),
    OUT_STOCK_STATUS_TASK_EXCE("12", "待处理"),
    OUT_STOCK_STATUS_TASK_WAVE("13", "生成波次"),
    OUT_STOCK_STATUS_TASK_WORKING("14", "作业中")
    OUT_STOCK_STATUS_TASK_INIT("10", "初始化"),
    OUT_STOCK_STATUS_TASK_EXCE("11", "待处理"),
    OUT_STOCK_STATUS_TASK_WAVE("12", "生成波次"),
    OUT_STOCK_STATUS_TASK_WORKING("13", "作业中")
    ;
    AsnExceStatus(String val, String desc) {
        this.val = Short.parseShort(val);
rsf-server/src/main/java/com/vincent/rsf/server/manager/enums/POExceStatus.java
@@ -4,7 +4,7 @@
public enum POExceStatus {
    PO_EXCE_STATUS_UN_EXCE("0", "未执行"),
    PO_EXCE_STATUS_EXCE_ING("1", "执行中"),
    PO_EXCE_STATUS_SECTION_DONE("3", "部分完成"),
    PO_EXCE_STATUS_SECTION_DONE("2", "部分完成"),
    PO_EXCE_STATUS_ALL_DONE("3", "已完成"),
    ;
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/DeliveryService.java
@@ -3,6 +3,9 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.manager.entity.Delivery;
import java.util.List;
public interface DeliveryService extends IService<Delivery> {
    Delivery removeDo(List<Long> list);
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java
@@ -3,17 +3,15 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.framework.common.R;
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.AsnOrder;
import java.util.List;
import java.util.Map;
public interface OutStockService extends IService<AsnOrder> {
    R cancelOutOrder(String id);
    R genOutStock(List<Long> ids);
    R genOutStock(List<Long> ids, Long loginUserId);
    R generateWaves(List<Long> ids);
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/DeliveryServiceImpl.java
@@ -1,12 +1,45 @@
package com.vincent.rsf.server.manager.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.exception.BusinessException;
import com.vincent.rsf.server.manager.enums.AsnExceStatus;
import com.vincent.rsf.server.manager.mapper.DeliveryMapper;
import com.vincent.rsf.server.manager.entity.Delivery;
import com.vincent.rsf.server.manager.service.DeliveryItemService;
import com.vincent.rsf.server.manager.service.DeliveryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("deliveryService")
public class DeliveryServiceImpl extends ServiceImpl<DeliveryMapper, Delivery> implements DeliveryService {
    @Autowired
    private DeliveryItemService deliveryItemService;
    @Override
    public Delivery removeDo(List<Long> list) {
        List<Delivery> deliveries = this.list(new LambdaQueryWrapper<Delivery>().eq(Delivery::getId, list));
        if (deliveries.isEmpty()) {
            throw new BusinessException("数据错误:单据信息不存在!!");
        }
        deliveries.forEach(delivery -> {
            if (delivery.getExceStatus().equals(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)){
                if (!this.removeById(delivery.getId())) {
                    throw new CoolException("主单删除失败!!");
                }
                if (!deliveryItemService.removeById(delivery.getId())) {
                    throw new CoolException("单据明细删除失败!1");
                }
            } else {
                throw new CoolException("单据已执行,不可执行删除操作!!");
            }
        });
        return null;
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java
@@ -10,6 +10,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.manager.entity.excel.OutStockTemplate;
import com.vincent.rsf.server.manager.enums.OrderType;
import com.vincent.rsf.server.manager.enums.OrderWorkType;
import com.vincent.rsf.server.common.domain.BaseParam;
@@ -98,17 +99,17 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R excelImport(MultipartFile file, HashMap<String, Object> hashMap, Long loginUserId) throws Exception {
        ExcelImportResult result = ExcelImportUtil.importExcelMore(file.getInputStream(), AsnOrderTemplate.class, ExcelUtil.getDefaultImportParams());
        ExcelImportResult result = ExcelImportUtil.importExcelMore(file.getInputStream(), OutStockTemplate.class, ExcelUtil.getDefaultImportParams());
        if (result.getList().isEmpty()) {
            throw new CoolException("物料导入失败!!");
        }
        if (result.getList().isEmpty()) {
            throw new CoolException("表格内容不能为空!!");
        }
        List<AsnOrderTemplate> resultList = result.getList();
        Map<String, List<AsnOrderTemplate>> listMap = resultList.stream().collect(Collectors.groupingBy(AsnOrderTemplate::getCode));
        List<OutStockTemplate> resultList = result.getList();
        Map<String, List<OutStockTemplate>> listMap = resultList.stream().collect(Collectors.groupingBy(OutStockTemplate::getCode));
        for (String key : listMap.keySet()) {
            AsnOrderTemplate template = listMap.get(key).stream().findFirst().get();
            OutStockTemplate template = listMap.get(key).stream().findFirst().get();
            AsnOrder asnOrder = outStockService.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getCode, template.getCode()));
            if (Objects.isNull(asnOrder)) {
                continue;
@@ -125,7 +126,7 @@
                throw new CoolException("单据保存失败!!");
            }
            List<AsnOrderItem> items = new ArrayList<>();
            for (AsnOrderTemplate orderTemplate : listMap.get(key)) {
            for (OutStockTemplate orderTemplate : listMap.get(key)) {
                AsnOrderItem orderItem = new AsnOrderItem();
                Matnr matnr = null;
                if (!Objects.isNull(orderTemplate.getMatnrCode()) || StringUtils.isNotBlank(orderTemplate.getMatnrCode())) {
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -10,6 +10,7 @@
import com.vincent.rsf.server.manager.controller.params.AsnOrderAndItemsParams;
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.WaveExceStatus;
import com.vincent.rsf.server.manager.mapper.AsnOrderMapper;
import com.vincent.rsf.server.manager.service.*;
@@ -51,6 +52,10 @@
    private WaveService waveService;
    @Autowired
    private WaveItemService waveItemService;
    @Autowired
    private OutStockItemService outStockItemService;
    @Autowired
    private OutStockService outStockService;
    /**
@@ -61,7 +66,7 @@
     * @time 2025/4/7 13:28
     */
    @Transactional(rollbackFor = Exception.class)
    private void svaeOrUpdateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception {
    public void svaeOrUpdateOrderItem(AsnOrderAndItemsParams params, Long loginUserId) throws Exception {
        AsnOrder orders = params.getOrders();
        params.getItems().forEach(item -> {
            item.put("asnId", orders.getId());
@@ -101,19 +106,50 @@
        if (Objects.isNull(order)) {
            throw new CoolException("单据不存在!!");
        }
        if (!order.getExceStatus().equals(AsnExceStatus.ASN_EXCE_STATUS_UN_EXCE.val)) {
        if (!order.getExceStatus().equals(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)) {
            throw new CoolException("当前单据状态为" + AsnExceStatus.getExceStatus(order.getExceStatus()) + ", 不可执行取消操作!!");
        }
        order.setExceStatus(AsnExceStatus.ASN_EXCE_STATUS_TASK_CANCEL.val).setStatus(0);
        if (!this.saveOrUpdate(order)) {
            throw new CoolException("单据取消失败!!");
        List<AsnOrderItem> orderItems = outStockItemService.list(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, id));
        if (!orderItems.isEmpty()) {
            for (AsnOrderItem orderItem : orderItems) {
                if (!Objects.isNull(orderItem.getPoDetlId())) {
                    DeliveryItem deliveryItem = deliveryItemService.getById(orderItem.getPoDetlId());
                    Double workQty = Math.round((deliveryItem.getWorkQty() - orderItem.getAnfme()) * 10000) / 10000.0;
                    deliveryItem.setWorkQty(workQty.compareTo(0.0) >= 0 ? workQty : 0);
                    if (!deliveryItemService.updateById(deliveryItem)) {
                        throw new CoolException("DO单明细更新失败!!");
                    }
                }
            }
        }
        if (!Objects.isNull(order.getPoId())) {
            Delivery delivery = deliveryService.getById(order.getPoId());
            if (!Objects.isNull(delivery)) {
                Double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
                Double workQty = Math.round((delivery.getWorkQty() - sum) * 10000) / 10000.0;
                delivery.setWorkQty(workQty.compareTo(0.0) >= 0 ? workQty : 0).setExceStatus(POExceStatus.PO_EXCE_STATUS_UN_EXCE.val);
                if (!deliveryService.updateById(delivery)) {
                    throw new CoolException("DO单据修改失败!!");
                }
            }
        }
        if (!this.remove(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getId, id))) {
            throw new CoolException("主单删除失败!!");
        }
        if (!outStockItemService.remove(new LambdaQueryWrapper<AsnOrderItem>().eq(AsnOrderItem::getAsnId, id))) {
            throw new CoolException("单据明细删除失败!!");
        }
//        if (!this.saveOrUpdate(order)) {
//            throw new CoolException("单据取消失败!!");
//        }
        return R.ok("操作成功");
    }
    /**
     * @param
     * @param loginUserId
     * @return
     * @author Ryan
     * @description 通过DO单生成出库单
@@ -121,7 +157,7 @@
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R genOutStock(List<Long> ids) {
    public R genOutStock(List<Long> ids, Long loginUserId) {
        if (Objects.isNull(ids) || ids.isEmpty()) {
            throw new CoolException("参数不能为空!!");
        }
@@ -143,9 +179,13 @@
                throw new CoolException("编码规则错误:请检查 「SYS_OUT_STOCK_CODE」编码是否设置成功");
            }
            order.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
                    .setType(delivery.getType())
                    .setWkType(delivery.getWkType())
                    .setCode(ruleCode)
                    .setPoId(delivery.getId())
                    .setId(null)
                    .setUpdateBy(loginUserId)
                    .setCreateBy(loginUserId)
                    .setPoCode(delivery.getCode());
            if (!this.save(order)) {
                throw new CoolException("主单保存失败!!");
@@ -153,28 +193,57 @@
            List<AsnOrderItem> orderItems = new ArrayList<>();
            listMap.get(key).forEach(item -> {
                AsnOrderItem orderItem = new AsnOrderItem();
                Double anfme = Math.round((item.getAnfme() - item.getWorkQty() - item.getQty()) * 10000) / 10000.0;
                BeanUtils.copyProperties(item, orderItem);
                orderItem.setId(null)
                        .setPoCode(order.getPoCode())
                        .setMaktx(item.getMaktx())
                        .setMatnrCode(item.getMatnrCode())
                        .setFieldsIndex(item.getFieldsIndex())
                        .setAnfme(anfme)
                        .setWorkQty(0.0)
                        .setAsnId(order.getId())
                        .setAsnCode(order.getCode())
                        .setStockUnit(item.getUnit())
                        .setPurUnit(item.getUnit())
                        .setPlatWorkCode(item.getPlatWorkCode())
                        .setPlatOrderCode(item.getPlatOrderCode())
                        .setProjectCode(item.getProjectCode())
                        .setPlatItemId(item.getPlatItemId())
                        .setUpdateBy(loginUserId)
                        .setCreateBy(loginUserId)
                        .setPoDetlId(item.getId());
                orderItems.add(orderItem);
                if (!deliveryItemService.update(new LambdaUpdateWrapper<DeliveryItem>()
                        .set(DeliveryItem::getWorkQty, item.getAnfme())
                        .eq(DeliveryItem::getId, item.getId()))) {
                    throw new CoolException("DO单明细修改失败!!");
                }
            });
            double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
            Double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
            //修改计划数量
            order.setAnfme(sum);
            order.setAnfme(sum).setWorkQty(0.0);
            if (!this.saveOrUpdate(order)) {
                throw new CoolException("主单数量修改失败!!");
            }
            if (!asnOrderItemService.saveBatch(orderItems)) {
                throw new CoolException("明细保存失败!!");
            }
            Short exceStatus = POExceStatus.PO_EXCE_STATUS_SECTION_DONE.val;
            if (delivery.getAnfme().compareTo(order.getAnfme()) <= 0) {
                exceStatus = AsnExceStatus.ASN_EXCE_STATUS_TASK_DONE.val;
            }
            if (!deliveryService.update(new LambdaUpdateWrapper<Delivery>()
                    .set(Delivery::getExceStatus, exceStatus)
                    .set(Delivery::getWorkQty, sum)
                    .eq(Delivery::getId, key))) {
                throw new CoolException("主单修改失败!!");
            }
        });
        return R.ok();
    }
rsf-server/src/main/resources/mapper/manager/AsnOrderItemMapper.xml
@@ -13,6 +13,7 @@
                    aoi.asn_code,
                    aoi.plat_item_id,
                    aoi.po_detl_id,
                    aoi.plat_work_code,
                    aoi.po_code,
                    aoi.fields_index,
                    aoi.matnr_id,
@@ -21,6 +22,7 @@
                    aoi.anfme,
                    aoi.stock_unit,
                    aoi.pur_qty,
                    aoi.work_qty,
                    aoi.pur_unit,
                    aoi.prod_time,
                    aoi.qty,
@@ -72,6 +74,7 @@
                    aoi.asn_id,
                    aoi.asn_code,
                    aoi.plat_item_id,
                    aoi.plat_work_code,
                    aoi.po_detl_id,
                    aoi.po_code,
                    aoi.fields_index,
@@ -80,6 +83,7 @@
                    aoi.maktx,
                    aoi.anfme,
                    aoi.stock_unit,
                    aoi.work_qty,
                    aoi.pur_qty,
                    aoi.pur_unit,
                    aoi.prod_time,