14个文件已修改
216 ■■■■ 已修改文件
rsf-admin/src/config/setting.js 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/delivery/DeliveryList.jsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderList.jsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/orders/outStock/OutStockPublic.jsx 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockItemController.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/DeliveryTemplate.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/OutStockTemplate.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/config/setting.js
@@ -39,4 +39,6 @@
export const LOGIN_BACKGROUND = 'media';  // image | media
export const CUSTOM_PAGES_DATA_INTERVAL = 1000;
export const CUSTOM_PAGES_DATA_INTERVAL = 1000;
export const DEFAULT_TYPE = 15; //默认效率优化  15:效率优化 16:先进先出
rsf-admin/src/i18n/en.js
@@ -1168,7 +1168,7 @@
        recover: "recover",
        createWave: "Create Wave",
        order: 'Orders',
        modiftySite: 'Modify SiteNo',
    },
    request: {
        error: {
rsf-admin/src/i18n/zh.js
@@ -1171,6 +1171,7 @@
        publicWorking: '下发执行',
        createWave: "生成波次",
        recover: "继续收货",
        modiftySite: '修改库口',
    },
    request: {
        error: {
rsf-admin/src/page/orders/delivery/DeliveryList.jsx
@@ -122,7 +122,7 @@
                    rowClick={(id, resource, record) => false}
                    expand={false}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'platId', 'platCode', 'memo', 'startTime', 'endTime', 'updateBy', 'createTime']}
                    omit={['id', 'createTime', 'createBy', 'platId', 'platCode', 'memo', 'startTime','qty', 'endTime', 'updateBy', 'createTime']}
                >
                    <NumberField source="id" />
                    <TextField source="code" label="table.field.delivery.code" />
@@ -131,7 +131,7 @@
                    <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="workQty" label="table.field.delivery.workQty" />
                    <NumberField source="workQty" label="table.field.delivery.qty" />
                    <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 />
rsf-admin/src/page/orders/outStock/OutOrderList.jsx
@@ -5,6 +5,7 @@
  DatagridConfigurable,
  SearchInput,
  TopToolbar,
  Toolbar,
  SelectColumnsButton,
  EditButton,
  FilterButton,
@@ -140,7 +141,7 @@
            <CreateByOrderButton setCreateDialog={setCreateDialog} />
            <MyCreateButton onClick={() => { setManualDialog(true); setmodalType(0) }} />
            <SelectColumnsButton preferenceKey='outStock' />
            <ImportButton value={'outStock'} />
            <ImportButton value={'outStockItem'} />
            {/* <MyExportButton /> */}
          </TopToolbar>
        )}
@@ -298,6 +299,6 @@
  }
  return (
    record.exceStatus == 10 ? <ConfirmButton label={"toolbar.publicWorking"} startIcon={<AddTaskIcon />} onConfirm={taskEvent} size={"small"} /> : <></>
    record.workQty < record.anfme ? <ConfirmButton label={"toolbar.publicWorking"} startIcon={<AddTaskIcon />} onConfirm={taskEvent} size={"small"} /> : <></>
  )
}
rsf-admin/src/page/orders/outStock/OutOrderModal.jsx
@@ -5,6 +5,7 @@
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    Toolbar,
    Button,
    SelectColumnsButton,
    EditButton,
@@ -94,7 +95,6 @@
    const [params, setParams] = useState({});
    const [drawerVal, setDrawerVal] = useState(false);
    const refresh = useRefresh();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
