This commit is contained in:
18942506660
2024-11-07 09:46:58 +08:00
56 changed files with 3239 additions and 74 deletions

View File

@@ -0,0 +1,122 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.OutStock;
using WMS.Web.Core.Dto.ProductInventory;
using WMS.Web.Core.Dto.SingleData;
using WMS.Web.Core.Internal.Results;
using WMS.Web.Domain.Infrastructure;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Services.Public;
using WMS.Web.Domain.Values;
using WMS.Web.Repositories;
using WMS.Web.Core;
using WMS.Web.Domain.IService;
using WMS.Web.Domain.Options;
using Google.Protobuf.WellKnownTypes;
using WMS.Web.Domain.Services;
using Microsoft.Extensions.Options;
using System.Linq;
using WMS.Web.Core.Dto;
namespace WMS.Web.Api.Controllers
{
/// <summary>
/// 成品仓即时库存
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class ProductInventoryController : ControllerBase
{
private readonly ILoginService _loginService;
private readonly IBasicsRepositories _basicsRepositories;
private readonly IProductInventoryRepositories _repositories;
private readonly QiniuOptions _option;
private readonly IExportExcelService _exportExcelService;
private readonly IProductInventoryService _productInventoryService;
public ProductInventoryController(ILoginService loginService, IBasicsRepositories basicsRepositories,
IProductInventoryRepositories repositories, IOptions<QiniuOptions> option,
IExportExcelService exportExcelServic, IProductInventoryService productInventoryService) {
_loginService = loginService;
_basicsRepositories = basicsRepositories;
_repositories = repositories;
_option = option?.Value;
_exportExcelService = exportExcelServic;
_productInventoryService = productInventoryService;
}
/// <summary>
/// 获取仓库
/// </summary>
/// <param name="name">仓库模糊匹配 不必填</param>
/// <returns></returns>
[HttpGet]
[Route("GetUcStock")]
public async Task<ResultList<UcStockHeadOfficeResponse>> GetUcStock([FromQuery] string name)
{
//var loginInfo = _loginService.GetLoginInfo(this.HttpContext.Request.Headers["Authorization"]);
//if (loginInfo == null || loginInfo.UserInfo == null)
// return ResultList<UcStockHeadOfficeResponse>.ReFailure(ResultCodes.Token_Invalid_Error);
var r = await _basicsRepositories.GetUcStockByHeadOfficeAsync(name, 1);
var response = r.Where(w => w.ManagementSystem == 1 || w.ManagementSystem == 4
|| (w.ManagementSystem == 2 && !string.IsNullOrEmpty(w.WarehouseCodeOfJushuitan))
||(w.ManagementSystem == 3 && !string.IsNullOrEmpty(w.WarehouseCodeOfLingxing))).ToList();
return ResultList<UcStockHeadOfficeResponse>.ReSuccess(r);
}
/// <summary>
/// 列表
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost]
[Route("GetList")]
public async Task<ResultPagedNumber2List<ProductInventoryQueryResponse>> GetPagedList([FromBody] ProductInventoryQueryRequest dto)
{
//var loginInfo = _loginService.GetLoginInfo(this.HttpContext.Request.Headers["Authorization"]);
//if (loginInfo == null || loginInfo.UserInfo == null)
// return ResultPagedNumber2List<ProductInventoryQueryResponse>.ReFailure(ResultCodes.Token_Invalid_Error);
var (list, count, details) = await _repositories.GetListAsync(dto);
var result = ResultPagedNumber2List<ProductInventoryQueryResponse>.ReSuccess(list,count,details);
return result;
}
/// <summary>
/// 导出
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost]
[Route("Export")]
public Task<Result<string>> Export([FromBody] ProductInventoryQueryRequest dto)
{
var loginInfo = _loginService.GetLoginInfo(this.HttpContext.Request.Headers["Authorization"]);
if (loginInfo == null)
return Task.FromResult(Result<string>.ReFailure(ResultCodes.Token_Invalid_Error));
string fileName = FileDownLoadOrderType.ProductInventory.GetRemark() + loginInfo.UserInfo.CompanyId + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx";
string res = _option.Url + fileName;
Task.Run(async () =>
{
await _exportExcelService.ExportList<ProductInventoryQueryResponse, ProductInventoryQueryRequest>(dto, fileName, loginInfo.UserInfo.StaffId, loginInfo.UserInfo.CompanyId, FileDownLoadOrderType.ProductInventory);
});
return Task.FromResult(Result<string>.ReSuccess(res));
}
/// <summary>
/// 刷新数据
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("Refresh")]
public async Task<Result> Refresh()
{
//var loginInfo = _loginService.GetLoginInfo(this.HttpContext.Request.Headers["Authorization"]);
//if (loginInfo == null || loginInfo.UserInfo == null)
// return Result.ReFailure(ResultCodes.Token_Invalid_Error);
return await _productInventoryService.Refresh();
}
}
}

View File

