kyy
2025-07-25 0a7af16f00ca918f5b61c6540c58193d53c5b70a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
using MES.Service.DB;
using MES.Service.Dto.webApi;
using MES.Service.Modes;
using MES.Service.util;
using SqlSugar;
 
namespace MES.Service.service;
 
public class MesCgthSqManager : Repository<MesCgthSq>
{
    // 明细表管理器(用于处理明细数据)
    //private readonly MesCgthSqDetailManager _detailManager = new();
    /// <summary>
    /// 批量保存采购退货单(主表+明细)
    /// </summary>
    public bool SaveList(List<ErpCgth> erpCgthList)
    {
        // 逐条处理,全部成功才返回true
        var result = erpCgthList.Select(Save).ToList();
        return result.All(b => b);
    }
 
    /// <summary>
    /// 保存采购退货单(主表+明细)
    /// </summary>
    public bool Save(ErpCgth erpCgth)
    {
        // 从ERP数据中提取主表和明细表DTO
        var erpMain = erpCgth.ErpCgtha;
        var erpDetails = erpCgth.ErpCgthB;
 
        // 映射主表和明细表实体
        var mesMain = MapErpCgthaToMesCgthSq(erpMain);
        var mesDetails = MapErpCgthBToMesCgthSqDetail(erpDetails, mesMain.Id); // 关联主表ID
 
        // 使用事务处理主从表联动操作
        return UseTransaction(db =>
        {
            // 根据操作类型(TYPE)执行不同逻辑(假设TYPE=1新增,2更新,3删除)
            switch (erpMain.TYPE)
            {
                case "1": // 新增
                case "2": // 更新(统一走新增或更新逻辑)
                case "4": 
                    return SaveOrUpdateData(db, mesMain, mesDetails) ? 1 : 0;
                case "3": // 删除
                    return DeleteData(db, mesMain, mesDetails) ? 1 : 0;
                default:
                    throw new NotImplementedException($"操作类型[{erpMain.TYPE}]未实现");
            }
        }) > 0;
    }
 
    /// <summary>
    /// 新增或更新数据(主表+明细)
    /// </summary>
    private bool SaveOrUpdateData(SqlSugarScope db, MesCgthSq mesMain, List<MesCgthSqDetail> mesDetails)
    {
        // 1. 处理主表:若已存在则更新,不存在则新增
        bool isMainExist = db.Queryable<MesCgthSq>().Where(m => m.BillNo == mesMain.BillNo).Any();
        int mainResult;
        if (isMainExist)
        {
            // 更新主表(忽略空字段)
            mainResult = db.Updateable(mesMain)
                .IgnoreColumns(m => m.Id) // 不更新主键
                .Where(m => m.BillNo == mesMain.BillNo)
                .ExecuteCommand();
        }
        else
        {
            // 新增主表(生成主键)
            mesMain.Id = Guid.NewGuid();
            mainResult = db.Insertable(mesMain).ExecuteCommand();
        }
 
        // 2. 处理明细表:先删除旧明细,再插入新明细(确保数据同步)
        // (通过主表ERPID关联旧明细)
        int oldDetailCount = db.Deleteable<MesCgthSqDetail>()
            .Where(d => d.Mid == mesMain.Id)
            .ExecuteCommand();
 
        // 插入新明细(关联主表ID)
        int detailResult = mesDetails.Count > 0
            ? db.Insertable(mesDetails).ExecuteCommand()
            : 1; // 无明细时默认成功
 
        // 3. 校验结果
        if (mainResult > 0 && detailResult > 0)
        {
            return true;
        }
 
        throw new NotImplementedException("主表或明细保存失败");
    }
 
    /// <summary>
    /// 删除数据(主表+明细)
    /// </summary>
    private bool DeleteData(SqlSugarScope db, MesCgthSq mesMain, List<MesCgthSqDetail> mesDetails)
    {
        // 处理ERPID为空的情况,转换为统一的空字符串进行比较
        string mainErpId = mesMain.ErpId?.ToString() ?? string.Empty;
    
        // 1. 删除明细(通过主表ERPID关联)
        int detailResult = db.Deleteable<MesCgthSqDetail>()
            .Where(d => (d.Eid.ToString() ?? string.Empty) == mainErpId)
            .ExecuteCommand();
 
        // 2. 删除主表(通过ERPID关联)
        int mainResult = db.Deleteable<MesCgthSq>()
            .Where(m => (m.ErpId.ToString() ?? string.Empty) == mainErpId)
            .ExecuteCommand();
 
        return mainResult > 0 && detailResult >= 0; // 允许明细原本不存在(>=0)
    }
 
