Procházet zdrojové kódy

feat: 发货单反写检验申请,导出数据包不成功回滚

JaneDoe před 2 měsíci
rodič
revize
778fe7b2f7

+ 195 - 53
UniformMaterialManagementSystem/ViewModels/DeliveryReceiptViewModel.cs

@@ -15,6 +15,7 @@ using System.Windows.Controls;
 using System.Windows.Media.Media3D;
 using CommunityToolkit.Mvvm.ComponentModel;
 using CommunityToolkit.Mvvm.Input;
+using DocumentFormat.OpenXml.Bibliography;
 using DocumentFormat.OpenXml.Drawing;
 using DocumentFormat.OpenXml.Drawing.Charts;
 using DocumentFormat.OpenXml.InkML;
@@ -408,6 +409,13 @@ namespace UniformMaterialManagementSystem.ViewModels
                 }
             }
 
+            // 记录包号和材料批号信息
+            Dictionary<string, string> packBatckNos = new Dictionary<string, string>();
+            foreach (DeliveryReceiptDetail dtl in CurrDeliveryReceipt.DeliveryReceiptDetails)
+            {
+                packBatckNos.Add(dtl.PacketNo, dtl.BatchNo);
+            }
+
             // 界面删除
             string currContracNo = CurrDeliveryReceipt.ContractNo;
             string currProductName = CurrDeliveryReceipt.ProductName;
@@ -425,7 +433,12 @@ namespace UniformMaterialManagementSystem.ViewModels
             MessageBox.Show("删除成功");
 
             // 删除后反写到数据库
-            UpdataContractDetail(currContracNo, currProductName);
+            bool isSuccCD = UpdataContractDetail(currContracNo, currProductName);
+            bool isSuccAD = UpdateApplyDetail(packBatckNos, false);
+            if (isSuccCD && isSuccAD)
+            {
+                MessageBox.Show("反写合同明细、检验申请明细成功。");
+            }
         }
 
         [RelayCommand]
@@ -459,11 +472,11 @@ namespace UniformMaterialManagementSystem.ViewModels
             }
 
             // 保存到数据库
-            bool isNeedRewrite = false;
+            bool needUpdtCD = false;
+            bool needUpdtIAD = false;
             var serviceDtl = App.Current.Services.GetService<IDataBaseService<DeliveryReceiptDetail>>();
             if (CurrDeliveryReceipt.IsNewRow)
             {
-                isNeedRewrite = true;
                 // 新增行插入到数据库
                 CurrDeliveryReceipt.IsNewRow = false;
                 _service.Insert(CurrDeliveryReceipt);
@@ -473,6 +486,10 @@ namespace UniformMaterialManagementSystem.ViewModels
                     dtl.IsNewRow = false;
                     serviceDtl?.Insert(dtl);
                 }
+
+                // 新增行需要反写数据
+                needUpdtCD = true;
+                needUpdtIAD = true;
             }
             else
             {
@@ -484,7 +501,8 @@ namespace UniformMaterialManagementSystem.ViewModels
                                         .Where(p => entry.Property(p.Name).IsModified)
                                         .Select(p => p.Name)
                                         .ToList();
-                isNeedRewrite = modifiedProperties.Contains("ShippedPackets") || modifiedProperties.Contains("ShippedQty");
+                needUpdtCD = modifiedProperties.Contains("ShippedQty") || modifiedProperties.Contains("ShippedPackets");
+                needUpdtIAD = modifiedProperties.Contains("ShippedPackets");
 
                 // 已保存行更新到数据库
                 _service.Update(CurrDeliveryReceipt);
@@ -514,10 +532,31 @@ namespace UniformMaterialManagementSystem.ViewModels
             }
             MessageBox.Show("当前行保存成功。");
 