@@ -28,6 +28,10 @@ using System.Reflection;
using WMS.Web.Domain.Services; using WMS.Web.Domain.Services;
using SkiaSharp; using SkiaSharp;
using Google.Protobuf.Collections; using Google.Protobuf.Collections;
using NPOI.SS.Formula.Functions;
using System.Text.Json;
using WMS.Web.Core.Dto.LingXing;
using WMS.Web.Domain.Services.Public;
namespace WMS.Web.Api.Controllers namespace WMS.Web.Api.Controllers
{ {
@@ -57,11 +61,16 @@ namespace WMS.Web.Api.Controllers
private readonly IMemoryCache _memoryCache; private readonly IMemoryCache _memoryCache;
private readonly IRedisConcurrentProcessService _redisConcurrentProcessService; private readonly IRedisConcurrentProcessService _redisConcurrentProcessService;
private IInStockService _inStockService; private IInStockService _inStockService;
private readonly ILingXingService _lingXingService;
private readonly IProductInventoryService _productInventoryService;
private readonly IJuShuiTanService _juShuiTanService;
private readonly IErpInventoryService _erpInventoryService;
public TestController(IErpService erpService, IInStockTaskService inStockTaskService, IBoxInventoryRepositories boxInventoryRepositories, IRedisConcurrentProcessService redisConcurrentProcessService, public TestController(IErpService erpService, IInStockTaskService inStockTaskService, IBoxInventoryRepositories boxInventoryRepositories, IRedisConcurrentProcessService redisConcurrentProcessService,
IBasicsRepositories transactionRepositories, IOpsService opsService, IBoxService boxService, IBasicsRepositories basicsRepositories, IMemoryCache memoryCache, IBasicsRepositories transactionRepositories, IOpsService opsService, IBoxService boxService, IBasicsRepositories basicsRepositories, IMemoryCache memoryCache,
IOutStockTaskRepositories outStockTaskRepositories, IOutStockTaskService outStockTaskService, IOptions<AppOptions> options, ILoginService loginService, ISendMessageService sendMessageService, IOutStockTaskRepositories outStockTaskRepositories, IOutStockTaskService outStockTaskService, IOptions<AppOptions> options, ILoginService loginService, ISendMessageService sendMessageService,
ITakeStockService takeStockService, ITakeStockRepositories takeStockRepositories, IOutStockService outStockService, IInStockTaskRepositories inStockTaskRepositories, ITakeStockService takeStockService, ITakeStockRepositories takeStockRepositories, IOutStockService outStockService, IInStockTaskRepositories inStockTaskRepositories,
IWebHostEnvironment env, IMaterialService materialService, IOutStockRepositories outStockRepositories, IInStockService inStockService) IWebHostEnvironment env, IMaterialService materialService, IOutStockRepositories outStockRepositories, IInStockService inStockService, ILingXingService lingXingService
, IProductInventoryService productInventoryService, IJuShuiTanService juShuiTanService, IErpInventoryService erpInventoryService)
{ {
_inStockService = inStockService; _inStockService = inStockService;
_redisConcurrentProcessService = redisConcurrentProcessService; _redisConcurrentProcessService = redisConcurrentProcessService;
@@ -85,12 +94,50 @@ namespace WMS.Web.Api.Controllers
_outStockService = outStockService; _outStockService = outStockService;
_outStockRepositories = outStockRepositories; _outStockRepositories = outStockRepositories;
_env = env; _env = env;
_lingXingService = lingXingService;
_productInventoryService = productInventoryService;
_juShuiTanService = juShuiTanService;
_erpInventoryService = erpInventoryService;
} }
[HttpGet] [HttpGet]
[Route("hj")] [Route("hj")]
public async Task<string> TestHJ() public async Task<string> TestHJ()
{ {
////var myJson = "{\"name\":\"小明\",\"address\":\"威海\"}";//json字符串
//var myJson= "{\"code\":\"200\",\"msg\":\"OK\",\"data\":{\"access_token\":\"05895ad6-e318-41da-9b2c-579dedd18fd1\",\"refresh_token\":\"ad9145cf-8af9-4617-9dbe-187b0ff3edf9\",\"expires_in\":7162}}";
//var myObj = JsonConvert.DeserializeObject<dynamic>(myJson);//反序列化为 dynamic 对象
//var my2 = System.Text.Json.JsonSerializer.Deserialize<dynamic>(myJson);
//string m = myObj.code;
//var m2 = my2.Object;
//var md = m2.code;
//var b33= await _juShuiTanService.GetStock();
// var bc = await _lingXingService.GetStock();
//List<(string orgCode, string stockCode)> request = new List<(string orgCode, string stockCode)>();
//request.Add(("101", "CK001"));
//request.Add(("101", "CK002"));
//var list = await _erpService.BillQueryForInventory(request);
//var b33 = await _juShuiTanService.GetStock();
//var b = b33.Data.Where(w => w.Id == 10923342).FirstOrDefault();
//await _juShuiTanService.GetTest();
//string codes = "AD";
//var b = await _erpInventoryService.GetInventory(new List<string>() { "111"});
//int count = 10 / 5;
var bcd=await _productInventoryService.LingXing();
//LingXingResponse<LingXingStockResponse> r = new LingXingResponse<LingXingStockResponse>();
//string str = "{\"code\":0,\"message\":\"success\",\"error_details\":[],\"request_id\":\"7A739491-8740-01AC-304E-0203AF887AE2\",\"response_time\":\"2024-10-16 17:58:57\",\"data\":[{\"wid\":437,\"type\":1,\"name\":\"ORICO_OD\",\"is_delete\":0}],\"total\":1}";
//var ss=JsonConvert.DeserializeObject<LingXingResponse<LingXingStockResponse>>(str);
//var b = System.Text.Json.JsonSerializer.Deserialize<LingXingResponse<LingXingStockResponse>>(str);
//await _productInventoryService.LingXing();
//var s = await _lingXingService.GetSeller();
//var ns = s.Data.Where(w =>w.Id== "2101").ToList();
//string str = string.Join(",", s.Data.Select(s => s.Id).ToList());
//var sd= await _lingXingService.GetInventory(new LingXingInventoryRequest() { wid = "437" });
//string sdsdf = sd.Message;
//List<string> list = new List<string>(); //List<string> list = new List<string>();
//list.Add("GD-02-15"); //list.Add("GD-02-15");
//list.Add("GD-01-15"); //list.Add("GD-01-15");

View File

@@ -37,15 +37,27 @@
}, },
"ErpOptions": { "ErpOptions": {
"EndpointAddress": "http://erp.orico.com.cn/k3cloud/ERPGW.asmx", //原:119.23.206.129 "EndpointAddress": "http://erp.orico.com.cn/k3cloud/ERPGW.asmx", //原:119.23.206.129
"UserName": "mes", //测试账号密码 mes/A1B2C3Dh/ce20210909 正式账号密码 orico/A123321./Orico "UserName": "mes", //测试账号密码 mes/A1B2C3Dh/ce20210909/6723b1acf19987 正式账号密码 orico/A123321./Orico/663a26829afbdd
"Password": "A1B2C3Dh.", "Password": "A1B2C3Dh.",
"ErpId": "ce20210909" "ErpId": "ce20210909",
"ZhangTaoId": "6723b1acf19987"
}, },
"OpsOptions": { "OpsOptions": {
"Url": "https://api.opsscm.test.f2b211.com/", //https://api.opsscm.test.f2b211.com/ "Url": "https://api.opsscm.test.f2b211.com/", //https://api.opsscm.test.f2b211.com/
"UserName": "admin", "UserName": "admin",
"PassWord": "888888" "PassWord": "888888"
}, },
"LingXingOptions": {
"Url": "https://openapi.lingxing.com",
"AppId": "ak_QGK2J8TssERmu",
"AppSecret": "n/HUKD2wVdTbvhnFZbVBPw=="
},
"JuShuiTanOptions": {
"Url": "https://openapi.jushuitan.com",
"AppKey": "17231841286c45f99eb9acf445404349",
"AppSecret": "5ce9641ae6db4abb8b96eea7df6a81e9",
"AccessToken": "4605358c37374780a8a4395e6cdb1c3f" //一年后过期(2025/10/18)
},
"Qiniu": { "Qiniu": {
"AccessKey": "dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms", "AccessKey": "dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms",
"SecretKey": "KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q", "SecretKey": "KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q",
@@ -89,6 +101,7 @@
"JobStartExpreSend": "0 0 12,16,20 * * ?", "JobStartExpreSend": "0 0 12,16,20 * * ?",
"JobStartExpreMaterial": "0 30 23 * * ?", "JobStartExpreMaterial": "0 30 23 * * ?",
"JobStartErpDelete": "0 5 * * * ?", "JobStartErpDelete": "0 5 * * * ?",
"JobStartProductInventory": "0 0/30 * * * ?",
//a.是否启用集群:键和值 //a.是否启用集群:键和值
"JobStoreClusteredKey": "quartz.jobStore.clustered", "JobStoreClusteredKey": "quartz.jobStore.clustered",
"JobStoreClusteredValue": true, "JobStoreClusteredValue": true,

View File

@@ -1006,14 +1006,24 @@
仓库 仓库
</summary> </summary>
</member> </member>
<member name="P:WMS.Web.Core.Dto.Erp.ErpInventoryDto.Erp_SubStockId"> <member name="P:WMS.Web.Core.Dto.Erp.ErpInventoryDto.Erp_SubStockName">
<summary> <summary>
子仓库(跟金蝶交互字段) 子仓库
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.Erp.ErpInventoryDto.Batch">
<summary>
批号
</summary> </summary>
</member> </member>
<member name="P:WMS.Web.Core.Dto.Erp.ErpInventoryDto.Qty"> <member name="P:WMS.Web.Core.Dto.Erp.ErpInventoryDto.Qty">
<summary> <summary>
可用
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.Erp.ErpInventoryDto.BeforeQty">
<summary>
库存量
</summary> </summary>
</member> </member>
<member name="T:WMS.Web.Core.Dto.Erp.ErpNumberDto"> <member name="T:WMS.Web.Core.Dto.Erp.ErpNumberDto">
@@ -4199,6 +4209,197 @@
wms箱ID wms箱ID
</summary> </summary>
</member> </member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryRequst.page_index">
<summary>
页码
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryRequst.page_size">
<summary>
页条数
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryRequst.wms_co_id">
<summary>
仓库Id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryRequst.modified_begin">
<summary>
开始时间
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryRequst.modified_end">
<summary>
结算时间
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.sku_id">
<summary>
商品
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.qty">
<summary>
总量
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.ky_qty">
<summary>
可用数:可用数[同步线上的库存数]=
主仓实际库存-订单占有数+虚拟库存+采购在途(业务设置)+进货仓(业务设置)+销退仓库存(业务设置)
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.order_lock">
<summary>
订单占有数
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.virtual_qty">
<summary>
虚拟库存
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.purchase_qty">
<summary>
采购在途
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.return_qty">
<summary>
销退仓库存
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanInventoryResponse.in_qty">
<summary>
进货仓
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanStockRequst.page_index">
<summary>
页码
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanStockRequst.page_size">
<summary>
页条数
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanStockResponse.Id">
<summary>
仓库id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.JuShuiTan.JuShuiTanStockResponse.Name">
<summary>
仓库名
</summary>
</member>
<member name="T:WMS.Web.Core.Dto.LingXing.LingXingInventoryRequest">
<summary>
领星即时库存
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingInventoryRequest.wid">
<summary>
仓库Id 1,3,234,33
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingInventoryRequest.sku">
<summary>
物料规格型号
</summary>
</member>
<member name="T:WMS.Web.Core.Dto.LingXing.LingXingInventoryResponse">
<summary>
领星即时库存
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingInventoryResponse.StockId">
<summary>
仓库Id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingInventoryResponse.SKU">
<summary>
SKU
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingInventoryResponse.SellerId">
<summary>
店铺id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingInventoryResponse.Product_Total">
<summary>
库存总量
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingInventoryResponse.Product_Valid_Num">
<summary>
可用量
</summary>
</member>
<member name="T:WMS.Web.Core.Dto.LingXing.LingXingLoginRequest">
<summary>
领星登录
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingLoginRequest.AppId">
<summary>
id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingLoginRequest.AppSecret">
<summary>
Secret
</summary>
</member>
<member name="T:WMS.Web.Core.Dto.LingXing.LingXingRequest">
<summary>
领星请求
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingRequest.offset">
<summary>
不是页码 是从第几条数据开始 如果是第二页的话 就是1*800
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingRequest.length">
<summary>
页条数
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingRequest.type">
<summary>
海外仓
</summary>
</member>
<member name="T:WMS.Web.Core.Dto.LingXing.LingXingSellerResponse">
<summary>
店铺信息
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingSellerResponse.Id">
<summary>
id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingSellerResponse.Name">
<summary>
name
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingStockResponse.Id">
<summary>
id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.LingXing.LingXingStockResponse.Name">
<summary>
name
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.Login.AccessTokenDto.ClientName"> <member name="P:WMS.Web.Core.Dto.Login.AccessTokenDto.ClientName">
<summary> <summary>
客户端名称 客户端名称
@@ -5914,6 +6115,86 @@
每页条数 不传默认每页10 条 每页条数 不传默认每页10 条
</summary> </summary>
</member> </member>
<member name="T:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryRequest">
<summary>
成品即时库存列表
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryRequest.MaterialNumber">
<summary>
物料编码
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryRequest.StockCode">
<summary>
仓库编码
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryRequest.Customer">
<summary>
客户/店铺
</summary>
</member>
<member name="T:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse">
<summary>
成品即时库存
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Id">
<summary>
单据Id
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Type">
<summary>
单据类型
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.MaterialNumber">
<summary>
物料编码
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Specifications">
<summary>
物料规格型号
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.MaterialName">
<summary>
物料名称
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Stock">
<summary>
仓库
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Org">
<summary>
组织
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Customer">
<summary>
客户/店铺
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Batch">
<summary>
批号
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.Qty">
<summary>
可用量
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.ProductInventory.ProductInventoryQueryResponse.BeforeQty">
<summary>
库存量
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.SendDataDto.CustomerCode"> <member name="P:WMS.Web.Core.Dto.SendDataDto.CustomerCode">
<summary> <summary>
客户编码 客户编码
@@ -6204,6 +6485,31 @@
仓库名称 仓库名称
</summary> </summary>
</member> </member>
<member name="T:WMS.Web.Core.Dto.SingleData.UcStockHeadOfficeResponse">
<summary>
根据总公司查仓库
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.SingleData.UcStockHeadOfficeResponse.WarehouseCodeOfLingxing">
<summary>
领星仓库编码
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.SingleData.UcStockHeadOfficeResponse.WarehouseCodeOfJushuitan">
<summary>
聚水潭仓库编码
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.SingleData.UcStockHeadOfficeResponse.WarehouseUseTo">
<summary>
用途 0 总公司
</summary>
</member>
<member name="P:WMS.Web.Core.Dto.SingleData.UcStockHeadOfficeResponse.ManagementSystem">
<summary>
管理系统 1 金蝶 2 聚水潭 3 领星 4WMS
</summary>
</member>
<member name="T:WMS.Web.Core.Dto.SingleData.UcStockResponse"> <member name="T:WMS.Web.Core.Dto.SingleData.UcStockResponse">
<summary> <summary>
仓库响应 仓库响应
@@ -7197,6 +7503,78 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.#ctor">
<summary>
实体分页集合结果
</summary>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.#ctor(System.Collections.Generic.IList{`0},System.Int32,System.Collections.Generic.List{System.Decimal})">
<summary>
实体分页集合结果
</summary>
<param name="data">实体集合</param>
<param name="totalCount">总条数</param>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.#ctor(System.Collections.Generic.IList{`0},System.Int32,System.ValueTuple{System.Int32,System.String})">
<summary>
实体分页集合结果
</summary>
<param name="data"></param>
<param name="totalCount"></param>
<param name="result"></param>
</member>
<member name="P:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.TotalCount">
<summary>
Total count of Items.
</summary>
</member>
<member name="P:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.Details">
<summary>
总数量
</summary>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.ReSuccess(System.Collections.Generic.IList{`0},System.Int32,System.Collections.Generic.List{System.Decimal})">
<summary>
创建成功的返回消息
</summary>
<param name="data">实体集合</param>
<param name="totalCount">总条数</param>
<returns></returns>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.ReSuccess">
<summary>
创建成功的返回消息
</summary>
<returns></returns>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.ReFailure(System.String,System.Int32)">
<summary>
创建返回信息(返回处理失败)
</summary>
<param name="message">结果消息</param>
<param name="status">结果状态</param>
<returns></returns>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.ReFailure(System.ValueTuple{System.Int32,System.String})">
<summary>
创建返回信息(返回处理失败)
</summary>
<param name="result">结果消息</param>
<returns></returns>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.ReFailure(WMS.Web.Core.Internal.Results.Result)">
<summary>
创建返回信息(返回处理失败)
</summary>
<param name="result">结果</param>
<returns></returns>
</member>
<member name="M:WMS.Web.Core.Internal.Results.ResultPagedNumber2List`1.AsTask">
<summary>
转换为 task
</summary>
<returns></returns>
</member>
<member name="T:WMS.Web.Core.Internal.Results.ResultPagedNumberList`1"> <member name="T:WMS.Web.Core.Internal.Results.ResultPagedNumberList`1">
<summary> <summary>
分页列表结果对象 分页列表结果对象

View File

@@ -1,4 +1,5 @@
using System; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@@ -9,22 +10,37 @@ namespace WMS.Web.Core.Dto.Erp
/// <summary> /// <summary>
/// 物料编码 /// 物料编码
/// </summary> /// </summary>
[JsonProperty("FMATERIALNUMBER")]
public string MaterialNumber { get; set; } public string MaterialNumber { get; set; }
/// <summary> /// <summary>
/// 组织编码 /// 组织编码
/// </summary> /// </summary>
[JsonProperty("FSTOCKORGNUMBER")]
public string OrgCode { get; set; } public string OrgCode { get; set; }
/// <summary> /// <summary>
/// 仓库 /// 仓库
/// </summary> /// </summary>
[JsonProperty("FSTOCKNUMBER")]
public string StockCode { get; set; } public string StockCode { get; set; }
/// <summary> /// <summary>
/// 子仓库(跟金蝶交互字段) /// 子仓库
/// </summary> /// </summary>
public int Erp_SubStockId { get; set; } [JsonProperty("FSTOCKLOC")]
public string Erp_SubStockName { get; set; }
/// <summary> /// <summary>
/// 数量 /// 批号
/// </summary> ///</summary>
public decimal Qty { get; set; } [JsonProperty("FLOTNUMBER")]
public string Batch { get; set; }
/// <summary>
/// 可用量
///</summary>
[JsonProperty("FAVBQTY")]
public decimal Qty { get; set; } = 0;
/// <summary>
/// 库存量
///</summary>
[JsonProperty("FQTY")]
public decimal BeforeQty { get; set; } = 0;
} }
} }

View File

@@ -0,0 +1,36 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.JuShuiTan
{
public class JuShuiTanInventoryRequst
{
/// <summary>
/// 页码
/// </summary>
[JsonProperty("page_index")]
public int page_index { get; set; } = 1;
/// <summary>
/// 页条数
/// </summary>
[JsonProperty("page_size")]
public int page_size { get; set; } = 30;
/// <summary>
/// 仓库Id
/// </summary>
[JsonProperty("wms_co_id")]
public int wms_co_id { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[JsonProperty("modified_begin")]
public string modified_begin { get; set; }
/// <summary>
/// 结算时间
/// </summary>
[JsonProperty("modified_end")]
public string modified_end { get; set; }
}
}

View File

@@ -0,0 +1,55 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using Ubiety.Dns.Core.Common;
namespace WMS.Web.Core.Dto.JuShuiTan
{
public class JuShuiTanInventoryResponse
{
/// <summary>
/// 商品
/// </summary>
[JsonProperty("sku_id")]
public string sku_id { get; set; }
[JsonProperty("wms_co_id")]
public int wms_co_id { get; set; }
/// <summary>
/// 总量
/// </summary>
[JsonProperty("qty")]
public int? qty { get; set; }
/// <summary>
/// 可用数:可用数[同步线上的库存数]=
/// 主仓实际库存-订单占有数+虚拟库存+采购在途(业务设置)+进货仓(业务设置)+销退仓库存(业务设置)
/// </summary>
[JsonProperty("ky_qty")]
public int ky_qty { get; set; }
/// <summary>
/// 订单占有数
/// </summary>
[JsonProperty("order_lock")]
public int? order_lock { get; set; }
/// <summary>
/// 虚拟库存
/// </summary>
[JsonProperty("virtual_qty")]
public int? virtual_qty { get; set; }
/// <summary>
/// 采购在途
/// </summary>
[JsonProperty("purchase_qty")]
public int? purchase_qty { get; set; }
/// <summary>
/// 销退仓库存
/// </summary>
[JsonProperty("return_qty")]
public int? return_qty { get; set; }
/// <summary>
/// 进货仓
/// </summary>
[JsonProperty("in_qty")]
public int? in_qty { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.JuShuiTan
{
public class JuShuiTanStockRequst
{
/// <summary>
/// 页码
/// </summary>
[JsonProperty("page_index")]
public int page_index { get; set; } = 1;
/// <summary>
/// 页条数
/// </summary>
[JsonProperty("page_size")]
public int page_size { get; set; } = 30;
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.JuShuiTan
{
public class JuShuiTanStockResResponse
{
public int code { get; set; }
public string msg { get; set; }
public object data { get; set; }
}
}

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.JuShuiTan
{
public class JuShuiTanStockResponse
{
/// <summary>
/// 仓库id
/// </summary>
[JsonProperty("wms_co_id")]
public int Id { get; set; }
/// <summary>
/// 仓库名
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,26 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.LingXing
{
/// <summary>
/// 领星即时库存
/// </summary>
[Serializable]
public class LingXingInventoryRequest:LingXingRequest
{
/// <summary>
/// 仓库Id 1,3,234,33
/// </summary>
[JsonProperty("wid")]
public string wid { get; set; }
/// <summary>
/// 物料规格型号
/// </summary>
[JsonProperty("sku")]
public string sku { get; set; }
}
}

View File

@@ -0,0 +1,41 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.LingXing
{
/// <summary>
/// 领星即时库存
/// </summary>
[Serializable]
public class LingXingInventoryResponse
{
/// <summary>
/// 仓库Id
/// </summary>
[JsonProperty("wid")]
public int StockId { get; set; }
/// <summary>
/// SKU
/// </summary>
[JsonProperty("sku")]
public string SKU { get; set; }
/// <summary>
/// 店铺id
/// </summary>
[JsonProperty("seller_id")]
public string SellerId { get; set; }
/// <summary>
/// 库存总量
/// </summary>
[JsonProperty("product_total")]
public decimal Product_Total { get; set; }
/// <summary>
/// 可用量
/// </summary>
[JsonProperty("product_valid_num")]
public decimal Product_Valid_Num { get; set; }
}
}

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.LingXing
{
public class LingXingKongRequest
{
}
}

View File

@@ -0,0 +1,24 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.LingXing
{
/// <summary>
/// 领星登录
/// </summary>
public class LingXingLoginRequest
{
/// <summary>
/// id
/// </summary>
[JsonProperty("appId")]
public string AppId { get; set; }
/// <summary>
/// Secret
/// </summary>
[JsonProperty("appSecret")]
public string AppSecret { get; set; }
}
}

View File

@@ -0,0 +1,29 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.LingXing
{
/// <summary>
/// 领星请求
/// </summary>
public class LingXingRequest
{
/// <summary>
/// 不是页码 是从第几条数据开始 如果是第二页的话 就是1*800
/// </summary>
[JsonProperty("offset")]
public int offset { get; set; } = 0;
/// <summary>
/// 页条数
/// </summary>
[JsonProperty("length")]
public int length { get; set; } = 800;
/// <summary>
/// 海外仓
/// </summary>
[JsonProperty("type")]
public int type { get; set; } = 1;
}
}

View File

@@ -0,0 +1,23 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
namespace WMS.Web.Core.Dto.LingXing
{
public class LingXingResponse
{
public LingXingResponse() { }
[JsonProperty("code")]
public int Code { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("error_details")]
public List<object> Error_details { get; set; }
[JsonProperty("total")]
public int Total { get; set; }
[JsonProperty("data")]
public object Data { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.LingXing
{
/// <summary>
/// 店铺信息
/// </summary>
public class LingXingSellerResponse
{
public LingXingSellerResponse() { }
/// <summary>
/// id
/// </summary>
[JsonProperty("sid")]
public string Id { get; set; }
/// <summary>
/// name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.LingXing
{
public class LingXingStockResponse
{
public LingXingStockResponse() { }
/// <summary>
/// id
/// </summary>
[JsonProperty("wid")]
public int Id { get; set; }
/// <summary>
/// name
/// </summary>
[JsonProperty("name")]
public string Name { get; set; }
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.ProductInventory
{
/// <summary>
/// 成品即时库存列表
/// </summary>
public class ProductInventoryQueryRequest : PaginationBaseRequestDto
{
/// <summary>
/// 物料编码
///</summary>
public string MaterialNumber { get; set; }
/// <summary>
/// 仓库编码
///</summary>
public string StockCode { get; set; }
/// <summary>
/// 客户/店铺
///</summary>
public string Customer { get; set; }
}
}

View File

@@ -0,0 +1,69 @@
using Npoi.Mapper.Attributes;
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Core.Dto.ProductInventory
{
/// <summary>
/// 成品即时库存
/// </summary>
public class ProductInventoryQueryResponse
{
/// <summary>
/// 单据Id
/// </summary>
[Ignore]
public int Id { get; set; }
/// <summary>
/// 单据类型
/// </summary>
[Ignore]
public string Type { get; set; }
/// <summary>
/// 物料编码
/// </summary>
[Column("物料编码")]
public string MaterialNumber { get; set; }
/// <summary>
/// 物料规格型号
/// </summary>
[Column("规格型号")]
public string Specifications { get; set; }
/// <summary>
/// 物料名称
/// </summary>
[Column("物料名称")]
public string MaterialName { get; set; }
/// <summary>
/// 仓库
///</summary>
[Column("仓库")]
public string Stock { get; set; }
/// <summary>
/// 组织
///</summary>
[Column("组织")]
public string Org { get; set; }
/// <summary>
/// 客户/店铺
///</summary>
[Column("客户/店铺")]
public string Customer { get; set; }
/// <summary>
/// 批号
///</summary>
[Column("批号")]
public string Batch { get; set; }
/// <summary>
/// 可用量
///</summary>
[Column("可用量")]
public decimal Qty { get; set; } = 0;
/// <summary>
/// 库存量
///</summary>
[Column("库存量")]
public decimal BeforeQty { get; set; } = 0;
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace WMS.Web.Core.Dto.SingleData
{
/// <summary>
/// 根据总公司查仓库
/// </summary>
public class UcStockHeadOfficeResponse: UcStockResponse
{
/// <summary>
/// 领星仓库编码
/// </summary>
public string WarehouseCodeOfLingxing { get; set; } = "";
/// <summary>
/// 聚水潭仓库编码
/// </summary>
public string WarehouseCodeOfJushuitan { get; set; } = "";
/// <summary>
/// 用途 0 总公司
/// </summary>
public int? WarehouseUseTo { get; set; }
/// <summary>
/// 管理系统 1 金蝶 2 聚水潭 3 领星 4WMS
/// </summary>
public int? ManagementSystem { get; set; }
}
}

View File

@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace WMS.Web.Core.Internal.Results
{
public class ResultPagedNumber2List<T> : ResultList<T>
{
/// <summary>
/// 实体分页集合结果
/// </summary>
public ResultPagedNumber2List()
{
}
/// <summary>
/// 实体分页集合结果
/// </summary>
/// <param name="data">实体集合</param>
/// <param name="totalCount">总条数</param>
public ResultPagedNumber2List(IList<T> data, int totalCount, List<decimal> details) : base(data)
{
TotalCount = totalCount;
Details = details;
}
/// <summary>
/// 实体分页集合结果
/// </summary>
/// <param name="data"></param>
/// <param name="totalCount"></param>
/// <param name="result"></param>
public ResultPagedNumber2List(IList<T> data, int totalCount, ValueTuple<int, string> result) : base(data, result)
{
TotalCount = totalCount;
}
/// <summary>
/// Total count of Items.
/// </summary>
public int TotalCount { get; set; }
/// <summary>
/// 总数量
/// </summary>
public List<decimal> Details { get; set; }
/// <summary>
/// 创建成功的返回消息
/// </summary>
/// <param name="data">实体集合</param>
/// <param name="totalCount">总条数</param>
/// <returns></returns>
public static ResultPagedNumber2List<T> ReSuccess(IList<T> data, int totalCount, List<decimal> details)
{
return new ResultPagedNumber2List<T>(data, totalCount, details);
}
/// <summary>
/// 创建成功的返回消息
/// </summary>
/// <returns></returns>
public new static ResultPagedNumber2List<T> ReSuccess()
{
return new ResultPagedNumber2List<T>(new List<T>(), 0, new List<decimal>());
}
/// <summary>
/// 创建返回信息(返回处理失败)
/// </summary>
/// <param name="message">结果消息</param>
/// <param name="status">结果状态</param>
/// <returns></returns>
public new static ResultPagedNumber2List<T> ReFailure(string message, int status)
{
var result = new ResultPagedNumber2List<T>();
result.To(message, status);
return result;
}
/// <summary>
/// 创建返回信息(返回处理失败)
/// </summary>
/// <param name="result">结果消息</param>
/// <returns></returns>
public new static ResultPagedNumber2List<T> ReFailure(ValueTuple<int, string> result)
{
var res = new ResultPagedNumber2List<T>();
res.To(result);
return res;
}
/// <summary>
/// 创建返回信息(返回处理失败)
/// </summary>
/// <param name="result">结果</param>
/// <returns></returns>
public new static ResultPagedNumber2List<T> ReFailure(Result result)
{
var re = new ResultPagedNumber2List<T>();
re.To(result);
return re;
}
/// <summary>
/// 转换为 task
/// </summary>
/// <returns></returns>
public new Task<ResultPagedNumber2List<T>> AsTask()
{
return Task.FromResult(this);
}
}
}

View File

@@ -0,0 +1,64 @@
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>
/// 成品仓即时库存
/// </summary>
[Serializable]
[Table("t_wms_product_inventory")]
public class ProductInventory : EntityBase
{
public ProductInventory() { }
/// <summary>
/// 主键 订单编号
/// </summary>
[Column("Id")]
public override int Id { get; set; }
/// <summary>
/// 物料编码
/// </summary>
[Column("MaterialNumber")]
public string MaterialNumber { get; set; }
/// <summary>
/// 单据类型
/// </summary>
[Column("Type")]
public ProductInventoryType Type { get; set; } = ProductInventoryType.JinDie;
/// <summary>
/// 组织编码
///</summary>
[Column("OrgCode")]
public string OrgCode { get; set; }
/// <summary>
/// 仓库
///</summary>
[Column("StockCode")]
public string StockCode { get; set; }
/// <summary>
/// 客户/店铺
///</summary>
[Column("Customer")]
public string Customer { get; set; }
/// <summary>
/// 批号
///</summary>
[Column("Batch")]
public string Batch { get; set; }
/// <summary>
/// 可用量
///</summary>
[Column("Qty")]
public decimal Qty { get; set; } = 0;
/// <summary>
/// 库存量
///</summary>
[Column("BeforeQty")]
public decimal BeforeQty { get; set; } = 0;
}
}

View File

@@ -0,0 +1,18 @@

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Internal.Results;
namespace WMS.Web.Domain.IService
{
public interface IProductInventoryService
{
Task<Result> LingXing();
Task<Result> Erp();
Task<Result> JuShuiTan();
Task<Result> Refresh();
}
}

View File

@@ -5,6 +5,7 @@ using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Dto.Erp.Customer; using WMS.Web.Core.Dto.Erp.Customer;
using WMS.Web.Core.Dto.Erp.Org; using WMS.Web.Core.Dto.Erp.Org;
using WMS.Web.Core.Dto.Erp.Supplier; using WMS.Web.Core.Dto.Erp.Supplier;
using WMS.Web.Core.Dto.SingleData;
namespace WMS.Web.Domain.IService.Public namespace WMS.Web.Domain.IService.Public
{ {
@@ -173,5 +174,12 @@ namespace WMS.Web.Domain.IService.Public
/// <param name="code"></param> /// <param name="code"></param>
/// <returns></returns> /// <returns></returns>
string GetSubStockName(List<Erp_SubStockDto> erpStocks, string code); string GetSubStockName(List<Erp_SubStockDto> erpStocks, string code);
/// <summary>
/// 成品即时库存仓库
/// </summary>
/// <param name="list"></param>
/// <param name="code"></param>
/// <returns></returns>
string GetProductInventoryStockName(List<UcStockHeadOfficeResponse> list, string code);
} }
} }

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Internal.Results;
namespace WMS.Web.Domain.IService.Public
{
public interface IErpInventoryService
{
Task<Result<List<ErpInventoryDto>>> GetInventory(List<string> stockCodes);
}
}

View File

@@ -178,7 +178,7 @@ namespace WMS.Web.Domain.IService.Public
/// 及时库存 /// 及时库存
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
Task<ResultList<ErpInventoryDto>> BillQueryForInventory(List<(string materialNumber, string orgCode, string stockCode, int subStockId)> request); Task<ResultList<ErpInventoryDto>> BillQueryForInventory(List<(string orgCode, string stockCode)> request);
//同步数据(保存提交审核) //同步数据(保存提交审核)
Task<Result<string>> Save<T>(T dto, string formId); Task<Result<string>> Save<T>(T dto, string formId);
//提交 //提交

View File

@@ -13,6 +13,7 @@ namespace WMS.Web.Domain.IService.Public
Task<T> GetAsync<T>(string url, Dictionary<string, string> dicHeaders, int timeoutSecond = 180); Task<T> GetAsync<T>(string url, Dictionary<string, string> dicHeaders, int timeoutSecond = 180);
Task<T> PostAsync<T>(string url, string requestBody, int timeoutSecond = 180); Task<T> PostAsync<T>(string url, string requestBody, int timeoutSecond = 180);
Task<T> PostAsync<T>(string url, string requestBody, Dictionary<string, string> dicHeaders, int timeoutSecond = 180); Task<T> PostAsync<T>(string url, string requestBody, Dictionary<string, string> dicHeaders, int timeoutSecond = 180);
Task<T> PostAsync<T>(string url, HttpContent content, Dictionary<string, string> dicHeaders, int timeoutSecond = 180);
Task<T> ExecuteAsync<T>(string url, HttpMethod method, string requestBody, Dictionary<string, string> dicHeaders, int timeoutSecond = 180); Task<T> ExecuteAsync<T>(string url, HttpMethod method, string requestBody, Dictionary<string, string> dicHeaders, int timeoutSecond = 180);
} }
} }

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.JuShuiTan;
using WMS.Web.Core.Internal.Results;
namespace WMS.Web.Domain.IService.Public
{
public interface IJuShuiTanService
{
Task GetTest();
Task<Result<List<JuShuiTanStockResponse>>> GetStock();
Task<Result<List<JuShuiTanInventoryResponse>>> GetInventory(List<int> StockId);
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.LingXing;
using WMS.Web.Core.Internal.Results;
namespace WMS.Web.Domain.IService.Public
{
/// <summary>
/// 领星服务接口
/// </summary>
public interface ILingXingService
{
/// <summary>
/// 获取领星所有仓库
/// </summary>
/// <returns></returns>
public Task<Result<List<LingXingStockResponse>>> GetStock();
/// <summary>
/// 获取领星所有仓库
/// </summary>
/// <returns></returns>
public Task<Result<List<LingXingSellerResponse>>> GetSeller();
/// <summary>
/// 获取即时库存
/// </summary>
/// <returns></returns>
public Task<Result<List<LingXingInventoryResponse>>> GetInventory(List<int> ids);
}
}

View File

@@ -71,6 +71,11 @@ namespace WMS.Web.Domain.Infrastructure
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
Task<List<UcStockResponse>> GetUcStockAsync(string systemCode,string name, int companyId); Task<List<UcStockResponse>> GetUcStockAsync(string systemCode,string name, int companyId);
/// <summary>
/// 获取仓库总公司
/// </summary>
/// <returns></returns>
Task<List<UcStockHeadOfficeResponse>> GetUcStockByHeadOfficeAsync(string name, int companyId);
/// <summary> /// <summary>
/// 获取事务 用来处理即时库存 /// 获取事务 用来处理即时库存

View File

@@ -0,0 +1,42 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.Inventory;
using WMS.Web.Core.Dto.ProductInventory;
using WMS.Web.Domain.Entitys;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Values;
namespace WMS.Web.Domain.Infrastructure
{
/// <summary>
/// 成品仓即时库存
/// </summary>
public interface IProductInventoryRepositories
{
/// <summary>
/// 添加
/// </summary>
/// <param name="entitys"></param>
/// <param name="isTransaction"></param>
/// <returns></returns>
Task<bool> AddRange(List<ProductInventory> entitys, bool isTransaction = true);
/// <summary>
/// 删除
/// </summary>
/// <param name="isTransaction"></param>
/// <returns></returns>
Task<bool> Delete(ProductInventoryType type, bool isTransaction = true);
Task<bool> EditEntityList(List<ProductInventory> entitys, bool isTransaction = true);
Task<List<ProductInventory>> GetEntityList(ProductInventoryType type);
/// <summary>
/// 列表-分页
/// </summary>
/// <param name="dto"></param>
/// <param name="companyId"></param>
/// <returns></returns>
Task<(List<ProductInventoryQueryResponse> list, int total, List<decimal> details)> GetListAsync(ProductInventoryQueryRequest dto, int companyId = 0);
}
}

View File

@@ -0,0 +1,17 @@
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Text;
using WMS.Web.Core.Dto.Erp;
using WMS.Web.Domain.Entitys;
namespace WMS.Web.Domain.Mappers
{
public class ProductInventoryMapper : Profile
{
public ProductInventoryMapper()
{
CreateMap<ProductInventory, ProductInventory>().ReverseMap();
}
}
}

View File

@@ -28,6 +28,10 @@ namespace WMS.Web.Domain.Options
/// erp-Id /// erp-Id
/// </summary> /// </summary>
public string ErpId { get; set; } public string ErpId { get; set; }
/// <summary>
/// 账号Id
/// </summary>
public string ZhangTaoId { get; set; }
public readonly string cache_materail_all_key = "erp_materials_list_all"; public readonly string cache_materail_all_key = "erp_materials_list_all";
public readonly string cache_materail_key = "erp_materials_list"; public readonly string cache_materail_key = "erp_materials_list";
public readonly string cache_org_key = "erp_org_list"; public readonly string cache_org_key = "erp_org_list";

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Domain.Options
{
public class JuShuiTanOptions
{
public string Url { get; set; }
public string AppKey { get; set; }
public string AppSecret { get; set; }
public string AccessToken { get; set; }
}
}

View File

@@ -103,6 +103,11 @@ namespace WMS.Web.Domain.Options
/// 监测金蝶删单 /// 监测金蝶删单
/// </summary> /// </summary>
public string JobStartErpDelete { get; set; } public string JobStartErpDelete { get; set; }
/// <summary>
/// 成品仓库即时库存
/// </summary>
public string JobStartProductInventory { get; set; }
/// <summary> /// <summary>
/// 是否启用集群:键 /// 是否启用集群:键
/// </summary> /// </summary>

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WMS.Web.Domain.Options
{
/// <summary>
/// 领星配置
/// </summary>
public class lingXingOptions
{
public string Url { get; set; }
public string AppId { get; set; }
public string AppSecret { get; set; }
}
}

View File

@@ -0,0 +1,48 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Quartz;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Domain.IService;
namespace WMS.Web.Domain.QuartzJob
{
//成品即时库存
public class InventoryQuartzJob : IJob
{
private readonly ILogger<InventoryQuartzJob> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IProductInventoryService _productInventoryService;
public InventoryQuartzJob(ILogger<InventoryQuartzJob> logger,
IServiceScopeFactory serviceScopeFactory, IProductInventoryService productInventoryService)
{
this._logger = logger;
_serviceScopeFactory = serviceScopeFactory;
_productInventoryService = productInventoryService;
}
/// <summary>
/// 执行方法
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task Execute(IJobExecutionContext context)
{
try
{
if (DateTime.Now.Hour < 8 || DateTime.Now.Hour > 20) return;
_logger.LogInformation($"同步成品即时库存->开始定时任务");
var result = await _productInventoryService.Refresh();
}
catch (Exception ex)
{
_logger.LogInformation($"同步成品即时库存:定时任务执行失败->{ex.Message}");
}
}
}
}

View File

@@ -0,0 +1,342 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.POIFS.FileSystem;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Dto.Login;
using WMS.Web.Core.Internal.Results;
using WMS.Web.Domain.Entitys;
using WMS.Web.Domain.Infrastructure;
using WMS.Web.Domain.IService;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Values;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
namespace WMS.Web.Domain.Services
{
public class ProductInventoryService : IProductInventoryService
{
private readonly IErpService _erpService;
private readonly ISingleDataService _singleDataService;
private readonly IErpBasicDataExtendService _erpBasicDataExtendService;
private readonly IProductInventoryRepositories _repositories;
private readonly ILingXingService _lingXingService;
private readonly IBasicsRepositories _basicsRepositories;
public readonly IBasicsRepositories _transactionRepositories;
public readonly IJuShuiTanService _juShuiTanService;
public readonly IErpInventoryService _erpInventoryService;
private readonly ILogger<ProductInventoryService> _logger;
public ProductInventoryService(IErpService erpService,
ISingleDataService singleDataService,
IErpBasicDataExtendService erpBasicDataExtendService,
IProductInventoryRepositories repositories,
ILingXingService lingXingService,
IBasicsRepositories basicsRepositories,
IBasicsRepositories transactionRepositories,
IJuShuiTanService juShuiTanService,
IErpInventoryService erpInventoryService,
ILogger<ProductInventoryService> logger)
{
_erpService = erpService;
_singleDataService = singleDataService;
_erpBasicDataExtendService = erpBasicDataExtendService;
_repositories = repositories;
_lingXingService = lingXingService;
_basicsRepositories = basicsRepositories;
_transactionRepositories = transactionRepositories;
_juShuiTanService = juShuiTanService;
_erpInventoryService = erpInventoryService;
_logger = logger;
}
/// <summary>
/// 金蝶
/// </summary>
/// <returns></returns>
public async Task<Result> Erp()
{
//获取单点配置
var r = await _basicsRepositories.GetUcStockByHeadOfficeAsync("", 1);
//r = r.Where(w => w.Code.Equals("CK001")).ToList();
var codes = r.Where(w =>
w.ManagementSystem == 1 || w.ManagementSystem == 4).Select(s => (s.Code, s.ErpOrgCode)).ToList();
if (codes.Count() <= 0) return Result.ReSuccess();
//var str = string.Join(",", codes.Select(s => s.Code).ToList());
var res = await _erpInventoryService.GetInventory(codes.Select(s => s.Code).ToList());
_logger.LogInformation($"拉取金蝶数据结果:{res.IsSuccess} {res.Message}");
if (!res.IsSuccess) return res;
//过滤掉不符合要求的组织和仓库组合
List<ErpInventoryDto> listOld = new List<ErpInventoryDto>();
foreach (var item in codes)
{
var zList = res.Data.Where(w => w.OrgCode == item.ErpOrgCode && w.StockCode == item.Code).ToList();
listOld.AddRange(zList);
}
List<ProductInventory> inventoryList = new List<ProductInventory>();
foreach (var item in listOld)
{
string subStock = "";
if (!string.IsNullOrEmpty(item.Erp_SubStockName))
subStock = item.Erp_SubStockName.Split(':')[1].Replace(";", "");
var entity = new ProductInventory()
{
Type = ProductInventoryType.JinDie,
MaterialNumber = item.MaterialNumber,
Customer = subStock,
OrgCode = item.OrgCode,
StockCode = item.StockCode,
Qty = item.Qty,
Batch = item.Batch,
BeforeQty = item.BeforeQty
};
inventoryList.Add(entity);
}
IDbContextTransaction _transaction = _transactionRepositories.GetTransaction();
Result res_Rollback = Result.ReSuccess();
bool isSuccess = true;
//修改库存
//先删除之前的再添加
if (res_Rollback.IsSuccess)
{
isSuccess = await _repositories.Delete(ProductInventoryType.JinDie, false);
if (isSuccess == false) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError);
}
if (res_Rollback.IsSuccess)
{
isSuccess = await _repositories.AddRange(inventoryList, false);
if (isSuccess == false) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError);
}
//提交事务
isSuccess = _transactionRepositories.CommitTransaction(res_Rollback.IsSuccess ? false : true, _transaction);
if (!res_Rollback.IsSuccess) return res_Rollback;
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// 聚水潭
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result> JuShuiTan()
{
//获取单点配置
var r = await _basicsRepositories.GetUcStockByHeadOfficeAsync("", 1);
var listNames = r.Where(w =>
w.ManagementSystem == 2 && !string.IsNullOrEmpty(w.WarehouseCodeOfJushuitan))
.Select(s => s.WarehouseCodeOfJushuitan)
.ToList();
if (listNames.Count() <= 0) return Result.ReSuccess();
//获取原数据
var yList = await _repositories.GetEntityList(ProductInventoryType.JushuiTan);
//获取领星仓库
var resStock = await _juShuiTanService.GetStock();
if (!resStock.IsSuccess) return resStock;
var ids = resStock.Data.Where(w => listNames.Contains(w.Name)).Select(s => s.Id).ToList();
//获取领星库存
var resInventory = await _juShuiTanService.GetInventory(ids);
_logger.LogInformation($"拉取聚水潭数据结果:{resInventory.IsSuccess} {resInventory.Message}");
if (!resInventory.IsSuccess) return resStock;
//物料
var materials_result = await _erpService.BillQueryForMaterial();
List<ErpMaterialDto> materials = new List<ErpMaterialDto>();
if (materials_result.IsSuccess)
materials = materials_result.Data.ToList();
List<ProductInventory> inventoryList = new List<ProductInventory>();
List<ProductInventory> update_List = new List<ProductInventory>();
foreach (var item in resInventory.Data)
{
//如果物料不匹配 过滤
var m = materials.FirstOrDefault(f => f.Specifications.Equals(item.sku_id));
if (m == null) continue;
//找仓库
var l_stock = resStock.Data.FirstOrDefault(f => f.Id == item.wms_co_id);
if (l_stock == null) continue;
var stock = r.FirstOrDefault(f => f.WarehouseCodeOfJushuitan.Equals(l_stock.Name));
if (stock == null) continue;
var entity = new ProductInventory()
{
Type = ProductInventoryType.JushuiTan,
MaterialNumber = m.MaterialNumber,
Customer = "",
OrgCode = stock.ErpOrgCode,
StockCode = stock.Code,
Qty = item.ky_qty,
BeforeQty = item.qty ?? 0
};
var old_Entity = yList.FirstOrDefault(f => f.MaterialNumber.Equals(entity.MaterialNumber) &&
f.OrgCode.Equals(entity.OrgCode) && f.StockCode.Equals(entity.StockCode));
if (old_Entity != null)
{
old_Entity.Qty = entity.Qty;
old_Entity.BeforeQty = entity.BeforeQty;
update_List.Add(old_Entity);
}
else
inventoryList.Add(entity);
}
IDbContextTransaction _transaction = _transactionRepositories.GetTransaction();
Result res_Rollback = Result.ReSuccess();
bool isSuccess = true;
//修改库存
//先删除之前的再添加
if (res_Rollback.IsSuccess)
{
isSuccess = await _repositories.EditEntityList(update_List, false);
if (isSuccess == false) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError);
}
if (res_Rollback.IsSuccess)
{
isSuccess = await _repositories.AddRange(inventoryList, false);
if (isSuccess == false) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError);
}
//提交事务
isSuccess = _transactionRepositories.CommitTransaction(res_Rollback.IsSuccess ? false : true, _transaction);
if (!res_Rollback.IsSuccess) return res_Rollback;
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
/// <summary>
/// 领星
/// </summary>
/// <returns></returns>
public async Task<Result> LingXing()
{
//获取单点配置
var r = await _basicsRepositories.GetUcStockByHeadOfficeAsync("", 1);
var listNames = r.Where(w =>
w.ManagementSystem == 3 && !string.IsNullOrEmpty(w.WarehouseCodeOfLingxing))
.Select(s => s.WarehouseCodeOfLingxing)
.ToList();
if (listNames.Count() <= 0) return Result.ReSuccess();
//获取领星仓库
var resStock = await _lingXingService.GetStock();
_logger.LogInformation($"拉取领星仓库:{JsonConvert.SerializeObject(resStock)}");
if (!resStock.IsSuccess) return resStock;
var ids = resStock.Data.Where(w => listNames.Contains(w.Name)).Select(s => s.Id).ToList();
string strIds = string.Join(",", ids);
//获取领星库存
var resInventory = await _lingXingService.GetInventory(ids);
_logger.LogInformation($"拉取领星数据结果:{resInventory.IsSuccess} {resInventory.Message}");
if (!resInventory.IsSuccess) return resStock;
foreach (var i in ids)
{
_logger.LogInformation($"拉取领星数据{i} 数据总数:{resInventory.Data.Where(w => w.StockId == i).Count()}");
}
//物料
var materials_result = await _erpService.BillQueryForMaterial();
List<ErpMaterialDto> materials = new List<ErpMaterialDto>();
if (materials_result.IsSuccess)
materials = materials_result.Data.ToList();
//获取店铺
var sellerList = await _lingXingService.GetSeller();
//合并
var group = resInventory.Data.GroupBy(g => (g.StockId, g.SKU, g.SellerId));
//int cc = group.Count();
List<ProductInventory> inventoryList = new List<ProductInventory>();
foreach (var item in group)
{
//如果物料不匹配 过滤
var m = materials.FirstOrDefault(f => f.Specifications.Equals(item.Key.SKU));
if (m == null) continue;
//找仓库
var l_stock = resStock.Data.FirstOrDefault(f => f.Id == item.Key.StockId);
if (l_stock == null) continue;
var stock = r.FirstOrDefault(f => f.WarehouseCodeOfLingxing.Equals(l_stock.Name));
if (stock == null) continue;
//店铺
var seller = sellerList.Data.FirstOrDefault(f => f.Id == item.Key.SellerId);
var pList = resInventory.Data.Where(w => w.SKU == item.Key.SKU
&& w.StockId == item.Key.StockId && w.SellerId == item.Key.SellerId).ToList();
var entity = new ProductInventory()
{
Type = ProductInventoryType.LingXing,
MaterialNumber = m.MaterialNumber,
Customer = seller != null ? seller.Name : "",
OrgCode = stock.ErpOrgCode,
StockCode = stock.Code,
Qty = pList.Sum(s => s.Product_Valid_Num),
BeforeQty = pList.Sum(s => s.Product_Total)
};
inventoryList.Add(entity);
}
IDbContextTransaction _transaction = _transactionRepositories.GetTransaction();
Result res_Rollback = Result.ReSuccess();
bool isSuccess = true;
//修改库存
//先删除之前的再添加
if (res_Rollback.IsSuccess)
{
isSuccess = await _repositories.Delete(ProductInventoryType.LingXing, false);
if (isSuccess == false) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError);
}
if (res_Rollback.IsSuccess)
{
isSuccess = await _repositories.AddRange(inventoryList, false);
if (isSuccess == false) res_Rollback = Result.ReFailure(ResultCodes.DateWriteError);
}
//提交事务
isSuccess = _transactionRepositories.CommitTransaction(res_Rollback.IsSuccess ? false : true, _transaction);
if (!res_Rollback.IsSuccess) return res_Rollback;
if (!isSuccess)
return Result.ReFailure(ResultCodes.DateWriteError);
return Result.ReSuccess();
}
public async Task<Result> Refresh()
{
_logger.LogInformation($"同步成品仓库存->开始 {DateTime.Now}");
try
{
var res = await this.Erp();
_logger.LogInformation($"同步成品仓库存(物料) {res.IsSuccess} {res.Message}");
if (!res.IsSuccess) return res;
res = await this.JuShuiTan();
_logger.LogInformation($"同步成品仓库存(聚水潭) {res.IsSuccess} {res.Message}");
if (!res.IsSuccess) return res;
res = await this.LingXing();
_logger.LogInformation($"同步成品仓库存(领星) {res.IsSuccess} {res.Message}");
if (!res.IsSuccess) return res;
}
catch (Exception ex)
{
_logger.LogError($"同步成品仓库异常:{ex.ToString()}");
}
_logger.LogInformation($"同步成品仓库存->结束 {DateTime.Now}");
return Result.ReSuccess();
}
}
}

View File

@@ -7,6 +7,7 @@ using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Dto.Erp.Customer; using WMS.Web.Core.Dto.Erp.Customer;
using WMS.Web.Core.Dto.Erp.Org; using WMS.Web.Core.Dto.Erp.Org;
using WMS.Web.Core.Dto.Erp.Supplier; using WMS.Web.Core.Dto.Erp.Supplier;
using WMS.Web.Core.Dto.SingleData;
using WMS.Web.Domain.Infrastructure; using WMS.Web.Domain.Infrastructure;
using WMS.Web.Domain.IService.Public; using WMS.Web.Domain.IService.Public;
@@ -407,6 +408,18 @@ namespace WMS.Web.Domain.Services.Public
var stock = erpStocks.Where(x => x.Code == code).FirstOrDefault(); var stock = erpStocks.Where(x => x.Code == code).FirstOrDefault();
return stock == null ? "" : stock.Name; return stock == null ? "" : stock.Name;
} }
/// <summary>
/// 成品即时库存仓库
/// </summary>
/// <param name="list"></param>
/// <param name="code"></param>
/// <returns></returns>
public string GetProductInventoryStockName(List<UcStockHeadOfficeResponse> list, string code)
{
if (list == null || list.Count == 0)
return "";
var stock = list.Where(x => x.Code == code).FirstOrDefault();
return stock == null ? "" : stock.Name;
}
} }
} }

View File

@@ -0,0 +1,320 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MySqlX.XDevAPI.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Dto.JuShuiTan;
using WMS.Web.Core.Internal.Results;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Options;
using WMS.Web.Domain.Values;
namespace WMS.Web.Domain.Services.Public
{
public class ErpInventoryService : IErpInventoryService
{
private ErpOptions _erpOptions;
private readonly ILogger<ErpInventoryService> _logger;
public ErpInventoryService(IOptions<ErpOptions> erpOptions, ILogger<ErpInventoryService> logger)
{
_erpOptions = erpOptions?.Value;
_logger = logger;
}
private bool Login(HttpClientEx httpClient)
{
string baseUrl = _erpOptions.EndpointAddress.Replace("/ERPGW.asmx", ""); //"http://192.168.1.1/k3cloud";//服务器地址
httpClient.Url = string.Format("{0}/Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc", baseUrl);
List<object> Parameters = new List<object>();
Parameters.Add(_erpOptions.ZhangTaoId);//帐套Id
Parameters.Add(_erpOptions.UserName);//用户名
Parameters.Add(_erpOptions.Password);//密码
Parameters.Add(2052);//多语言:中文
httpClient.Content = JsonConvert.SerializeObject(Parameters);
string response = httpClient.AsyncRequest();
var iResult = JObject.Parse(response)["LoginResultType"].Value<int>();
return iResult == 1 ? true : false;
}
public async Task<Result<List<ErpInventoryDto>>> GetInventory(List<string> stockCodes)
{
List<ErpInventoryDto> list = new List<ErpInventoryDto>();
HttpClientEx httpClient = new HttpClientEx();
var isSuccess = Login(httpClient);
string baseUrl = _erpOptions.EndpointAddress.Replace("/ERPGW.asmx", "");
httpClient.Url = string.Format("{0}/Kingdee.K3.SCM.WebApi.ServicesStub.InventoryQueryService.GetInventoryData.common.kdsvc", baseUrl);
int count = stockCodes.Count() / 10;
count = count + 1;
for (int ic = 1; ic <= count; ic++)
{
var codes = stockCodes.Skip((ic-1) * 10).Take(10).ToList();
if (codes.Count() <= 0)
{
return Result<List<ErpInventoryDto>>.ReSuccess(list.Where(w => w.Qty > 0 || w.BeforeQty > 0).ToList());
}
string code = string.Join(",", codes);
//foreach (var code in stockCodes)
//{
List<object> Parameters = new List<object>();
var model = new InventoryParamModel();
model.fstocknumbers = code;
//model.fmaterialnumbers = "G01-11-572474";
model.isshowauxprop = true;
model.isshowstockloc = true;
model.pageindex = 1;
model.pagerows = 5000;
Parameters.Add(model);
httpClient.Content = JsonConvert.SerializeObject(Parameters);
//_logger.LogInformation($"1.开始进行连接 {code}");
string content = httpClient.AsyncRequest();
//_logger.LogInformation($"金蝶返回数据{content}");
JObject resData = JObject.Parse(content);
if (resData["success"].ToString().ToLower() != "true")
return Result<List<ErpInventoryDto>>.ReFailure(ResultCodes.Erp_Inventory_Error);
string json = resData["data"].ToString();
var datas = JsonConvert.DeserializeObject<List<ErpInventoryDto>>(json);
if (datas != null && datas.Count() > 0)
list.AddRange(datas);
int num = Convert.ToInt32(resData["rowcount"]) / 5000;
for (int i = 1; i <= num; i++)
{
model.pageindex++;
httpClient.Content = JsonConvert.SerializeObject(Parameters);
content = httpClient.AsyncRequest();
//_logger.LogInformation($"金蝶返回数据{content}");
resData = JObject.Parse(content);
if (resData["success"].ToString().ToLower() != "true")
return Result<List<ErpInventoryDto>>.ReFailure(ResultCodes.Erp_Inventory_Error);
json = resData["data"].ToString();
datas = JsonConvert.DeserializeObject<List<ErpInventoryDto>>(json);
if (datas != null && datas.Count() > 0)
list.AddRange(datas);
}
}
var blist = list.Where(w => w.Qty > 0 || w.BeforeQty > 0).ToList();
return Result<List<ErpInventoryDto>>.ReSuccess(blist);
}
}
class HttpClientEx
{
/// <summary>
/// Seivice URL
/// </summary>
public string Url { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// Cookie保证登录后所有访问持有一个Cookie
/// </summary>
static CookieContainer Cookie = new CookieContainer();
/// <summary>
/// HTTP访问
/// </summary>
public string AsyncRequest()
{
HttpWebRequest httpRequest = HttpWebRequest.Create(Url) as HttpWebRequest;
httpRequest.Method = "POST";
httpRequest.ContentType = "application/json";
httpRequest.CookieContainer = Cookie;
httpRequest.Timeout = 1000 * 60 * 10;//10min
using (Stream reqStream = httpRequest.GetRequestStream())
{
JObject jObj = new JObject();
jObj.Add("format", 1);
jObj.Add("useragent", "ApiClient");
jObj.Add("rid", Guid.NewGuid().ToString().GetHashCode().ToString());
jObj.Add("parameters", Content);
jObj.Add("timestamp", DateTime.Now);
jObj.Add("v", "1.0");
string sContent = jObj.ToString();
var bytes = UnicodeEncoding.UTF8.GetBytes(sContent);
reqStream.Write(bytes, 0, bytes.Length);
reqStream.Flush();
}
using (var repStream = httpRequest.GetResponse().GetResponseStream())
{
using (var reader = new StreamReader(repStream))
{
return ValidateResult(reader.ReadToEnd());
}
}
}
private static string ValidateResult(string responseText)
{
if (responseText.StartsWith("response_error:"))
{
return responseText.TrimStart("response_error:".ToCharArray());
}
return responseText;
}
}
class InventoryParamModel
{
/// <summary>
/// 库存组织编码,多个使用英文逗号【,】分隔
/// </summary>
public string fstockorgnumbers { get; set; }
/// <summary>
/// 物料编码,多个使用英文逗号【,】分隔
/// </summary>
public string fmaterialnumbers { get; set; }
/// <summary>
/// 仓库编码,多个使用英文逗号【,】分隔
/// </summary>
public string fstocknumbers { get; set; }
/// <summary>
/// 批号编码,多个使用英文逗号【,】分隔
/// </summary>
public string flotnumbers { get; set; }
/// <summary>
/// 是否查询仓位
/// </summary>
public bool isshowstockloc { get; set; }
/// <summary>
/// 是否查询辅助属性
/// </summary>
public bool isshowauxprop { get; set; }
/// <summary>
/// 当前页码
/// </summary>
public int pageindex { get; set; }
/// <summary>
/// 每页显示行数
/// </summary>
public int pagerows { get; set; }
}
}

View File

@@ -160,7 +160,7 @@ namespace WMS.Web.Domain.Services.Public
/// <param name="billNo">模糊搜索</param> /// <param name="billNo">模糊搜索</param>
/// <param name="sourceBillNos">单据编号集合精确查找</param> /// <param name="sourceBillNos">单据编号集合精确查找</param>
/// <returns></returns> /// <returns></returns>
public async Task<ResultList<ErpInStockResultDto>> BillQueryForPurchaseInStock(List<string> sourceBillNos = null, DateTime? beginTime = null,bool isCheck=true) public async Task<ResultList<ErpInStockResultDto>> BillQueryForPurchaseInStock(List<string> sourceBillNos = null, DateTime? beginTime = null, bool isCheck = true)
{ {
string result_json = ""; string result_json = "";
try try
@@ -194,7 +194,7 @@ namespace WMS.Web.Domain.Services.Public
//5.仓库wms系统的仓库值---现在这个没有加,因为还单点没有和金蝶同步 //5.仓库wms系统的仓库值---现在这个没有加,因为还单点没有和金蝶同步
//param.FilterString = " FDocumentStatus='C' and (FBillTypeID='83d822ca3e374b4ab01e5dd46a0062bd' or FBillTypeID='6d01d059713d42a28bb976c90a121142') and FMRPCloseStatus='A'"; //param.FilterString = " FDocumentStatus='C' and (FBillTypeID='83d822ca3e374b4ab01e5dd46a0062bd' or FBillTypeID='6d01d059713d42a28bb976c90a121142') and FMRPCloseStatus='A'";
param.FilterString = " FMRPCloseStatus='A'"; param.FilterString = " FMRPCloseStatus='A'";
if(isCheck) param.FilterString += " and FDocumentStatus='C'"; if (isCheck) param.FilterString += " and FDocumentStatus='C'";
for (int i = 0; i < stocks.Count(); i++) for (int i = 0; i < stocks.Count(); i++)
{ {
if (i == 0) if (i == 0)
@@ -2637,7 +2637,7 @@ namespace WMS.Web.Domain.Services.Public
} }
} }
public async Task<ResultList<ErpInventoryDto>> BillQueryForInventory(List<(string materialNumber, string orgCode, string stockCode, int subStockId)> request) public async Task<ResultList<ErpInventoryDto>> BillQueryForInventory(List<(string orgCode, string stockCode)> request)
{ {
try try
{ {
@@ -2650,51 +2650,76 @@ namespace WMS.Web.Domain.Services.Public
//3.获取金蝶采购订单:拼接参数和条件 //3.获取金蝶采购订单:拼接参数和条件
var query = new ErpBillQueryDto(token_result.Data); var query = new ErpBillQueryDto(token_result.Data);
var param = new ErpBillQueryParamDto(FormIdParam.STK_Inventory.ToString()); var param = new ErpBillQueryParamDto(FormIdParam.STK_Inventory.ToString());
param.FieldKeys = "FBASEQTY,FMATERIALID.FNumber,FSTOCKORGID.FNumber,FSTOCKID.FNumber,FSTOCKLOCID"; // ORICO_AD,FF100004 ORICO_GD,FF100005 ORICO_HD,FF100007 ORICO_JD,FF100008
param.Limit = 100; param.FieldKeys = "FMATERIALID.FNumber,FSTOCKORGID.FNumber,FSTOCKID.FNumber,FLot.FNumber,FBASEQTY,FSTOREURNOM,FSTOREURNUM,FSTOCKLOCID.FF100004.FName,FSTOCKLOCID.FF100005.FName,FSTOCKLOCID.FF100007.FName,FSTOCKLOCID.FF100008.FName";
//param.FilterString = $"FSTOCKORGID.FNumber='{request[0].orgCode}' and FSTOCKID.FNumber='{request[0].stockCode}'"; param.Limit = 10000;
//param.FilterString = $""; //param.FilterString = $" FMATERIALID.FNumber='G01-11-572474' and FSTOCKID.FNumber='AD' and FBASEQTY>0";
//param.FilterString = $" FBASEQTY>0";
for (int i = 0; i < request.Count(); i++) for (int i = 0; i < request.Count(); i++)
{ {
if (i == 0) if (i == 0)
{ {
param.FilterString = $"(FMATERIALID.FNumber='{request[0].materialNumber}' and FSTOCKORGID.FNumber='{request[0].orgCode}' and FSTOCKID.FNumber='{request[0].stockCode}' and FSTOCKLOCID={request[0].subStockId})"; param.FilterString += $" and ((FSTOCKORGID.FNumber='{request[0].orgCode}' and FSTOCKID.FNumber='{request[0].stockCode}' )";
if (request.Count() == 1) param.FilterString += ")";
} }
else else
{ {
param.FilterString += $" or (FMATERIALID.FNumber='{request[i].materialNumber}' and FSTOCKORGID.FNumber='{request[i].orgCode}' and FSTOCKID.FNumber='{request[i].stockCode}' and FSTOCKLOCID={request[i].subStockId})"; param.FilterString += $" or (FSTOCKORGID.FNumber='{request[i].orgCode}' and FSTOCKID.FNumber='{request[i].stockCode}' ))";
} }
} }
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);
bool isHave = true;
var erp_list = new List<ErpInventoryDto>(); var erp_list = new List<ErpInventoryDto>();
foreach (var item in result) int skip = 0;
while (isHave)
{ {
//4.1.页码页码按照金蝶的要求从0开始
param.StartRow = (Convert.ToInt32(skip) * param.Limit);
var lis = erp_list.FirstOrDefault(f => f.MaterialNumber.Equals(item[1]) query.Data = JsonConvert.SerializeObject(param);
&& f.OrgCode.Equals(item[2]) var json = JsonConvert.SerializeObject(query);
&& f.StockCode.Equals(item[3]));
if (lis == null) //4.请求查询接口
var result_json = await _client.ExecuteBillQueryAsync(json);
var result = JsonConvert.DeserializeObject<List<List<string>>>(result_json);
//4.4.判断数据是否全部拉取完成:并停止循环的条件
if (result == null || result.Count == 0)
isHave = false;
foreach (var item in result)
{ {
lis = new ErpInventoryDto(); string name = GetName(item[7], item[8], item[9], item[10]);
lis.Qty = Convert.ToDecimal(item[0]); var lis = erp_list.FirstOrDefault(f => f.MaterialNumber.Equals(item[0])
lis.MaterialNumber = item[1]; && f.OrgCode.Equals(item[1])
lis.OrgCode = item[2]; && f.StockCode.Equals(item[2]) && f.Erp_SubStockName.Equals(name));
lis.StockCode = item[3];
lis.Erp_SubStockId = Convert.ToInt32(item[4]);
erp_list.Add(lis);
}
else
lis.Qty = lis.Qty + Convert.ToDecimal(item[0]);
}
return ResultList<ErpInventoryDto>.ReSuccess(erp_list); if (lis == null)
{
lis = new ErpInventoryDto();
lis.MaterialNumber = item[0];
lis.OrgCode = item[1];
lis.StockCode = item[2];
lis.Batch = item[3];
//查询库存单位数量FQTYFMaterialid.FSTOREURNOM,FMaterialid.FSTOREURNUM
//查出结果后用(FBASEQTY*FSTOREURNOM/FSTOREURNUM)计算得到库存单位数量。
lis.BeforeQty = Convert.ToDecimal(item[4]) * Convert.ToDecimal(item[5]) / Convert.ToDecimal(item[6]);
//lis.Qty= Convert.ToDecimal(item[10]) * Convert.ToDecimal(item[5]) / Convert.ToDecimal(item[6]);
lis.Erp_SubStockName = name;
erp_list.Add(lis);
}
else
{
lis.BeforeQty = lis.BeforeQty + (Convert.ToDecimal(item[4]) * Convert.ToDecimal(item[5]) / Convert.ToDecimal(item[6]));
//lis.Qty = lis.Qty + Convert.ToDecimal(item[5]);
}
}
//4.6页面的叠加
skip++;
}
var list = erp_list.Where(w => w.BeforeQty > 0 || w.Qty > 0).ToList();
return ResultList<ErpInventoryDto>.ReSuccess(list);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -2704,7 +2729,14 @@ namespace WMS.Web.Domain.Services.Public
} }
public string GetName(string name1,string name2,string name3,string name4)
{
if (!string.IsNullOrEmpty(name1)) return name1;
if (!string.IsNullOrEmpty(name2)) return name2;
if (!string.IsNullOrEmpty(name3)) return name3;
if (!string.IsNullOrEmpty(name4)) return name4;
return "";
}
#endregion #endregion
} }

View File

@@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
@@ -48,8 +49,9 @@ namespace WMS.Web.Domain.Services.Public
var responseContent = await response.Content.ReadAsStringAsync(); //2.当前使用这里是为了迎合错误信息观看 var responseContent = await response.Content.ReadAsStringAsync(); //2.当前使用这里是为了迎合错误信息观看
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); //var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
//var t = await JsonSerializer.DeserializeAsync<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });//3.配合1的ReadAsStream使用 //var t = await JsonSerializer.DeserializeAsync<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });//3.配合1的ReadAsStream使用
var t = JsonConvert.DeserializeObject<T>(responseContent);
return t; return t;
} }
@@ -80,8 +82,9 @@ namespace WMS.Web.Domain.Services.Public
var responseContent = await response.Content.ReadAsStringAsync(); //2.当前使用这里是为了迎合错误信息观看 var responseContent = await response.Content.ReadAsStringAsync(); //2.当前使用这里是为了迎合错误信息观看
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); //var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
//var t = await JsonSerializer.DeserializeAsync<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });//3.配合1的ReadAsStream使用 //var t = await JsonSerializer.DeserializeAsync<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });//3.配合1的ReadAsStream使用
var t = JsonConvert.DeserializeObject<T>(responseContent);
return t; return t;
} }
@@ -111,7 +114,8 @@ namespace WMS.Web.Domain.Services.Public
var responseContent = await response.Content.ReadAsStringAsync(); var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); //var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
var t = JsonConvert.DeserializeObject<T>(responseContent);
return t; return t;
} }
@@ -135,7 +139,8 @@ namespace WMS.Web.Domain.Services.Public
var responseContent = await response.Content.ReadAsStringAsync(); var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); //var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
var t = JsonConvert.DeserializeObject<T>(responseContent);
if (t == null) if (t == null)
_logger.LogInformation($"获取单点数据为空---{responseContent}"); _logger.LogInformation($"获取单点数据为空---{responseContent}");
return t; return t;
@@ -163,8 +168,8 @@ namespace WMS.Web.Domain.Services.Public
var responseContent = await response.Content.ReadAsStringAsync(); var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); //var t = JsonSerializer.Deserialize<T>(responseContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
var t = JsonConvert.DeserializeObject<T>(responseContent);
return t; return t;
} }
@@ -226,5 +231,20 @@ namespace WMS.Web.Domain.Services.Public
if (timeoutSecond != null) httpClient.Timeout = TimeSpan.FromSeconds(timeoutSecond.Value); if (timeoutSecond != null) httpClient.Timeout = TimeSpan.FromSeconds(timeoutSecond.Value);
return httpClient; return httpClient;
} }
public async Task<T> PostAsync<T>(string url, HttpContent content, Dictionary<string, string> dicHeaders, int timeoutSecond = 180)
{
var client = BuildHttpClient(dicHeaders, timeoutSecond);
var response = await client.PostAsync(url, content);
var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var t = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(responseContent);
return t;
}
_logger.LogError($"HttpGet:{url} Error:{responseContent}");
throw new WebHttpException(response.StatusCode.ToString(), responseContent);
}
} }
} }