    /// <summary>
    /// ErpCgtha 映射到 MesCgthSq(仅映射ErpCgtha中存在的字段)
    /// </summary>
    private MesCgthSq MapErpCgthaToMesCgthSq(ErpCgtha erpMain)
    {
        return new MesCgthSq
        {
            // 主表核心字段(仅从ErpCgtha取值)
            ErpId = erpMain.ERPID, // ERP主表ID
            BillNo = erpMain.billNo, // 单据编号
            Type = erpMain.TYPE, // 操作类型
            FDate = erpMain.FDate, // 退料日期
            FDocumentStatus = erpMain.FDocumentStatus, // 单据状态
            FSupplierId = erpMain.FSupplierID, // 供应商ID
            FBillTypeId = erpMain.FBillTypeID, // 单据类型
            FBusinessType = erpMain.FBusinessType, // 业务类型
            ReturnType = erpMain.FMRTYPE, // 退料类型(对应ErpCgtha的退料类型)
            ReturnMethod = erpMain.FMRMODE, // 退料方式(对应ErpCgtha的退料方式)
            CreateBy = erpMain.FCreatorId, // 创建人
            FPurchaseOrgId = erpMain.FPurchaseOrgId, // 采购组织
            ThOrgId = erpMain.FStockOrgId, // 退料组织
            FRequireOrgId = erpMain.FRequireOrgId, // 需求组织
            FMRDeptId = erpMain.FMRDeptId, // 退料部门
            FStockerId = erpMain.FSTOCKERID, // 仓管员
            FPurchaserId = erpMain.FPURCHASERID, // 采购员
            FMRReason = erpMain.FMRREASON, // 退料原因
            FPurchaseDeptId = erpMain.FPURCHASEDEPTID, // 采购部门
            FPurchaserGroupId = erpMain.FPURCHASERGROUPID, // 采购组
            FACCTYPE = erpMain.FACCTYPE, // 验收方式
            FCreateDate = erpMain.FCreateDate, // 创建日期
            FWPVTINTEGERL6W = erpMain.F_WPVT_INTEGER_L6W, // 扫码标识
            // DepotId = string.IsNullOrEmpty(erpMain.FSTOCKID)
            //     ? null
            //     : Convert.ToInt32(erpMain.FSTOCKID), // 仓库ID(转换为int)
            SuppId = string.IsNullOrEmpty(erpMain.FSupplierID)
                ? null
                : Convert.ToInt32(erpMain.FSupplierID), // 供应商ID(转换为int)
            // 系统自动赋值字段
            CreateDate = DateTime.Now,
            LastUpdateTime = DateTime.Now
        };
    }
 
    /// <summary>
    /// ErpCgthB 映射到 MesCgthSqDetail(仅映射ErpCgthB中存在的字段)
    /// </summary>
    private List<MesCgthSqDetail> MapErpCgthBToMesCgthSqDetail(List<ErpCgthB> erpDetails, Guid mainId)
    {
        return erpDetails.Select(erpDetail => new MesCgthSqDetail
        {
            // 关联主表ID
            Mid= mainId, // 主表ID(MesCgthSq的Id)
            // 明细核心字段(仅从ErpCgthB取值)
            ErpId = string.IsNullOrEmpty(erpDetail.ERPID) ? null : Convert.ToInt32(erpDetail.ERPID), // ERP明细ID
            Eid = string.IsNullOrEmpty(erpDetail.EID) ? null : Convert.ToInt32(erpDetail.EID), // 外部系统ID
            FsrcBillNo = erpDetail.FSRCBillNo, // 源单单号
            FsrcBillTypeId = erpDetail.FSRCBillTypeId, // 源单类型
            ItemId = string.IsNullOrEmpty(erpDetail.FMATERIALID)
                ? null
                : Convert.ToInt32(erpDetail.FMATERIALID), // 物料ID
            FUnitId = erpDetail.FUnitID, // 库存单位
            DepotId = string.IsNullOrEmpty(erpDetail.FSTOCKID) ? null : Convert.ToInt64(erpDetail.FSTOCKID), // 仓库ID
            FstockLocId = erpDetail.FSTOCKLOCID, // 仓位
            FLot = erpDetail.FLot, // 批号
            SqNum = erpDetail.FRMREALQTY, // 实退数量
            Remark = erpDetail.FNOTE, // 备注
            FMtoNo = erpDetail.FMtoNo, // 计划跟踪号
            // 系统自动赋值字段
            IsFinish = false // 初始未完成
        }).ToList();
    }
 
   }