From 42429ae61571ff9563c9e987cd52be2132e77775 Mon Sep 17 00:00:00 2001
From: pan <antony1029@163.com>
Date: 星期四, 06 十一月 2025 17:13:29 +0800
Subject: [PATCH] 提交出库

---
 项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs |  168 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 165 insertions(+), 3 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs"
index cd8417b..14c2945 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs"
@@ -1,4 +1,5 @@
-锘縰sing System;
+锘縰sing Microsoft.Extensions.Logging;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -13,12 +14,173 @@
 {
     public class MaterialUnitService : ServiceBase<Dt_MaterialUnit, IRepository<Dt_MaterialUnit>>, IMaterialUnitService
     {
+        private readonly ILogger<MaterialUnitService> _logger;
         public IRepository<Dt_MaterialUnit> Repository => BaseDal;
-        public MaterialUnitService(IRepository<Dt_MaterialUnit> BaseDal) : base(BaseDal)
+
+        public IRepository<Dt_MaterielInfo> _materielInfoRepository;
+        public MaterialUnitService(IRepository<Dt_MaterialUnit> BaseDal, ILogger<MaterialUnitService> logger, IRepository<Dt_MaterielInfo> materielInfoRepository) : base(BaseDal)
         {
+            _logger = logger;
+            _materielInfoRepository = materielInfoRepository;
+        }
+        /// <summary>
+        /// 鍗曚綅杞崲
+        /// </summary>
+        public async Task<decimal> ConvertAsync(string materialCode, decimal quantity, string fromUnit, string toUnit)
+        {
+            if (string.IsNullOrEmpty(materialCode))
+                throw new ArgumentException("鐗╂枡缂栧彿涓嶈兘涓虹┖");
+
+            if (string.IsNullOrEmpty(fromUnit) || string.IsNullOrEmpty(toUnit))
+                throw new ArgumentException("鍗曚綅涓嶈兘涓虹┖");
+
+            // 濡傛灉鍗曚綅鐩稿悓锛岀洿鎺ヨ繑鍥�
+            if (fromUnit.Equals(toUnit, StringComparison.OrdinalIgnoreCase))
+                return quantity;
+
+            var ratio = await GetConversionRatioAsync(materialCode, fromUnit, toUnit);
+
+            if (ratio == null)
+            {
+                _logger.LogWarning($"鏈壘鍒扮墿鏂� {materialCode} 浠� {fromUnit} 鍒� {toUnit} 鐨勫崟浣嶈浆鎹㈠叧绯�");
+                throw new InvalidOperationException($"鏈壘鍒扮墿鏂� {materialCode} 浠� {fromUnit} 鍒� {toUnit} 鐨勫崟浣嶈浆鎹㈠叧绯�");
+            }
+
+            return quantity * ratio.Value;
         }
 
-     
+        /// <summary>
+        /// 閲囪喘鍗曚綅杞簱瀛樺崟浣�
+        /// </summary>
+        public async Task<decimal> ConvertPurchaseToStockAsync(string materialCode, decimal quantity)
+        {
+            // 鑾峰彇鐗╂枡淇℃伅
+            var material = await _materielInfoRepository.Db.Queryable<Dt_MaterielInfo>()
+                .Where(x => x.MaterielCode == materialCode)
+                .FirstAsync();
+
+            if (material == null)
+            {
+                throw new ArgumentException($"鏈壘鍒扮墿鏂欑紪鍙�: {materialCode}");
+            }
+
+            return await ConvertAsync(materialCode, quantity, material.purchaseUOM, material.inventoryUOM);
+        }
+
+        /// <summary>
+        /// 棰嗘枡鍗曚綅杞簱瀛樺崟浣�
+        /// </summary>
+        public async Task<decimal> ConvertIssueToStockAsync(string materialCode, decimal quantity)
+        {
+            // 鑾峰彇鐗╂枡淇℃伅
+            var material = await _materielInfoRepository.Db.Queryable<Dt_MaterielInfo>()
+                .Where(x => x.MaterielCode == materialCode)
+                .FirstAsync();
+
+            if (material == null)
+            {
+                throw new ArgumentException($"鏈壘鍒扮墿鏂欑紪鍙�: {materialCode}");
+            }
+
+            return await ConvertAsync(materialCode, quantity, material.usageUOM, material.inventoryUOM);
+        }
+        /// <summary>
+        /// 鑾峰彇鍗曚綅杞崲姣旂巼
+        /// </summary>
+        public async Task<decimal?> GetConversionRatioAsync(string materialCode, string fromUnit, string toUnit)
+        {
+            // 灏濊瘯鐩存帴鏌ユ壘杞崲鍏崇郴
+            var conversion = await Repository.Db.Queryable<Dt_MaterialUnit>()
+                .Where(x => x.ItemNo == materialCode &&
+                           x.FromUom == fromUnit &&
+                           x.ToUom == toUnit)
+                .FirstAsync();
+
+            if (conversion != null)
+            {
+                return conversion.Ratio;
+            }
+
+            // 灏濊瘯鏌ユ壘鍙嶅悜杞崲鍏崇郴锛堝彇鍊掓暟锛�
+            var reverseConversion = await Repository.Db.Queryable<Dt_MaterialUnit>()
+                .Where(x => x.ItemNo == materialCode &&
+                           x.FromUom == toUnit &&
+                           x.ToUom == fromUnit)
+                .FirstAsync();
+
+            if (reverseConversion != null)
+            {
+                return 1 / reverseConversion.Ratio;
+            }
+
+            // 灏濊瘯閫氳繃涓棿鍗曚綅锛堝簱瀛樺崟浣嶏級杩涜杞崲
+            var material = await _materielInfoRepository.Db.Queryable<Dt_MaterielInfo>()
+                .Where(x => x.MaterielCode == materialCode)
+                .FirstAsync();
+
+            if (material != null)
+            {
+                var stockUnit = material.inventoryUOM;
+
+                // 濡傛灉鐩爣鍗曚綅宸茬粡鏄簱瀛樺崟浣嶏紝鐩存帴鏌ユ壘婧愬崟浣嶅埌搴撳瓨鍗曚綅鐨勮浆鎹�
+                if (toUnit.Equals(stockUnit, StringComparison.OrdinalIgnoreCase))
+                {
+                    var toStockRatio = await GetDirectRatioAsync(materialCode, fromUnit, stockUnit);
+                    if (toStockRatio != null) return toStockRatio;
+                }
+
+                // 濡傛灉婧愬崟浣嶆槸搴撳瓨鍗曚綅锛岀洿鎺ユ煡鎵惧簱瀛樺崟浣嶅埌鐩爣鍗曚綅鐨勮浆鎹�
+                if (fromUnit.Equals(stockUnit, StringComparison.OrdinalIgnoreCase))
+                {
+                    var fromStockRatio = await GetDirectRatioAsync(materialCode, stockUnit, toUnit);
+                    if (fromStockRatio != null) return fromStockRatio;
+                }
+
+                // 閫氳繃搴撳瓨鍗曚綅杩涜闂存帴杞崲锛歠romUnit -> stockUnit -> toUnit
+                var ratio1 = await GetDirectRatioAsync(materialCode, fromUnit, stockUnit);
+                var ratio2 = await GetDirectRatioAsync(materialCode, stockUnit, toUnit);
+
+                if (ratio1 != null && ratio2 != null)
+                {
+                    return ratio1 * ratio2;
+                }
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// 鑾峰彇鐩存帴杞崲姣旂巼锛堝寘鍚鍚戝拰鍙嶅悜鏌ユ壘锛�
+        /// </summary>
+        private async Task<decimal?> GetDirectRatioAsync(string materialCode, string fromUnit, string toUnit)
+        {
+            // 姝e悜鏌ユ壘
+            var conversion = await Repository.Db.Queryable<Dt_MaterialUnit>()
+                .Where(x => x.ItemNo == materialCode &&
+                           x.FromUom == fromUnit &&
+                           x.ToUom == toUnit)
+                .FirstAsync();
+
+            if (conversion != null)
+            {
+                return conversion.Ratio;
+            }
+
+            // 鍙嶅悜鏌ユ壘
+            var reverseConversion = await Repository.Db.Queryable<Dt_MaterialUnit>()
+                .Where(x => x.ItemNo == materialCode &&
+                           x.FromUom == toUnit &&
+                           x.ToUom == fromUnit)
+                .FirstAsync();
+
+            if (reverseConversion != null)
+            {
+                return 1 / reverseConversion.Ratio;
+            }
+
+            return null;
+        }
+
     }
 }
 

--
Gitblit v1.9.3