View File

@@ -0,0 +1,245 @@
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Dto.JuShuiTan;
using WMS.Web.Core.Help;
using WMS.Web.Core.Internal.Results;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Options;
using WMS.Web.Domain.Values;
namespace WMS.Web.Domain.Services.Public
{
public class JuShuiTanService : IJuShuiTanService
{
private readonly IHttpClientService _httpClientService;
private readonly ILogger<JuShuiTanService> _logger;
private readonly IMemoryCache _memoryCache;
private int hours = 10;//过期时间 默认10小时
private readonly JuShuiTanOptions _option;
public JuShuiTanService(IHttpClientService httpClientService, ILogger<JuShuiTanService> logger,
IMemoryCache memoryCache, IOptions<JuShuiTanOptions> option)
{
this._memoryCache = memoryCache;
this._httpClientService = httpClientService;
this._logger = logger;
_option = option?.Value;
}
public async Task GetTest()
{
//await GetStock();
var list = new List<int>();
list.Add(10923342);
await GetInventory(list);
}
public async Task<Result<List<JuShuiTanStockResponse>>> GetStock()
{
var stock_list = _memoryCache.Get<List<JuShuiTanStockResponse>>("jushuitan_stock");
if (stock_list != null && stock_list.Count > 0)
return Result<List<JuShuiTanStockResponse>>.ReSuccess(stock_list);
List<JuShuiTanStockResponse> list = new List<JuShuiTanStockResponse>();
JuShuiTanStockRequst request = new JuShuiTanStockRequst();
var resContent = PostUrl("/open/wms/partner/query", JsonConvert.SerializeObject(request));
JObject resData = JObject.Parse(resContent);
if (Convert.ToInt32(resData["code"]) != 0)
{
_logger.LogInformation($"聚水潭获取仓库失败:{resData["msg"].ToString()}");
return Result<List<JuShuiTanStockResponse>>.ReFailure(ResultCodes.JuShuiTanDataError);
}
string json = resData["data"]["datas"].ToString();
var datas = JsonConvert.DeserializeObject<List<JuShuiTanStockResponse>>(json);
list.AddRange(datas);
int count = Convert.ToInt32(resData["data"]["page_count"]);
for (int i = 1; i < count; i++)
{
request.page_index++;
resContent = PostUrl("/open/wms/partner/query", JsonConvert.SerializeObject(request));
resData = JObject.Parse(resContent);
if (Convert.ToInt32(resData["code"]) != 0)
{
_logger.LogInformation($"聚水潭获取仓库失败:{resData["msg"].ToString()}");
return Result<List<JuShuiTanStockResponse>>.ReFailure(ResultCodes.JuShuiTanDataError);
}
json = resData["data"]["datas"].ToString();
datas = JsonConvert.DeserializeObject<List<JuShuiTanStockResponse>>(json);
list.AddRange(datas);
}
//设置缓存
_memoryCache.Set("jushuitan_stock", list, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(DateTimeUtil.GetTotalMinutesTimeSpan())));
return Result<List<JuShuiTanStockResponse>>.ReSuccess(list);
}
public async Task<Result<List<JuShuiTanInventoryResponse>>> GetInventory(List<int> StockId)
{
List<JuShuiTanInventoryResponse> list = new List<JuShuiTanInventoryResponse>();
foreach (var id in StockId)
{
Thread.Sleep(1000);//不能太频繁请求
JuShuiTanInventoryRequst request = new JuShuiTanInventoryRequst();
request.wms_co_id = id;//10923342;
request.page_size = 100;
request.modified_begin = DateTime.Now.AddDays(-6).AddHours(-23).ToString("yyyy-MM-dd HH:mm:ss");
request.modified_end = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var resContent = PostUrl("/open/inventory/query", JsonConvert.SerializeObject(request));
JObject resData = JObject.Parse(resContent);
if (Convert.ToInt32(resData["code"]) != 0)
{
_logger.LogInformation($"聚水潭获取即时库存失败:{resData["msg"].ToString()}");
return Result<List<JuShuiTanInventoryResponse>>.ReFailure(ResultCodes.JuShuiTanDataError);
}
string json = resData["data"]["inventorys"].ToString();
var datas = JsonConvert.DeserializeObject<List<JuShuiTanInventoryResponse>>(json);
datas.ForEach(f => f.wms_co_id = id);
list.AddRange(datas);
int count = Convert.ToInt32(resData["data"]["page_count"]);
for (int i = 1; i < count; i++)
{
Thread.Sleep(1000);//不能太频繁请求
request.page_index++;
resContent = PostUrl("/open/inventory/query", JsonConvert.SerializeObject(request));
resData = JObject.Parse(resContent);
if (Convert.ToInt32(resData["code"]) != 0)
{
_logger.LogInformation($"聚水潭获取即时库存失败:{resData["msg"].ToString()}");
return Result<List<JuShuiTanInventoryResponse>>.ReFailure(ResultCodes.JuShuiTanDataError);
}
json = resData["data"]["inventorys"].ToString();
datas = JsonConvert.DeserializeObject<List<JuShuiTanInventoryResponse>>(json);
datas.ForEach(f => f.wms_co_id = id);
list.AddRange(datas);
}
}
//主仓实际库存-订单占有数+虚拟库存+采购在途(业务设置)+进货仓(业务设置)+销退仓库存(业务设置)
foreach (var item in list)
{
item.qty = item.qty == null ? 0 : item.qty;
item.ky_qty = (item.qty ?? 0) - (item.order_lock ?? 0) + (item.virtual_qty ?? 0)
+ (item.purchase_qty ?? 0) + (item.in_qty ?? 0) + (item.return_qty ?? 0);
}
//这里不能过滤掉都是0的 因为要修改
//var resList = list.Where(w => w.qty > 0 || w.ky_qty > 0).ToList();
return Result<List<JuShuiTanInventoryResponse>>.ReSuccess(list);
}
/// <summary>
/// 调用接口
/// </summary>
private string PostUrl(string urlStr, string biz)
{
Hashtable ht = new Hashtable();
System.DateTime starttime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
string time = Math.Floor((System.DateTime.Now - starttime).TotalSeconds).ToString();
string app_key = _option.AppKey;// "17231841286c45f99eb9acf445404349";
string app_secret = _option.AppSecret;// "5ce9641ae6db4abb8b96eea7df6a81e9";
string access_token = _option.AccessToken;// "4605358c37374780a8a4395e6cdb1c3f";
//string biz = "{\"modified_begin\":\"2022-06-10 00:00:00\",\"modified_end\":\"2022-06-12 00:00:00\",\"page_index\":1,\"page_size\":30}";
ht.Add("access_token", access_token);
ht.Add("app_key", app_key);
ht.Add("biz", biz);
ht.Add("charset", "utf-8");
ht.Add("timestamp", time);
ht.Add("version", "2");
string sign = getSign(app_secret, ht);
ht.Add("sign", sign);
string posturl = _option.Url + urlStr;
Encoding datacode = Encoding.UTF8;
string paramData = GetParamData(ht);
return PostWebRequest(posturl, paramData, datacode);
}
string getSign(string signKey, Hashtable param)
{
ArrayList keys = new ArrayList(param.Keys);
keys.Sort(); //按字母顺序进行排序
string resultStr = "";
foreach (string key in keys)
{
if (key != null && key != "" && key != "sign")
{
resultStr = resultStr + key + param[key];
}
}
resultStr = signKey + resultStr;
MD5 md5 = MD5.Create();
byte[] rstRes = md5.ComputeHash(Encoding.UTF8.GetBytes(resultStr));
string hex = BitConverter.ToString(rstRes, 0).Replace("-", string.Empty).ToLower();
return hex;
}
private string PostWebRequest(string postUrl, string paramData, Encoding dataEncode)
{
string ret = string.Empty;
try
{
byte[] byteArray = dataEncode.GetBytes(paramData);
//转化
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
webReq.Method = "POST";
webReq.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
webReq.ContentLength = byteArray.Length;
Stream newStream = webReq.GetRequestStream();
newStream.Write(byteArray, 0, byteArray.Length);
//写入参数
newStream.Close();
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), dataEncode);
ret = sr.ReadToEnd();
sr.Close();
response.Close();
newStream.Close();
}
catch (Exception ex)
{
}
return ret;
}
private string GetParamData(Hashtable ht)
{
string str = "";
foreach (DictionaryEntry items in ht)
{
str += items.Key.ToString() + "=" + System.Web.HttpUtility.UrlEncode(items.Value.ToString(), System.Text.Encoding.UTF8) + "&";
}
return str.Substring(0, str.Length - 1);
}
}
}