-            // 反写合同数据
-            if (isNeedRewrite)
+            // 反写合同明细数据
+            bool isSuccCD = false;
+            if (needUpdtCD)
             {
-                UpdataContractDetail(CurrDeliveryReceipt.ContractNo, CurrDeliveryReceipt.ProductName);
+                isSuccCD = UpdataContractDetail(CurrDeliveryReceipt.ContractNo, CurrDeliveryReceipt.ProductName);
+                if (!isSuccCD) { return; } // 反写不成功会提示异常
+            }
+
+            // 反写检验申请明细的 ShippedStatus:是否发货完成
+            bool isSuccAD = false;
+            if (needUpdtIAD)
+            {
+                Dictionary<string, string> packBatckNos = new Dictionary<string, string>();
+                foreach (DeliveryReceiptDetail dtl in CurrDeliveryReceipt.DeliveryReceiptDetails)
+                {
+                    packBatckNos.Add(dtl.PacketNo, dtl.BatchNo);
+                }
+                isSuccAD = UpdateApplyDetail(packBatckNos, true);
+                if (!isSuccCD) { return; }
+            }
+
+            // 反写成功提示
+            if (isSuccCD && isSuccAD)
+            {
+                MessageBox.Show("反写合同明细、检验申请明细成功。");
             }
         }
 
@@ -612,24 +651,47 @@ namespace UniformMaterialManagementSystem.ViewModels
                 return;
             }
 
-            // 需要存在 bin\DataBase 目录,且目录下存在一份 .db 文件,需要存在表
-            // 导出主表到 bin\DataBase 目录下的 .db:根据主键判断,存在数据则更新,不存在则插入
-            var deliveries = DeliveryReceipts;
-            DataBaseUtil.ExportTable(deliveries, "DeliveryReceipts"); // 数据库表名输错会抛出异常,但在本方法里获取不到抛出异常
+            // 导出数据包
+            bool isNeedRollback = true;
+            try
+            {
+                // 需要存在 bin\DataBase 目录,且目录下存在一份 .db 文件,需要存在表
+                // 选择的发货单导出到 .db 文件:根据主键判断,存在数据则更新,不存在则插入
+                var deliveries = DeliveryReceipts;
+                DataBaseUtil.ExportTable(deliveries, "DeliveryReceipts"); // 数据库表名输错会抛出异常,但在本方法里获取不到抛出异常
+
+                // 选择发货单的明细导出到 .db 文件
+                List<DeliveryReceiptDetail> details = new List<DeliveryReceiptDetail>();
+                foreach (var delivery in selectedDeliveries)
+                {
+                    details.AddRange(delivery.DeliveryReceiptDetails);
+                }
+                DataBaseUtil.ExportTable(details, "DeliveryReceiptDetails");
 
-            // 必须先导出主表,否则明细插入数据库时报错:Foreign Key constraint failed
-            List<DeliveryReceiptDetail> details = new List<DeliveryReceiptDetail>();
-            foreach (var delivery in DeliveryReceipts)
+                // 将选择的数据导出为加密数据包
+                string exportPath = DataBaseUtil.ExportData();
+                if (!string.IsNullOrEmpty(exportPath))
+                {
+                    isNeedRollback = false;
+                    MessageBox.Show("导出成功。");
+                }
+            }
+            catch (Exception ex)
             {
-                details.AddRange(delivery.DeliveryReceiptDetails);
+                MessageBox.Show("导出出错:" + ex.Message);
             }
-            DataBaseUtil.ExportTable(details, "DeliveryReceiptDetails");
 
-            // 将选择的数据导出为加密数据包
-            string exportPath = DataBaseUtil.ExportData();
-            if (!string.IsNullOrEmpty(exportPath))
+            // 导出不成功,回滚导出状态
+            if (!isNeedRollback) { return; }
+            foreach (var delivery in selectedDeliveries)
             {
-                MessageBox.Show("导出成功。");
+                delivery.IsExportDelivery = false;
+                _service.Update(delivery);
+            }
+            bool isRollbackSuccess = _service.SaveChanges();
+            if (!isRollbackSuccess)
+            {
+                MessageBox.Show("回滚发货单导出状态失败,请联系系统管理员!");
             }
         }
 
@@ -871,12 +933,16 @@ namespace UniformMaterialManagementSystem.ViewModels
             if (result != MessageBoxResult.Yes) { return; }
 
             // 删除行
+            Dictionary<string, string> packBatckNos = new Dictionary<string, string>();
             foreach (DeliveryReceiptDetail dtl in savedRows)
             {
                 // 界面删除
                 details.Remove(dtl);
                 // 数据库删除
                 serviceDtl?.Delete(dtl);
+
+                // 记录包号和材料批号信息(反写检验申请明细)
+                packBatckNos.Add(dtl.PacketNo, dtl.BatchNo);
             }
 
             // 删除成功后更新数据
