同步金蝶-代码处理提交

This commit is contained in:
tongfei
2023-12-15 14:04:26 +08:00
parent 6c4c973c16
commit d6c4208531
15 changed files with 548 additions and 50 deletions

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using WMS.Web.Domain.Values;
@@ -73,6 +74,12 @@ namespace WMS.Web.Domain.Entitys
/// 仓位ID
/// </summary>
public int SubStockId { get; set; }
/// <summary>
/// ERP明细
/// </summary>
public List<InStockErpDetails> ErpDetails { get; set; } = new List<InStockErpDetails>();
/// <summary>
/// 明细
/// </summary>
@@ -125,5 +132,44 @@ namespace WMS.Web.Domain.Entitys
}
this.BillNo = "RK" + idStr;
}
/// <summary>
/// 同步金蝶(成功)
/// </summary>
/// <param name="erpDetailId"></param>
/// <param name="operateId"></param>
/// <param name="erpBillNo"></param>
public void SyncSuccess(int erpDetailId, int operateId, string erpBillNo)
{
var erpd = this.ErpDetails.Where(s=>s.ErpDetailId==erpDetailId).FirstOrDefault();
erpd.SuccessSync = SyncStatus.Success;
erpd.ErpSyncBillNo = erpBillNo;
//所有erp明细同步成功才是整个单据成功
if (this.ErpDetails.Where(w => w.SuccessSync == SyncStatus.Success).Count() == this.Details.Count())
{
this.SuccessSync = SyncStatus.Success;
this.Remark = "";
}
this.OperateId = operateId;
this.SyncTime = DateTime.Now;
}
/// <summary>
/// 同步金蝶(失败)
/// </summary>
/// <param name="remark"></param>
/// <param name="erpDetailId"></param>
/// <param name="operateId"></param>
/// <param name="syncStatus"></param>
public void SyncFail(string remark, int erpDetailId, int operateId, SyncStatus syncStatus)
{
var erpd = this.ErpDetails.FirstOrDefault(w => w.ErpDetailId == erpDetailId);
erpd.SuccessSync = syncStatus;
this.SuccessSync = SyncStatus.Fail;
this.Remark = remark;
this.OperateId = operateId;
this.SyncTime = DateTime.Now;
}
}
}

View File

@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
using WMS.Web.Core;
using WMS.Web.Domain.Values;
namespace WMS.Web.Domain.Entitys
{
@@ -10,12 +12,12 @@ namespace WMS.Web.Domain.Entitys
/// </summary>
[Serializable]
[Table("t_wms_instock_details")]
public class InStockDetails
public class InStockDetails : EntityBase
{
/// <summary>
/// ID
/// </summary>
public int Id { get; set; }
public override int Id { get; set; }
/// <summary>
/// 单据头ID
/// </summary>
@@ -43,30 +45,14 @@ namespace WMS.Web.Domain.Entitys
/// 供应商ID
/// </summary>
public int SupplierId { get; set; }
///// <summary>
///// 组织ID
///// </summary>
//public int OrgId { get; set; }
///// <summary>
///// 组织编码
///// </summary>
//public string OrgCode { get; set; }
/// <summary>
/// 物料ID
/// </summary>
public int MaterialId { get; set; }
///// <summary>
///// 仓库编码
///// </summary>
//public string StockCode { get; set; }
///// <summary>
///// 仓位ID
///// </summary>
//public int SubStockId { get; set; }
/// <summary>
/// 数量
/// </summary>
public decimal Qty { get; set; }
public decimal Qty { get; set; }
/// <summary>
/// 序列号集

View File

@@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
using WMS.Web.Core;
using WMS.Web.Domain.Values;
namespace WMS.Web.Domain.Entitys
{
/// <summary>
/// wms入库单ERP明细
/// </summary>
[Serializable]
[Table("t_wms_instock_erp_details")]
public class InStockErpDetails : EntityBase
{
/// <summary>
/// ID
/// </summary>
public override int Id { get; set; }
/// <summary>
/// 单据头ID
/// </summary>
public int Fid { get; set; }
/// <summary>
/// 对应金蝶的明细ID
/// </summary>
public int ErpDetailId { get; set; }
/// <summary>
/// 来源单号
/// </summary>
public string SourceBillNo { get; set; }
/// <summary>
/// 物料ID
/// </summary>
public int MaterialId { get; set; }
/// <summary>
/// 数量
/// </summary>
public decimal Qty { get; set; }
/// <summary>
/// 同步成功或者失败 默认是失败状态
/// </summary>
public SyncStatus SuccessSync { get; set; } = SyncStatus.Fail;
/// <summary>
/// 同步到金蝶后金蝶的单据Id
/// </summary>
public string ErpSyncBillNo { get; set; }
}
}

View File

@@ -19,11 +19,12 @@ namespace WMS.Web.Domain.IService
{
/// <summary>
/// 同步
/// 同步金蝶
/// </summary>
/// <param name="dto"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
Task<Result> Sync(OperateRequest dto);
Task<Result> Sync(OperateRequest dto, LoginInDto loginInfo);
/// <summary>
/// 收货

View File

@@ -20,6 +20,13 @@ namespace WMS.Web.Domain.IService.Public
/// <returns></returns>
Task<ResultList<ErpBaseDto>> BillQueryForBillType();
/// <summary>
/// erp:查询采购入库单信息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Task<Result<ErpPurchaseInStockSaveDto>> BillQueryForPurchaseInStock(string id);
/// <summary>
/// erp:单据查询-采购入库单
/// </summary>

View File

@@ -50,5 +50,20 @@ namespace WMS.Web.Domain.Infrastructure
/// <param name="isTransaction"></param>
/// <returns></returns>
Task<bool> AddRangeTotalDetails(List<InStockTotalDetails> entitys, bool isTransaction = true);
/// <summary>
/// 修改
/// </summary>
/// <param name="entity"></param>
/// <param name="isTransaction"></param>
/// <returns></returns>
Task<InStock> Update(InStock entity, bool isTransaction = true);
/// <summary>
/// 根据单据头id获取数据
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
Task<List<InStock>> GetList(List<int> ids);
}
}

View File

@@ -1,5 +1,7 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -21,6 +23,7 @@ using WMS.Web.Domain.IService;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Mappers;
using WMS.Web.Domain.Values;
using WMS.Web.Domain.Values.Erp;
namespace WMS.Web.Domain.Services
{
@@ -43,10 +46,12 @@ namespace WMS.Web.Domain.Services
private readonly IInStockTaskRepositories _inStockTaskRepositories;
private readonly IErpBasicDataExtendService _erpBasicDataExtendService;
private readonly IBoxInventoryRepositories _boxInventoryRepositories;
private readonly ILogger<InStockService> _logger;
public InStockService(IMapper mapper, ISerialNumbersRepositories serialNumbersRepositories, IErpService erpService, IBoxInventoryService boxInventoryService, ISerialNumberService serialNumberService, ILoginService loginService, IBoxRepositories boxRepositories,
IBasicsRepositories basicsRepositories, IErpBasicDataExtendService erpBasicDataExtendService, IChangeMoveBoxService changeMoveBoxService, IInStockTaskBoxRepositories inStockTaskBoxRepositories,
IInStockRepositories inStockRepositories, IInStockTaskRepositories inStockTaskRepositories, IBoxInventoryRepositories boxInventoryRepositories)
IInStockRepositories inStockRepositories, IInStockTaskRepositories inStockTaskRepositories, IBoxInventoryRepositories boxInventoryRepositories, ILogger<InStockService> logger)
{
_logger = logger;
_mapper = mapper;
_erpService = erpService;
_loginService = loginService;
@@ -67,9 +72,15 @@ namespace WMS.Web.Domain.Services
/// 同步-金蝶
/// </summary>
/// <param name="dto"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
public async Task<Result> Sync(OperateRequest dto)
public async Task<Result> Sync(OperateRequest dto, LoginInDto loginInfo)
{
var list = await _inStockRepositories.GetList(dto.Ids);
foreach (var entity in list)
{
await this.PurchaseInStock(entity, loginInfo);
}
return Result.ReSuccess();
}
@@ -235,6 +246,15 @@ namespace WMS.Web.Domain.Services
entity.Details = _mapper.Map<List<InStockDetails>>(dto.Details);
entity.Create(loginInfo.UserInfo.StaffId);
//组装erp明细
entity.ErpDetails = dto.Details.GroupBy(x => new { x.ErpDetailId, x.MaterialId, x.SourceBillNo })
.Select(x => new InStockErpDetails
{
ErpDetailId = x.Key.ErpDetailId,
MaterialId = x.Key.MaterialId,
SourceBillNo = x.Key.SourceBillNo,
Qty = x.Sum(t => t.Qty)
}).ToList();
//序列号集:箱里面的
var serialNumbers = await _serialNumbersRepositories.GetEntityListByBoxIds(dto.Details.GroupBy(x => x.BoxId).Select(x => x.Key).ToList());
@@ -270,7 +290,7 @@ namespace WMS.Web.Domain.Services
var isSuccess = await _inStockRepositories.AddRangeTotalDetails(totalDetails, isTransaction);
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
//同步金蝶后,反写任务单的已交数量
//反写任务单的已交数量
var taskIds = dto.Details.GroupBy(x => x.TaskId).Select(x => x.Key).ToList();
var tasks = await _inStockTaskRepositories.GetList(taskIds);
if (tasks != null && tasks.Count != 0)
@@ -305,6 +325,10 @@ namespace WMS.Web.Domain.Services
if (!boxInventoryResult.IsSuccess)
return boxInventoryResult;
//同步金蝶
if (entity.Type == InstockType.Purchase)
await this.PurchaseInStock(entity, loginInfo);
return Result.ReSuccess();
@@ -685,6 +709,91 @@ namespace WMS.Web.Domain.Services
return Result<ContrastMaterialsResponse>.ReSuccess(response);
}
/// <summary>
/// 采购:同步金蝶
/// </summary>
/// <param name="entity"></param>
/// <param name="loginInfo"></param>
/// <returns></returns>
private async Task<Result> PurchaseInStock(InStock entity, LoginInDto loginInfo)
{
if (entity.Type != InstockType.Purchase) return Result.ReSuccess();
if (entity.SuccessSync == SyncStatus.Success) return Result.ReSuccess();
var erpDetails = entity.ErpDetails.Where(w => w.SuccessSync == SyncStatus.Fail).ToList();
foreach (var s in erpDetails)
{
var erp_details = entity.ErpDetails
.Where(w => w.SourceBillNo.Equals(s)).Select(s => s.ErpDetailId).ToList();
var erpDto = new ErpPushDto()
{
RuleId = "PUR_PurchaseOrder-STK_InStock",//转换规则内码 采购订单下推采购入库单
FormId = FormIdParam.PUR_PurchaseOrder.ToString(),
TargetFormId = FormIdParam.STK_InStock.ToString(),
DetailsId = s.ErpDetailId.ToString()
};
//下推金蝶
var res = await this.Push(erpDto, s, entity.BillNo);
if (res.result.IsSuccess)
entity.SyncSuccess(s.ErpDetailId, loginInfo?.UserInfo?.StaffId ?? 0, res.erpBillNo);
else
entity.SyncFail(res.result.Message, s.ErpDetailId, loginInfo?.UserInfo?.StaffId ?? 0, res.syncStatus);
}
//最好一条一条执行,否则执行失败 但是金蝶那边又同步成功 就会造成数据比价乱
var isSuccess = await _inStockRepositories.Update(entity, true);
if (entity == null) return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// 下推
/// </summary>
/// <param name="dto"></param>
/// <param name="erpDetail"></param>
/// <param name="billNo"></param>
/// <returns></returns>
private async Task<(Result result, SyncStatus syncStatus, string erpBillNo)> Push(ErpPushDto dto, InStockErpDetails erpDetail, string billNo)
{
var res = await _erpService.Push(dto);
if (!res.IsSuccess)
{
_logger.LogInformation($"入库单->下推失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{res.Message}");
return (Result.ReFailure(res.Message, res.Status), SyncStatus.Fail, "");
}
string id = res.Data;
var resPurchaseInStock = await _erpService.BillQueryForPurchaseInStock(id);
var purchaseInStock = resPurchaseInStock.Data;
purchaseInStock.Details[0].Qty = erpDetail.Qty;
//{"Id":12709885,"Number":"XSCKD10629570","DIndex":0}
string formId = dto.TargetFormId.ToString();
_logger.LogInformation($"入库单->开始同步金蝶 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 数据: {JsonConvert.SerializeObject(dto)}");
var res_s = await _erpService.Save<ErpPurchaseInStockSaveDto>(purchaseInStock, formId);
if (!res_s.IsSuccess)
{
_logger.LogInformation($"入库单->修改数量失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{res_s.Message}");
return (Result.ReFailure(res_s.Message, res_s.Status), SyncStatus.SubmitFail, id);
}
//提交
_logger.LogInformation($"入库单->保存成功 开始提交 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
ErpOperateDto o_dto = new ErpOperateDto(formId, res_s.Data);//res_s.Data
var resSubmit = await _erpService.Submit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->提交失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.SubmitFail, o_dto.Numbers.First());
}
//审核
_logger.LogInformation($"入库单->提交成功 开始审核 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId}");
resSubmit = await _erpService.Audit(o_dto, formId);
if (!resSubmit.IsSuccess)
{
_logger.LogInformation($"入库单->审核失败 单号:{billNo} erp明细Id:{erpDetail.ErpDetailId} 错误:{resSubmit.Message}");
return (resSubmit, SyncStatus.CheckFail, o_dto.Numbers.First());
}
_logger.LogInformation($"同步金蝶成功");
return (Result.ReSuccess(), SyncStatus.Success, o_dto.Numbers.First());
}
}
}

View File

@@ -2092,6 +2092,48 @@ namespace WMS.Web.Domain.Services.Public
}
}
public async Task<Result<ErpPurchaseInStockSaveDto>> BillQueryForPurchaseInStock(string id)
{
try
{
//1.先登录金蝶-拿到token
var token_result = await this.Init();
if (!token_result.IsSuccess)
return Result<ErpPurchaseInStockSaveDto>.ReFailure(token_result);
//3.获取金蝶采购订单:拼接参数和条件
var query = new ErpBillQueryDto(token_result.Data);
var param = new ErpBillQueryParamDto(FormIdParam.STK_InStock.ToString());
param.FieldKeys = "FID,FInStockEntry_FEntryID,FRealQty";
param.Limit = 10000;
param.FilterString = $"FID={id}";
query.Data = JsonConvert.SerializeObject(param);
var json = JsonConvert.SerializeObject(query);
//4.请求查询接口
var result_json = await _client.ExecuteBillQueryAsync(json);
var result = JsonConvert.DeserializeObject<List<List<string>>>(result_json);
//5.返回数据的组装
var erp_list = new ErpPurchaseInStockSaveDto(id);
foreach (var item in result)
{
var lis = new ErpPurchaseInStockDetailsSaveDto();
lis.DetailId = item[1];
lis.Qty = Convert.ToDecimal(item[2]);
lis.PurchaseDetailId = "";
erp_list.Details.Add(lis);
}
return Result<ErpPurchaseInStockSaveDto>.ReSuccess(erp_list);
}
catch (Exception ex)
{
return Result<ErpPurchaseInStockSaveDto>.ReFailure(ResultCodes.Erp_BillQuery_Error);
}
}
#endregion
}
}