View File

@@ -0,0 +1,392 @@
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Options;
using WMS.Web.Core.Internal.Results;
using WMS.Web.Core.Dto.LingXing;
using System.Json;
using System.Net.Http;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Reflection;
using WMS.Web.Core.Help;
using static System.Net.WebRequestMethods;
using WMS.Web.Domain.Values;
using WMS.Web.Core.Dto.JuShuiTan;
using System.Threading;
namespace WMS.Web.Domain.Services.Public
{
/// <summary>
/// 领星服务接口
/// </summary>
public class LingXingService : ILingXingService
{
private readonly IHttpClientService _httpClientService;
private readonly ILogger<LingXingService> _logger;
private readonly IMemoryCache _memoryCache;
private int hours = 10;//过期时间 默认10小时
private readonly lingXingOptions _option;
public LingXingService(IHttpClientService httpClientService, ILogger<LingXingService> logger,
IMemoryCache memoryCache, IOptions<lingXingOptions> option)
{
this._memoryCache = memoryCache;
this._httpClientService = httpClientService;
this._logger = logger;
_option = option?.Value;
}
public async Task<Result<string>> Login()
{
string endStr = "/api/auth-server/oauth/access-token";
var formData = new MultipartFormDataContent();
formData.Add(new StringContent(_option.AppId), "appId");
formData.Add(new StringContent(_option.AppSecret), "appSecret");
var res = await _httpClientService.PostAsync<dynamic>(_option.Url + endStr, formData, null);
if (res.code != "200")
{
_logger.LogInformation($"领星获取授权失败:{res.msg}");
return Result<string>.ReFailure(ResultCodes.LingXingTokenError);
}
string token = res.data.access_token;
return Result<string>.ReSuccess(token);
}
/// <summary>
/// 获取所有仓库
/// </summary>
/// <returns></returns>
public async Task<Result<List<LingXingStockResponse>>> GetStock()
{
var stock_list = _memoryCache.Get<List<LingXingStockResponse>>("lingxing_stock");
if (stock_list != null && stock_list.Count > 0)
return Result<List<LingXingStockResponse>>.ReSuccess(stock_list);
List<LingXingStockResponse> list = new List<LingXingStockResponse>();
//默认获取本地仓库 如果需要海外仓 另外需传参数type
var request = new LingXingRequest();
var resUrl = await GetStr<LingXingRequest>("/erp/sc/data/local_inventory/warehouse", request);
if (!resUrl.IsSuccess) return Result<List<LingXingStockResponse>>.ReFailure(ResultCodes.LingXingUrlError);
var res = await _httpClientService.PostAsync<LingXingResponse>(resUrl.Data, JsonConvert.SerializeObject(request), null);
if (res.Code != 0) return Result<List<LingXingStockResponse>>.ReFailure(ResultCodes.LingXingDataError);
list.AddRange(JsonConvert.DeserializeObject<List<LingXingStockResponse>>(res.Data.ToString()));
//海外仓
request = new LingXingRequest();
request.type = 3;
resUrl = await GetStr<LingXingRequest>("/erp/sc/data/local_inventory/warehouse", request);
if (!resUrl.IsSuccess) return Result<List<LingXingStockResponse>>.ReFailure(ResultCodes.LingXingUrlError);
res = await _httpClientService.PostAsync<LingXingResponse>(resUrl.Data, JsonConvert.SerializeObject(request), null);
if (res.Code != 0) return Result<List<LingXingStockResponse>>.ReFailure(ResultCodes.LingXingDataError);
list.AddRange(JsonConvert.DeserializeObject<List<LingXingStockResponse>>(res.Data.ToString()));
//设置缓存
_memoryCache.Set("lingxing_stock", list, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(DateTimeUtil.GetTotalMinutesTimeSpan())));
return Result<List<LingXingStockResponse>>.ReSuccess(list);
}
/// <summary>
/// 获取所有店铺
/// </summary>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result<List<LingXingSellerResponse>>> GetSeller()
{
var seller_list = _memoryCache.Get<List<LingXingSellerResponse>>("lingxing_seller");
if (seller_list != null && seller_list.Count > 0)
return Result<List<LingXingSellerResponse>>.ReSuccess(seller_list);
var request = new LingXingKongRequest();
var resUrl = await GetStr<LingXingKongRequest>("/erp/sc/data/seller/lists", request);
if (!resUrl.IsSuccess) return Result<List<LingXingSellerResponse>>.ReFailure(ResultCodes.LingXingUrlError);
var res = await _httpClientService.GetAsync<LingXingResponse>(resUrl.Data);
if (res.Code != 0)
{
_logger.LogInformation($"领星获取数据失败{res.Message}");
return Result<List<LingXingSellerResponse>>.ReFailure(ResultCodes.LingXingDataError);
}
var list = JsonConvert.DeserializeObject<List<LingXingSellerResponse>>(res.Data.ToString());
//设置缓存
_memoryCache.Set("lingxing_seller", list, new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromMinutes(DateTimeUtil.GetTotalMinutesTimeSpan())));
return Result<List<LingXingSellerResponse>>.ReSuccess(list);
}
/// <summary>
/// 获取即使库存
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task<Result<List<LingXingInventoryResponse>>> GetInventory(List<int> ids)
{
List<LingXingInventoryResponse> list = new List<LingXingInventoryResponse>();
foreach (var id in ids)
{
LingXingInventoryRequest dto = new LingXingInventoryRequest();
dto.wid = id.ToString();
//dto.length = 50;
//dto.sku = "NTONPOWER-OSP-3A2U-US-BK-4.6M";
var resUrl = await GetStr<LingXingInventoryRequest>("/erp/sc/routing/data/local_inventory/inventoryDetails", dto);
if (!resUrl.IsSuccess) return Result<List<LingXingInventoryResponse>>.ReFailure(ResultCodes.LingXingUrlError);
var res = await _httpClientService.PostAsync<LingXingResponse>(resUrl.Data, JsonConvert.SerializeObject(dto), null);
if (res.Code != 0)
{
_logger.LogInformation($"领星获取数据失败{res.Message}");
return Result<List<LingXingInventoryResponse>>.ReFailure(ResultCodes.LingXingDataError);
}
list.AddRange(JsonConvert.DeserializeObject<List<LingXingInventoryResponse>>(res.Data.ToString()));
//var b = list.Where(w => w.SKU.Equals("NTONPOWER-OSP-3A2U-US-BK-4.6M")).ToList();
int num = res.Total / 800;
for (int i = 1; i <= num; i++)
{
Thread.Sleep(1000);//怕拉取过于频繁接口限制
dto.offset = i * 800;
if (i == num) dto.length = res.Total - (num * 800);
var resUrl_f = await GetStr<LingXingInventoryRequest>("/erp/sc/routing/data/local_inventory/inventoryDetails", dto);
if (!resUrl_f.IsSuccess) return Result<List<LingXingInventoryResponse>>.ReFailure(ResultCodes.LingXingUrlError);
var res_f = await _httpClientService.PostAsync<LingXingResponse>(resUrl_f.Data, JsonConvert.SerializeObject(dto), null);
if (res_f.Code != 0)
{
_logger.LogInformation($"领星获取数据失败{res.Message}");
return Result<List<LingXingInventoryResponse>>.ReFailure(ResultCodes.LingXingDataError);
}
var d = JsonConvert.DeserializeObject<List<LingXingInventoryResponse>>(res_f.Data.ToString());
//var bc = d.Where(w => w.SKU.Equals("NTONPOWER-OSP-3A2U-US-BK-4.6M")).Any();
//_logger.LogInformation($"次数:{i} 是否存在{bc}");
list.AddRange(d);
}
}
//var bcd = list.Where(w => w.SKU.Equals("NTONPOWER-OSP-3A2U-US-BK-4.6M")).ToList();
return Result<List<LingXingInventoryResponse>>.ReSuccess(list.Where(w => w.Product_Total > 0 && w.Product_Valid_Num > 0).ToList());
}
#region
public async Task<Result<string>> GetStr<T>(string urlStr, T data)
{
var res = await Login();
if (!res.IsSuccess) return res;
LxSignInfo lxSign = new LxSignInfo();
lxSign.access_token = res.Data;
lxSign.app_key = _option.AppId;
lxSign.timestamp = DateTime.Now.DateTimeToTimeStamp().ToString();
#region ASCII排序
Dictionary<string, object> testParamDics = new Dictionary<string, object>();
var ssi = GetEntityPropertyToDic(testParamDics, lxSign.GetType().GetProperties(), lxSign);//把签名参数实体转化为键值对
var ssdata = GetEntityPropertyToDic(testParamDics, data.GetType().GetProperties(), data);//把参数实体转化为键值对
// List<KeyValueInfo<string, string>> list = new List<KeyValueInfo<string, string>>();
Dictionary<string, string> list = new Dictionary<string, string>();
//string[] arrays = new string[data];
foreach (var item in typeof(LxSignInfo).GetProperties())
{
//KeyValueInfo<string, string> keys = new KeyValueInfo<string, string>();
//keys.Key = item.Name;
//keys.Value = ssi[$"{item.Name}"].ToString();
//list.Add(keys);
list.Add(item.Name, ssi[$"{item.Name}"].ToString());
}
foreach (var item in typeof(T).GetProperties())
{
//KeyValueInfo<string, string> keys = new KeyValueInfo<string, string>();
//keys.Key = item.Name;
//keys.Value = JsonConvert.SerializeObject(ssdata[$"{item.Name}"]);
//if (ssdata[$"{item.Name}"] == null) { list.Add(keys); continue; }
//if (string.IsNullOrEmpty(ssdata[$"{item.Name}"].ToString()))
//{
// continue;//跳过值为NULL的
//}
if (ssdata[$"{item.Name}"] == null) { list.Add(item.Name, JsonConvert.SerializeObject(ssdata[$"{item.Name}"])); continue; }
if (string.IsNullOrEmpty(ssdata[$"{item.Name}"].ToString()))
{
continue;//跳过值为NULL的
}
list.Add(item.Name, JsonConvert.SerializeObject(ssdata[$"{item.Name}"]));
}
string[] arrays = new string[list.Count];
int i = 0;
foreach (var item in list)
{
arrays[i] = item.Key;
i++;
}
Array.Sort(arrays, string.CompareOrdinal); //ASCII排序
string sig = null;
int j = 0;
foreach (var item in arrays)
{
string key = list.Where(a => a.Key == item).ToList()[0].Key.ToString();
string value = list.Where(a => a.Key == item).ToList()[0].Value.ToString();
#region
if (value.IndexOf("{", StringComparison.OrdinalIgnoreCase) > -1) { }
else
{
value = Regex.Replace(value, @"[\""]+", "");//去掉双引号
}
#endregion
if (j == i - 1)
{
sig += $"{key}={value}";
}
else
{
sig += $"{key}={value}&";
}
j++;
}
#endregion
#region MD5加密转大写+AES/ECB/PKCS5PADDING加密
//sig = Regex.Replace(sig, @"[\""]+", "");//去掉双引号
var md5 = MD5Encrypt(sig, false);
var signs = Encrypt(md5, lxSign.app_key);
#endregion
#region
signs = WebUtility.UrlEncode(signs);
#endregion
#region
var url = _option.Url + urlStr;
var ret = $"{url}?app_key={lxSign.app_key}&access_token={lxSign.access_token}&timestamp={lxSign.timestamp}&sign={signs}";
return Result<string>.ReSuccess(ret);
#endregion
}
/// <summary>
/// 32位MD5加密
/// </summary>
/// <param name="strText">要加密字符串</param>
/// <param name="IsLower">是否以小写方式返回</param>
/// <returns></returns>
public static string MD5Encrypt(string strText, bool IsLower = true)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strText);
bytes = md5.ComputeHash(bytes);
md5.Clear();
string ret = "";
for (int i = 0; i < bytes.Length; i++)
{
ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
}
if (IsLower == false) { return ret.PadLeft(32, '0').ToUpper(); }
return ret.PadLeft(32, '0');
}
/// <summary>
/// AES加密
/// </summary>
/// <param name="str">需要加密的字符串</param>
/// <param name="key">32位密钥</param>
///<param name="lv">向量(默认偏移量)</param>
/// <returns>加密后的字符串</returns>
public static string Encrypt(string str, string key)
{
try
{
Byte[] keyArray = System.Text.Encoding.UTF8.GetBytes(key);
Byte[] toEncryptArray = System.Text.Encoding.UTF8.GetBytes(str);
var rijndael = new System.Security.Cryptography.RijndaelManaged();
rijndael.Key = keyArray;
rijndael.Mode = System.Security.Cryptography.CipherMode.ECB;
rijndael.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
rijndael.IV = System.Text.Encoding.UTF8.GetBytes(key);
System.Security.Cryptography.ICryptoTransform cTransform = rijndael.CreateEncryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
catch (Exception ex)
{
//YellowJLog("调用AES加密方法异常异常原因" + ex.Message, "加密异常");
return "";
}
}
/// <summary>
/// 类实体的属性与值转化成键值对形式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="inParam"></param>
/// <param name="infos"></param>
/// <param name="Entity"></param>
public static Dictionary<string, object> GetEntityPropertyToDic<T>(Dictionary<string, object> inParam, PropertyInfo[] infos, T Entity)
{
foreach (var info in infos)
{
var itemTpe = info.PropertyType;
//实体中有嵌套类的处理
if (itemTpe.IsClass && !itemTpe.Name.Equals("String", StringComparison.OrdinalIgnoreCase))
{
//if (info.GetValue(Entity) == null) continue;
//GetEntityPropertyToDic(inParam, itemTpe.GetProperties(), info.GetValue(Entity));
//inParam.Add(info.Name, info.GetValue(JsonConvert.SerializeObject(Entity), null));
inParam.Add(info.Name, info.GetValue(Entity, null));
}
else
{
inParam.Add(info.Name, info.GetValue(Entity, null));
//sig = Regex.Replace(sig, @"[\""]+", "");//去掉双引号
}
}
return inParam;
}
#endregion
}
public class LxSignInfo
{
public string access_token { get; set; }
public string app_key { get; set; }
public string timestamp { get; set; }
}
}

