| | |
| | | using System; |
| | | using Microsoft.Extensions.Logging; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Text; |
| | |
| | | { |
| | | 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; |
| | | } |
| | | |
| | | // éè¿åºååä½è¿è¡é´æ¥è½¬æ¢ï¼fromUnit -> 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) |
| | | { |
| | | // æ£åæ¥æ¾ |
| | | 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; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |