skyouc
2025-06-06 c312a110ee4823a4a1f912a05e9648edc56f96e7
DO 单生成出库单功能优化
9个文件已修改
171 ■■■■ 已修改文件
rsf-admin/src/i18n/en.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderItemList.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderList.jsx 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/work/outBound/OutBoundList.jsx 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeliveryItemController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -602,7 +602,8 @@
            },
            outStockItem: {
                asnId: "ID",
                asnCode: "DO Code",
                asnCode: "Out Code",
                poCode: 'DO Code',
                poDetlId: "poDetlId",
                poDetlCode: "DO Detl Code",
                matnrId: "matnrId",
@@ -1156,6 +1157,7 @@
        asnCreate: "Create By Order",
        poCreate: "Create By PO",
        createTask: "createTask",
        publicWorking: 'Public Working',
        recover: "recover",
        createWave: "Create Wave",
        order: 'Orders',
rsf-admin/src/i18n/zh.js
@@ -662,6 +662,7 @@
            outStockItem: {
                asnId: "主单标识",
                asnCode: "单号",
                poCode: 'DO单号',
                poDetlId: "平台明细ID",
                poDetlCode: "DO单",
                matnrId: "物料标识",
@@ -1161,6 +1162,7 @@
        poCreate: "通过PO单创建",
        orderPrint: '打印单据',
        createTask: "下发任务",
        publicWorking: '下发执行',
        createWave: "生成波次",
        recover: "继续收货",
    },
rsf-admin/src/page/orders/outStock/OutOrderItemList.jsx
@@ -141,6 +141,7 @@
            <NumberField source="id" />
            <NumberField source="asnId" label="table.field.outStockItem.asnId" />
            <TextField source="asnCode" label="table.field.outStockItem.asnCode" />
            <TextField source="poCode" label="table.field.outStockItem.poCode" />
            <TextField source="poDetlId" label="table.field.outStockItem.poDetlId" />
            <TextField source="matnrId" label="table.field.outStockItem.matnrId" />
            <TextField source="matnrCode" label="table.field.outStockItem.matnrCode" />
rsf-admin/src/page/orders/outStock/OutOrderList.jsx
@@ -37,14 +37,11 @@
  useRedirect,
  useUnselectAll,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { Box, Typography, Card, Stack, Drawer } from '@mui/material';
import { styled } from '@mui/material/styles';
import EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import BillStatusField from '../../components/BillStatusField';
import ConfirmButton from '../../components/ConfirmButton';
import PageDrawer from "../../components/PageDrawer";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import EditIcon from '@mui/icons-material/Edit';
import request from '@/utils/request';
@@ -58,6 +55,7 @@
import PublicIcon from '@mui/icons-material/Public';
import SelectMatnrModal from "./SelectMatnrModal";
import AddTaskIcon from '@mui/icons-material/AddTask';
import PageEditDrawer from "../../components/PageEditDrawer";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
  '& .css-1vooibu-MuiSvgIcon-root': {
@@ -130,7 +128,6 @@
            theme.transitions.create(['all'], {
              duration: theme.transitions.duration.enteringScreen,
            }),
          marginRight: drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
        }}
        title={"menu.outStock"}
        empty={false}
@@ -152,16 +149,13 @@
        <StyledDatagrid
          sx={{ width: '100%' }}
          preferenceKey='outStock'
          bulkActionButtons={
            <PublicTaskButton />}
          bulkActionButtons={<PublicTaskButton />}
          rowClick={false}
          expandSingle={true}
          omit={['id', 'createTime', 'createBy', 'memo', 'poId', 'rleStatus$']}
          omit={['id', 'createTime', 'createBy', 'memo', 'rleStatus$']}
        >
          <NumberField source="id" />
          <TextField source="code" label="table.field.outStock.code" />
          <TextField source="poCode" label="table.field.outStock.poCode" />
          <NumberField source="poId" label="table.field.outStock.poId" />
          <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" />
@@ -179,7 +173,7 @@
            <MyButton setCreateDialog={setManualDialog} setmodalType={setmodalType} />
            <EditButton label="toolbar.detail" icon={(<DetailsIcon />)}></EditButton>
            <CancelButton />
            <PublicButton />
            <PublicButton setDrawerVal={setDrawerVal} drawerVal={drawerVal} />
          </WrapperField>
        </StyledDatagrid>
      </List>