View File

@@ -262,14 +262,14 @@ namespace WMS.Web.Domain.Services
int subStockId = subs.Data.FirstOrDefault(w => w.OrgCode.Equals(d.OrgCode) && w.StockCode.Equals(d.Erp_SubStockCode))?.Id ?? 0; int subStockId = subs.Data.FirstOrDefault(w => w.OrgCode.Equals(d.OrgCode) && w.StockCode.Equals(d.Erp_SubStockCode))?.Id ?? 0;
requestInventory.Add((d.MaterialNumber, d.OrgCode, d.StockCode, subStockId)); requestInventory.Add((d.MaterialNumber, d.OrgCode, d.StockCode, subStockId));
}; };
var res_s = await sc_erpService.BillQueryForInventory(requestInventory); //var res_s = await sc_erpService.BillQueryForInventory(requestInventory);
if (!res_s.IsSuccess) //if (!res_s.IsSuccess)
{ //{
entity.Sync(false, res_s.Message, SyncStatus.Fail, ""); // entity.Sync(false, res_s.Message, SyncStatus.Fail, "");
await sc_takeStockRepositories.Edit(entity, true); // await sc_takeStockRepositories.Edit(entity, true);
_logger.LogInformation($"及时库存获取异常->错误:{res_s.Message} 数据: {JsonConvert.SerializeObject(entity)}"); // _logger.LogInformation($"及时库存获取异常->错误:{res_s.Message} 数据: {JsonConvert.SerializeObject(entity)}");
return Result<ErpTakeStockSaveDto>.ReFailure(res_s.Message, res_s.Status); // return Result<ErpTakeStockSaveDto>.ReFailure(res_s.Message, res_s.Status);
} //}
//组装dto //组装dto
#region dto #region dto
//子仓库 ORICO_JD1000008 GD1000005 HD1000007 AD1000004 //子仓库 ORICO_JD1000008 GD1000005 HD1000007 AD1000004
@@ -278,9 +278,10 @@ namespace WMS.Web.Domain.Services
{ {
int subStockId = subs.Data.FirstOrDefault(w => w.OrgCode.Equals(d.OrgCode) && w.StockCode.Equals(d.Erp_SubStockCode))?.Id ?? 0; int subStockId = subs.Data.FirstOrDefault(w => w.OrgCode.Equals(d.OrgCode) && w.StockCode.Equals(d.Erp_SubStockCode))?.Id ?? 0;
var number = d.MaterialNumber; var number = d.MaterialNumber;
var erpInventory = res_s.Data.FirstOrDefault(f => f.MaterialNumber == number && f.StockCode == d.StockCode //var erpInventory = res_s.Data.FirstOrDefault(f => f.MaterialNumber == number && f.StockCode == d.StockCode
&& f.OrgCode == d.OrgCode && f.Erp_SubStockId == subStockId); //&& f.OrgCode == d.OrgCode && f.Erp_SubStockId == subStockId);
decimal qty = erpInventory?.Qty ?? 0; //decimal qty = erpInventory?.Qty ?? 0;
decimal qty = 0;
var unitNumber = _erpBasicDataExtendService.GetMaterialUnitNumber(materials, d.MaterialNumber); var unitNumber = _erpBasicDataExtendService.GetMaterialUnitNumber(materials, d.MaterialNumber);
detils.Add(new ErpTakeStockDetailsSaveDto() detils.Add(new ErpTakeStockDetailsSaveDto()
{ {

View File

@@ -70,5 +70,11 @@ namespace WMS.Web.Domain.Values
/// </summary> /// </summary>
[EnumRemark("出库信息")] [EnumRemark("出库信息")]
OutStockTaskInfo = 12, OutStockTaskInfo = 12,
/// <summary>
/// 成品即时库存
/// </summary>
[EnumRemark("成品即时库存")]
ProductInventory = 13,
} }
} }

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
using WMS.Web.Core;
namespace WMS.Web.Domain.Values
{
/// <summary>
/// 成品即时库存类型
/// </summary>
public enum ProductInventoryType
{
/// <summary>
/// 金蝶
/// </summary>
[EnumRemark("金蝶")]
JinDie = 0,
/// <summary>
/// 领星
/// </summary>
[EnumRemark("领星")]
LingXing = 1,
/// <summary>
/// 聚水潭
/// </summary>
[EnumRemark("聚水潭")]
JushuiTan = 2,
}
}

View File

@@ -97,6 +97,11 @@ namespace WMS.Web.Domain.Values
public static ValueTuple<int, string> SubscribeNotificationNoData = (700001, "订阅通知信息不存在"); public static ValueTuple<int, string> SubscribeNotificationNoData = (700001, "订阅通知信息不存在");
public static ValueTuple<int, string> GetBarCodeSerialNumberError = (800001, "获取序列码异常"); public static ValueTuple<int, string> GetBarCodeSerialNumberError = (800001, "获取序列码异常");
public static ValueTuple<int, string> LingXingTokenError = (810001, "获取领星授权失败");
public static ValueTuple<int, string> LingXingUrlError = (810002, "拼接领星请求参数失败");
public static ValueTuple<int, string> LingXingDataError = (810003, "请求领星数据失败");
public static ValueTuple<int, string> JuShuiTanDataError = (810004, "请求聚水潭数据失败");
public static ValueTuple<int, string> SyncSuccessError = (800002, "单据已经同步成功"); public static ValueTuple<int, string> SyncSuccessError = (800002, "单据已经同步成功");
} }
} }

