kyy
2025-09-04 2e37035392c187b26a09a2c2edcc6133e96532cc
1、收料通知单接口 2、采购订单接口加委外订单分录内码
已修改3个文件
已添加7个文件
976 ■■■■■ 文件已修改
MES.Service/Dto/webApi/ErpRohinData.cs 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/Dto/webApi/ErpSltz.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/Dto/webApi/ErpSltzBList.cs 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/Dto/webApi/ErpSltza.cs 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/Modes/MesInvItemArn.cs 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/Modes/MesInvItemArnDetail.cs 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/Modes/MesRohInData.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/service/BasicData/MesInvItemArnManager.cs 263 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/service/BasicData/MesRohInManager.cs 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MESApplication/Controllers/BasicData/MesInvItemArnController.cs 339 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
MES.Service/Dto/webApi/ErpRohinData.cs
@@ -53,5 +53,8 @@
    public string? FDEMANDBILLENTRYSEQ { get; set; }
    public string? SalesOrderId { get; set; }
    public string? OrderLineId { get; set; }
    public string? FSUBREQENTRYID { get; set; }
    
}
MES.Service/Dto/webApi/ErpSltz.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,7 @@
namespace MES.Service.Dto.webApi;
public class ErpSltz
{
    public ErpSltza ErpSltza { get; set; }
    public List<ErpSltzBList> ErpSltzBList { get; set; }
}
MES.Service/Dto/webApi/ErpSltzBList.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,84 @@
namespace MES.Service.Dto.webApi;
public class ErpSltzBList
{
    /// <summary>
    /// æ”¶æ–™é€šçŸ¥å•分录内码
    /// </summary>
    public string? LineNo { get; set; }
    /// <summary>
    /// è®¢å•单号
    /// </summary>
    public string? FBillNo { get; set; }
    /// <summary>
    /// ç‰©æ–™ç¼–码
    /// </summary>
    public string? ProductCode { get; set; }
    /// <summary>
    /// è®¢å•数量
    /// </summary>
    public string? PurchaseQty { get; set; }
    /// <summary>
    /// æœ¬æ¬¡åº”收数量
    /// </summary>
    public string? DeliveryQty { get; set; }
    /// <summary>
    /// äº¤è´§æ•°é‡
    /// </summary>
    public string? IncludeQty { get; set; }
    /// <summary>
    /// æ”¶æ–™å•位
    /// </summary>
    public string? PurchaseUnit { get; set; }
    /// <summary>
    /// åº“存单位
    /// </summary>
    public string? InventoryUnit { get; set; }
    /// <summary>
    /// å¤‡æ³¨
    /// </summary>
    public string? Remark { get; set; }
    /// <summary>
    /// æºå•单号
    /// </summary>
    public string? FSrcBillNo { get; set; }
    /// <summary>
    /// æºå•分录内码
    /// </summary>
    public string? FSrcBillLine { get; set; }
    /// <summary>
    /// é”€å”®è®¢å•号
    /// </summary>
    public string? SalesOrderId { get; set; }
    /// <summary>
    /// è®¡åˆ’跟踪号
    /// </summary>
    public string? FMtoNo { get; set; }
    /// <summary>
    /// æ‰¹å·
    /// </summary>
    public string? FLot { get; set; }
    /// <summary>
    /// æ€¥æ–™æ ‡è¯†
    /// </summary>
    public string? urgentFlag { get; set; }
    /// <summary>
    /// ä»“库
    /// </summary>
    public string? DepotId { get; set; }
}
MES.Service/Dto/webApi/ErpSltza.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
namespace MES.Service.Dto.webApi;
public class ErpSltza
{
    /// <summary>
    /// æ“ä½œç±»åž‹
    /// </summary>
    public string? TYPE { get; set; }
    /// <summary>
    /// å•据编号
    /// </summary>
    public string? billNo { get; set; }
    /// <summary>
    /// ä¾›åº”商
    /// </summary>
    public string? SupplierId { get; set; }
    /// <summary>
    /// å•据日期
    /// </summary>
    public string? FDate { get; set; }
    /// <summary>
    /// å¤‡æ³¨
    /// </summary>
    public string? Remark { get; set; }
    /// <summary>
    /// æ˜¯å¦ä¾›å
    /// </summary>
    public string? F_ZJXF_sfgx { get; set; }
    /// <summary>
    /// æ”¶æ–™é€šçŸ¥å•表头内码
    /// </summary>
    public string? erpId { get; set; }
    /// <summary>
    /// åˆ›å»ºäºº
    /// </summary>
    public string? createBy { get; set; }
    /// <summary>
    /// æ˜¯å¦å§”外
    /// </summary>
    public string? fType { get; set; }
    /// <summary>
    /// æ”¶æ–™ç»„织
    /// </summary>
    public string? ReceiveOrgId { get; set; }
}
MES.Service/Modes/MesInvItemArn.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
using SqlSugar;
namespace MES.Service.Modes;
/// <summary>
/// æ”¶æ–™å•表(对应MES_INV_ITEM_ARN表)
/// </summary>
[SugarTable("MES_INV_ITEM_ARN")]
public class MesInvItemArn
{
    /// <summary>
    /// è®°å½•唯一标识(主键)
    /// </summary>
    [SugarColumn(ColumnName = "GUID", IsPrimaryKey = true)]
    public Guid Id { get; set; }
    /// <summary>
    /// æ”¶æ–™å•号
    /// </summary>
    [SugarColumn(ColumnName = "bill_no")]
    public string? BillNo { get; set; }
    /// <summary>
    /// ä¾›åº”商编号
    /// </summary>
    [SugarColumn(ColumnName = "supp_id")]
    public string? SuppId { get; set; }
    /// <summary>
    /// å•据日期
    /// </summary>
    [SugarColumn(ColumnName = "create_date")]
    public DateTime? CreateDate { get; set; }
    /// <summary>
    /// å¤‡æ³¨ä¿¡æ¯
    /// </summary>
    [SugarColumn(ColumnName = "remark")]
    public string? Remark { get; set; }
    /// <summary>
    /// æ˜¯å¦srm(0否、1是)
    /// </summary>
    [SugarColumn(ColumnName = "IS_SRM")]
    public int? IsSrm { get; set; }
    /// <summary>
    /// ERPID
    /// </summary>
    [SugarColumn(ColumnName = "ebeln_k3id")]
    public string? EbelnK3id { get; set; }
    /// <summary>
    /// åˆ›å»ºäºº
    /// </summary>
    [SugarColumn(ColumnName = "create_by")]
    public string? CreateBy { get; set; }
    /// <summary>
    /// æ˜¯å¦å§”外
    /// </summary>
    [SugarColumn(ColumnName = "f_type")]
    public bool? FType { get; set; }
    /// <summary>
    /// æ”¶æ–™ç»„织
    /// </summary>
    [SugarColumn(ColumnName = "ReceiveOrgId")]
    public string? ReceiveOrgId { get; set; }
}
MES.Service/Modes/MesInvItemArnDetail.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,117 @@
using SqlSugar;
namespace MES.Service.Modes;
/// <summary>
/// æ”¶æ–™å•明细表(对应MES_INV_ITEM_ARN_DETAIL表)
/// </summary>
[SugarTable("MES_INV_ITEM_ARN_DETAIL")]
public class MesInvItemArnDetail
{
    // /// <summary>
    // /// æ”¶æ–™é€šçŸ¥å•分录内码
    // /// </summary>
    // [SugarColumn(IsPrimaryKey = true)] // é»˜è®¤ä¸ºä¸»é”®ï¼ˆè‹¥å®žé™…主键不是该字段,可根据业务调整主键配置)
    // public int? LineNo { get; set; }
    /// <summary>
    /// é‡‡è´­å•号
    /// </summary>
    [SugarColumn(ColumnName = "ebeln")]
    public string? Ebeln { get; set; }
    /// <summary>
    /// æ˜Žç»†è¡¨è®°å½•唯一标识(主键)
    /// </summary>
    [SugarColumn(ColumnName = "GUID", IsPrimaryKey = true)]
    public Guid Id { get; set; }
    /// <summary>
    /// å…³è”主表(MES_INV_ITEM_ARN)的 ID
    /// </summary>
    [SugarColumn(ColumnName = "parent_Guid")]
    public Guid? Mid { get; set; }
    /// <summary>
    /// ç‰©æ–™ç¼–码
    /// </summary>
    [SugarColumn(ColumnName = "item_id")]
    public int? ItemId { get; set; }
    /// <summary>
    /// é‡‡è´­è®¢å•数量
    /// </summary>
    [SugarColumn(ColumnName = "ebeln_qty")]
    public decimal? EbelnQty { get; set; }
    /// <summary>
    /// æœ¬æ¬¡åº”收数量
    /// </summary>
    [SugarColumn(ColumnName = "sub_qty")]
    public decimal? SubQty { get; set; }
    /// <summary>
    /// æœ¬æ¬¡å®žæ”¶æ•°é‡
    /// </summary>
    [SugarColumn(ColumnName = "quantity")]
    public decimal? Quantity { get; set; }
    // /// <summary>
    // /// é‡‡è´­å•位
    // /// </summary>
    // [SugarColumn] // æœªæä¾›å…·ä½“MES标识,默认按属性名映射(若实际字段名不同,需补充ColumnName)
    // public string? PurchaseUnit { get; set; }
    //
    // /// <summary>
    // /// åº“存单位
    // /// </summary>
    // [SugarColumn] // æœªæä¾›å…·ä½“MES标识,默认按属性名映射(若实际字段名不同,需补充ColumnName)
    // public string? InventoryUnit { get; set; }
    /// <summary>
    /// å¤‡æ³¨
    /// </summary>
    [SugarColumn(ColumnName = "memo")]
    public string? Memo { get; set; }
    /// <summary>
    /// é‡‡è´­å•ID
    /// </summary>
    [SugarColumn(ColumnName = "ebeln_k3id")]
    public int? EbelnK3id { get; set; }
    /// <summary>
    /// é‡‡è´­å•行ID
    /// </summary>
    [SugarColumn(ColumnName = "line_k3id")]
    public int? LineK3id { get; set; }
    // /// <summary>
    // /// é”€å”®è®¢å•号
    // /// </summary>
    // [SugarColumn] // æœªæä¾›å…·ä½“MES标识,默认按属性名映射(若实际字段名不同,需补充ColumnName)
    // public string? SalesOrderId { get; set; }
    //
    // /// <summary>
    // /// è®¡åˆ’跟踪号
    // /// </summary>
    // [SugarColumn] // æœªæä¾›å…·ä½“MES标识,默认按属性名映射(若实际字段名不同,需补充ColumnName)
    // public string? FMtoNo { get; set; }
    //
    // /// <summary>
    // /// æ‰¹å·
    // /// </summary>
    // [SugarColumn] // æœªæä¾›å…·ä½“MES标识,默认按属性名映射(若实际字段名不同,需补充ColumnName)
    // public string? FLot { get; set; }
    /// <summary>
    /// æ€¥æ–™æ ‡è¯†
    /// </summary>
    [SugarColumn(ColumnName = "urgent_flag")]
    public bool? UrgentFlag { get; set; }
    // /// <summary>
    // /// æ”¶è´§ä»“库编号
    // /// </summary>
    // [SugarColumn(ColumnName = "FSTOCKID")]
    // public string? FStockId { get; set; }
}
MES.Service/Modes/MesRohInData.cs
@@ -355,4 +355,11 @@
    /// </summary>
    [SugarColumn(ColumnName = "FDEMANDBILLNO_LINE")]
    public string? FdemandbillnoLine { get; set; }
    /// <summary>
    ///     å§”外订单分录内码
    /// </summary>
    [SugarColumn(ColumnName = "FSUBREQENTRYID")]
    public string? FSUBREQENTRYID { get; set; }
}
MES.Service/service/BasicData/MesInvItemArnManager.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,263 @@
using MES.Service.DB;
using MES.Service.Dto.webApi;
using MES.Service.Modes;
using MES.Service.util;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MES.Service.service;
/// <summary>
/// æ”¶æ–™å•数据管理类(处理ERP收料单数据同步到MES收料单表)
/// å…³è”主表:MesInvItemArn,明细表:MesInvItemArnDetail
/// å…³è”ERP DTO:ErpSltz(聚合类)、ErpSltza(ERP主表)、ErpSltzBList(ERP明细)
/// </summary>
public class MesInvItemArnManager : Repository<MesInvItemArn>
{
    /// <summary>
    /// æ‰¹é‡ä¿å­˜æ”¶æ–™å•(主表+明细)- äº‹åŠ¡ä¿è¯æ‰¹é‡æ“ä½œä¸€è‡´æ€§
    /// </summary>
    /// <param name="erpSltzList">ERP收料单列表(含主表+明细)</param>
    /// <returns>全部成功返回true,否则false</returns>
    public bool SaveList(List<ErpSltz> erpSltzList)
    {
        if (erpSltzList == null || !erpSltzList.Any())
            throw new ArgumentNullException(nameof(erpSltzList), "待保存的收料单列表不能为空");
        // ä¿®å¤ï¼šç”¨äº‹åŠ¡åŒ…è£¹æ‰¹é‡æ“ä½œï¼Œç¡®ä¿æ•°æ®ä¸€è‡´æ€§
        return UseTransaction(db =>
        {
            foreach (var erpSltz in erpSltzList)
            {
                // ä¿®å¤ï¼šè°ƒç”¨äº‹åŠ¡å†…çš„Save方法,传入db实例
                if (!Save(db, erpSltz))
                {
                    return 0; // å•条失败,事务回滚
                }
            }
            return 1; // å…¨éƒ¨æˆåŠŸ
        }) > 0;
    }
    /// <summary>
    /// å•条保存收料单(主表+明细)- äº‹åŠ¡å†…è°ƒç”¨ï¼ˆä¿®æ­£è®¿é—®ä¿®é¥°ç¬¦ï¼Œç¡®ä¿äº‹åŠ¡å†…å¯ç”¨ï¼‰
    /// </summary>
    /// <param name="db">事务内的SqlSugar实例</param>
    /// <param name="erpSltz">ERP收料单(含主表+明细)</param>
    /// <returns>单条处理成功返回true</returns>
    private bool Save(SqlSugarScope db, ErpSltz erpSltz)
    {
        // 1. å‚数校验
        if (erpSltz == null)
            throw new ArgumentNullException(nameof(erpSltz), "收料单数据不能为空");
        if (erpSltz.ErpSltza == null)
            throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "收料单主表数据不能为空");
        // 2. æå–ERP主表和明细数据
        var erpMain = erpSltz.ErpSltza;
        var erpDetails = erpSltz.ErpSltzBList ?? new List<ErpSltzBList>();
        // 3. ä¿®å¤ï¼šç”¨äº‹åŠ¡å†…çš„db查询,确保数据一致性
        Guid mainId = GetOrCreateMainId(db, erpMain);
        // 4. æ˜ å°„ERP数据到MES实体(修复字段注释,补充关键属性)
        var mesMain = MapErpSltzaToMesInvItemArn(erpMain, mainId);
        var mesDetails = MapErpSltzBListToMesInvItemArnDetail(erpDetails, mainId);
        // 5. æ ¹æ®æ“ä½œç±»åž‹å¤„理数据
        switch (erpMain.TYPE?.Trim())
        {
            case "1": // æ–°å¢ž
            case "2": // æ›´æ–°
                return HandleSaveOrUpdate(db, mesMain, mesDetails, mainId);
            case "3": // åˆ é™¤
                return HandleDelete(db, mesMain, mesDetails, mainId);
            default:
                throw new NotImplementedException($"未实现的收料单操作类型:{erpMain.TYPE}(支持类型:1-新增,2-更新,3-删除)");
        }
    }
    /// <summary>
    /// å•条保存收料单(主表+明细)- å¯¹å¤–公开接口(供控制器调用)
    /// </summary>
    /// <param name="erpSltz">ERP收料单数据(含主表+明细)</param>
    /// <returns>保存成功返回true</returns>
    public bool Save(ErpSltz erpSltz)
    {
        if (erpSltz == null)
            throw new ArgumentNullException(nameof(erpSltz), "收料单数据不能为空");
        if (erpSltz.ErpSltza == null)
            throw new ArgumentNullException(nameof(erpSltz.ErpSltza), "收料单主表数据不能为空");
        // äº‹åŠ¡å†…å¤„ç†ä¸»ä»Žè¡¨ä¿å­˜
        return UseTransaction(db =>
        {
            return Save(db, erpSltz) ? 1 : 0;
        }) > 0;
    }
    /// <summary>
    /// æå‰èŽ·å–æˆ–ç”ŸæˆMES主表ID(修复:用事务内db查询)
    /// </summary>
    private Guid GetOrCreateMainId(SqlSugarScope db, ErpSltza erpMain)
    {
        if (string.IsNullOrEmpty(erpMain.billNo))
            throw new ArgumentException("ERP收料单单据号不能为空,无法确定主表唯一性", nameof(erpMain.billNo));
        // ä¿®å¤ï¼šç”¨äº‹åŠ¡å†…çš„db查询,而非Context
        var existingMain = db.Queryable<MesInvItemArn>()
            .Where(m => m.BillNo == erpMain.billNo)
            .First();
        return existingMain != null
            ? existingMain.Id
            : Guid.NewGuid();
    }
    /// <summary>
    /// å¤„理收料单新增/更新(主表+明细)
    /// </summary>
    private bool HandleSaveOrUpdate(SqlSugarScope db, MesInvItemArn mesMain, List<MesInvItemArnDetail> mesDetails, Guid mainId)
    {
        mesMain.Id = mainId;
        bool isMainExist = db.Queryable<MesInvItemArn>().Where(m => m.Id == mainId).Any();
        int mainOperateResult;
        if (isMainExist)
        {
            mainOperateResult = db.Updateable(mesMain)
                .IgnoreColumns(m => new { m.CreateDate })
                .Where(m => m.Id == mainId)
                .ExecuteCommand();
        }
        else
        {
            mesMain.CreateDate = DateTime.Now;
            mainOperateResult = db.Insertable(mesMain).ExecuteCommand();
        }
        // å¤„理明细
        int deleteOldDetailResult = db.Deleteable<MesInvItemArnDetail>()
            .Where(d => d.Mid == mainId)
            .ExecuteCommand();
        int insertNewDetailResult = mesDetails.Count > 0
            ? db.Insertable(mesDetails).ExecuteCommand()
            : 1;
        return mainOperateResult > 0 && (deleteOldDetailResult >= 0 && insertNewDetailResult > 0);
    }
    /// <summary>
    /// å¤„理收料单删除(主表+明细)
    /// </summary>
    private bool HandleDelete(SqlSugarScope db, MesInvItemArn mesMain, List<MesInvItemArnDetail> mesDetails, Guid mainId)
    {
        db.Deleteable<MesInvItemArnDetail>().Where(d => d.Mid == mainId).ExecuteCommand();
        int mainDeleteResult = db.Deleteable<MesInvItemArn>().Where(m => m.Id == mainId).ExecuteCommand();
        return mainDeleteResult >= 0;
    }
    /// <summary>
    /// ERP主表映射到MES主表(修复:取消关键字段注释,修正FType逻辑)
    /// </summary>
    private MesInvItemArn MapErpSltzaToMesInvItemArn(ErpSltza erpMain, Guid mainId)
    {
        // å•据日期转换
        DateTime.TryParse(erpMain.FDate, out DateTime parsedDate);
        // æ˜¯å¦SRM转换(0-否,1-是)
        int.TryParse(erpMain.F_ZJXF_sfgx, out int isSrm);
        // ä¾›åº”商ID转换(字符串直接赋值,匹配MES字段类型)
        string suppId = string.IsNullOrEmpty(erpMain.SupplierId) ? null : erpMain.SupplierId.Trim();
        // ä¿®å¤ï¼šâ€œæ˜¯å¦å§”外”逻辑(假设ERP的fType是“1”=是,“0”=否,或bool字符串)
        bool isOutsourcing = false;
        if (!string.IsNullOrEmpty(erpMain.fType))
        {
            isOutsourcing = erpMain.fType.Trim() == "1" || erpMain.fType.Trim().Equals("true", StringComparison.OrdinalIgnoreCase);
        }
        return new MesInvItemArn
        {
            // ä¿®å¤ï¼šå–消关键字段注释,补充赋值
            Id = mainId,
            BillNo = erpMain.billNo?.Trim() ?? throw new ArgumentException("收料单单据号不能为空"),
            SuppId = suppId,
            CreateDate = parsedDate == DateTime.MinValue ? null : (DateTime?)parsedDate,
            Remark = erpMain.Remark?.Trim(),
            IsSrm = isSrm,
            EbelnK3id = erpMain.erpId?.Trim(), // ERP主表ID(对应ebeln_k3id)
            CreateBy = erpMain.createBy?.Trim() ?? "SYSTEM", // é»˜è®¤ä¸ºç³»ç»Ÿ
            FType = isOutsourcing, // ä¿®å¤ï¼šæ­£ç¡®çš„æ˜¯å¦å§”外逻辑
            ReceiveOrgId = erpMain.ReceiveOrgId?.Trim(),
            // LastUpdateUser = erpMain.FCreatorId?.Trim() ?? "SYSTEM",
            // LastUpdateTime = DateTime.Now,
            // IsOut = false, // åˆå§‹æœªå‡ºåº“
            // Status = false // åˆå§‹æœªå®¡æ ¸
        };
    }
    /// <summary>
    /// ERP明细映射到MES明细(修复:取消关键字段注释,修正EbelnK3id转换)
    /// </summary>
    private List<MesInvItemArnDetail> MapErpSltzBListToMesInvItemArnDetail(List<ErpSltzBList> erpDetails, Guid mainId)
    {
        return erpDetails.Select(erpDetail =>
        {
            // æ•°å€¼ç±»åž‹å®‰å…¨è½¬æ¢
            int.TryParse(erpDetail.LineNo, out int lineNo); // æ˜Žç»†ä¸»é”®
            int.TryParse(erpDetail.ProductCode, out int itemId); // ç‰©æ–™ç¼–码
            decimal.TryParse(erpDetail.PurchaseQty, out decimal purchaseQty); // é‡‡è´­è®¢å•数量
            decimal.TryParse(erpDetail.DeliveryQty, out decimal deliveryQty); // æœ¬æ¬¡åº”收数量
            decimal.TryParse(erpDetail.IncludeQty, out decimal includeQty); // æœ¬æ¬¡å®žæ”¶æ•°é‡
            // ä¿®å¤ï¼šç”¨é‡‡è´­å•ID字段(ebeln_k3id)转int,而非源单单号
            int.TryParse(erpDetail.FSrcBillNo, out int ebelnK3id);
            int.TryParse(erpDetail.FSrcBillLine, out int lineK3id); // é‡‡è´­å•行ID
            bool.TryParse(erpDetail.urgentFlag, out bool urgentFlag); // æ€¥æ–™æ ‡è¯†
            return new MesInvItemArnDetail
            {
                // ä¿®å¤ï¼šå–消关键字段注释,补充赋值
            //    LineNo = lineNo, // æ˜Žç»†ä¸»é”®ï¼ˆå¿…须赋值)
                Mid = mainId, // å¤–键(关联主表ID,必须赋值)
                Ebeln = erpDetail.FBillNo?.Trim(), // é‡‡è´­å•号
                ItemId = itemId,
                EbelnQty = purchaseQty,
                SubQty = deliveryQty,
                Quantity = includeQty,
              //  PurchaseUnit = erpDetail.PurchaseUnit?.Trim(), // é‡‡è´­å•位(补充赋值)
              //  InventoryUnit = erpDetail.InventoryUnit?.Trim(), // åº“存单位(补充赋值)
                Memo = erpDetail.Remark?.Trim(),
                EbelnK3id = ebelnK3id, // ä¿®å¤ï¼šæ­£ç¡®çš„采购单ID转换
                LineK3id = lineK3id,
             //   SalesOrderId = erpDetail.SalesOrderId?.Trim(), // é”€å”®è®¢å•号(补充赋值)
              //  FMtoNo = erpDetail.FMtoNo?.Trim(), // è®¡åˆ’跟踪号(补充赋值)
             //   FLot = erpDetail.FLot?.Trim(), // æ‰¹å·ï¼ˆè¡¥å……赋值)
                UrgentFlag = urgentFlag
                //FStockId = erpDetail.DepotId?.Trim() // æ”¶è´§ä»“库编号
            };
        }).ToList();
    }
    /// <summary>
    /// æŒ‰å•据号查询MES收料单(主表+明细)
    /// </summary>
    public (MesInvItemArn main, List<MesInvItemArnDetail> details) GetByBillNo(string billNo)
    {
        if (string.IsNullOrEmpty(billNo))
            throw new ArgumentNullException(nameof(billNo), "查询条件单据号不能为空");
        var main = Context.Queryable<MesInvItemArn>()
            .Where(m => m.BillNo == billNo)
            .First();
        var details = main != null
            ? Context.Queryable<MesInvItemArnDetail>()
                .Where(d => d.Mid == main.Id)
                .ToList()
            : new List<MesInvItemArnDetail>();
        return (main, details);
    }
}
MES.Service/service/BasicData/MesRohInManager.cs
@@ -90,21 +90,16 @@
    {
        var eid = long.Parse(rohIn.id);
        var mesRohIn = new MesRohIn();
        var single = base.GetSingle(it => it.EbelnK3id == eid);
        if (single != null) mesRohIn.Guid = single.Guid;
        mesRohIn.EbelnK3id = eid;
        mesRohIn.BillNo = rohIn.FBillNo;
        mesRohIn.DocumentStatus = rohIn.FDocumentStatus;
        mesRohIn.DocumentType = rohIn.FBillTypeID;
        mesRohIn.BusinessType = rohIn.FBusinessType;
        if (rohIn.FDate != null)
            mesRohIn.PurchaseDate = DateTime.ParseExact(rohIn.FDate,
                "yyyy-MM-dd HH:mm:ss", null);
        mesRohIn.Supplier = rohIn.FSupplierId;
        mesRohIn.CloseStatus = rohIn.FCloseStatus;
        mesRohIn.PurchaseOrg = rohIn.FPurchaseOrgId;
@@ -117,25 +112,19 @@
        mesRohIn.Remarks = rohIn.Remarks;
        mesRohIn.CancellationStatus = rohIn.FCancelStatus;
        mesRohIn.CancellationPerson = rohIn.FCancellerId;
        if (rohIn.FCancelDate != null)
            if (!mesRohIn.CancellationPerson.IsNullOrEmpty())
                mesRohIn.CancellationDate =
                    DateTime.ParseExact(rohIn.FCancelDate,
                        "yyyy-MM-dd HH:mm:ss", null);
        mesRohIn.CreateBy = rohIn.FCreatorId;
        if (rohIn.FCreateDate != null)
            mesRohIn.CreateDate = DateTime.ParseExact(rohIn.FCreateDate,
                "yyyy-MM-dd HH:mm:ss", null);
        mesRohIn.LastupdateBy = rohIn.FModifierId;
        if (rohIn.FModifyDate != null)
            mesRohIn.LastupdateDate = DateTime.ParseExact(rohIn.FModifyDate,
                "yyyy-MM-dd HH:mm:ss", null);
        mesRohIn.ErpCheckBy = rohIn.FApproverId;
        mesRohIn.ErpCheckDate = rohIn.FApproveDate;
        mesRohIn.Changereason = rohIn.FChangeReason;
@@ -143,10 +132,8 @@
            ? DateTime.ParseExact(rohIn.Prearrivaldate,
                "yyyy-MM-dd HH:mm:ss", null)
            : null;
        mesRohIn.ReceiveOrgId = rohIn.FReceiveOrgId;
        mesRohIn.ProviderId = rohIn.FProviderId;
        mesRohIn.Anred = rohIn.FTContact;
        mesRohIn.Telf1 = rohIn.Fmobilephone;
        mesRohIn.FixedTelephone = rohIn.FixedTelephone;
@@ -195,21 +182,8 @@
                BusinessClose = s.FMRPCloseStatus,
                BusinessFreeze = s.FMRPFreezeStatus,
                Freezer = s.FFreezerId,
                //FreezeTime = !string.IsNullOrEmpty(s.FFreezeDate)
                //            && DateTime.TryParseExact(s.FFreezeDate,
                //                new[] { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" },  // æ”¯æŒå¤šç§æ ¼å¼
                //                CultureInfo.InvariantCulture,
                //                DateTimeStyles.None,
                //                out var parsedDate)
                //            && parsedDate > new DateTime(1900, 1, 1)
                //                ? parsedDate
                //                : (DateTime?)null,
                BusinessTerminate = s.FMRPTerminateStatus,
                Terminator = s.FTerminaterId,
                //TerminateTime = s.FTerminateDate != null
                //    ? DateTime.ParseExact(s.FTerminateDate,
                //        "yyyy-MM-dd HH:mm:ss", null)
                //    : null,
                TotalReceivedQty = Convert.ToDecimal(s.FReceiveQty), //累计收料数
                RemainingReceivedQty =
                    Convert.ToDecimal(s.FRemainReceiveQty),
@@ -237,7 +211,9 @@
                DemandDepartment = s.FRequireDeptId,
                ReceivingDepartment = s.FReceiveDeptId,
                SalesOrderId = s.SalesOrderId,
                OrderLineId = s.OrderLineId
                OrderLineId = s.OrderLineId,
                FSUBREQENTRYID = s.FSUBREQENTRYID
            };
            if (s.FFreezeDate != null)