@@ -197,11 +191,13 @@
        open={createDialog}
        setOpen={setCreateDialog}
      />
      <PageDrawer
        title='AsnOrder Detail'
      <PageEditDrawer
        title={"toolbar.publicWorking"}
        drawerVal={drawerVal}
        setDrawerVal={setDrawerVal}
      />
      >
      </PageEditDrawer>
    </Box >
  )
}
@@ -286,18 +282,20 @@
  }
  return (
    record?.exceStatus == 10 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />} onConfirm={cancelOrder} /> : <></>
    record?.exceStatus == 10 ? <ConfirmButton label={"toolbar.cancel"} startIcon={<CancelOutlinedIcon />} onConfirm={cancelOrder} size={"small"} /> : <></>
  )
}
const PublicButton = () => {
//下发执行
const PublicButton = ({ setDrawerVal }) => {
  const record = useRecordContext();
  const refresh = useRefresh();
  const taskEvent = () => {
    setDrawerVal(true)
    refresh();
  }
  return (
    <ConfirmButton label={"toolbar.createTask"} startIcon={<AddTaskIcon />} onConfirm={taskEvent} />
    <ConfirmButton label={"toolbar.publicWorking"} startIcon={<AddTaskIcon />} onConfirm={taskEvent} size={"small"} />
  )
}
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx
@@ -110,11 +110,9 @@
            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)
@@ -135,20 +133,18 @@
                        <TextInput
                            source="deliveryCode"
                            label="table.field.deliveryItem.deliveryCode"
                            defaultValue={params?.matnrName}
                            defaultValue={params?.deliveryCode}
                            onChange={handleChange}
                            resettable
                        />
                    </Stack>
                    <Stack>
                        <TextInput
                            source="matnrName"
                            source="maktx"
                            label="table.field.deliveryItem.matnrName"
                            defaultValue={params?.matnrName}
                            defaultValue={params?.maktx}
                            onChange={handleChange}
                            resettable
                        />
                    </Stack>
                    <Stack>