View File

@@ -211,5 +211,9 @@ namespace WMS.Web.Domain.Values.Single
/// 获取仓位详情根据仓位Codes集合和公司ID /// 获取仓位详情根据仓位Codes集合和公司ID
/// </summary> /// </summary>
GetWmsSubWarehouseByCodesAndCompany = 48, GetWmsSubWarehouseByCodesAndCompany = 48,
/// <summary>
/// 获取仓库::根据总公司标记获取仓库
/// </summary>
GetWmsWarehouseByHeadOfficeAndNameAndCompany = 49,
} }
} }

View File

@@ -135,7 +135,7 @@ namespace WMS.Web.Repositories
public async Task<List<UcStockResponse>> GetUcStockAsync(string systemCode, string name, int companyId) public async Task<List<UcStockResponse>> GetUcStockAsync(string systemCode, string name, int companyId)
{ {
var result = await _singleDataService.GetSysConfigData<ResultList<UcStockResponse>, SystemCodeRequest> var result = await _singleDataService.GetSysConfigData<ResultList<UcStockResponse>, SystemCodeRequest>
(new SystemCodeRequest(systemCode,name, companyId), (new SystemCodeRequest(systemCode, name, companyId),
SysConfigAction.GetWmsWarehouseBySystemCodeAndNameAndCompany); SysConfigAction.GetWmsWarehouseBySystemCodeAndNameAndCompany);
if (!result.Success) if (!result.Success)
return null; return null;
@@ -168,7 +168,42 @@ namespace WMS.Web.Repositories
} }
return true; return true;
} }
/// <summary>
/// 根据总公司获取仓位
/// </summary>
/// <param name="name"></param>
/// <param name="companyId"></param>
/// <returns></returns>
public async Task<List<UcStockHeadOfficeResponse>> GetUcStockByHeadOfficeAsync(string name, int companyId)
{
var result = await _singleDataService.GetSysConfigData<ResultList<UcStockHeadOfficeResponse>, SystemCodeRequest>
(new SystemCodeRequest("", name, companyId),
SysConfigAction.GetWmsWarehouseByHeadOfficeAndNameAndCompany);
if (!result.Success)
return null;
return result.Data.Where(w => w.ManagementSystem != null).ToList();
//List<UcStockHeadOfficeResponse> list = new List<UcStockHeadOfficeResponse>();
//list.Add(new UcStockHeadOfficeResponse()
//{
// ManagementSystem = 1,
// Code = "CK001",
// ErpOrgCode = "101"
//});
//list.Add(new UcStockHeadOfficeResponse()
//{
// ManagementSystem = 1,
// Code = "AD",
// ErpOrgCode = "101"
//});
//list.Add(new UcStockHeadOfficeResponse()
//{
// ManagementSystem = 2,
// Code = "CK002",
// ErpOrgCode = "101",
// WarehouseCodeOfJushuitan = "ORICO_JD"
//});
//return list;
}
} }
} }

