verou
2025-03-10 dfe8dff347916be46691fc5d956c45880c4446de
fix:规则子项
7个文件已添加
27 文件已重命名
22个文件已修改
924 ■■■■ 已修改文件
rsf-admin/src/i18n/en.js 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/zh.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/ResourceContent.js 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocCreate.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocEdit.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocList.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/LocPanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/basicInfo/loc/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictData/DictDataCreate.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictData/DictDataEdit.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictData/DictDataList.jsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictData/DictDataPanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictData/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictType/DictTypeCreate.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictType/DictTypeEdit.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictType/DictTypeList.jsx 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictType/DictTypePanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/dicts/dictType/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRule/SerialRuleCreate.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRule/SerialRuleDetail.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRule/SerialRuleEdit.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRule/SerialRuleList.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRule/SerialRulePanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRule/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemCreate.jsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemEdit.jsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemList.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemPanel.jsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/system/serialRuleItem/index.jsx 补丁 | 查看 | 原始文档 | blame | 历史
rsf-common/src/main/java/com/vincent/rsf/common/domain/CommonReponse.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/asnOrder.sql 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/asnOrderItem.sql 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/config/RemotesInfoProperties.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/config/RestTemplateConfig.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/PoItemsDto.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/ErpInspectItem.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/ErpInspectParams.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/ErpApiService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ErpApiServiceImpl.java 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/common/config/SysStockProperties.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrder.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/PurchaseItem.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/PurchaseMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/AsnOrderService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/utils/SerialRuleUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/purchase.sql 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/purchaseItem.sql 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/application-dev.yml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/application-prod.yml 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/manager/PurchaseMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/i18n/en.js
@@ -135,6 +135,10 @@
        companys: 'Companys',
        serialRuleItem: 'SerialRuleItem',
        serialRule: 'SerialRule',
        asnOrder: 'AsnOrder',
        asnOrderItem: 'AsnOrderItem',
        purchase: 'Purchase',
        purchaseItem: 'PurchaseItem',
        whMat: 'Warehouse Mat',
    },
    table: {
@@ -396,7 +400,85 @@
                size: "size",
                minWeight: "minWeight",
                maxWeight: "maxWeight",
            }
            },
            asnOrder: {
                code: "Code",
                poCode: "poCode",
                poId: "poId",
                type: "Type",
                wkType: "wkType",
                anfme: "anfme",
                qty: "qty",
                logisNo: "logisNo",
                arrTime: "Arrived",
                rleStatus: "Release",
                ntyStatus: "Notify",
            },
            asnOrderItem: {
                asnId: "asnId",
                asnCode: "asnCode",
                poDetlId: "poDetlId",
                poDetlCode: "poDetlCode",
                matnrId: "matnrId",
                matnk: "matnk",
                anfme: "anfme",
                stockUnit: "stockUnit",
                purQty: "purQty",
                purUnit: "purUnit",
                qty: "qty",
                splrCode: "splrCode",
                splrName: "splrName",
                qrcode: "qrcode",
                barcode: "barcode",
                packName: "packName",
                ntyStatus: "ntyStatus",
            },
            purchaseItem: {
                purchaseId: "purchaseId",
                erpItemId: "erpItemId",
                matnrCode: "matnrCode",
                matnrName: "matnrName",
                unit: "unit",
                anfme: "anfme",
                qty: "qty",
                nromQty: "nromQty",
                asnQty: "asnQty",
                printQty: "printQty",
                splrName: "splrName",
                splrCode: "splrCode",
                splrBatch: "splrBatch",
            },
            purchase: {
                code: "code",
                erpId: "erpId",
                type: "type",
                wkType: "wkType",
                source: "source",
                preArr: "preArr",
                anfme: "anfme",
                qty: "qty",
                workQty: "workQty",
                channel: "channel",
                erpCode: "erpCode",
                project: "project",
                startTime: "startTime",
                endTime: "endTime",
            },
            purchaseItem: {
                purchaseId: "purchaseId",
                erpItemId: "erpItemId",
                matnrCode: "matnrCode",
                matnrName: "matnrName",
                unit: "unit",
                anfme: "anfme",
                qty: "qty",
                nromQty: "nromQty",
                asnQty: "asnQty",
                printQty: "printQty",
                splrName: "splrName",
                splrCode: "splrCode",
                splrBatch: "splrBatch",
            },
        }
    },
    page: {
rsf-admin/src/i18n/zh.js
@@ -134,6 +134,10 @@
        companys: '往来企业',
        serialRuleItem: '编码规则子表',
        serialRule: '编码规则',
        asnOrder: '收货通知单',
        asnOrderItem: '收货明细',
        purchase: 'PO单',
        purchaseItem: 'PO单明细',
        whMat: '库区物料关系',
    },
    table: {
@@ -396,7 +400,70 @@
                size: "尺寸",
                minWeight: "最小重量",
                maxWeight: "最大重量",
            }
            },
            asnOrder: {
                code: "编码",
                poCode: "PO编码",
                poId: "PO标识",
                type: "单据类型",
                wkType: "业务类型",
                anfme: "数量",
                qty: "已完成数量",
                logisNo: "logisNo",
                arrTime: "预计到达时间",
                rleStatus: "释放状态",
                ntyStatus: "质检上报状态",
            },
            asnOrderItem: {
                asnId: "主单标识",
                asnCode: "主单编码",
                poDetlId: "PO单标识",
                poDetlCode: "PO单编码",
                matnrId: "物料标识",
                matnk: "物料名称",
                anfme: "数量",
                stockUnit: "库存单位",
                purQty: "采购数量",
                purUnit: "采购单位",
                qty: "已完成数量",
                splrCode: "供应商编码",
                splrName: "供应商名称",
                qrcode: "二维码",
                barcode: "条形码",
                packName: "包装名称",
                ntyStatus: "报检状态",
            },
            purchase: {
                code: "编码",
                erpId: "erp标识",
                type: "单据类型",
                wkType: "业务类型",
                source: "来源",
                preArr: "预计到达",
                anfme: "数量",
                qty: "已完成数量",
                workQty: "执行中数量",
                channel: "收货通道",
                erpCode: "Erp编码",
                project: "项目名称",
                startTime: "开始时间",
                endTime: "结束时间",
            },
            purchaseItem: {
                purchaseId: "PO主单标识",
                erpItemId: "erp明细标识",
                matnrCode: "物料编码",
                matnrName: "物料名称",
                unit: "计量单位",
                anfme: "数量",
                qty: "已完成",
                nromQty: "标包数量",
                asnQty:  "单据数量",
                printQty: "打印数量",
                splrName: "供应商名称",
                splrCode: "供应商编码",
                splrBatch: "供应商批次",
            },
        }
    },
    page: {
rsf-admin/src/page/ResourceContent.js
@@ -17,16 +17,20 @@
import matnrGroup from './basicInfo/matnrGroup';
import warehouse from './basicInfo/warehouse';
import warehouseAreas from './warehouseAreas';
import loc from './loc';
import loc from './basicInfo/loc';
import container from './container';
import contract from './contract';
import qlyInspect from './qlyInspect';
import dictType from './dictType';
import dictData from './dictData';
import dictType from './system/dicts/dictType';
import dictData from './system/dicts/dictData';
import companys from './basicInfo/companys';
import serialRuleItem from './serialRuleItem';
import serialRule from './serialRule';
import serialRuleItem from './system/serialRuleItem';
import serialRule from './system/serialRule';
import whMat from './basicInfo/whMat';
import asnOrder from './asnOrder';
import asnOrderItem from './asnOrderItem';
import purchaseItem from './purchaseItem';
import purchase from './purchase';
const ResourceContent = (node) => {
@@ -77,6 +81,14 @@
            return serialRule;
        case 'whMat':
            return whMat;
        case 'asnOrder':
            return asnOrder;
        case 'asnOrderItem':
            return asnOrderItem;
        case 'purchaseItem':
            return purchaseItem;
        case 'purchase':
            return purchase;
        default:
            return {
                list: ListGuesser,
rsf-admin/src/page/basicInfo/loc/LocCreate.jsx
File was renamed from rsf-admin/src/page/loc/LocCreate.jsx
@@ -27,9 +27,9 @@
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import MemoInput from "../../components/MemoInput";
const LocCreate = (props) => {
    const { open, setOpen } = props;
rsf-admin/src/page/basicInfo/loc/LocEdit.jsx
File was renamed from rsf-admin/src/page/loc/LocEdit.jsx
@@ -24,10 +24,10 @@
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import MemoInput from "../../components/MemoInput";
import StatusSelectInput from "../../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
rsf-admin/src/page/basicInfo/loc/LocList.jsx
File was renamed from rsf-admin/src/page/loc/LocList.jsx
@@ -36,11 +36,11 @@
import { styled } from '@mui/material/styles';
import LocCreate from "./LocCreate";
import LocPanel from "./LocPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import EmptyData from "../../components/EmptyData";
import MyCreateButton from "../../components/MyCreateButton";
import MyExportButton from '../../components/MyExportButton';
import PageDrawer from "../../components/PageDrawer";
import MyField from "../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
rsf-admin/src/page/basicInfo/loc/LocPanel.jsx
File was renamed from rsf-admin/src/page/loc/LocPanel.jsx
@@ -4,7 +4,7 @@
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import PanelTypography from "../../components/PanelTypography";
import * as Common from '@/utils/common'
const LocPanel = () => {
rsf-admin/src/page/basicInfo/loc/index.jsx
rsf-admin/src/page/system/dicts/dictData/DictDataCreate.jsx
File was renamed from rsf-admin/src/page/dictData/DictDataCreate.jsx
@@ -27,9 +27,9 @@
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
import DialogCloseButton from "../../../components/DialogCloseButton";
import StatusSelectInput from "../../../components/StatusSelectInput";
import MemoInput from "../../../components/MemoInput";
const DictDataCreate = (props) => {
    const { open, setOpen } = props;
rsf-admin/src/page/system/dicts/dictData/DictDataEdit.jsx
File was renamed from rsf-admin/src/page/dictData/DictDataEdit.jsx
@@ -24,10 +24,10 @@
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
import EditBaseAside from "../../../components/EditBaseAside";
import CustomerTopToolBar from "../../../components/EditTopToolBar";
import MemoInput from "../../../components/MemoInput";
import StatusSelectInput from "../../../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
rsf-admin/src/page/system/dicts/dictData/DictDataList.jsx
File was renamed from rsf-admin/src/page/dictData/DictDataList.jsx
@@ -36,14 +36,14 @@
import { styled } from '@mui/material/styles';
import DictDataCreate from "./DictDataCreate";
import DictDataPanel from "./DictDataPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import EmptyData from "../../../components/EmptyData";
import MyCreateButton from "../../../components/MyCreateButton";
import MyExportButton from '../../../components/MyExportButton';
import PageDrawer from "../../../components/PageDrawer";
import MyField from "../../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
import CustomerTopToolBar from "../components/EditTopToolBar";
import CustomerTopToolBar from "../../../components/EditTopToolBar";
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
rsf-admin/src/page/system/dicts/dictData/DictDataPanel.jsx
File was renamed from rsf-admin/src/page/dictData/DictDataPanel.jsx
@@ -4,7 +4,7 @@
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import PanelTypography from "../../../components/PanelTypography";
import * as Common from '@/utils/common'
const DictDataPanel = () => {
rsf-admin/src/page/system/dicts/dictData/index.jsx
rsf-admin/src/page/system/dicts/dictType/DictTypeCreate.jsx
File was renamed from rsf-admin/src/page/dictType/DictTypeCreate.jsx
@@ -27,9 +27,9 @@
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
import DialogCloseButton from "../../../components/DialogCloseButton";
import StatusSelectInput from "../../../components/StatusSelectInput";
import MemoInput from "../../../components/MemoInput";
const DictTypeCreate = (props) => {
    const { open, setOpen } = props;
rsf-admin/src/page/system/dicts/dictType/DictTypeEdit.jsx
File was renamed from rsf-admin/src/page/dictType/DictTypeEdit.jsx
@@ -24,10 +24,10 @@
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
import EditBaseAside from "../../../components/EditBaseAside";
import CustomerTopToolBar from "../../../components/EditTopToolBar";
import MemoInput from "../../../components/MemoInput";
import StatusSelectInput from "../../../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
rsf-admin/src/page/system/dicts/dictType/DictTypeList.jsx
File was renamed from rsf-admin/src/page/dictType/DictTypeList.jsx
@@ -36,11 +36,11 @@
import { styled } from '@mui/material/styles';
import DictTypeCreate from "./DictTypeCreate";
import DictTypePanel from "./DictTypePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import EmptyData from "../../../components/EmptyData";
import MyCreateButton from "../../../components/MyCreateButton";
import MyExportButton from '../../../components/MyExportButton';
import PageDrawer from "../../../components/PageDrawer";
import MyField from "../../../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
rsf-admin/src/page/system/dicts/dictType/DictTypePanel.jsx
File was renamed from rsf-admin/src/page/dictType/DictTypePanel.jsx
@@ -4,7 +4,7 @@
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import PanelTypography from "../../../components/PanelTypography";
import * as Common from '@/utils/common'
const DictTypePanel = () => {
rsf-admin/src/page/system/dicts/dictType/index.jsx
rsf-admin/src/page/system/serialRule/SerialRuleCreate.jsx
rsf-admin/src/page/system/serialRule/SerialRuleDetail.jsx
rsf-admin/src/page/system/serialRule/SerialRuleEdit.jsx
File was renamed from rsf-admin/src/page/serialRule/SerialRuleEdit.jsx
@@ -24,10 +24,10 @@
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import MemoInput from "../../components/MemoInput";
import StatusSelectInput from "../../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
rsf-admin/src/page/system/serialRule/SerialRuleList.jsx
rsf-admin/src/page/system/serialRule/SerialRulePanel.jsx
File was renamed from rsf-admin/src/page/serialRule/SerialRulePanel.jsx
@@ -4,7 +4,7 @@
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import PanelTypography from "../../components/PanelTypography";
import * as Common from '@/utils/common'
const SerialRulePanel = () => {
rsf-admin/src/page/system/serialRule/index.jsx
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemCreate.jsx
File was renamed from rsf-admin/src/page/serialRuleItem/SerialRuleItemCreate.jsx
@@ -27,9 +27,9 @@
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
import DialogCloseButton from "../../components/DialogCloseButton";
import StatusSelectInput from "../../components/StatusSelectInput";
import MemoInput from "../../components/MemoInput";
const SerialRuleItemCreate = (props) => {
    const { open, setOpen } = props;
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemEdit.jsx
File was renamed from rsf-admin/src/page/serialRuleItem/SerialRuleItemEdit.jsx
@@ -24,10 +24,10 @@
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
import EditBaseAside from "../../components/EditBaseAside";
import CustomerTopToolBar from "../../components/EditTopToolBar";
import MemoInput from "../../components/MemoInput";
import StatusSelectInput from "../../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemList.jsx
rsf-admin/src/page/system/serialRuleItem/SerialRuleItemPanel.jsx
File was renamed from rsf-admin/src/page/serialRuleItem/SerialRuleItemPanel.jsx
@@ -4,7 +4,7 @@
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import PanelTypography from "../../components/PanelTypography";
import * as Common from '@/utils/common'
const SerialRuleItemPanel = () => {
rsf-admin/src/page/system/serialRuleItem/index.jsx
rsf-common/src/main/java/com/vincent/rsf/common/domain/CommonReponse.java
New file
@@ -0,0 +1,31 @@
package com.vincent.rsf.common.domain;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Map;
/***
 * 下发任务响应Bean
 */
@Data
@Accessors(chain = true)
public class CommonReponse implements Serializable {
    /***
     * 响应状态码。
     * 0:表示接口请求成功。
     * 其他值:表示接口请求失败,详细信息请参考错误码。
     */
    private Integer code;
    /**
     *返回信息说明。
     * 成功:"success"。
     * 其他:详细描述。
     * */
    private String msg;
    /**
     *返回的响应数据结构。
     * */
    private Map<String, Object> data;
}
rsf-server/src/main/java/asnOrder.sql
@@ -23,6 +23,7 @@
    arrTime: "arrTime",
    rleStatus: "rleStatus",
    name: "name",
    ntyStatus: "ntyStatus",
},
-- ResourceContent
rsf-server/src/main/java/asnOrderItem.sql
@@ -2,10 +2,10 @@
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.asnOrderItem', '0', '/manager/asnOrderItem', 'asnOrderItem', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query ASN单据', '', '1', 'manager:asnOrderItem:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create ASN单据', '', '1', 'manager:asnOrderItem:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update ASN单据', '', '1', 'manager:asnOrderItem:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete ASN单据', '', '1', 'manager:asnOrderItem:remove', '3', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query ASN单据', '139', '1', 'manager:asnOrderItem:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create ASN单据', '139', '1', 'manager:asnOrderItem:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update ASN单据', '139', '1', 'manager:asnOrderItem:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete ASN单据', '139', '1', 'manager:asnOrderItem:remove', '3', '1', '1');
-- locale menu name
asnOrderItem: 'AsnOrderItem',
@@ -28,6 +28,7 @@
    qrcode: "qrcode",
    barcode: "barcode",
    packName: "packName",
    ntyStatus: "ntyStatus",
},
-- ResourceContent
rsf-server/src/main/java/com/vincent/rsf/server/api/config/RemotesInfoProperties.java
New file
@@ -0,0 +1,46 @@
package com.vincent.rsf.server.api.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 * @author Ryan
 * @version 1.0
 * @title RemotesInfoProperties
 * @description
 * @create 2025/3/7 09:48
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "platform.erp")
public class RemotesInfoProperties {
    /**
     * 接口host
     */
    private String host;
    /**
     * 端口号
     */
    private String port;
    /**
     * 接口链接前缀
     */
    private String prePath;
    @Data
    @Configuration
    @ConfigurationProperties(prefix = "platform.erp.api")
    public class ApiInfo {
        /**
         * 一键上报质检接口
         */
        private String notifyInspect;
    }
    public String getBaseUrl() {
        return  this.host + ":" + this.port + "/" + this.prePath;
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/api/config/RestTemplateConfig.java
New file
@@ -0,0 +1,22 @@
package com.vincent.rsf.server.api.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
 * @author Ryan
 * @version 1.0
 * @title RestTemplateConfig
 * @description
 * @create 2025/3/7 10:01
 */
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate getInstant() {
        return  new RestTemplate();
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/dto/PoItemsDto.java
New file
@@ -0,0 +1,43 @@
package com.vincent.rsf.server.api.entity.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
 * @author Ryan
 * @version 1.0
 * @title PoItemsDto
 * @description
 * @create 2025/3/7 08:49
 */
@Data
@Accessors(chain = true)
@ApiModel(value = "PoItemsDto", description = "PO单据")
public class PoItemsDto implements Serializable {
    @ApiModelProperty("PO单明细标识")
    private String id;
    @ApiModelProperty("PO主单标识")
    private String purchaseId;
    @ApiModelProperty("Erp明细单标识")
    private String erpItemId;
    @ApiModelProperty("物料编码")
    private String matnrCode;
    @ApiModelProperty("物料名称")
    private String matnrName;
    @ApiModelProperty("计量单位")
    private String unit;
    @ApiModelProperty("数量")
    private String anfme;
}
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/ErpInspectItem.java
New file
@@ -0,0 +1,38 @@
package com.vincent.rsf.server.api.entity.params;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
/**
 * @author Ryan
 * @version 1.0
 * @title ErpInspectItem
 * @description
 * @create 2025/3/7 09:35
 */
@Data
@Accessors(chain = true)
@ApiModel(value = "ErpInspectItem", description = "Erp质检单据明细")
public class ErpInspectItem {
    /**
     * erp明细编码
     */
    public String poItemId;
    /**
     * 物料编码
     */
    public String matnrCode;
    /**
     * 计量单位
     */
    public String unit;
    /**
     * 数量
     */
    public Double anfme;
}
rsf-server/src/main/java/com/vincent/rsf/server/api/entity/params/ErpInspectParams.java
New file
@@ -0,0 +1,36 @@
package com.vincent.rsf.server.api.entity.params;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
 * @author Ryan
 * @version 1.0
 * @title ErpInspectParams
 * @description
 * @create 2025/3/6 15:08
 */
@Data
@Accessors(chain = true)
@ApiModel(value = "ErpInspectParams", description = "Erp质检单据")
public class ErpInspectParams implements Serializable {
    /**
     * 主单标识
     */
    public String poId;
    /**
     * 主单编码
     */
    private String poCode;
    /**
     * 质检明细
     */
    private List<ErpInspectItem> children;
}
rsf-server/src/main/java/com/vincent/rsf/server/api/service/ErpApiService.java
@@ -2,6 +2,7 @@
import com.vincent.rsf.server.api.controller.params.Order;
import com.vincent.rsf.server.api.entity.dto.PoItemsDto;
import java.util.List;
@@ -15,4 +16,6 @@
public interface ErpApiService {
    boolean syncPurchasee(List<Order> orders);
    boolean reportInspectNotify(List<PoItemsDto> items);
}
rsf-server/src/main/java/com/vincent/rsf/server/api/service/impl/ErpApiServiceImpl.java
@@ -1,10 +1,21 @@
package com.vincent.rsf.server.api.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.vincent.rsf.common.domain.CommonReponse;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.controller.params.OrderItem;
import com.vincent.rsf.server.api.config.RemotesInfoProperties;
import com.vincent.rsf.server.api.entity.dto.PoItemsDto;
import com.vincent.rsf.server.api.entity.enums.OrderType;
import com.vincent.rsf.server.api.entity.params.ErpInspectItem;
import com.vincent.rsf.server.api.entity.params.ErpInspectParams;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import com.vincent.rsf.server.manager.entity.AsnOrderItem;
import com.vincent.rsf.server.manager.entity.PurchaseItem;
import com.vincent.rsf.server.manager.service.AsnOrderItemService;
import com.vincent.rsf.server.manager.service.AsnOrderService;
import com.vincent.rsf.server.manager.service.PurchaseItemService;
import com.vincent.rsf.server.manager.service.PurchaseService;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
@@ -12,13 +23,21 @@
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import com.vincent.rsf.server.api.service.ErpApiService;
import com.vincent.rsf.server.manager.entity.Purchase;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author Ryan
@@ -27,14 +46,26 @@
 * @description
 * @create 2025/3/4 16:27
 */
@Service
public class ErpApiServiceImpl extends ServiceImpl implements ErpApiService {
@Slf4j
@Service("erpApiService")
public class ErpApiServiceImpl implements ErpApiService {
    @Autowired
    private PurchaseService purchaseService;
    @Autowired
    private PurchaseItemService purchaseItemService;
    @Autowired
    private AsnOrderService asnOrderService;
    @Autowired
    private AsnOrderItemService asnOrderItemService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RemotesInfoProperties remotesInfoProperties;
    @Autowired
    private RemotesInfoProperties.ApiInfo apiInfo;
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -69,4 +100,106 @@
        return true;
    }
    /**
     * @author Ryan
     * @description 上报质检列表
     * @params [items 列表]
     * @return boolean
     * @time 2025/3/7 09:12
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean reportInspectNotify(List<PoItemsDto> items) {
        if (items.isEmpty()) {
            throw new CoolException("上报内容为空!!");
        }
        List<ErpInspectParams> inspectParams =  new ArrayList<>();
        Map<String, List<PoItemsDto>> listMap = items.stream().collect(Collectors.groupingBy(PoItemsDto::getPurchaseId));
        listMap.keySet().forEach(key -> {
            Purchase purchase = purchaseService.getOne(new LambdaQueryWrapper<Purchase>().eq(Purchase::getId, Long.valueOf(key)));
            if (Objects.isNull(purchase)) {
                throw new CoolException("采购单信息有误!!");
            }
            ErpInspectParams params = new ErpInspectParams();
            List<ErpInspectItem> inspectItems = new ArrayList<>();
            //赋值erp主单编码,编号
            params.setPoId(purchase.getErpId())
                    .setPoCode(purchase.getErpCode());
            List<PoItemsDto> dtos = listMap.get(key);
            if (dtos.isEmpty()) {
                throw new CoolException("单据信息错误!!");
            }
            dtos.forEach(dto -> {
                ErpInspectItem inspect= new ErpInspectItem();
                BeanUtils.copyProperties(dto, inspect);
                //赋值erp明细编码
                inspect.setPoItemId(dto.getErpItemId());
                inspectItems.add(inspect);
            });
            params.setChildren(inspectItems);
            inspectParams.add(params);
        });
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        //获取上报质检接口
        String url = remotesInfoProperties.getBaseUrl() + apiInfo.getNotifyInspect();
        // 设置请求参数
        params.add("params", JSONObject.toJSONString(inspectParams));
        log.info("请求地址:{},请求参数:{}", url, JSONObject.toJSONString(inspectParams));
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        HttpEntity httpEntity = new HttpEntity<>(params, headers);
        // 请求
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        log.info("下发任务 返回结果:{}", exchange);
        if (Objects.isNull(exchange.getBody()) || exchange.getBody() == null) {
            throw new CoolException("下发任务失败!!");
        } else {
            CommonReponse reponse = (CommonReponse) JSON.parse(exchange.getBody());
            if (reponse.getCode() == 0) {
                //修改asn上报状态
                Set<String> itemSets = items.stream().map(PoItemsDto::getId).collect(Collectors.toSet());
                Set<Long> longSet = new HashSet<>();
                itemSets.forEach(set -> {
                    longSet.add(Long.parseLong(set));
                });
                List<AsnOrderItem> asnOrderItems = asnOrderItemService.list(new LambdaQueryWrapper<AsnOrderItem>().in(AsnOrderItem::getPoDetlId, longSet));
                if (asnOrderItems.isEmpty()) {
                    throw new CoolException("ASN单据不存在!!");
                }
                List<Long> list = asnOrderItems.stream().map(AsnOrderItem::getId).collect(Collectors.toList());
                /**************************     修改ASN明细单状态         ******************************/
                if (!asnOrderItemService.update(new LambdaUpdateWrapper<AsnOrderItem>().in(AsnOrderItem::getId, list).set(AsnOrderItem::getStatus, 1))) {
                    throw new CoolException("ASN明细单据状态修改失败!!");
                }
                /**************************     修改ASN主单数据         ******************************/
                //获取ASN明细订单标识
                List<Long> ids = asnOrderItems.stream().map(AsnOrderItem::getAsnId).collect(Collectors.toList());
                //ASN明细单据分组
                Map<Long, List<AsnOrderItem>> asnIds = asnOrderItems.stream().collect(Collectors.groupingBy(AsnOrderItem::getAsnId));
                ids.forEach(id -> {
                    int count = asnOrderService.count(new LambdaQueryWrapper<AsnOrder>().in(AsnOrder::getId, id));
                    if (count == asnIds.get(id).size()) {
                        if (!asnOrderService.update(new LambdaUpdateWrapper<AsnOrder>().eq(AsnOrder::getId, id).set(AsnOrder::getStatus, 1))) {
                            throw new CoolException("ASN主单状态修改失败!!");
                        }
                    } else {
                        if (!asnOrderService.update(new LambdaUpdateWrapper<AsnOrder>().eq(AsnOrder::getId, id).set(AsnOrder::getStatus, 2))) {
                            throw new CoolException("ASN主单状态修改失败!!");
                        }
                    }
                });
                return true;
            } else {
                throw new CoolException(reponse.getMsg());
            }
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/common/CodeBuilder.java
@@ -22,8 +22,8 @@
//        generator.username="sa";
//        generator.password="Zoneyung@zy56$";
        generator.table="man_asn_order_item";
        generator.tableDesc="ASN单据";
        generator.table="man_purchase_item";
        generator.tableDesc="采购明细单";
        generator.packagePath="com.vincent.rsf.server.manager";
        generator.build();
@@ -31,7 +31,7 @@
/*
 CREATE TABLE `man_tablename` (
 `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
 `uuid` VARCHAR(255) DEFAULT NULL COMMENT '编号',
 `code` VARCHAR(255) DEFAULT NULL COMMENT '编号',
 `name` VARCHAR(255) DEFAULT NULL COMMENT '名称(*)',
 `status` INT(1) NOT NULL DEFAULT '1' COMMENT '状态{1:正常,0:冻结}',
 `deleted` INT(1) NOT NULL DEFAULT '0' COMMENT '是否删除{1:是,0:否}',
rsf-server/src/main/java/com/vincent/rsf/server/common/config/SysStockProperties.java
New file
@@ -0,0 +1,48 @@
package com.vincent.rsf.server.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 * @author Ryan
 * @version 1.0
 * @title SysStockFlowProperties
 * @description
 * @create 2025/3/5 17:02
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "stock")
public class SysStockProperties {
    /**
     * wms是否允许打印货物标签, 默认可打印
     */
    private Boolean flagPrinter;
    /**
     * 是否自动生成ASN单(默认:是),为『否』则开启PO单手动生成ASN单功能
     */
    private Boolean flagAutoAsn;
    @Data
    @Configuration
    @ConfigurationProperties(prefix = "stock.inspect")
    public class InspectProperties {
        /**
         * 是否开启上架校验
         */
        private Boolean flagAvailable;
        /**
         * 是否开启收货校验, 上架校验和收货校验,只会开启一个
         */
        private Boolean flagReceiving;
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/controller/AsnOrderController.java
@@ -12,6 +12,7 @@
import com.vincent.rsf.server.manager.entity.AsnOrder;
import com.vincent.rsf.server.manager.service.AsnOrderService;
import com.vincent.rsf.server.system.controller.BaseController;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@@ -20,6 +21,7 @@
import java.util.*;
@RestController
@Api(tags = "ASN入库通知单")
public class AsnOrderController extends BaseController {
    @Autowired
@@ -107,6 +109,23 @@
        ExcelUtil.build(ExcelUtil.create(asnOrderService.list(), AsnOrder.class), response);
    }
    /**
     * 质检上报
     * @param orders
     * @return
     */
    @PostMapping("/asnOrder/inspect")
    @PreAuthorize("hasAuthority('manager:asnOrder:list')")
    public R notifyInspect(@RequestBody List<AsnOrder> orders) {
        if (orders.isEmpty()) {
            return R.error("上报单据不能为空!!");
        }
        if (asnOrderService.notifyInspect(orders)) {
            return R.ok("质检上报成功!!");
        } else {
            return R.error("一键上报失败!!");
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/AsnOrder.java
@@ -95,6 +95,12 @@
    private Date arrTime;
    /**
     * 质检上报状态
     */
    @ApiModelProperty("上报状态 0:未上报, 1:已上报")
    private Integer ntyStatus;
    /**
     * 释放状态 0:  正常   1:  已释放  
     */
    @ApiModelProperty(value= "释放状态 0:  正常   1:  已释放  ")
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/Purchase.java
@@ -55,11 +55,15 @@
    @ApiModelProperty(value= "单据类型")
    private String type;
    @ApiModelProperty(value = "erp主单标识")
    private String erpId;
    /**
     * 单据来源
     */
    @ApiModelProperty(value= "单据来源")
    private String from;
    private String source;
    /**
     * 预计到达时间
@@ -171,10 +175,11 @@
    public Purchase() {}
    public Purchase(String code,String type,String from,Date preArr,Double anfme,Double qty,Double workQty,String channel,String erpCode,Date startTime,Date endTime,String project,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
    public Purchase(String code,String type,String source,String erpId ,Date preArr,Double anfme,Double qty,Double workQty,String channel,String erpCode,Date startTime,Date endTime,String project,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.code = code;
        this.type = type;
        this.from = from;
        this.source = source;
        this.erpId = erpId;
        this.preArr = preArr;
        this.anfme = anfme;
        this.qty = qty;
rsf-server/src/main/java/com/vincent/rsf/server/manager/entity/PurchaseItem.java
@@ -47,7 +47,7 @@
     * erp行号
     */
    @ApiModelProperty(value= "erp行号")
    private String erpId;
    private String erpItemId;
    /**
     * 物料编码
@@ -168,9 +168,9 @@
    public PurchaseItem() {}
    public PurchaseItem(Long purchaseId,String erpId,String matnrCode,String matnrName,String unit,Double anfme,Double qty,Double nromQty,Double asnQty,Double printQty,String splrName,String splrCode,String splrBatch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
    public PurchaseItem(Long purchaseId,String erpItemId,String matnrCode,String matnrName,String unit,Double anfme,Double qty,Double nromQty,Double asnQty,Double printQty,String splrName,String splrCode,String splrBatch,Integer status,Integer deleted,Integer tenantId,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
        this.purchaseId = purchaseId;
        this.erpId = erpId;
        this.erpItemId = erpItemId;
        this.matnrCode = matnrCode;
        this.matnrName = matnrName;
        this.unit = unit;
rsf-server/src/main/java/com/vincent/rsf/server/manager/mapper/PurchaseMapper.java
@@ -1,12 +1,18 @@
package com.vincent.rsf.server.manager.mapper;
import com.vincent.rsf.server.api.entity.dto.PoItemsDto;
import com.vincent.rsf.server.manager.entity.Purchase;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Set;
@Mapper
@Repository
public interface PurchaseMapper extends BaseMapper<Purchase> {
    List<PoItemsDto> poList(@Param("ids") Set<Long> ids);
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/schedules/ScheduleJobs.java
File was renamed from rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/ScheduleJobs.java
@@ -1,15 +1,19 @@
package com.vincent.rsf.server.manager.utils;
package com.vincent.rsf.server.manager.schedules;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.common.config.SysStockProperties;
import com.vincent.rsf.server.common.utils.DateUtils;
import com.vincent.rsf.server.manager.entity.*;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.system.constant.SerialRuleCode;
import com.vincent.rsf.server.system.utils.SerialRuleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -38,6 +42,9 @@
    @Autowired
    private AsnOrderItemService asnOrderItemService;
    @Resource
    private SysStockProperties flowProperties;
    /**
     * @author Ryan
     * @description  根据PO单据生成ASN单,自动生成ASN单为全量生成
@@ -48,6 +55,10 @@
    @Scheduled(cron = "0 0/30 * * * ?  ")
    @Transactional(rollbackFor = Exception.class)
    public void genAsnOrder() {
        //判断是否开启自动生成ASN单据
        if (!flowProperties.getFlagAutoAsn()) {
            return;
        }
        //获取未生成ASN单据
        List<Purchase> purchases = purchaseService.list(new LambdaQueryWrapper<Purchase>().eq(Purchase::getStatus, 0));
        //采购单为空,直接跳出当前任务
@@ -67,7 +78,10 @@
                throw new CoolException("子列表数据为空,请查询PO单是否正确录入!!");
            }
            AsnOrder order = new AsnOrder();
            //根据编码规则生成ASN单号
            String code = SerialRuleUtils.generateRuleCode(SerialRuleCode.SYS_ASN_ORDER, purchase);
            order.setAnfme(purchase.getAnfme())
                    .setCode(code)
                    .setArrTime(purchase.getPreArr())
                    .setQty(purchase.getQty())
                    .setPoId(purchase.getId())
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/AsnOrderService.java
@@ -3,6 +3,9 @@
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import java.util.List;
public interface AsnOrderService extends IService<AsnOrder> {
    boolean notifyInspect(List<AsnOrder> orders);
}
rsf-server/src/main/java/com/vincent/rsf/server/manager/service/impl/AsnOrderServiceImpl.java
@@ -1,12 +1,58 @@
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.api.entity.dto.PoItemsDto;
import com.vincent.rsf.server.api.service.ErpApiService;
import com.vincent.rsf.server.manager.entity.AsnOrderItem;
import com.vincent.rsf.server.manager.entity.Purchase;
import com.vincent.rsf.server.manager.entity.PurchaseItem;
import com.vincent.rsf.server.manager.mapper.AsnOrderItemMapper;
import com.vincent.rsf.server.manager.mapper.AsnOrderMapper;
import com.vincent.rsf.server.manager.entity.AsnOrder;
import com.vincent.rsf.server.manager.mapper.PurchaseMapper;
import com.vincent.rsf.server.manager.service.AsnOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
 * @author Ryan
 * @description
 * @throws
 * @return
 * @time 2025/3/7 08:02
 */
@Service("asnOrderService")
public class AsnOrderServiceImpl extends ServiceImpl<AsnOrderMapper, AsnOrder> implements AsnOrderService {
    @Autowired
    private ErpApiService erpApiService;
    @Resource
    private PurchaseMapper purchaseMapper;
    @Resource
    private AsnOrderItemMapper asnOrderItemMapper;
    @Override
    public boolean notifyInspect(List<AsnOrder> orders) {
        if (orders.isEmpty()) {
            throw new CoolException("上报参数不能为空!!");
        }
        Set<Long> asnIds = orders.stream().map(AsnOrder::getId).collect(Collectors.toSet());
        if (asnIds.isEmpty()) {
            throw new CoolException("ASN单据不能为空!!");
        }
        List<PoItemsDto> items = purchaseMapper.poList(asnIds);
        if (erpApiService.reportInspectNotify(items)) {
            return true;
        } else {
            return false;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/constant/SerialRuleCode.java
@@ -9,5 +9,13 @@
 */
public class SerialRuleCode {
    /**
     * 系统PO单同步编码规则
     */
    public final static String PURCHASE_CODE = "sys_purchase_code";
    /**
     * ASN通知单生成编码规则
     */
    public final static String SYS_ASN_ORDER = "sys_ans_order";
}
rsf-server/src/main/java/com/vincent/rsf/server/system/utils/SerialRuleUtils.java
@@ -41,7 +41,7 @@
                .getOne(new LambdaQueryWrapper<SerialRule>()
                        .eq(SerialRule::getCode, code));
        if (Objects.isNull(serialRule)) {
            throw new CoolException("采购编码规则不存在!!");
            throw new CoolException("当前业务:" + code + ",编码规则不存在!!");
        }
        SerialRuleItemService serialRuleItemService = SpringUtils.getBean(SerialRuleItemService.class);
rsf-server/src/main/java/purchase.sql
@@ -2,10 +2,10 @@
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.purchase', '0', '/manager/purchase', 'purchase', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query ERP采购单', '', '1', 'manager:purchase:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create ERP采购单', '', '1', 'manager:purchase:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update ERP采购单', '', '1', 'manager:purchase:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete ERP采购单', '', '1', 'manager:purchase:remove', '3', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 采购单', '148', '1', 'manager:purchase:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 采购单', '148', '1', 'manager:purchase:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 采购单', '148', '1', 'manager:purchase:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 采购单', '148', '1', 'manager:purchase:remove', '3', '1', '1');
-- locale menu name
purchase: 'Purchase',
@@ -13,17 +13,19 @@
-- locale field
purchase: {
    code: "code",
    erpId: "erpId",
    type: "type",
    from: "from",
    wkType: "wkType",
    source: "source",
    preArr: "preArr",
    anfme: "anfme",
    qty: "qty",
    workQty: "workQty",
    channel: "channel",
    erpCode: "erpCode",
    project: "project",
    startTime: "startTime",
    endTime: "endTime",
    project: "project",
},
-- ResourceContent
rsf-server/src/main/java/purchaseItem.sql
@@ -2,10 +2,10 @@
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.purchaseItem', '0', '/manager/purchaseItem', 'purchaseItem', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query ERP采购单', '', '1', 'manager:purchaseItem:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create ERP采购单', '', '1', 'manager:purchaseItem:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update ERP采购单', '', '1', 'manager:purchaseItem:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete ERP采购单', '', '1', 'manager:purchaseItem:remove', '3', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 采购明细单', '153', '1', 'manager:purchaseItem:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 采购明细单', '153', '1', 'manager:purchaseItem:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 采购明细单', '153', '1', 'manager:purchaseItem:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 采购明细单', '153', '1', 'manager:purchaseItem:remove', '3', '1', '1');
-- locale menu name
purchaseItem: 'PurchaseItem',
@@ -13,18 +13,18 @@
-- locale field
purchaseItem: {
    purchaseId: "purchaseId",
    erpId: "erpId",
    erpItemId: "erpItemId",
    matnrCode: "matnrCode",
    matnrName: "matnrName",
    unit: "unit",
    anfme: "anfme",
    qty: "qty",
    nomQty: "nomQty",
    nromQty: "nromQty",
    asnQty: "asnQty",
    printQty: "printQty",
    pulrName: "pulrName",
    pulrCode: "pulrCode",
    pulrBatch: "pulrBatch",
    splrName: "splrName",
    splrCode: "splrCode",
    splrBatch: "splrBatch",
},
-- ResourceContent
rsf-server/src/main/resources/application-dev.yml
@@ -65,4 +65,32 @@
  password: xltys1995
  port: 6379
  timeout: 5000
  index: 15
  index: 15
#平台接口信息配置(如:ERP, QMS, WCS等)
platform:
  #企业ERP平台
  erp:
    #localhost
    host: http://127.0.0.1
    #端口号
    port: 8080
    #接品链接前缀
    prePath: rsf-server
    #接口明细
    api:
      #质检上报接口
      notifyInspect: /report/inspect
#仓库功能参数配置
stock:
  #是否允许打印货物标签, 默认允许打印,也可由供应商提供标签
  flagPrinter: false
  #是否自动生成ASN单(默认:是),为『否』则开启PO单手动生成ASN单功能
  flagAutoAsn: true
  #质检功能 是否校验上架(默认:是),是否校验收货(默认:否)
  inspect:
    #判断是后检验合格后,才允许上架
    flagAvailable: true
    #判断是否校验合格后,才允许收货
    flagReceiving: false
rsf-server/src/main/resources/application-prod.yml
@@ -62,4 +62,7 @@
  password: xltys1995
  port: 6379
  timeout: 5000
  index: 11
  index: 11
stock:
  flagAvailable: true
rsf-server/src/main/resources/mapper/manager/PurchaseMapper.xml
@@ -2,4 +2,27 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.manager.mapper.PurchaseMapper">
    <select id="poList" resultType="com.vincent.rsf.server.api.entity.dto.PoItemsDto">
        SELECT
            id,
            purchase_id,
            erp_item_id,
            matnr_code,
            matnr_name,
            unit,
            anfme
        FROM
            man_purchase_item mpi
        WHERE
            id IN ( SELECT po_detl_id FROM man_asn_order_item
            <where>
                1 = 1
                <if test="ids != null and ids.size() > 0">
                    <foreach collection="ids" index="index" item="item" separator="," open="AND asn_id IN (" close=")">
                        #{item}
                    </foreach>
                </if>
            </where>
        )
    </select>
</mapper>