@@ -255,7 +231,7 @@
            var single = rohInDataManager.GetSingle(it =>
                it.EbelnK3id == entity.EbelnK3id);
            if (single != null) entity.Guid = single.Guid;
            return entity;
        }).ToList();
    }
MESApplication/Controllers/BasicData/MesInvItemArnController.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,339 @@
using System.Dynamic;
using MES.Service.Dto.webApi;
using MES.Service.Modes;
using MES.Service.service;
using MES.Service.service.BasicData;
using MES.Service.util;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace MESApplication.Controllers.BasicData;
/// <summary>
/// æ”¶æ–™å•控制器(处理收料单相关API请求,关联MES_INV_ITEM_ARN主表与MES_INV_ITEM_ARN_DETAIL明细表)
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class MesInvItemArnController : ControllerBase
{
    // æ¶ˆæ¯ä¸­å¿ƒç®¡ç†å™¨ï¼ˆç”¨äºŽæŽ¥å£æ—¥å¿—记录)
    private readonly MessageCenterManager _messageCenterManager = new();
    // æ”¶æ–™å•业务逻辑管理器(核心业务处理)
    private readonly MesInvItemArnManager _mesInvItemArnManager = new();
    // æŽ¥å£åŸºç¡€é…ç½®ï¼ˆè¯·æ±‚方法、表名、基础URL)
    private readonly string _method = "POST";
    private readonly string _tableName = "MES_INV_ITEM_ARN";
    private readonly string _baseUrl = "http://localhost:10054/api/MesInvItemArn/";
    /// <summary>
    /// ä¿å­˜æ”¶æ–™å•(单条,含主表+明细)
    /// </summary>
    /// <param name="erpSltz">ERP收料单数据(含主表ErpSltza+明细ErpSltzBList)</param>
    /// <returns>保存结果(成功/失败状态+详情)</returns>
    [HttpPost("Save")]
    public ResponseResult Save(ErpSltz erpSltz)
    {
        // 1. åˆå§‹åŒ–消息中心实体(记录接口调用日志,用于追溯)
        var messageEntity = new MessageCenter
        {
            TableName = _tableName,
            Url = _baseUrl + "Save",
            Method = _method,
            Data = JsonConvert.SerializeObject(erpSltz),
            Status = 1, // çŠ¶æ€ï¼š1-待处理
            CreateBy = "SYSTEM", // åˆ›å»ºäººï¼šç³»ç»Ÿæ ‡è¯†
            Route = erpSltz?.ErpSltza?.billNo ?? "未知单据号" // è·¯ç”±æ ‡è¯†ï¼šç”¨æ”¶æ–™å•单据号
        };
        try
        {
            dynamic resultData = new ExpandoObject();
            // 2. è°ƒç”¨ä¸šåŠ¡å±‚ä¿å­˜æ–¹æ³•ï¼ˆå¤„ç†ä¸»è¡¨+明细同步)
            var saveSuccess = _mesInvItemArnManager.Save(erpSltz);
            resultData.saveResult = saveSuccess;
            // 3. æ›´æ–°æ¶ˆæ¯ä¸­å¿ƒçŠ¶æ€ï¼ˆä¿å­˜æˆåŠŸï¼‰
            messageEntity.Result = 1; // ç»“果:1-成功
            messageEntity.DealWith = 1; // å¤„理状态:1-已处理
            _messageCenterManager.save(messageEntity);
            // 4. è¿”回成功响应
            return new ResponseResult
            {
                status = 0,
                message = "收料单保存成功",
                data = resultData
            };
        }
        catch (Exception ex)
        {
            // 5. å¼‚常处理:记录错误日志
            messageEntity.Result = 0; // ç»“果:0-失败
            messageEntity.DealWith = 0; // å¤„理状态:0-未处理
            messageEntity.ResultData = ex.Message + (ex.InnerException != null ? $"(内部异常:{ex.InnerException.Message})" : ""); // é”™è¯¯è¯¦æƒ…
            _messageCenterManager.save(messageEntity);
            // 6. è¿”回错误响应
            return ResponseResult.ResponseError(ex);
        }
    }
    /// <summary>
    /// æ‰¹é‡ä¿å­˜æ”¶æ–™å•(多条,含主表+明细,事务保证一致性)
    /// </summary>
    /// <param name="erpSltzList">ERP收料单列表(每条含主表+明细)</param>
    /// <returns>批量保存结果(总条数、成功条数)</returns>
    [HttpPost("SaveList")]
    public ResponseResult SaveList(List<ErpSltz> erpSltzList)
    {
        // 1. åˆå§‹åŒ–消息中心实体
        var messageEntity = new MessageCenter
        {
            TableName = _tableName,
            Url = _baseUrl + "SaveList",
            Method = _method,
            Data = JsonConvert.SerializeObject(erpSltzList),
            Status = 1,
            CreateBy = "SYSTEM",
            Route = $"批量数据(共{erpSltzList?.Count ?? 0}条)"
        };
        try
        {
            dynamic resultData = new ExpandoObject();
            int totalCount = erpSltzList?.Count ?? 0;
            // 2. è°ƒç”¨ä¸šåŠ¡å±‚æ‰¹é‡ä¿å­˜æ–¹æ³•ï¼ˆäº‹åŠ¡å†…å¤„ç†ï¼Œè¦ä¹ˆå…¨æˆåŠŸè¦ä¹ˆå…¨å¤±è´¥ï¼‰
            var batchSaveSuccess = _mesInvItemArnManager.SaveList(erpSltzList);
            // 3. ç»„装返回数据(总条数、成功条数)
            resultData.totalCount = totalCount;
            resultData.successCount = batchSaveSuccess ? totalCount : 0;
            // 4. æ›´æ–°æ¶ˆæ¯ä¸­å¿ƒçŠ¶æ€
            messageEntity.Result = batchSaveSuccess ? 1 : 0;
            messageEntity.DealWith = 1;
            _messageCenterManager.save(messageEntity);
            // 5. è¿”回成功响应
            return new ResponseResult
            {
                status = 0,
                message = $"收料单批量保存完成,共{totalCount}条数据",
                data = resultData
            };
        }
        catch (Exception ex)
        {
            // 6. å¼‚常处理:记录错误日志
            messageEntity.Result = 0;
            messageEntity.DealWith = 0;
            messageEntity.ResultData = ex.Message + (ex.InnerException != null ? $"(内部异常:{ex.InnerException.Message})" : "");
            _messageCenterManager.save(messageEntity);
            // 7. è¿”回错误响应
            return ResponseResult.ResponseError(ex);
        }
    }
    /// <summary>
    /// èŽ·å–æ”¶æ–™å•åˆ—è¡¨ï¼ˆä¸»è¡¨æ•°æ®ï¼Œæ”¯æŒåŽç»­æ‰©å±•åˆ†é¡µ/筛选)
    /// </summary>
    /// <returns>收料单列表(总条数+列表数据)</returns>
    [HttpGet("GetList")]
    public ResponseResult GetList()
    {
        try
        {
            // 1. è°ƒç”¨ä¸šåŠ¡å±‚æŸ¥è¯¢åˆ—è¡¨æ–¹æ³•
            var invArnList = _mesInvItemArnManager.GetList();
            // 2. è¿”回查询结果
            return new ResponseResult
            {
                status = 0,
                message = "收料单列表查询成功",
                data = new { total = invArnList.Count, list = invArnList }
            };
        }
        catch (Exception ex)
        {
            // 3. å¼‚常处理
            return ResponseResult.ResponseError(ex);
        }
    }
    /// <summary>
    /// æ ¹æ®ID获取收料单详情(含主表+关联明细)
    /// </summary>
    /// <param name="id">收料单主表ID(Guid字符串)</param>
    /// <returns>收料单主表+明细详情</returns>
    // [HttpGet("GetById")]
    // public ResponseResult GetById(string id)
    // {
    //     try
    //     {
    //         // 1. æ ¡éªŒID格式(Guid转换)
    //         if (!Guid.TryParse(id, out Guid mainId))
    //         {
    //             return new ResponseResult
    //             {
    //                 status = 1,
    //                 message = "ID格式错误,请传入有效的Guid字符串",
    //                 data = null
    //             };
    //         }
    //
    //         // 2. è°ƒç”¨ä¸šåŠ¡å±‚æŸ¥è¯¢è¯¦æƒ…æ–¹æ³•ï¼ˆä¸»è¡¨+明细)
    //         var (mainEntity, detailList) = _mesInvItemArnManager.GetByIdWithDetails(mainId);
    //
    //         // 3. ç»„装返回数据(主表+明细)
    //         var resultData = new
    //         {
    //             main = mainEntity,
    //             details = detailList
    //         };
    //
    //         // 4. è¿”回详情结果
    //         return new ResponseResult
    //         {
    //             status = 0,
    //             message = "收料单详情查询成功",
    //             data = resultData
    //         };
    //     }
    //     catch (Exception ex)
    //     {
    //         // 5. å¼‚常处理
    //         return ResponseResult.ResponseError(ex);
    //     }
    // }
    /// <summary>
    /// æ ¹æ®å•据号获取收料单详情(含主表+关联明细)
    /// </summary>
    /// <param name="billNo">收料单单据号</param>
    /// <returns>收料单主表+明细详情</returns>
    [HttpGet("GetByBillNo")]
    public ResponseResult GetByBillNo(string billNo)
    {
        try
        {
            // 1. æ ¡éªŒå•据号参数
            if (string.IsNullOrEmpty(billNo))
            {
                return new ResponseResult
                {
                    status = 1,
                    message = "单据号不能为空",
                    data = null
                };
            }
            // 2. è°ƒç”¨ä¸šåŠ¡å±‚æŒ‰å•æ®å·æŸ¥è¯¢æ–¹æ³•ï¼ˆä¸»è¡¨+明细)
            var (mainEntity, detailList) = _mesInvItemArnManager.GetByBillNo(billNo);
            // 3. ç»„装返回数据
            var resultData = new
            {
                main = mainEntity,
                details = detailList
            };
            // 4. è¿”回详情结果
            return new ResponseResult
            {
                status = 0,
                message = $"单据号【{billNo}】收料单详情查询成功",
                data = resultData
            };
        }
        catch (Exception ex)
        {
            // 5. å¼‚常处理
            return ResponseResult.ResponseError(ex);
        }
    }
    /// <summary>
    /// æ–°å¢žæ”¶æ–™å•(直接传入MES实体,适用于内部系统创建)
    /// </summary>
    /// <param name="entity">收料单主表实体</param>
    /// <returns>新增结果(ID+成功状态)</returns>
    [HttpPost("Insert")]
    public ResponseResult Insert([FromBody] MesInvItemArn entity)
    {
        try
        {
            // 1. è¡¥å…¨å®žä½“默认值(主键、创建时间)
            entity.Id = Guid.NewGuid();
            entity.CreateDate = DateTime.Now;
            entity.CreateBy = "SYSTEM"; // é»˜è®¤ä¸ºç³»ç»Ÿåˆ›å»ºï¼Œå¯æ ¹æ®å®žé™…需求改为当前登录用户
          //  entity.LastUpdateTime = DateTime.Now;
           // entity.LastUpdateUser = "SYSTEM";
           // entity.Status = false; // åˆå§‹çŠ¶æ€ï¼šæœªå®¡æ ¸
           // entity.IsOut = false; // åˆå§‹çŠ¶æ€ï¼šæœªå‡ºåº“
            entity.IsSrm = 0; // åˆå§‹çŠ¶æ€ï¼šéžSRM
            // 2. è°ƒç”¨ä¸šåŠ¡å±‚æ–°å¢žæ–¹æ³•
            var insertSuccess = _mesInvItemArnManager.Insert(entity);
            // 3. è¿”回新增结果
            return new ResponseResult
            {
                status = 0,
                message = insertSuccess ? "收料单新增成功" : "收料单新增失败",
                data = new { id = entity.Id, success = insertSuccess }
            };
        }
        catch (Exception ex)
        {
            // 4. å¼‚常处理
            return ResponseResult.ResponseError(ex);
        }
    }
    /// <summary>
    /// æ›´æ–°æ”¶æ–™å•(直接传入MES实体,适用于内部系统更新)
    /// </summary>
    /// <param name="entity">收料单主表实体(需含ID)</param>
    /// <returns>更新结果(成功状态)</returns>
    // [HttpPost("Update")]
    // public ResponseResult Update([FromBody] MesInvItemArn entity)
    // {
    //     try
    //     {
    //         // 1. æ ¡éªŒID(必须传入已存在的ID)
    //         if (entity.Id == Guid.Empty)
    //         {
    //             return new ResponseResult
    //             {
    //                 status = 1,
    //                 message = "更新失败:收料单ID不能为空",
    //                 data = false
    //             };
    //         }
    //
    //         // 2. è¡¥å…¨æ›´æ–°å­—段(最后更新时间、最后更新人)
    //         entity.LastUpdateTime = DateTime.Now;
    //         entity.LastUpdateUser = "SYSTEM"; // å¯æ”¹ä¸ºå½“前登录用户
    //
    //         // 3. è°ƒç”¨ä¸šåŠ¡å±‚æ›´æ–°æ–¹æ³•ï¼ˆå¿½ç•¥åˆ›å»ºæ—¶é—´ï¼Œé¿å…è¦†ç›–ï¼‰
    //         var updateSuccess = _mesInvItemArnManager.Update(entity, ignoreColumns: m => new { m.CreateDate });
    //
    //         // 4. è¿”回更新结果
    //         return new ResponseResult
    //         {
    //             status = 0,
    //             message = updateSuccess ? "收料单更新成功" : "收料单更新失败(未找到对应数据或更新异常)",
    //             data = updateSuccess
    //         };
    //     }
    //     catch (Exception ex)
    //     {
    //         // 5. å¼‚常处理
    //         return ResponseResult.ResponseError(ex);
    //     }
    // }
}