View File

@@ -414,8 +414,16 @@ namespace WMS.Web.Repositories.Configuration
.SetValueComparer(valueComparer); ; .SetValueComparer(valueComparer); ;
}); });
//成品即时库存
builder.Entity<ProductInventory>(ent =>
{
ent.ToTable("t_wms_product_inventory");
ent.HasKey(x => x.Id);
});
base.OnModelCreating(builder); base.OnModelCreating(builder);
} }
public DbSet<ProductInventory> ProductInventory { get; set; }
public DbSet<Materials> Materials { get; set; } public DbSet<Materials> Materials { get; set; }
public DbSet<BoxMarkBillNo> BoxMarkBillNo { get; set; } public DbSet<BoxMarkBillNo> BoxMarkBillNo { get; set; }
public DbSet<BoxMark> BoxMark { get; set; } public DbSet<BoxMark> BoxMark { get; set; }

View File

@@ -182,7 +182,10 @@ namespace WMS.Web.Repositories.DependencyInjection
Services.Configure<EmailOptions>(Configuration.GetSection("EmailOptions")); Services.Configure<EmailOptions>(Configuration.GetSection("EmailOptions"));
Services.AddOptions<SmsOptions>(); Services.AddOptions<SmsOptions>();
Services.Configure<SmsOptions>(Configuration.GetSection("SmsOptions")); Services.Configure<SmsOptions>(Configuration.GetSection("SmsOptions"));
Services.AddOptions<lingXingOptions>();
Services.Configure<lingXingOptions>(Configuration.GetSection("LingXingOptions"));
Services.AddOptions<JuShuiTanOptions>();
Services.Configure<JuShuiTanOptions>(Configuration.GetSection("JuShuiTanOptions"));
} }
@@ -200,6 +203,7 @@ namespace WMS.Web.Repositories.DependencyInjection
Services.AddTransient<MaterialsQuartzJob>();//添加注入定时服务 Services.AddTransient<MaterialsQuartzJob>();//添加注入定时服务
Services.AddTransient<ErpDeleteQuartzJob>();//添加注入定时服务 Services.AddTransient<ErpDeleteQuartzJob>();//添加注入定时服务
//Services.AddTransient<OrderContractQuartzJob>();//添加注入定时服务 //Services.AddTransient<OrderContractQuartzJob>();//添加注入定时服务
Services.AddTransient<InventoryQuartzJob>();//添加注入定时服务
Services.AddQuartz(q => Services.AddQuartz(q =>
{ {
q.UsePersistentStore(x => q.UsePersistentStore(x =>
@@ -298,6 +302,18 @@ namespace WMS.Web.Repositories.DependencyInjection
//.WithCronSchedule(CronScheduleBuilder.DailyAtHourAndMinute(options.JobStartHour[5], options.JobStartMinute[5])) //.WithCronSchedule(CronScheduleBuilder.DailyAtHourAndMinute(options.JobStartHour[5], options.JobStartMinute[5]))
.WithDescription("ErpDeleteQuartzJobTriggerDecs")); .WithDescription("ErpDeleteQuartzJobTriggerDecs"));
#endregion #endregion
#region
var jobKey_Inventory = new JobKey("InventoryQuartzJob", options.QuartzJobValue);
q.AddJob<InventoryQuartzJob>(jobKey_Inventory, j => j.WithDescription("InventoryQuartzJob"));
q.AddTrigger(t => t
.WithIdentity("InventoryQuartzJobTrigger")
.ForJob(jobKey_Inventory)
.StartNow()
.WithCronSchedule(options.JobStartProductInventory)
//.WithCronSchedule(CronScheduleBuilder.DailyAtHourAndMinute(options.JobStartHour[5], options.JobStartMinute[5]))
.WithDescription("InventoryQuartzJobTriggerDecs"));
#endregion
}); });
//.net core核心托管-添加Quartz服务器 //.net core核心托管-添加Quartz服务器
Services.AddQuartzServer(options => Services.AddQuartzServer(options =>
@@ -345,8 +361,10 @@ namespace WMS.Web.Repositories.DependencyInjection
Services.AddTransient<ISendMessageService, SendMessageService>(); Services.AddTransient<ISendMessageService, SendMessageService>();
Services.AddTransient<IMaterialService, MaterialService>(); Services.AddTransient<IMaterialService, MaterialService>();
Services.AddTransient<IRedisConcurrentProcessService, RedisConcurrentProcessService>(); Services.AddTransient<IRedisConcurrentProcessService, RedisConcurrentProcessService>();
Services.AddTransient<ILingXingService, LingXingService>();
Services.AddTransient<IProductInventoryService, ProductInventoryService>();
Services.AddTransient<IJuShuiTanService, JuShuiTanService>();
Services.AddTransient<IErpInventoryService, ErpInventoryService>();
} }
} }
} }