rsf-admin/src/page/orders/outStock/OutStockPublic.jsx
@@ -1,4 +1,4 @@
import { Box, Card, Grid, LinearProgress, Select, MenuItem, ListItemText, Tooltip, IconButton } from "@mui/material";
import { Box, Card, Grid, LinearProgress, Select, MenuItem, ListItemText } from "@mui/material";
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    List,
@@ -38,7 +38,7 @@
    useRefresh,
    useRedirect,
} from 'react-admin';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE } from '@/config/setting';
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE, DEFAULT_ITEM_PAGE_SIZE, DEFAULT_TYPE } from '@/config/setting';
import { styled } from '@mui/material/styles';
import { DataGrid, useGridApiContext, GridActionsCellItem, useGridApiRef } from '@mui/x-data-grid';
import request from '@/utils/request';
@@ -46,6 +46,7 @@
import CloseSharpIcon from '@mui/icons-material/CloseSharp';
import ConfirmButton from '../../components/ConfirmButton';
import { Delete, Edit, Add } from '@mui/icons-material';
import OutStockSiteDialog from "./OutStockSiteDialog";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
@@ -59,27 +60,47 @@
    }
}));
const OutStockPublic = (props) => {
    const { record, open, setOpen } = props;
    const notify = useNotify();
    const gridRef = useGridApiRef();
    const [rows, setRows] = useState({});
    const translate = useTranslate();
    const [selectedIds, setSelectedIds] = React.useState([]);
    const [selectedIds, setSelectedIds] = useState([]);
    const [formData, setFormData] = useState({
        orderId: record?.id
        orderId: record?.id,
        waveId: DEFAULT_TYPE
    });
    const [dialog, setDialog] = useState(false);
    const [selectedValue, setSelectedValue] = useState({});
    const handleClickOpen = () => {
        setDialog(true);
    };
    const handleClose = (value) => {
        setDialog(false);
        setSelectedValue(value);
        const newRows = rows.map(item => {
            return {
                ...item,
                siteNo: value?.site
            }
        })
        setRows(newRows);
    };
    useEffect(() => {
        getWaveRule()
    }, [formData, open])
        if (open) {
            getWaveRule()
        }
    }, [open, formData])
    const getWaveRule = async () => {
        if (formData.waveId == null && formData.waveId == undefined) {
            return
        }
        const { data: { code, data, msg } } = await request.post('/outStock/order/getOutTaskItems', { ...formData });
        if (code === 200) {
            setRows(data)
        } else {
@@ -109,6 +130,7 @@
                                    <AutocompleteInput
                                        label="table.field.waveRule.type"
                                        onChange={(e) => handleChange(e, 'waveId')}
                                        defaultValue={15}
                                        value={formData.type}
                                        validate={required()}
                                    />
@@ -157,30 +179,46 @@
                    <Grid item xl={6.3} gap={2}>
                        <Card>
                            <Box sx={{ height: 500, width: '100%' }}>
                                <PreviewTable rows={rows} gridRef={gridRef} setRows={setRows} record={record}/>
                                <PreviewTable
                                    rows={rows}
                                    gridRef={gridRef}
                                    setRows={setRows}
                                    record={record}
                                    selectedIds={selectedIds}
                                    setDialog={setDialog}
                                    setSelectedIds={setSelectedIds}
                                />
                            </Box>
                            <Box sx={{ textAlign: 'center' }}>
                                <CloseButton setOpen={setOpen} />
                                <SubmitButton selectedIds={selectedIds} setSelectedIds={setSelectedIds} gridRef={gridRef} record={record}/>
                                <SubmitButton selectedIds={selectedIds} setSelectedIds={setSelectedIds} gridRef={gridRef} record={record} />
                            </Box>
                        </Card>
                    </Grid>
                </Grid>
                <Grid>
                    <OutStockSiteDialog
                        selectedValue={selectedValue}
                        open={dialog}
                        onClose={handleClose}
                    />
                </Grid>
            </Box>
        </>
    );
}
const PreviewTable = ({ rows, gridRef, setRows, record }) => {
const PreviewTable = ({ rows, gridRef, setRows, record, selectedIds, setSelectedIds, setDialog }) => {
    gridRef.current = useGridApiRef();
    const columns = [
        { field: 'id', headerName: 'ID', width: 40 },
        // { field: 'id', headerName: 'ID', width: 40 },
        { field: 'locCode', headerName: '库位', width: 110 },
        { field: 'barcode', headerName: '容器', width: 120 },
        { field: 'matnrCode', headerName: '物料编码', width: 120 },
        { field: 'batch', headerName: '批次', width: 90 },
        { field: 'unit', headerName: '单位', width: 90 },
        { field: 'outQty', headerName: '本次出库数量', width: 110 },
        { field: 'unit', headerName: '单位', width: 60 },
        { field: 'outQty', headerName: '出库数量', width: 110 ,valueFormatter: (val) => val <= 0 ? '库存不足' : val,},
        {
            field: 'siteNo',
            headerName: '出库口',
@@ -214,8 +252,8 @@
     * @param {*} params 
     */
    const handleDelete = (params, rows, setRows) => {
        const outRows = rows.filter(row => {
             return row.id !== params.id
        const outRows = rows.filter(row => {
            return row.id !== params.id
        })
        setRows(outRows)
    }
@@ -233,6 +271,28 @@
            </Box>
        );
    });
    const CustomToolBar = () => {
        const selectSiteNo = () => {
            setDialog(true)
        }
        return (
            selectedIds.length > 0 ? <Box sx={{
                p: 1,
                display: 'flex',
                justifyContent: 'flex-end',
                borderTop: '1px solid rgba(224, 224, 224, 1)'
            }}>
                <Button
                    onClick={selectSiteNo}
                    variant="outlined"
                    label="toolbar.modiftySite"
                    size="medium"
                    sx={{ mr: 1 }} />
            </Box> : <></>
        );
    }
    const OutStockSite = (params) => {
        const { id, field, siteNo, row: { staNos } } = params;
@@ -288,6 +348,7 @@
        <DataGrid
            rows={rows}
            columns={columns}
            slots={{ toolbar: CustomToolBar }}
            apiRef={gridRef}
            initialState={{
                pagination: {
@@ -297,6 +358,7 @@
                },
            }}
            checkboxSelection
            disableRowSelectionOnClick
            pageSizeOptions={[15, 25, 35, 45]}
            onRowSelectionModelChange={(ids) => {
                setSelectedIds(ids)
@@ -305,6 +367,8 @@
    )
}
//提交按钮
const SubmitButton = ({ selectedIds, setSelectedIds, gridRef, record }) => {
    const notify = useNotify();
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockController.java
@@ -10,6 +10,7 @@
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.manager.controller.params.OrderOutTaskParam;
import com.vincent.rsf.server.manager.controller.params.OutStockToTaskParams;
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.annotation.OperationLog;
@@ -240,6 +241,7 @@
    }
    @PostMapping("/outStock/order/getOutTaskItems")
    @ApiOperation("出库单库位预览")
    @PreAuthorize("hasAuthority('manager:outStock:list')")
    public R getOrderOutTaskItem(@RequestBody OrderOutTaskParam param) {
        if (Cools.isEmpty(param)) {
@@ -271,5 +273,31 @@
        return  outStockService.genOutStockTask(taskParams, getLoginUserId(), Long.parseLong(params.get("outId").toString()));
    }
    /**
     * 获取出库站点
     * @return
     */
    @GetMapping("/outStock/tasks/sites")
    @ApiOperation("获取出库库口")
    @PreAuthorize("hasAuthority('manager:outStock:list')")
    public R getSiteNos() {
        return outStockService.getSiteNos();
    }
    /**
     * @author Ryan
     * @description 下载模板
     * @param
     * @return
     * @time 2025/4/18 08:17
     */
    @PostMapping("/outStock/template/download")
    @ApiOperation("下载收货单模板")
    @PreAuthorize("hasAuthority('manager:outStockItem:update')")
    public void downloadTemplate(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        OutStockTemplate template = ExcelUtil.mockData(OutStockTemplate.class);
        List<OutStockTemplate> list = Arrays.asList(template);
        ExcelUtil.build(ExcelUtil.create(list, OutStockTemplate.class, true), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/OutStockItemController.java
@@ -159,7 +159,7 @@
    @PostMapping("/outStockItem/import")
    @ApiOperation("ASN导入接口")
    @PreAuthorize("hasAuthority('manager:outStockItem:update')")
    public R importExcel(@RequestParam(value = "file") MultipartFile file, @RequestParam String asnId) throws Exception {
    public R importExcel(@RequestParam(value = "file") MultipartFile file) throws Exception {
        if (Objects.isNull(file)) {
            R.error("文件不能为空!!");
        }
@@ -167,20 +167,6 @@
        return outStockItemService.excelImport(file, hashMap, getLoginUserId());
    }
    /**
     * @author Ryan
     * @description 下载模板
     * @param
     * @return
     * @time 2025/4/18 08:17
     */
    @PostMapping("/outStockItem/template/download")
    @ApiOperation("下载收货单模板")
    @PreAuthorize("hasAuthority('manager:outStockItem:update')")
    public void downloadTemplate(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        AsnOrderTemplate template = ExcelUtil.mockData(AsnOrderTemplate.class);
        List<AsnOrderTemplate> list = Arrays.asList(template);
        ExcelUtil.build(ExcelUtil.create(list, AsnOrderTemplate.class, true), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/DeliveryTemplate.java
@@ -29,7 +29,7 @@
    @Excel(name = "单据类型")
    @ApiModelProperty(value= "单据类型")
    @ExcelComment(value = "type", example = "入库单")
    @ExcelComment(value = "type", example = "出库单")
    private String type;
    @Excel(name = "单据来源")
@@ -54,7 +54,7 @@
    @Excel(name = "业务类型")
    @ApiModelProperty(value= "业务类型")
    @ExcelComment(value = "wkType", example = "采购入库单")
    @ExcelComment(value = "wkType", example = "销售出库单")
    private String wkType;
    @Excel(name = "项目名称")
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/excel/OutStockTemplate.java
@@ -68,7 +68,7 @@
     */
    @Excel(name = "*单据类型")
    @ApiModelProperty(value = "*单据类型")
    @ExcelComment(value = "type", example = "入库单")
    @ExcelComment(value = "type", example = "出库单")
    private String type;
    /**
@@ -76,7 +76,7 @@
     */
    @Excel(name = "*业务类型")
    @ApiModelProperty(value = "*业务类型")
    @ExcelComment(value = "wkType", example = "采购入库单")
    @ExcelComment(value = "wkType", example = "销售出库单")
    private String wkType;
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/OutStockService.java
@@ -24,4 +24,6 @@
    R getOrderOutTaskItem(OrderOutTaskParam param);
    R genOutStockTask(List<OutStockToTaskParams> params, Long loginUserId, Long outId);
    R getSiteNos();
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockItemServiceImpl.java
@@ -11,6 +11,7 @@
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.AsnExceStatus;
import com.vincent.rsf.server.manager.enums.OrderType;
import com.vincent.rsf.server.manager.enums.OrderWorkType;
import com.vincent.rsf.server.common.domain.BaseParam;
@@ -101,9 +102,6 @@
    public R excelImport(MultipartFile file, HashMap<String, Object> hashMap, Long loginUserId) throws Exception {
        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<OutStockTemplate> resultList = result.getList();
@@ -111,7 +109,7 @@
        for (String key : listMap.keySet()) {
            OutStockTemplate template = listMap.get(key).stream().findFirst().get();
            AsnOrder asnOrder = outStockService.getOne(new LambdaQueryWrapper<AsnOrder>().eq(AsnOrder::getCode, template.getCode()));
            if (Objects.isNull(asnOrder)) {
            if (!Objects.isNull(asnOrder)) {
                continue;
            }
            AsnOrder order = new AsnOrder();
@@ -129,7 +127,7 @@
            for (OutStockTemplate orderTemplate : listMap.get(key)) {
                AsnOrderItem orderItem = new AsnOrderItem();
                Matnr matnr = null;
                if (!Objects.isNull(orderTemplate.getMatnrCode()) || StringUtils.isNotBlank(orderTemplate.getMatnrCode())) {
                if (StringUtils.isNotBlank(orderTemplate.getMatnrCode())) {
                    matnr = matnrService.getOne(new LambdaQueryWrapper<Matnr>()
                            .eq(Matnr::getCode, orderTemplate.getMatnrCode()));
                }
@@ -151,9 +149,10 @@
                }
            }
            if (!items.isEmpty()) {
                double qty = items.stream().mapToDouble(AsnOrderItem::getQty).sum();
                double purQty = items.stream().mapToDouble(AsnOrderItem::getPurQty).sum();
                if (!outStockService.update(new LambdaUpdateWrapper<AsnOrder>().set(AsnOrder::getQty, qty).set(AsnOrder::getAnfme, purQty).eq(AsnOrder::getId, order.getId()))) {
                double purQty = items.stream().mapToDouble(AsnOrderItem::getAnfme).sum();
                if (!outStockService.update(new LambdaUpdateWrapper<AsnOrder>()
                                .set(AsnOrder::getExceStatus, AsnExceStatus.OUT_STOCK_STATUS_TASK_INIT.val)
                        .set(AsnOrder::getAnfme, purQty).eq(AsnOrder::getId, order.getId()))) {
                    throw new CoolException("单据数量修改失败!!");
                }
            }
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/OutStockServiceImpl.java
@@ -510,6 +510,20 @@
        return R.ok();
    }
    /**
     * 获取出库站点
     * @return
     */
    @Override
    public R getSiteNos() {
        List<Integer> list = Arrays.asList(TaskType.TASK_TYPE_MERGE_OUT.type,
                TaskType.TASK_TYPE_OUT.type,
                TaskType.TASK_TYPE_MERGE_OUT.type,
                TaskType.TASK_TYPE_PICK_AGAIN_OUT.type);
        List<DeviceSite> sites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>().in(DeviceSite::getType, list).groupBy(DeviceSite::getSite));
        return R.ok(sites);
    }
    private List<LocItem> getEfficiencyFirstItemList(AsnOrderItem asnOrderItem) {
        LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>();
@@ -602,8 +616,23 @@
                        issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString()));
                    }
                }
                } else {
                }
            }
            if (issued.doubleValue() > 0) {
                LocItem locItem = new LocItem()
                        .setId(new Random().nextLong())
                        .setMatnrCode(asnOrderItem.getMatnrCode())
                        .setMaktx(asnOrderItem.getMaktx())
                        .setAnfme(0.00)
                        .setOutQty(0.00)
                        .setWorkQty(0.00)
                        .setUnit(asnOrderItem.getStockUnit())
                        .setBatch(asnOrderItem.getSplrBatch());
                OrderOutItemDto orderOutItemDto = new OrderOutItemDto();
                orderOutItemDto.setLocItem(locItem);
                list.add(orderOutItemDto);
            }
        }