@@ -201,7 +197,7 @@
                <DialogContent>
                    <Grid item sx={24}>
                        <List
                            resource="deliveryItem"
                            resource="/deliveryItem/filters"
                            sx={{
                                flexGrow: 1,
                                transition: (theme) =>
@@ -223,13 +219,7 @@
                        >
                            <Box sx={{ position: 'relative', minHeight: "60vh", }}>
                                <LinearProgress
                                    sx={{
                                        height: "2px",
                                        position: 'absolute',
                                        top: 0,
                                        left: 0,
                                        right: 0,
                                    }}
                                    sx={{ height: "2px", position: 'absolute', top: 0, left: 0, right: 0, }}
                                />
                                <StyledDatagrid
                                    preferenceKey='deliveryItem'
@@ -242,7 +232,7 @@
                                    <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="maktx" 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" />
rsf-admin/src/page/work/outBound/OutBoundList.jsx
@@ -64,7 +64,6 @@
import { number } from "prop-types";
const OutBoundList = () => {
    const [createDialog, setCreateDialog] = useState(false);
    const [tabelData, setTableData] = useState([]);
    const [selectedRows, setSelectedRows] = useState([]);
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/DeliveryItemController.java
@@ -40,8 +40,6 @@
    private DeliveryItemService deliveryItemService;
    @Autowired
    private CompanysService companysService;
    @Autowired
    private DeliveryServiceImpl deliveryService;
    @PreAuthorize("hasAuthority('manager:deliveryItem:list')")
    @PostMapping("/deliveryItem/page")
@@ -49,6 +47,15 @@
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<DeliveryItem, BaseParam> pageParam = new PageParam<>(baseParam, DeliveryItem.class);
        QueryWrapper<DeliveryItem> wrapper = pageParam.buildWrapper(true);
        return R.ok().add(deliveryItemService.page(pageParam, wrapper));
    }
    @PreAuthorize("hasAuthority('manager:deliveryItem:list')")
    @PostMapping("/deliveryItem/filters/page")
    public R filter(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<DeliveryItem, BaseParam> pageParam = new PageParam<>(baseParam, DeliveryItem.class);
        QueryWrapper<DeliveryItem> wrapper = pageParam.buildWrapper(true);
        wrapper.apply("anfme > work_qty + qty ");
        return R.ok().add(deliveryItemService.page(pageParam, wrapper));
    }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -120,30 +120,25 @@
                    if (!deliveryItemService.updateById(deliveryItem)) {
                        throw new CoolException("DO单明细更新失败!!");
                    }
                    Delivery delivery = deliveryService.getOne(new LambdaQueryWrapper<Delivery>().eq(Delivery::getCode, orderItem.getPoCode()));
                    if (!Objects.isNull(delivery)) {
                        Double wkQty = Math.round((delivery.getWorkQty() - delivery.getAnfme()) * 10000) / 10000.0;
                        delivery.setWorkQty(wkQty.compareTo(0.0) >= 0 ? wkQty : 0).setExceStatus(POExceStatus.PO_EXCE_STATUS_UN_EXCE.val);
                        if (!deliveryService.updateById(delivery)) {
                            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("操作成功");
    }
@@ -166,37 +161,38 @@
            throw new CoolException("单据不存在!!");
        }
        Map<Long, List<DeliveryItem>> listMap = items.stream().collect(Collectors.groupingBy(DeliveryItem::getDeliveryId));
        //获取第一个ID
        Long deliveryId = items.stream().findFirst().get().getDeliveryId();
        Delivery delivery = deliveryService.getById(deliveryId);
        if (Objects.isNull(delivery)) {
            throw new CoolException("主单据不存在!!");
        }
        AsnOrder order = new AsnOrder();
        BeanUtils.copyProperties(delivery, order);
        String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_OUT_STOCK_CODE, order);
        if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) {
            throw new CoolException("编码规则错误:请检查 「SYS_OUT_STOCK_CODE」编码是否设置成功");
        }
        order.setExceStatus(AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
                .setType(delivery.getType())
                .setWkType(delivery.getWkType())
                .setCode(ruleCode)
                .setId(null)
                .setUpdateBy(loginUserId)
                .setCreateBy(loginUserId);
        if (!this.save(order)) {
            throw new CoolException("主单保存失败!!");
        }
        listMap.keySet().forEach(key -> {
            //TODO 判断单据是否已经存在,如存在则累加修改子表,不存在才新建
            Delivery delivery = deliveryService.getById(key);
            if (Objects.isNull(delivery)) {
                throw new CoolException("单据不存在!!");
            }
            AsnOrder order = new AsnOrder();
            BeanUtils.copyProperties(delivery, order);
            String ruleCode = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_OUT_STOCK_CODE, order);
            if (Objects.isNull(ruleCode) || StringUtils.isBlank(ruleCode)) {
                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("主单保存失败!!");
            }
            Delivery delivery1 = deliveryService.getById(key);
            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())
                        .setPoCode(delivery1.getCode())
                        .setMaktx(item.getMaktx())
                        .setMatnrCode(item.getMatnrCode())
                        .setFieldsIndex(item.getFieldsIndex())
@@ -210,6 +206,7 @@
                        .setPlatOrderCode(item.getPlatOrderCode())
                        .setProjectCode(item.getProjectCode())
                        .setPlatItemId(item.getPlatItemId())
                        .setFieldsIndex(item.getFieldsIndex())
                        .setUpdateBy(loginUserId)
                        .setCreateBy(loginUserId)
                        .setPoDetlId(item.getId());
@@ -223,17 +220,13 @@
            });
            Double sum = orderItems.stream().mapToDouble(AsnOrderItem::getAnfme).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) {
            if (delivery1.getAnfme().compareTo(sum) <= 0) {
                exceStatus = AsnExceStatus.ASN_EXCE_STATUS_TASK_DONE.val;
            }
@@ -243,8 +236,15 @@
                    .eq(Delivery::getId, key))) {
                throw new CoolException("主单修改失败!!");
            }
        });
        Double sum = items.stream().mapToDouble(DeliveryItem::getAnfme).sum();
        //修改计划数量
        order.setAnfme(sum).setWorkQty(0.0);
        if (!this.saveOrUpdate(order)) {
            throw new CoolException("主单数量修改失败!!");
        }
        return R.ok();
    }
rsf-server/src/main/resources/application.yml
@@ -25,7 +25,7 @@
  #  global-config:
  #    field-strategy: 0
  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    cache-enabled: true
    call-setters-on-nulls: true