@@ -899,8 +965,13 @@ namespace UniformMaterialManagementSystem.ViewModels
             // 删除成功提示
             MessageBox.Show($"删除 {savedRows.Count} 行已保存行。");
 
-            // 反写合同
-            UpdataContractDetail(CurrDeliveryReceipt.ContractNo, CurrDeliveryReceipt.ProductName);
+            // 反写
+            bool isSuccCD = UpdataContractDetail(CurrDeliveryReceipt.ContractNo, CurrDeliveryReceipt.ProductName);
+            bool isSuccAD = UpdateApplyDetail(packBatckNos, false);
+            if (isSuccCD && isSuccAD)
+            {
+                MessageBox.Show("反写合同明细、检验申请明细成功。");
+            }
         }
 
         [RelayCommand]
@@ -1107,10 +1178,10 @@ namespace UniformMaterialManagementSystem.ViewModels
 
                 // 判断导入的行是否存在对应的检验申请明细
                 string? importPackNo = drImprot["包号"].ToString();
-                var packApplyDetails = apply!.InspectApplyDetails.Where(x => x.PacketNo.Equals(importPackNo));
+                var packApplyDetails = apply!.InspectApplyDetails.Where(x => !x.ShippedStatus && x.PacketNo.Equals(importPackNo));
                 if (!packApplyDetails.Any())
                 {
-                    packNoMsg.AppendLine($"材料批号 [{importPackNo}] ,包号 [{importPackNo}] (对应检验申请 [{apply.ApplyNo}])");
+                    packNoMsg.AppendLine($"包号 [{importPackNo}] (对应检验申请 [{apply.ApplyNo}])");
                     continue;
                 }
 
@@ -1129,7 +1200,7 @@ namespace UniformMaterialManagementSystem.ViewModels
             }
             if (packNoMsg.Length > 0)
             {
-                packNoMsg = packNoMsg.Insert(0, "\n以下材料批号和包号在对应的检验申请中找不到对应的明细,请检查数据后重新导入!\n");
+                packNoMsg = packNoMsg.Insert(0, "\n以下包号不存在或已发货,请检查数据后重新导入!\n");
             }
 
             // 若没有需要导入的行,直接返回
@@ -1143,9 +1214,9 @@ namespace UniformMaterialManagementSystem.ViewModels
             decimal importQty = importRows.Select(x => x.ShippedQuantity).Sum();
             decimal contractQty = CurrDeliveryReceipt.ContractQty;
             decimal hasShippedQty = _service.Query(x => x.ProductName.Equals(CurrDeliveryReceipt!.ProductName) && x.ContractNo.Equals(CurrDeliveryReceipt.ContractNo) && !x.Guid.Equals(CurrDeliveryReceipt.Guid))
-                                    .Select(x => x.ShippedQty)
-                                    .ToList()
-                                    .Sum();
+                                            .Select(x => x.ShippedQty)
+                                            .ToList()
+                                            .Sum();
             decimal currRemainQty = contractQty - hasShippedQty;
             if (importQty > currRemainQty + _tolerance)
             {
@@ -1153,15 +1224,29 @@ namespace UniformMaterialManagementSystem.ViewModels
                 return;
             }
 
+
+
+            // 记录导入前的数据
+            Dictionary<string, string> origiPackBatchNos = new Dictionary<string, string>();
+            foreach (DeliveryReceiptDetail dtl in CurrDeliveryReceipt.DeliveryReceiptDetails)
+            {
+                origiPackBatchNos.Add(dtl.PacketNo, dtl.BatchNo);
+            }
+
             // 清空子表数据
             foreach (var dtl in CurrDeliveryReceipt.DeliveryReceiptDetails)
             {
                 serviceDtl?.Delete(dtl);
             }
