| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- namespace Admin.NET.Plugin.AiDOP.Supply;
- /// <summary>
- /// 采购申请转 DO/PO 服务。P4 初版仅处理本次生成的要货令 PR,不扫描历史 PR。
- /// </summary>
- public class PurchaseOrderTransferService : ITransient
- {
- private readonly ISqlSugarClient _db;
- private readonly NumberRuleService _numberRuleService;
- private readonly UserManager _userManager;
- public PurchaseOrderTransferService(ISqlSugarClient db, NumberRuleService numberRuleService, UserManager userManager)
- {
- _db = db;
- _numberRuleService = numberRuleService;
- _userManager = userManager;
- }
- public async Task<PurchaseOrderTransferResult> TransferGeneratedRequireGoodsAsync(List<PurchaseRequestMain> requests, string account)
- {
- var candidates = requests.Where(x => x.IsRequireGoods == 1).ToList();
- if (candidates.Count == 0) return new PurchaseOrderTransferResult();
- var createdOrders = new List<string>();
- var transferredPrIds = new List<long>();
- var groups = candidates
- .GroupBy(x => new
- {
- x.TenantId,
- x.CompanyId,
- x.FactoryId,
- x.PrPurchaseId,
- x.PrPurchaseNumber,
- x.PrPurchaseName,
- SupplierType = x.SupplierType ?? string.Empty
- })
- .ToList();
- foreach (var tenantGroup in groups.GroupBy(x => x.Key.TenantId.ToString()))
- {
- var groupList = tenantGroup.ToList();
- var purOrdNumbers = await _numberRuleService.NextBatchInCurrentTransactionAsync("DO", tenantGroup.Key, groupList.Count, account);
- if (purOrdNumbers.Count < groupList.Count || purOrdNumbers.Any(string.IsNullOrWhiteSpace))
- throw Oops.Oh($"当前DO/PO单号生成失败,请检查DO编号规则维护。Domain={tenantGroup.Key}");
- for (var i = 0; i < groupList.Count; i++)
- {
- var group = groupList[i];
- var purOrd = purOrdNumbers[i].Trim();
- var now = DateTime.Now;
- var supplierType = group.Key.SupplierType;
- var isOutsource = string.Equals(supplierType, "委外", StringComparison.OrdinalIgnoreCase);
- var poType = isOutsource ? "PW" : "po";
- var usage = isOutsource ? "委外加工" : supplierType;
- var buyer = ResolveBuyer(supplierType);
- var rows = group.OrderBy(x => x.PrSarriveDate).ThenBy(x => x.PrBillNo).ToList();
- await InsertPurchaseOrderMasterAsync(purOrd, poType, usage, buyer, group.Key.PrPurchaseNumber, now, account, group.Key.TenantId);
- var masterId = await _db.Ado.GetIntAsync(
- "SELECT IFNULL(MAX(RecID),0) FROM PurOrdMaster WHERE PurOrd=@PurOrd",
- new SugarParameter("@PurOrd", purOrd));
- if (masterId <= 0) throw Oops.Oh("DO/PO主表生成失败。");
- for (var lineIndex = 0; lineIndex < rows.Count; lineIndex++)
- {
- await InsertPurchaseOrderDetailAsync(purOrd, poType, masterId, lineIndex + 1, rows[lineIndex], account);
- rows[lineIndex].State = 4;
- rows[lineIndex].UpdateByName = account;
- rows[lineIndex].UpdateTime = now;
- transferredPrIds.Add(rows[lineIndex].Id);
- }
- createdOrders.Add(purOrd);
- }
- }
- return new PurchaseOrderTransferResult
- {
- CreatedOrderCount = createdOrders.Count,
- TransferredPrCount = transferredPrIds.Count,
- CreatedOrders = createdOrders,
- TransferredPrIds = transferredPrIds
- };
- }
- private async Task InsertPurchaseOrderMasterAsync(
- string purOrd,
- string poType,
- string? usage,
- string buyer,
- string? supplierCode,
- DateTime now,
- string account,
- long tenantId)
- {
- await _db.Ado.ExecuteCommandAsync(
- """
- INSERT INTO PurOrdMaster
- (
- Confirming, CreditTermsInt, Disc, ExchRate, EstVal, ExchRate1, ExchRate2,
- FixedPrice, FixedRate, Frt, PartialOK, AmtPrepaid, PrintPO, PST, Recurr,
- `Release`, Revision, Scheduled, ServiceCharge, SpecialCharge, Taxable,
- Tax1, Tax2, Tax3, TransportDays, IsActive, IsConfirm, Potype, IsChanged,
- TaxIn, Amt, IsPriceChanged,
- Buyer, Domain, PurOrd, OrdDate, ReqBy, Status, Supp, CreateUser, CreateTime,
- UpdateUser, UpdateTime, `Usage`, FSTID, Typed, tenant_id
- )
- VALUES
- (
- 0, 0, 0, 1, 0, 1, 1,
- 0, 0, 0, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1,
- 0, 0, 0, 0, 1, 1, @PoType, 0,
- 1, 0, 0,
- @Buyer, @Domain, @PurOrd, @Now, 'DO', '', @Supp, @CreateUser, @Now,
- @UpdateUser, @Now, @Usage, @FSTID, @Typed, @TenantId
- )
- """,
- new SugarParameter("@PoType", poType),
- new SugarParameter("@Buyer", buyer),
- new SugarParameter("@Domain", tenantId.ToString()),
- new SugarParameter("@PurOrd", purOrd),
- new SugarParameter("@Now", now),
- new SugarParameter("@Supp", supplierCode),
- new SugarParameter("@CreateUser", account),
- new SugarParameter("@UpdateUser", account),
- new SugarParameter("@Usage", usage),
- new SugarParameter("@FSTID", string.Equals(usage, "VMI", StringComparison.OrdinalIgnoreCase) ? "3" : string.Empty),
- new SugarParameter("@Typed", poType == "PW" ? "s" : string.Empty),
- new SugarParameter("@TenantId", tenantId <= 0 ? null : tenantId));
- }
- private async Task InsertPurchaseOrderDetailAsync(string purOrd, string poType, int masterId, int line, PurchaseRequestMain pr, string account)
- {
- var item = (await _db.Ado.SqlQueryAsync<ItemLookupRow>(
- """
- SELECT
- COALESCE(NULLIF(im.ItemNum,''), ic.number) AS ItemNum,
- COALESCE(NULLIF(im.Descr,''), ic.name) AS Descr,
- COALESCE(NULLIF(im.UM,''), ic.unit) AS UM,
- IFNULL(im.Location, '') AS Location,
- IFNULL(im.Rev, '') AS Rev,
- IFNULL(im.Drawing, '') AS Drawing
- FROM ic_item ic
- LEFT JOIN ItemMaster im ON ic.number = im.ItemNum
- WHERE ic.Id = @IcitemId
- LIMIT 1
- """,
- new SugarParameter("@IcitemId", pr.IcitemId))).FirstOrDefault();
- await _db.Ado.ExecuteCommandAsync(
- """
- INSERT INTO PurOrdDetail
- (
- QtyBO, RctCost, CreditTermsInt, UpdateCurrentCost, CumReceived1, CumReceived2,
- CumReceived3, CumReceived4, Disc, FixedPrice, InspectReq, SingleLot, SupplyPer,
- PurOrd, PST, PackingSlipQty, PayUMConv, PurCost, RctQty, QtyOrded, QtyReceived,
- QtyReturned, Active, QtyReleased, RctUMConversion, Scheduled, ScheduledChanged,
- SchedMRPReq, SafetyDays, SafetyHours, StdCost, Taxable, TaxIn, MaxTaxableAmt,
- TransportHours, UMConversion, VAT, IsActive, IsConfirm, Potype, IsChanged,
- TaxRate, IsRounding, ReceiptQty, BarCodeQty, IsClosed, QtyReturnedRefund, CumQtyBO,
- Line, ItemNum, Descr, UM, Rev, Drawing, Location, DueDate, NeedDate, LotSerial, PurOrdRecID, Status, Req,
- CreateUser, CreateTime, UpdateUser, UpdateTime, tenant_id
- )
- VALUES
- (
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- @PurOrd, 0, 0, 1, 0, 0, @QtyOrded, 0,
- 0, 1, 0, 1, 0, 0,
- 0, 0, 0, 0, 1, 1, 0,
- 0, 1, 0, 1, 1, @PoType, 0,
- 0, 0, 0, 0, 0, 0, 0,
- @Line, @ItemNum, @Descr, @UM, @Rev, @Drawing, @Location, @DueDate, @NeedDate, '', @PurOrdRecID, 'R', @Req,
- @CreateUser, @Now, @UpdateUser, @Now, @TenantId
- )
- """,
- new SugarParameter("@PurOrd", purOrd),
- new SugarParameter("@PoType", poType),
- new SugarParameter("@QtyOrded", pr.PrAqty ?? pr.PrSqty ?? pr.PrRqty ?? 0),
- new SugarParameter("@Line", line),
- new SugarParameter("@ItemNum", item?.ItemNum ?? pr.IcitemName ?? string.Empty),
- new SugarParameter("@Descr", item?.Descr ?? pr.IcitemName ?? string.Empty),
- new SugarParameter("@UM", item?.UM ?? pr.PrUnit ?? string.Empty),
- new SugarParameter("@Rev", item?.Rev ?? string.Empty),
- new SugarParameter("@Drawing", item?.Drawing ?? string.Empty),
- new SugarParameter("@Location", string.IsNullOrWhiteSpace(item?.Location) ? "1001" : item.Location),
- new SugarParameter("@DueDate", pr.PrSarriveDate),
- new SugarParameter("@NeedDate", pr.PrSarriveDate),
- new SugarParameter("@PurOrdRecID", masterId),
- new SugarParameter("@Req", pr.PrBillNo),
- new SugarParameter("@CreateUser", account),
- new SugarParameter("@UpdateUser", account),
- new SugarParameter("@Now", DateTime.Now),
- new SugarParameter("@TenantId", pr.TenantId <= 0 ? null : pr.TenantId));
- }
- private static string ResolveBuyer(string? supplierType)
- {
- return supplierType switch
- {
- "研发" => "130",
- "ECR" => "170",
- _ => "110"
- };
- }
- private sealed class ItemLookupRow
- {
- public string? ItemNum { get; set; }
- public string? Descr { get; set; }
- public string? UM { get; set; }
- public string? Location { get; set; }
- public string? Rev { get; set; }
- public string? Drawing { get; set; }
- }
- }
- public sealed class PurchaseOrderTransferResult
- {
- public int CreatedOrderCount { get; set; }
- public int TransferredPrCount { get; set; }
- public List<string> CreatedOrders { get; set; } = new();
- public List<long> TransferredPrIds { get; set; } = new();
- }
|