View File

@@ -8,6 +8,7 @@ using WMS.Web.Core.Dto.Inventory;
using WMS.Web.Core.Dto.MoveBoxRecord; using WMS.Web.Core.Dto.MoveBoxRecord;
using WMS.Web.Core.Dto.OutStock; using WMS.Web.Core.Dto.OutStock;
using WMS.Web.Core.Dto.OutStockTask; using WMS.Web.Core.Dto.OutStockTask;
using WMS.Web.Core.Dto.ProductInventory;
using WMS.Web.Core.Dto.TakeStock; using WMS.Web.Core.Dto.TakeStock;
using WMS.Web.Domain.Infrastructure; using WMS.Web.Domain.Infrastructure;
using WMS.Web.Repositories; using WMS.Web.Repositories;
@@ -57,6 +58,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddTransient<IAllFielRepositories<InventoryInOutDetailsQueryRequest>, InventoryInOutDetailsRepositories>(); services.AddTransient<IAllFielRepositories<InventoryInOutDetailsQueryRequest>, InventoryInOutDetailsRepositories>();
services.AddTransient<IAllFielRepositories<BoxInventoryQueryRequest>, BoxInventoryRepositories>(); services.AddTransient<IAllFielRepositories<BoxInventoryQueryRequest>, BoxInventoryRepositories>();
services.AddTransient<IAllFielRepositories<BackRecordQueryRequest>, BackRecordRepositories>(); services.AddTransient<IAllFielRepositories<BackRecordQueryRequest>, BackRecordRepositories>();
services.AddTransient<IAllFielRepositories<ProductInventoryQueryRequest>, ProductInventoryRepositories>();
#endregion #endregion
@@ -81,7 +83,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddTransient<IMaterialsRepositories, MaterialsRepositories>(); services.AddTransient<IMaterialsRepositories, MaterialsRepositories>();
services.AddTransient<ISubscribeNotificationRepositories, SubscribeNotificationRepositories>(); services.AddTransient<ISubscribeNotificationRepositories, SubscribeNotificationRepositories>();
services.AddTransient<IProductInventoryRepositories, ProductInventoryRepositories>();
} }
} }
} }

View File

@@ -49,7 +49,7 @@ namespace WMS.Web.Repositories.DependencyInjection
string[] pathlist = path.Split('/'); string[] pathlist = path.Split('/');
bool isLogin = pathlist.Where(x => x == "login" || x.ToLower() == "heart" bool isLogin = pathlist.Where(x => x == "login" || x.ToLower() == "heart"
|| x.ToLower() == "test" || x.ToLower() == "serialnumber" || x.ToLower() == "barcode" || || x.ToLower() == "test" || x.ToLower() == "serialnumber" || x.ToLower() == "barcode" ||
x.ToLower() == "swagger").Any(); x.ToLower() == "swagger" || x.ToLower() == "productinventory").Any();
if (isLogin) if (isLogin)
{ {
context.Response.StatusCode = 200; context.Response.StatusCode = 200;

View File

@@ -0,0 +1,230 @@
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WMS.Web.Core.Dto.Erp.Customer;
using WMS.Web.Core.Dto.Erp.Org;
using WMS.Web.Core.Dto.Erp;
using WMS.Web.Core.Dto.ProductInventory;
using WMS.Web.Domain.Entitys;
using WMS.Web.Domain.Infrastructure;
using WMS.Web.Domain.IService.Public;
using WMS.Web.Domain.Values;
using WMS.Web.Repositories.Configuration;
using WMS.Web.Core.Dto.OutStockTask;
using WMS.Web.Domain.Values.Single;
using WMS.Web.Core;
using NPOI.SS.Formula.Functions;
using WMS.Web.Domain.Mappers;
using WMS.Web.Core.Help;
using WMS.Web.Core.Dto.SingleData;
namespace WMS.Web.Repositories
{
/// <summary>
/// 成品仓即时库存
/// </summary>
public class ProductInventoryRepositories : IAllFielRepositories<ProductInventoryQueryRequest>, IProductInventoryRepositories
{
private readonly IMapper _mapper;
private readonly IServiceProvider _serviceProvider;
private readonly ILoginRepositories _loginRepositories;
private readonly IBasicsRepositories _basicsRepositories;
private readonly RepositoryDbContext _context;
private readonly IErpService _erpService;
private readonly ISingleDataService _singleDataService;
private readonly IErpBasicDataExtendService _erpBasicDataExtendService;
public ProductInventoryRepositories(RepositoryDbContext context,
IMapper mapper,
IErpService erpService,
IBasicsRepositories basicsRepositories,
ILoginRepositories loginRepositories,
IServiceProvider serviceProvider,
ISingleDataService singleDataService,
IErpBasicDataExtendService erpBasicDataExtendService)
{
_erpService = erpService;
_context = context;
_mapper = mapper;
_basicsRepositories = basicsRepositories;
_serviceProvider = serviceProvider;
_loginRepositories = loginRepositories;
_singleDataService = singleDataService;
_erpBasicDataExtendService = erpBasicDataExtendService;
}
public async Task<bool> AddRange(List<ProductInventory> entitys, bool isTransaction = true)
{
IDbContextTransaction _transaction = null;
if (isTransaction)
_transaction = _context.Database.BeginTransaction();
try
{
if (entitys != null && entitys.Count != 0)
{
await _context.ProductInventory.AddRangeAsync(entitys);
await _context.SaveChangesAsync();
}
if (_transaction != null)
_transaction.Commit();
return true;
}
catch
{
if (_transaction != null)
_transaction.Rollback();
return false;
}
}
public async Task<bool> Delete(ProductInventoryType type, bool isTransaction = true)
{
IDbContextTransaction _transaction = null;
if (isTransaction)
_transaction = _context.Database.BeginTransaction();
try
{
var list = await _context.ProductInventory.Where(w => w.Type == type).ToListAsync();
_context.RemoveRange(list);
if (_transaction != null)
_transaction.Commit();
return true;
}
catch
{
if (_transaction != null)
_transaction.Rollback();
return false;
}
}
public async Task<(List<ProductInventoryQueryResponse> list, int total, List<decimal> details)> GetListAsync(ProductInventoryQueryRequest dto, int companyId = 0)
{
//因为要开放给别的系统用 固定死
companyId = 1;
//if (companyId == 0)
// companyId = _loginRepositories.CompanyId;
#region erp基础资料
List<string> mNumber = new List<string>();
var materials_result = await _erpService.BillQueryForMaterial();
List<ErpMaterialDto> materials = new List<ErpMaterialDto>();
if (materials_result.IsSuccess)
materials = materials_result.Data.ToList();
//物料集合;模糊查询后的物料集合
if (!string.IsNullOrEmpty(dto.MaterialNumber))
{
if (materials != null)
mNumber = materials.Where(w => w.MaterialNumber.Contains(dto.MaterialNumber)
|| w.MaterialName.Contains(dto.MaterialNumber)
|| w.Specifications.Contains(dto.MaterialNumber)
).Select(s => s.MaterialNumber).ToList();
}
//取组织
var org_result = await _erpService.BillQueryForOrg();
List<ErpOrgDto> orgs = new List<ErpOrgDto>();
if (org_result.IsSuccess)
orgs = org_result.Data.ToList();
var p_stocks = await _basicsRepositories.GetUcStockByHeadOfficeAsync("", 1);
#endregion
var query = _context.ProductInventory
.OrderByDescending(o => o.Id)
.Where(adv => 1 == 1 && (adv.Qty > 0 || adv.BeforeQty > 0));
if (!string.IsNullOrEmpty(dto.MaterialNumber))
query = query.Where(w => mNumber.Contains(w.MaterialNumber));
if (!string.IsNullOrEmpty(dto.Customer))
query = query.Where(w => dto.Customer.Contains(w.Customer));
if (!string.IsNullOrEmpty(dto.StockCode))
{
var split = dto.StockCode.Split("_$");
query = query.Where(w => w.StockCode == split[0] && w.OrgCode == split[1]);
}
//组装
int total = await query.CountAsync();
decimal qty = await query.SumAsync(s => s.Qty);
decimal beforeQty = await query.SumAsync(s => s.BeforeQty);
List<decimal> details = new List<decimal>();
details.Add(qty);
details.Add(beforeQty);
var list = await query.Select(s => new ProductInventoryQueryResponse()
{
#region dto组装
Id = s.Id,
Type = s.Type.GetRemark(),
Stock = _erpBasicDataExtendService.GetProductInventoryStockName(p_stocks, s.StockCode),
Org = _erpBasicDataExtendService.GetOrgName(orgs, s.OrgCode),
MaterialName = _erpBasicDataExtendService.GetMaterialName(materials, s.MaterialNumber),
MaterialNumber = s.MaterialNumber,
Specifications = _erpBasicDataExtendService.GetMaterialSpecifications(materials, s.MaterialNumber),
Batch = s.Batch,
Customer = s.Customer,
Qty = s.Qty,
BeforeQty = s.BeforeQty
#endregion
}).Skip((dto.PageNo - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync();
return (list, total, details);
}
public async Task<(object obj, int total)> GetListField(ProductInventoryQueryRequest dto, int companyId)
{
var (list, count, qty) = await GetListAsync(dto, companyId);
return (list, count);
}
/// <summary>
/// 批量修改
/// </summary>
/// <param name="entitys"></param>
/// <param name="isTransaction"></param>
/// <returns></returns>
public async Task<bool> EditEntityList(List<ProductInventory> entitys, bool isTransaction = true)
{
IDbContextTransaction _transaction = null;
if (isTransaction)
_transaction = _context.Database.BeginTransaction();
try
{
List<int> list = entitys.Select(s => s.Id).ToList();
var res = await _context.ProductInventory
.Where(f => list.Contains(f.Id)).ToListAsync();
_mapper.ToMapList(entitys, res);
await _context.SaveChangesAsync();
if (_transaction != null)
_transaction.Commit();
}
catch (Exception ex)
{
if (_transaction != null)
_transaction.Rollback();
return false;
}
return true;
}
/// <summary>
/// 获取数据
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public async Task<List<ProductInventory>> GetEntityList(ProductInventoryType type)
{
var res = await _context.ProductInventory
.Where(f => f.Type == type)
.ToListAsync();
return res.Clone();
}
}
}