-            // 子表插入到数据库
+
+            // 导入的明细数据插入到数据库
+            Dictionary<string, string> importPackBatchNos = new Dictionary<string, string>();
             foreach (var dtl in importRows)
             {
                 serviceDtl?.Insert(dtl);
+
+                // 记录包号和材料批号,用于反写检验明细
+                importPackBatchNos.Add(dtl.PacketNo, dtl.BatchNo);
             }
             // 重新汇总子表
             CurrDeliveryReceipt.ShippedPackets = importRows.Count;
@@ -1187,7 +1272,13 @@ namespace UniformMaterialManagementSystem.ViewModels
             MessageBox.Show($"成功导入 {importRows.Count} 行。" + batchErrMsg + packNoMsg);
 
             // 反写合同数据
-            UpdataContractDetail(CurrDeliveryReceipt.ContractNo, CurrDeliveryReceipt.ProductName);
+            bool isSuccCD = UpdataContractDetail(CurrDeliveryReceipt.ContractNo, CurrDeliveryReceipt.ProductName);
+            bool isSuccAD1 = UpdateApplyDetail(origiPackBatchNos, false);
+            bool isSuccAD2 = UpdateApplyDetail(importPackBatchNos, true);
+            if (isSuccCD && isSuccAD1 && isSuccAD2)
+            {
+                MessageBox.Show("反写合同明细、检验申请明细成功。");
+            }
         }
 
         [RelayCommand]
@@ -1501,6 +1592,14 @@ namespace UniformMaterialManagementSystem.ViewModels
                 return false;
             }
 
+            // 子表必须有行
+            var details = CurrDeliveryReceipt!.DeliveryReceiptDetails;
+            if (CurrDeliveryReceipt.ShippedPackets == 0 || CurrDeliveryReceipt.ShippedQty == 0 || details == null || details.Count == 0)
+            {
+                MessageBox.Show("发货单明细为空,不允许保存!");
+                return false;
+            }
+
             // 检查子表必录项
             var nullBatchNoRows = CurrDeliveryReceipt!.DeliveryReceiptDetails.Where(x => string.IsNullOrEmpty(x.BatchNo));
             var nullPackageNoRows = CurrDeliveryReceipt.DeliveryReceiptDetails.Where(x => string.IsNullOrEmpty(x.PacketNo));
@@ -1600,10 +1699,10 @@ namespace UniformMaterialManagementSystem.ViewModels
 
                 // 判断导入的行是否存在对应的检验申请明细
                 string? importPackNo = dtl.PacketNo;
-                var packApplyDetails = apply!.InspectApplyDetails.Where(x => x.PacketNo.Equals(importPackNo));
+                var packApplyDetails = apply!.InspectApplyDetails.Where(x => !x.ShippedStatus && x.PacketNo.Equals(importPackNo));
                 if (!packApplyDetails.Any())
                 {
-                    packNoMsg.AppendLine($"材料批号 [{importPackNo}] ,包号 [{importPackNo}] (对应检验申请 [{apply.ApplyNo}])");
+                    packNoMsg.AppendLine($"包号 [{importPackNo}] (对应检验申请 [{apply.ApplyNo}])");
                     continue;
                 }
             }
@@ -1617,7 +1716,7 @@ namespace UniformMaterialManagementSystem.ViewModels
             }
             if (packNoMsg.Length > 0)
             {
-                packNoMsg = packNoMsg.Insert(0, "以下材料批号和包号在对应的检验申请中找不到对应的明细,请检查数据后重新导入!\n");
+                packNoMsg = packNoMsg.Insert(0, "以下包号不存在或已发货,请检查数据后重新导入!\n");
                 hint.AppendLine(packNoMsg.ToString());
             }
             if (hint.Length > 0)
@@ -1689,42 +1788,42 @@ namespace UniformMaterialManagementSystem.ViewModels
         /// 反写合同明细
         /// </summary>
         /// <returns></returns>
