| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 |
- using Admin.NET.Plugin.AiDOP.ProcurementExecution.Dto;
- using Admin.NET.Plugin.AiDOP.ProcurementExecution.Entity;
- using Yitter.IdGenerator;
- namespace Admin.NET.Plugin.AiDOP.ProcurementExecution;
- /// <summary>
- /// S4 供应商发货单(列表 + 表单)
- /// </summary>
- [ApiDescriptionSettings(Order = 321, Description = "S4供应商发货单")]
- [Route("api/ProcurementExecution")]
- [AllowAnonymous]
- [NonUnify]
- public class SupplierShipmentService : IDynamicApiController, ITransient
- {
- private readonly ISqlSugarClient _db;
- private readonly SqlSugarRepository<ScmShd> _masterRep;
- private readonly SqlSugarRepository<ScmShdzb> _detailRep;
- private readonly UserManager _userManager;
- public SupplierShipmentService(
- ISqlSugarClient db,
- SqlSugarRepository<ScmShd> masterRep,
- SqlSugarRepository<ScmShdzb> detailRep,
- UserManager userManager)
- {
- _db = db;
- _masterRep = masterRep;
- _detailRep = detailRep;
- _userManager = userManager;
- }
- [DisplayName("供应商发货单列表")]
- [HttpGet("supplier-shipment/list")]
- public async Task<object> GetList([FromQuery] SupplierShipmentListInput input)
- {
- var pars = new List<SugarParameter>();
- var conditions = new List<string> { "IFNULL(m.state, 1) <> 0" };
- if (!string.IsNullOrWhiteSpace(input.JhshrqFrom))
- {
- conditions.Add("m.jhshrq >= @jhshrqFrom");
- pars.Add(new SugarParameter("@jhshrqFrom", input.JhshrqFrom.Trim()));
- }
- if (!string.IsNullOrWhiteSpace(input.Gysmc))
- {
- conditions.Add("m.sh_purchase_name LIKE @gysmc");
- pars.Add(new SugarParameter("@gysmc", $"%{input.Gysmc.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.Shddh))
- {
- conditions.Add("m.shddh LIKE @shddh");
- pars.Add(new SugarParameter("@shddh", $"%{input.Shddh.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.Wldh))
- {
- conditions.Add("m.wldh LIKE @wldh");
- pars.Add(new SugarParameter("@wldh", $"%{input.Wldh.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.PoBill))
- {
- conditions.Add("m.po_bill LIKE @poBill");
- pars.Add(new SugarParameter("@poBill", $"%{input.PoBill.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.ShMaterialCode))
- {
- conditions.Add("m.sh_material_code LIKE @shMaterialCode");
- pars.Add(new SugarParameter("@shMaterialCode", $"%{input.ShMaterialCode.Trim()}%"));
- }
- if (!string.IsNullOrWhiteSpace(input.Shzt))
- {
- conditions.Add("m.shzt = @shzt");
- pars.Add(new SugarParameter("@shzt", input.Shzt.Trim()));
- }
- if (!string.IsNullOrWhiteSpace(input.Shpc))
- {
- conditions.Add("m.shpc LIKE @shpc");
- pars.Add(new SugarParameter("@shpc", $"%{input.Shpc.Trim()}%"));
- }
- var where = $" WHERE {string.Join(" AND ", conditions)} ";
- var orderBy = BuildListOrderBy(input.SortField, input.SortOrder);
- var offset = (input.Page - 1) * input.PageSize;
- var wrapped = $"{BuildListSql()} {where}";
- var total = await _db.Ado.GetIntAsync($"SELECT COUNT(*) FROM ({wrapped}) t", pars);
- var list = await _db.Ado.SqlQueryAsync<SupplierShipmentListRow>(
- $"SELECT * FROM ({wrapped}) t {orderBy} LIMIT {input.PageSize} OFFSET {offset}", pars);
- return new { total, page = input.Page, pageSize = input.PageSize, list };
- }
- [DisplayName("获取发货单详情")]
- [HttpGet("supplier-shipment/{id:long}")]
- public async Task<object> GetDetail(long id)
- {
- var master = await _masterRep.GetFirstAsync(x => x.Id == id) ?? throw Oops.Oh("发货单不存在");
- var details = await _detailRep.AsQueryable().Where(x => x.Glid == id.ToString()).OrderBy(x => x.Hh).ToListAsync();
- return new
- {
- id = master.Id,
- shddh = master.Shddh,
- jhshrq = master.Jhshrq,
- wlsc = master.Wlsc,
- yjdhrq = master.Yjdhrq,
- shPurchaseName = master.ShPurchaseName,
- shPurchaseNum = master.ShPurchaseNum,
- wldh = master.Wldh,
- sfpc = master.Sfpc ?? 0,
- chbg = master.Chbg,
- pcsm = master.Pcsm,
- state = master.State ?? 1,
- details = details.Select(d => new
- {
- id = d.Id,
- hh = d.Hh,
- poBill = d.PoBill,
- poBillLine = d.PoBillLine,
- orderType = d.OrderType,
- shMaterialCode = d.ShMaterialCode,
- shMaterialName = d.ShMaterialName,
- th = d.Th,
- shDeliveryQuantity = d.ShDeliveryQuantity,
- bzsl = d.Bzsl,
- bqsl = d.Bqsl,
- shMaterialDw = d.ShMaterialDw,
- scrq = d.Scrq,
- scph = d.Scph,
- remarks = d.Remarks,
- djsl = d.Djsl,
- jybb = d.Jybb,
- jhdbh = d.Jhdbh
- })
- };
- }
- [DisplayName("发货单新增草稿")]
- [HttpGet("supplier-shipment/create-draft")]
- public async Task<object> GetCreateDraft([FromQuery] string ids)
- {
- var pars = new List<SugarParameter> { new("@ids", ids) };
- var rows = await _db.Ado.SqlQueryAsync<SupplierShipmentDraftRow>(
- """
- SELECT
- CAST(IFNULL(ds.id, p.RecID) AS CHAR(50)) AS sourceId,
- ds.suppliercode AS gysdm,
- ds.supplier AS gysmc,
- p.PurOrd AS poBill,
- p.Line AS poBillLine,
- p.Potype AS orderType,
- p.ItemNum AS shMaterialCode,
- im.Descr AS shMaterialName,
- IFNULL(im.Drawing, p.Drawing) AS th,
- IFNULL(ds.SchedQty, p.QtyOrded - p.RctQty - p.ReceiptQty + p.QtyReturned) AS shDeliveryQuantity,
- p.StdPackQty AS bzsl,
- p.UM AS shMaterialDw,
- (p.QtyOrded - p.RctQty - p.ReceiptQty + p.QtyReturned) AS djsl,
- ds.DSNum AS jhdbh,
- im.Descr1 AS shMaterialGgxh
- FROM PurOrdDetail p
- LEFT JOIN srm_polist_ds ds ON p.PurOrd = ds.ponumber AND p.Line = ds.poline
- LEFT JOIN ItemMaster im ON p.ItemNum = im.ItemNum
- WHERE FIND_IN_SET(CAST(IFNULL(ds.id, p.RecID) AS CHAR(50)), REPLACE(IFNULL(@ids, ''), ' ', '')) > 0
- ORDER BY p.PurOrd, p.Line
- """, pars);
- if (rows.Count == 0)
- throw Oops.Oh("未找到可生成的交货明细");
- return new
- {
- shddh = string.Empty,
- jhshrq = DateTime.Now.ToString("yyyy-MM-dd"),
- wlsc = string.Empty,
- yjdhrq = string.Empty,
- shPurchaseName = rows[0].Gysmc,
- shPurchaseNum = rows[0].Gysdm,
- wldh = string.Empty,
- sfpc = 0,
- chbg = string.Empty,
- pcsm = string.Empty,
- details = rows.Select((r, i) => new
- {
- id = (long?)null,
- hh = i + 1,
- poBill = r.PoBill,
- poBillLine = r.PoBillLine?.ToString(),
- orderType = r.OrderType,
- shMaterialCode = r.ShMaterialCode,
- shMaterialName = r.ShMaterialName,
- th = r.Th,
- shDeliveryQuantity = r.ShDeliveryQuantity,
- bzsl = r.Bzsl,
- bqsl = 0,
- shMaterialDw = r.ShMaterialDw,
- scrq = string.Empty,
- scph = string.Empty,
- remarks = string.Empty,
- djsl = r.Djsl,
- jybb = string.Empty,
- jhdbh = r.Jhdbh
- })
- };
- }
- [DisplayName("保存发货单")]
- [ApiDescriptionSettings(Name = "SaveSupplierShipment"), HttpPost("supplier-shipment/save")]
- public async Task<object> Save([FromBody] SupplierShipmentSaveInput input)
- {
- var now = DateTime.Now;
- var userId = _userManager.UserId.ToString();
- var userName = _userManager.Account ?? "system";
- var shipDate = string.IsNullOrWhiteSpace(input.Jhshrq) ? now.ToString("yyyy-MM-dd") : input.Jhshrq!.Trim();
- if (input.Id is null or 0)
- {
- var newId = YitIdHelper.NextId();
- var entity = new ScmShd
- {
- Id = newId,
- Shddh = string.IsNullOrWhiteSpace(input.Shddh) ? $"SH{DateTime.Now:yyyyMMddHHmmss}" : input.Shddh!.Trim(),
- Jhshrq = shipDate,
- Wlsc = input.Wlsc,
- Yjdhrq = input.Yjdhrq,
- ShPurchaseName = input.ShPurchaseName,
- ShPurchaseNum = input.ShPurchaseNum,
- Wldh = input.Wldh,
- Sfpc = input.Sfpc ?? 0,
- Chbg = input.Chbg,
- Pcsm = input.Pcsm,
- State = 1,
- Shzt = "待收",
- Tjrid = userId,
- Tjrxm = userName,
- Tjrq = now.ToString("yyyy-MM-dd")
- };
- await _masterRep.InsertAsync(entity);
- await SaveDetailsAsync(newId, input.Details);
- return new { id = newId, message = "新增成功" };
- }
- var master = await _masterRep.GetFirstAsync(x => x.Id == input.Id.Value) ?? throw Oops.Oh("发货单不存在");
- master.Shddh = input.Shddh;
- master.Jhshrq = shipDate;
- master.Wlsc = input.Wlsc;
- master.Yjdhrq = input.Yjdhrq;
- master.ShPurchaseName = input.ShPurchaseName;
- master.ShPurchaseNum = input.ShPurchaseNum;
- master.Wldh = input.Wldh;
- master.Sfpc = input.Sfpc ?? 0;
- master.Chbg = input.Chbg;
- master.Pcsm = input.Pcsm;
- await _masterRep.UpdateAsync(master);
- await SaveDetailsAsync(input.Id.Value, input.Details);
- return new { id = input.Id, message = "编辑成功" };
- }
- [DisplayName("删除发货单")]
- [ApiDescriptionSettings(Name = "DeleteSupplierShipment"), HttpPost("supplier-shipment/delete")]
- public async Task<object> Delete([FromBody] SupplierShipmentDeleteInput input)
- {
- var master = await _masterRep.GetFirstAsync(x => x.Id == input.Id) ?? throw Oops.Oh("发货单不存在");
- master.State = 0;
- await _masterRep.UpdateAsync(master);
- return new { message = "删除成功" };
- }
- [DisplayName("生成标签(预留)")]
- [HttpPost("supplier-shipment/generate-label")]
- public Task<object> GenerateLabel([FromBody] SupplierShipmentOperationInput input)
- => Task.FromResult<object>(new { message = $"发货单{input.Id}:功能预留,暂未启用" });
- [DisplayName("打印送货单(预留)")]
- [HttpPost("supplier-shipment/print-shipping-note")]
- public Task<object> PrintShippingNote([FromBody] SupplierShipmentOperationInput input)
- => Task.FromResult<object>(new { message = $"发货单{input.Id}:功能预留,暂未启用" });
- [DisplayName("打印标签(预留)")]
- [HttpPost("supplier-shipment/print-label")]
- public Task<object> PrintLabel([FromBody] SupplierShipmentOperationInput input)
- => Task.FromResult<object>(new { message = $"发货单{input.Id}:功能预留,暂未启用" });
- private async Task SaveDetailsAsync(long masterId, List<SupplierShipmentDetailInput> inputDetails)
- {
- var dbDetails = await _detailRep.AsQueryable().Where(x => x.Glid == masterId.ToString()).ToListAsync();
- var dbById = dbDetails.ToDictionary(x => x.Id);
- var inputIds = new HashSet<long>(inputDetails.Where(d => d.Id is > 0).Select(d => d.Id!.Value));
- for (var i = 0; i < inputDetails.Count; i++)
- {
- var d = inputDetails[i];
- if (d.Id is > 0 && dbById.TryGetValue(d.Id.Value, out var existing))
- {
- existing.Hh = d.Hh ?? (i + 1);
- existing.PoBill = d.PoBill;
- existing.PoBillLine = d.PoBillLine;
- existing.OrderType = d.OrderType;
- existing.ShMaterialCode = d.ShMaterialCode;
- existing.ShMaterialName = d.ShMaterialName;
- existing.Th = d.Th;
- existing.ShDeliveryQuantity = d.ShDeliveryQuantity;
- existing.Bzsl = d.Bzsl;
- existing.Bqsl = d.Bqsl;
- existing.ShMaterialDw = d.ShMaterialDw;
- existing.Scrq = d.Scrq;
- existing.Scph = d.Scph;
- existing.Remarks = d.Remarks;
- existing.Djsl = d.Djsl;
- existing.Jybb = d.Jybb;
- existing.Jhdbh = d.Jhdbh;
- await _detailRep.UpdateAsync(existing);
- }
- else
- {
- var detail = new ScmShdzb
- {
- Id = YitIdHelper.NextId(),
- Glid = masterId.ToString(),
- Hh = d.Hh ?? (i + 1),
- PoBill = d.PoBill,
- PoBillLine = d.PoBillLine,
- OrderType = d.OrderType,
- ShMaterialCode = d.ShMaterialCode,
- ShMaterialName = d.ShMaterialName,
- Th = d.Th,
- ShDeliveryQuantity = d.ShDeliveryQuantity,
- Bzsl = d.Bzsl,
- Bqsl = d.Bqsl,
- ShMaterialDw = d.ShMaterialDw,
- Scrq = d.Scrq,
- Scph = d.Scph,
- Remarks = d.Remarks,
- Djsl = d.Djsl,
- Jybb = d.Jybb,
- Jhdbh = d.Jhdbh
- };
- await _detailRep.InsertAsync(detail);
- }
- }
- foreach (var old in dbDetails.Where(x => !inputIds.Contains(x.Id)))
- {
- await _detailRep.DeleteAsync(x => x.Id == old.Id);
- }
- }
- private static string BuildListOrderBy(string? sortField, string? sortOrder)
- {
- var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
- {
- ["shddh"] = "t.shddh",
- ["poBill"] = "t.po_bill",
- ["jhshrq"] = "t.jhshrq",
- ["shMaterialCode"] = "t.sh_material_code",
- ["shMaterialName"] = "t.sh_material_name",
- ["shDeliveryQuantity"] = "t.sh_delivery_quantity",
- ["sfpc"] = "t.sfpc",
- ["pcrksl"] = "t.pcrksl",
- ["shPurchaseName"] = "t.sh_purchase_name",
- ["shpc"] = "t.shpc",
- ["scph"] = "t.scph",
- ["wldh"] = "t.wldh",
- ["dycs"] = "t.dycs",
- ["shzt"] = "t.shzt"
- };
- var field = map.TryGetValue(sortField ?? string.Empty, out var sqlField) ? sqlField : "t.mid";
- var order = string.Equals(sortOrder, "asc", StringComparison.OrdinalIgnoreCase) ? "ASC" : "DESC";
- return $" ORDER BY {field} {order} ";
- }
- private static string BuildListSql() => """
- SELECT
- m.mid,
- m.id,
- m.sh_purchase_id,
- m.sh_purchase_name,
- m.sh_purchase_num,
- m.sh_purchase_address,
- m.sh_purchase_lxr,
- m.sh_purchase_phone,
- m.client,
- m.delivery_Address,
- m.expected_consignee,
- m.consignee_phone,
- m.estimated_delivery_date,
- m.po_billno,
- m.shddh,
- m.jhshrq,
- m.tjrid,
- m.tjrxm,
- m.tjrq,
- m.scbq,
- m.chbg,
- m.sfpc,
- m.pcsm,
- m.wlsc,
- m.yjdhrq,
- m.state,
- m.shzt,
- m.wldh,
- m.dycs,
- m.gys,
- m.sh_material_code,
- m.sh_material_name,
- m.sh_material_ggxh,
- m.hh,
- m.po_bill,
- m.shpc,
- m.scph,
- m.sh_delivery_quantity,
- m.th,
- n.rksl,
- n.bhgsl,
- n.thsl,
- n.zshl,
- n.Delivery,
- n.pc,
- l.pcrksl,
- po.potype,
- po.Usage
- FROM
- (
- SELECT
- a.id mid,
- b.id,
- a.sh_purchase_id,
- a.sh_purchase_name,
- a.sh_purchase_num,
- a.sh_purchase_address,
- a.sh_purchase_lxr,
- a.sh_purchase_phone,
- a.client,
- a.delivery_Address,
- a.expected_consignee,
- a.consignee_phone,
- a.estimated_delivery_date,
- a.po_billno,
- a.shddh,
- a.jhshrq,
- a.tjrid,
- a.tjrxm,
- a.tjrq,
- a.scbq,
- a.chbg,
- a.sfpc,
- a.pcsm,
- a.wlsc,
- a.yjdhrq,
- a.state,
- IFNULL(a.shzt, '待收') shzt,
- a.wldh,
- a.dycs,
- CONCAT(IFNULL(a.sh_purchase_num, ''), IFNULL(a.sh_purchase_name, '')) gys,
- b.sh_material_code,
- b.sh_material_name,
- b.sh_material_ggxh,
- b.hh,
- b.po_bill,
- c.shpc,
- b.scph,
- b.sh_delivery_quantity,
- b.th
- FROM scm_shd a
- LEFT JOIN scm_shdzb b ON a.id = b.glid
- LEFT JOIN (SELECT DISTINCT glid, shpc FROM scm_shbq) c ON b.id = c.glid
- ) m
- LEFT JOIN
- (
- SELECT
- Delivery,
- LotSerial pc,
- SUM(ReceiptQty) zshl,
- AVG(yssl) rksl,
- SUM(QtyReturn) bhgsl,
- SUM(QtyReturned) thsl
- FROM vscm_cgshrk
- GROUP BY Delivery, LotSerial
- ) n ON m.shddh = n.Delivery AND m.shpc = n.pc
- LEFT JOIN
- (
- SELECT LotSerial, SUM(QtyChange) pcrksl
- FROM InvTransHist
- WHERE QtyChange > 0 AND Reason LIKE '%收货'
- GROUP BY LotSerial
- ) l ON m.shpc = l.LotSerial
- LEFT JOIN PurOrdMaster po ON m.po_bill = po.purord
- """;
- private sealed class SupplierShipmentListRow
- {
- public long Mid { get; set; }
- public long Id { get; set; }
- public string? ShPurchaseName { get; set; }
- public string? ShPurchaseNum { get; set; }
- public string? Shddh { get; set; }
- public string? Jhshrq { get; set; }
- public int? Sfpc { get; set; }
- public string? Wldh { get; set; }
- public int? Dycs { get; set; }
- public string? Shzt { get; set; }
- public string? ShMaterialCode { get; set; }
- public string? ShMaterialName { get; set; }
- public decimal? ShDeliveryQuantity { get; set; }
- public decimal? Pcrksl { get; set; }
- public string? PoBill { get; set; }
- public string? Usage { get; set; }
- public string? Shpc { get; set; }
- public string? Scph { get; set; }
- public string? Th { get; set; }
- public int? State { get; set; }
- }
- private sealed class SupplierShipmentDraftRow
- {
- public string? SourceId { get; set; }
- public string? Gysdm { get; set; }
- public string? Gysmc { get; set; }
- public string? PoBill { get; set; }
- public int? PoBillLine { get; set; }
- public string? OrderType { get; set; }
- public string? ShMaterialCode { get; set; }
- public string? ShMaterialName { get; set; }
- public string? Th { get; set; }
- public decimal? ShDeliveryQuantity { get; set; }
- public decimal? Bzsl { get; set; }
- public string? ShMaterialDw { get; set; }
- public decimal? Djsl { get; set; }
- public string? Jhdbh { get; set; }
- public string? ShMaterialGgxh { get; set; }
- }
- }
|