diff --git a/Reportapi/MyCode.Project.Domain/Message/Request/KingDee/SaveModel/PurchaseReturnModel.cs b/Reportapi/MyCode.Project.Domain/Message/Request/KingDee/SaveModel/PurchaseReturnModel.cs new file mode 100644 index 0000000..318ff28 --- /dev/null +++ b/Reportapi/MyCode.Project.Domain/Message/Request/KingDee/SaveModel/PurchaseReturnModel.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCode.Project.Domain.Message.Request.KingDee.SaveModel +{ + /// + /// 采购退料单模型 + /// + public class PurchaseReturnModel + { + public int? FID { get; set; } + public FBillTypeID FBillTypeID { get; set; } + public string FDate { get; set; } + public string FMRTYPE { get; set; } + public string FMRMODE { get; set; } + public FStockOrgId FStockOrgId { get; set; } + public bool? FIsConvert { get; set; } + public FRequireOrgId FRequireOrgId { get; set; } + public FPurchaseOrgId FPurchaseOrgId { get; set; } + public FSupplierID FSupplierID { get; set; } + public FACCEPTORID FACCEPTORID { get; set; } + public string FAcceptAddress { get; set; } + public FSettleId FSettleId { get; set; } + public FCHARGEID FCHARGEID { get; set; } + public string FOwnerTypeIdHead { get; set; } + public FOwnerIdHead FOwnerIdHead { get; set; } + public int? FCDateOffsetValue { get; set; } + public FAcceptorContactID FAcceptorContactID { get; set; } + public FSalOutStockOrgId FSalOutStockOrgId { get; set; } + public string FACCTYPE { get; set; } + public FPURMRBFIN FPURMRBFIN { get; set; } + public List FPURMRBENTRY { get; set; } + } + + public class FRequireOrgId + { + public string FNumber { get; set; } + } + + public class FSupplierID + { + public string FNumber { get; set; } + } + + public class FACCEPTORID + { + public string FNumber { get; set; } + } + + public class FSettleId + { + public string FNumber { get; set; } + } + + public class FCHARGEID + { + public string FNumber { get; set; } + } + + public class FAcceptorContactID + { + public string FCONTACTNUMBER { get; set; } + } + + public class FPURMRBFIN + { + public FSettleOrgId FSettleOrgId { get; set; } + public FSettleCurrId FSettleCurrId { get; set; } + public bool? FIsIncludedTax { get; set; } + public string FPRICETIMEPOINT { get; set; } + public FLOCALCURRID FLOCALCURRID { get; set; } + public FEXCHANGETYPEID FEXCHANGETYPEID { get; set; } + public decimal? FEXCHANGERATE { get; set; } + public bool? FISPRICEEXCLUDETAX { get; set; } + public decimal? FHSExchangeRate { get; set; } + } + + public class FLOCALCURRID + { + public string FNumber { get; set; } + } + + public class FEXCHANGETYPEID + { + public string FNumber { get; set; } + } + + public class FPURMRBENTRY + { + public string FRowType { get; set; } + public FMATERIALID FMATERIALID { get; set; } + public string FMaterialDesc { get; set; } + public FUnitID FUnitID { get; set; } + public decimal? FRMREALQTY { get; set; } + public decimal? FREPLENISHQTY { get; set; } + public decimal? FKEAPAMTQTY { get; set; } + public FPRICEUNITID FPRICEUNITID { get; set; } + public decimal? FPrice { get; set; } + public decimal? FExtAuxUnitQty { get; set; } + public bool? FIsReceiveUpdateStock { get; set; } + public decimal? FInvoicedJoinQty { get; set; } + public bool? FGiveAway { get; set; } + public decimal? FPriceBaseQty { get; set; } + public FCARRYUNITID FCARRYUNITID { get; set; } + public decimal? FCarryQty { get; set; } + public decimal? FCarryBaseQty { get; set; } + public int? FPOORDERENTRYID { get; set; } + public bool? FBILLINGCLOSE { get; set; } + public decimal? FRMMUSTQTY { get; set; } + public decimal? FAUXUNITQTY { get; set; } + public string FOWNERTYPEID { get; set; } + public FOwnerId FOWNERID { get; set; } + public decimal? FENTRYTAXRATE { get; set; } + public decimal? FDISCOUNTRATE { get; set; } + public decimal? FTAXPRICE { get; set; } + public decimal? FPriceDiscount { get; set; } + public int? FReturnStockEntryId { get; set; } + public bool? FIsStock { get; set; } + public string FSRCBillTypeId { get; set; } + public string FSRCBillNo { get; set; } + public int? FSUBREQBILLSEQ { get; set; } + public int? FSUBREQENTRYID { get; set; } + } + + public class FMATERIALID + { + public string FNumber { get; set; } + } + + public class FPRICEUNITID + { + public string FNumber { get; set; } + } + + public class FCARRYUNITID + { + public string FNumber { get; set; } + } +} + diff --git a/Reportapi/MyCode.Project.Domain/Message/Request/KingDee/SaveModel/SalesReturnModel.cs b/Reportapi/MyCode.Project.Domain/Message/Request/KingDee/SaveModel/SalesReturnModel.cs new file mode 100644 index 0000000..31c5724 --- /dev/null +++ b/Reportapi/MyCode.Project.Domain/Message/Request/KingDee/SaveModel/SalesReturnModel.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; + +namespace MyCode.Project.Domain.Message.Request.KingDee.SaveModel +{ + public class SalesReturnModel + { + public int? FID { get; set; } + public FBillTypeID FBillTypeID { get; set; } + public string FDate { get; set; } + public FSaleOrgId FSaleOrgId { get; set; } + public FRetcustId FRetcustId { get; set; } + public FSaledeptid FSaledeptid { get; set; } + public FTransferBizType FTransferBizType { get; set; } + public FSalesManId FSalesManId { get; set; } + public FStockOrgId FStockOrgId { get; set; } + public FReceiveCustId FReceiveCustId { get; set; } + public FSettleCustId FSettleCustId { get; set; } + public FPayCustId FPayCustId { get; set; } + public string FOwnerTypeIdHead { get; set; } + public int? FCDateOffsetValue { get; set; } + public bool? FIsTotalServiceOrCost { get; set; } + public bool? FAllRefundNoGoods { get; set; } + public FSubHeadEntityReturn SubHeadEntity { get; set; } + public List FEntity { get; set; } + } + + public class FSubHeadEntityReturn + { + public FSettleCurrId FSettleCurrId { get; set; } + public FSettleOrgId FSettleOrgId { get; set; } + public FLocalCurrId FLocalCurrId { get; set; } + public FExchangeTypeId FExchangeTypeId { get; set; } + public decimal? FExchangeRate { get; set; } + } + + public class FRetcustId + { + public string FNumber { get; set; } + } + + public class FSaledeptid + { + public string FNumber { get; set; } + } + + public class FTransferBizType + { + public string FNumber { get; set; } + } + + public class FSalesManId + { + public string FNumber { get; set; } + } + + public class FReceiveCustId + { + public string FNumber { get; set; } + } + + public class FSettleCustId + { + public string FNumber { get; set; } + } + + public class FPayCustId + { + public string FNumber { get; set; } + } + + public class FSalesReturnEntryItem + { + public string FRowType { get; set; } + public FMaterialId FMaterialId { get; set; } + public FUnitID FUnitID { get; set; } + public decimal? FInventoryQty { get; set; } + public decimal? FRealQty { get; set; } + public decimal? FPrice { get; set; } + public decimal? FTaxPrice { get; set; } + public bool? FIsFree { get; set; } + public decimal? FEntryTaxRate { get; set; } + public FReturnType FReturnType { get; set; } + public string FOwnerTypeId { get; set; } + public FOwnerId FOwnerId { get; set; } + public string FDeliveryDate { get; set; } + public decimal? FDiscountRate { get; set; } + public decimal? FPriceDiscount { get; set; } + public decimal? FAuxUnitQty { get; set; } + public decimal? FExtAuxUnitQty { get; set; } + public string FSrcBillTypeID { get; set; } + public string FSrcBillNo { get; set; } + public string FISCONSUMESUM { get; set; } + public FSalUnitID FSalUnitID { get; set; } + public decimal? FSalUnitQty { get; set; } + public decimal? FSalBaseQty { get; set; } + public decimal? FPriceBaseQty { get; set; } + public bool? FIsOverLegalOrg { get; set; } + public int? FSOEntryId { get; set; } + public decimal? FARNOTJOINQTY { get; set; } + public bool? FIsReturnCheck { get; set; } + public bool? FSettleBySon { get; set; } + public int? FBOMEntryId { get; set; } + public FMaterialID_Sal FMaterialID_Sal { get; set; } + public int? FMrbEntryId { get; set; } + public string FINSTOCKDATE { get; set; } + public bool? FVmiBusinessStatus { get; set; } + } + + public class FReturnType + { + public string FNumber { get; set; } + } +} + diff --git a/Reportapi/MyCode.Project.Domain/MyCode.Project.Domain.csproj b/Reportapi/MyCode.Project.Domain/MyCode.Project.Domain.csproj index 1f6ee06..801eb06 100644 --- a/Reportapi/MyCode.Project.Domain/MyCode.Project.Domain.csproj +++ b/Reportapi/MyCode.Project.Domain/MyCode.Project.Domain.csproj @@ -76,6 +76,7 @@ + diff --git a/Reportapi/MyCode.Project.Services/IServices/IPurchaseReturnService.cs b/Reportapi/MyCode.Project.Services/IServices/IPurchaseReturnService.cs new file mode 100644 index 0000000..3c3c8db --- /dev/null +++ b/Reportapi/MyCode.Project.Services/IServices/IPurchaseReturnService.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MyCode.Project.Services.IServices +{ + public interface IPurchaseReturnService + { + /// + /// 推送采购退料单到金蝶云星空 + /// + /// StorageGoodsDocOutHead表的主键ID(Guid格式的字符串) + /// 返回金蝶API的响应结果(JSON格式) + string PushPurchaseReturnToKingDee(string id); + } +} + diff --git a/Reportapi/MyCode.Project.Services/IServices/ISalesReturnService.cs b/Reportapi/MyCode.Project.Services/IServices/ISalesReturnService.cs new file mode 100644 index 0000000..8d93ed6 --- /dev/null +++ b/Reportapi/MyCode.Project.Services/IServices/ISalesReturnService.cs @@ -0,0 +1,8 @@ +namespace MyCode.Project.Services.IServices +{ + public interface ISalesReturnService + { + string PushSalesReturnToKingDee(string id); + } +} + diff --git a/Reportapi/MyCode.Project.Services/Implementation/SalesReturnService.cs b/Reportapi/MyCode.Project.Services/Implementation/SalesReturnService.cs new file mode 100644 index 0000000..73f0571 --- /dev/null +++ b/Reportapi/MyCode.Project.Services/Implementation/SalesReturnService.cs @@ -0,0 +1,297 @@ +using MyCode.Project.Domain.Message.Request.KingDee; +using MyCode.Project.Domain.Message.Request.KingDee.SaveModel; +using MyCode.Project.Domain.Message.Response.KingDee.K3Result; +using MyCode.Project.Domain.Message.Response.KingDee.K3Result.Model; +using MyCode.Project.Domain.Model; +using MyCode.Project.Domain.Repositories; +using MyCode.Project.Infrastructure.Common; +using MyCode.Project.Infrastructure.Exceptions; +using MyCode.Project.OutSideService; +using MyCode.Project.Services.IServices; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace MyCode.Project.Services.Implementation +{ + /// + /// 销售退货单服务实现 + /// 功能:处理销售退货单推送到金蝶云星空的业务逻辑 + /// + public class SalesReturnService : ServiceBase, ISalesReturnService + { + private const string BILL_TYPE_CODE = "XSTHD01_SYS"; + private const string OWNER_TYPE = "BD_OwnerOrg"; + private const string EXCHANGE_TYPE = "HLTX01_SYS"; + private const string DEFAULT_ORG = "100"; + private const string DEFAULT_CURRENCY = "PRE001"; + private const string DEFAULT_UNIT = "Pcs"; + private const string ROW_TYPE_SERVICE = "Service"; + private const string RETURN_TYPE_CODE = "THLX01_SYS"; + private const string TRANSFER_BIZ_TYPE = "OverOrgSal"; + private const string FORM_ID = "SAL_RETURNSTOCK"; + private const int TRADE_TYPE_RETURN_ORDER = 8; + + private IPushKingDeeOrderRepository _pushKingDeeOrderRepository; + private IPushKingDeeOrderItemRepository _pushKingDeeOrderItemRepository; + private IYTKJTShopParameterRepository _yTKJTShopParameterRepository; + private IKingDeeService _kingDeeService; + + public SalesReturnService( + IPushKingDeeOrderRepository pushKingDeeOrderRepository, + IPushKingDeeOrderItemRepository pushKingDeeOrderItemRepository, + IYTKJTShopParameterRepository yTKJTShopParameterRepository, + IKingDeeService kingDeeService) + { + _pushKingDeeOrderRepository = pushKingDeeOrderRepository; + _pushKingDeeOrderItemRepository = pushKingDeeOrderItemRepository; + _yTKJTShopParameterRepository = yTKJTShopParameterRepository; + _kingDeeService = kingDeeService; + } + + /// + /// 推送销售退货单到金蝶云星空 + /// + /// PushKingDeeOrder表的主键ID(Guid格式的字符串) + /// 返回金蝶API的响应结果(JSON格式) + public string PushSalesReturnToKingDee(string id) + { + string result2 = ""; + var orderHead = _pushKingDeeOrderRepository.Queryable().Where(t => id == t.Id.ToString()).First(); + if (orderHead.Status != 0) + { + throw new BaseException("单据已经下推."); + } + + if (orderHead.TradeType != TRADE_TYPE_RETURN_ORDER) + { + throw new BaseException($"订单类型 {orderHead.TradeType} 不是销售退货单(TradeType应为8),无法推送"); + } + + var param = _yTKJTShopParameterRepository + .Queryable() + .Where(t => t.FSHOPCODE == orderHead.ShopCode) + .Where(t => t.FDOCUMENTSTATUS == "C") + .First(); + if (param is null) + { + throw new BaseException($"门店编号:{orderHead.ShopCode},门店名称:{orderHead.ShopName},没有找到对应的门店参数 "); + } + + if (param.FSYNCHRONIZEKINGDEE == "1") + { + var response = PushKingdeeSalesReturn(orderHead, param); + result2 = JsonHelper.ToJson(response); + if (response.IsSuccess) + { + orderHead.Status = 2; + _pushKingDeeOrderRepository.Update(orderHead); + } + } + + return result2; + } + + /// + /// 推送到金蝶云星空 + /// + /// 源单信息 + /// 门店配置 + /// + private K3CloudResponseStatus PushKingdeeSalesReturn(PushKingDeeOrder orderHead, YTKJTShopParameter param) + { + var itemList = _pushKingDeeOrderItemRepository + .Queryable() + .Where(t => orderHead.Id == t.PushKingDeeOrderId) + .ToList(); + + if (itemList == null || itemList.Count == 0) + { + throw new BaseException($"销售退货单 {orderHead.Sheet} 没有找到明细数据,无法推送"); + } + + string orgId = param.FSALEORGID?.ToString() ?? DEFAULT_ORG; + + string warehouseCode = orderHead.WarehouseCode ?? param.FWAREHOUSECODE ?? ""; + + if (string.IsNullOrEmpty(warehouseCode)) + { + throw new BaseException($"销售退货单 {orderHead.Sheet} 仓库编码为空,无法推送"); + } + + var entryList = itemList.Select(n => BuildEntryItem(n, param, orgId, warehouseCode, orderHead.ConsignTime)).ToList(); + + if (entryList.Count == 0) + { + throw new BaseException($"销售退货单 {orderHead.Sheet} 明细数据转换失败,无法推送"); + } + + var model = BuildMainModel(orderHead, param, orgId, entryList); + + BillSave billSave = new BillSave() + { + Model = model, + IsAutoSubmitAndAudit = true, + }; + + var responseStatus = _kingDeeService.Save(FORM_ID, billSave); + return responseStatus; + } + + /// + /// 构建明细行数据 + /// + private FSalesReturnEntryItem BuildEntryItem(PushKingDeeOrderItem item, YTKJTShopParameter param, string orgId, string warehouseCode, DateTime? consignTime) + { + string rowType = ROW_TYPE_SERVICE; + + decimal realQty = Math.Abs(item.SellCount); + + decimal taxRate = param.FTAXRATE; + decimal taxPrice = item.SellCount != 0 ? Math.Round(Math.Abs(item.DivideSellTotal) / item.SellCount, 10) : 0; + + decimal price = taxRate > 0 && taxPrice > 0 ? Math.Round(taxPrice / (1 + taxRate / 100), 10) : taxPrice; + + string deliveryDate = consignTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + string inStockDate = consignTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + + return new FSalesReturnEntryItem() + { + FRowType = rowType, + FMaterialId = new FMaterialId() + { + FNumber = item.Barcode ?? "" + }, + FUnitID = new FUnitID() + { + FNumber = item.Unit ?? DEFAULT_UNIT + }, + FInventoryQty = 0, + FRealQty = realQty, + FPrice = price, + FTaxPrice = taxPrice, + FIsFree = false, + FEntryTaxRate = param.FTAXRATE, + FReturnType = new FReturnType() + { + FNumber = RETURN_TYPE_CODE + }, + FOwnerTypeId = OWNER_TYPE, + FOwnerId = new FOwnerId() + { + FNumber = orgId + }, + FDeliveryDate = deliveryDate, + FDiscountRate = 0, + FPriceDiscount = 0, + FAuxUnitQty = 0, + FExtAuxUnitQty = 0, + FSrcBillTypeID = "", + FSrcBillNo = "", + FISCONSUMESUM = "0", + FSalUnitID = new FSalUnitID() + { + FNumber = item.Unit ?? DEFAULT_UNIT + }, + FSalUnitQty = realQty, + FSalBaseQty = realQty, + FPriceBaseQty = realQty, + FIsOverLegalOrg = false, + FSOEntryId = 0, + FARNOTJOINQTY = realQty, + FIsReturnCheck = false, + FSettleBySon = false, + FBOMEntryId = 0, + FMaterialID_Sal = new FMaterialID_Sal() + { + FNUMBER = item.Barcode ?? "" + }, + FMrbEntryId = 0, + FINSTOCKDATE = inStockDate, + FVmiBusinessStatus = false + }; + } + + /// + /// 构建主表数据 + /// + private SalesReturnModel BuildMainModel(PushKingDeeOrder orderHead, YTKJTShopParameter param, string orgId, List entryList) + { + string dateStr = orderHead.ConsignTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + string customerId = param.FSALESCUSTOMERS > 0 ? param.FSALESCUSTOMERS.ToString() : ""; + string salesManId = param.FSALER.HasValue && param.FSALER.Value > 0 ? param.FSALER.Value.ToString() : ""; + + return new SalesReturnModel() + { + FID = 0, + FBillTypeID = new FBillTypeID() + { + FNUMBER = BILL_TYPE_CODE + }, + FDate = dateStr, + FSaleOrgId = new FSaleOrgId() + { + FNumber = orgId + }, + FRetcustId = new FRetcustId() + { + FNumber = customerId + }, + FSaledeptid = new FSaledeptid() + { + FNumber = "02" + }, + FTransferBizType = new FTransferBizType() + { + FNumber = TRANSFER_BIZ_TYPE + }, + FSalesManId = new FSalesManId() + { + FNumber = salesManId + }, + FStockOrgId = new FStockOrgId() + { + FNumber = orgId + }, + FReceiveCustId = new FReceiveCustId() + { + FNumber = customerId + }, + FSettleCustId = new FSettleCustId() + { + FNumber = customerId + }, + FPayCustId = new FPayCustId() + { + FNumber = customerId + }, + FOwnerTypeIdHead = OWNER_TYPE, + FCDateOffsetValue = 0, + FIsTotalServiceOrCost = false, + FAllRefundNoGoods = false, + SubHeadEntity = new FSubHeadEntityReturn() + { + FSettleCurrId = new FSettleCurrId() + { + FNumber = DEFAULT_CURRENCY + }, + FSettleOrgId = new FSettleOrgId() + { + FNumber = orgId + }, + FLocalCurrId = new FLocalCurrId() + { + FNumber = DEFAULT_CURRENCY + }, + FExchangeTypeId = new FExchangeTypeId() + { + FNumber = EXCHANGE_TYPE + }, + FExchangeRate = 1m + }, + FEntity = entryList + }; + } + } +} + diff --git a/Reportapi/MyCode.Project.Services/MyCode.Project.Services.csproj b/Reportapi/MyCode.Project.Services/MyCode.Project.Services.csproj index 10d8448..7518282 100644 --- a/Reportapi/MyCode.Project.Services/MyCode.Project.Services.csproj +++ b/Reportapi/MyCode.Project.Services/MyCode.Project.Services.csproj @@ -121,6 +121,7 @@ + @@ -133,6 +134,7 @@ + diff --git a/Reportapi/MyCode.Project.WebApi/Controllers/TestController.cs b/Reportapi/MyCode.Project.WebApi/Controllers/TestController.cs index ffd833d..f65d226 100644 --- a/Reportapi/MyCode.Project.WebApi/Controllers/TestController.cs +++ b/Reportapi/MyCode.Project.WebApi/Controllers/TestController.cs @@ -22,10 +22,12 @@ namespace MyCode.Project.WebApi.Controllers private IOrderPushService _orderPushService; private IPurchaseStockInService _purchaseStockInService; private ISalesOutboundService _salesOutboundService; + private ISalesReturnService _salesReturnService; public TestController(IJackYunTaskService jackYunTaskService, IWMSService wMSService , IJackYunStockinService jackYunStockinService, IOrderPushService orderPushService - , IPurchaseStockInService purchaseStockInService, ISalesOutboundService salesOutboundService) + , IPurchaseStockInService purchaseStockInService, ISalesOutboundService salesOutboundService + , ISalesReturnService salesReturnService) { _jackYunTaskService = jackYunTaskService; _wMSService = wMSService; @@ -33,6 +35,7 @@ namespace MyCode.Project.WebApi.Controllers _orderPushService = orderPushService; _purchaseStockInService = purchaseStockInService; _salesOutboundService = salesOutboundService; + _salesReturnService = salesReturnService; } /// @@ -65,6 +68,16 @@ namespace MyCode.Project.WebApi.Controllers return _salesOutboundService.PushSalesOutboundToKingDee(id); } + /// + /// 测试推送销售退货单到金蝶云星空 + /// + [HttpGet] + [AllowAnonymous] + public string TaskSendKingdeeSalesReturnById(string id) + { + return _salesReturnService.PushSalesReturnToKingDee(id); + } + #region 调度运行抓吉客云销售订单