-        private void UpdataContractDetail(string contactNo, string productName)
+        private bool UpdataContractDetail(string contactNo, string productName)
         {
-            // 反写合同明细
+            // 获取发货单对应的合同明细
             var serviceCD = App.Current.Services.GetService<IDataBaseService<ContractDetail>>();
-            if (serviceCD == null) { return; }
+            if (serviceCD == null) { return false; }
             var contractDetails = serviceCD.Query(x => x.Contract.ContractNo.Equals(contactNo) && x.Material.Name.Equals(productName))
-                                  .Include(x => x.Contract)
-                                  .Include(x => x.Material);
+                                           .Include(x => x.Contract)
+                                           .Include(x => x.Material);
             if (contractDetails == null || !contractDetails.Any())
             {
                 MessageBox.Show("获取对应的合同明细失败!");
-                return;
+                return false;
             }
 
-            // 更新发货数量
+            // 重新计算发货数量
             ContractDetail? contractDtl = contractDetails.FirstOrDefault();
-            if (contractDtl == null) { return; }
-            // 除了本单
+            if (contractDtl == null) { return false; }
             decimal hasShippedQty = _service.Query(x => x.ProductName.Equals(productName) && x.ContractNo.Equals(contactNo))
-                                    .Select(x => x.ShippedQty)
-                                    .ToList()
-                                    .Sum();
+                                            .Select(x => x.ShippedQty)
+                                            .ToList()
+                                            .Sum();
             contractDtl.ShippedQuantity = hasShippedQty;
-            // 保存、导入时会校验数量,删除时不会超出数量,所以不用再次校验
+
+            // 更新合同明细的 ShippedStatus:是否发货完成
             if (hasShippedQty < contractDtl.ContractQty) // 主表的发运数量只汇总 > 0 的,不为负数
             {
                 contractDtl.ShippedStatus = false;
             }
             else if (hasShippedQty >= contractDtl.ContractQty && hasShippedQty < contractDtl.ContractQty + _tolerance)
             {
-                contractDtl.ShippedStatus = false;
+                contractDtl.ShippedStatus = true;
             }
-            else if (hasShippedQty >= contractDtl.ContractQty + _tolerance)
+            else if (hasShippedQty >= contractDtl.ContractQty + _tolerance) // 保存、导入时会校验数量,删除时不会超出数量
             {
-                MessageBox.Show("反写合同明细出错:发运数量超出合同数量!");
-                return;
+                MessageBox.Show("反写合同明细出错:发运数量超出合同数量,请检查数据后重试!");
+                return false;
             }
 
             // 保存到数据库
@@ -1733,11 +1832,54 @@ namespace UniformMaterialManagementSystem.ViewModels
             if (!isContractSuccess)
             {
                 MessageBox.Show("反写合同明细失败!");
-                return;
+                return false;
             }
 
-            MessageBox.Show("反写合同明细成功。");
-            return;
+            return true;
+        }
+
+        /// <summary>
+        /// 反写检验申请明细
+        /// </summary>
+        private bool UpdateApplyDetail(Dictionary<string, string> packBatchNos, bool isShippedComplete)
+        {
+            // 更新检验申请明细
+            int updateCount = 0;
+            var serviceIAD = App.Current.Services.GetService<IDataBaseService<InspectApplyDetail>>();
+            if (serviceIAD == null) { return false; }
+            foreach (string packNo in packBatchNos.Keys)
+            {
+                // 获取包号对应的检验申请明细
+                var serviceIA = App.Current.Services.GetService<IDataBaseService<InspectApply>>();
+                if (serviceIA == null) { return false; }
+                InspectApply? apply = serviceIA.Query(x => x.BatchNo.Equals(packBatchNos[packNo]))
+                                               .Include(x => x.InspectApplyDetails)
+                                               .FirstOrDefault();
+                if (apply == null) { return false; }
+                InspectApplyDetail? applyDetail = apply.InspectApplyDetails.Where(x => x.PacketNo.Equals(packNo)).FirstOrDefault();
+                if (applyDetail == null) { return false; }
+
+                // 更新 ShippedStatus :是否发货完成
+                bool origiStatus = applyDetail.ShippedStatus;
+                if (origiStatus != isShippedComplete)
+                {
+                    applyDetail.ShippedStatus = isShippedComplete;
+                    serviceIAD.Update(applyDetail);
+                    updateCount++;
+                }
+            }
+            // 若不需要更新直接返回 true
+            if (updateCount == 0) { return true; }
+
+            // 保存到数据库
+            bool isSucc = serviceIAD.SaveChanges();
+            if (!isSucc)
+            {
+                MessageBox.Show("反写检验申请明细失败!");
+                return false;
+            }
+
+            return true;
         }
 
         #endregion