using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text.Json; using System.Threading.Tasks; using AutoMapper; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Volo.Abp; using Volo.Abp.BackgroundWorkers; using Volo.Abp.Data; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectMapping; using Volo.Abp.TenantManagement; using Volo.Abp.Threading; using Volo.Abp.Uow; using Win_in.Sfs.Scp.v1.Domain; using Win_in.Sfs.Scp.v1.Domain.Asns; using Win_in.Sfs.Scp.WebApi.Agent; using Win_in.Sfs.Scp.WebApi.Asns; using Win_in.Sfs.Scp.WebApi.EntityFrameworkCore; using IObjectMapper = Volo.Abp.ObjectMapping.IObjectMapper; namespace Win_in.Sfs.Scp.WebApi { public class AsnBackgroundWorker : AsyncPeriodicBackgroundWorkerBase { private readonly AsnOptions _options; private readonly IObjectMapper _objectMapper; private readonly IPostService _postService; public AsnBackgroundWorker( AbpAsyncTimer timer, IOptions options, IServiceScopeFactory serviceScopeFactory, IObjectMapper objectMapper, IPostService postService ) : base(timer, serviceScopeFactory) { _options = options.Value; _objectMapper = objectMapper; Timer.Period = options.Value.PeriodSeconds * 1000; //default 5 minutes _postService = postService; } [UnitOfWork] protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) { Logger.LogInformation("Get ASN from SCP: Start"); if (!_options.Active) { Logger.LogInformation("Get ASN from SCP: Switch is closed!"); return; } //Resolve dependencies var scpAsnManager = workerContext.ServiceProvider.GetRequiredService(); var x12AsnRepository = workerContext.ServiceProvider.GetRequiredService(); // var noPoAsnRepository = workerContext.ServiceProvider.GetRequiredService(); var tenantStore = workerContext.ServiceProvider.GetRequiredService(); var currentTenant = workerContext.ServiceProvider.GetRequiredService(); var dataFilter = workerContext.ServiceProvider.GetRequiredService(); //Do the work foreach (var site in _options.Sites) { var asnX12List = new List(); // var noPoAsnList = new List(); var siteCode = site.Code; var siteMinUid = site.MinUid; try { var tenant = await tenantStore.FindAsync(siteCode); using (currentTenant.Change(tenant.Id, tenant.Name)) { using (dataFilter.Disable()) { long lastUid = 0; var x12 = await x12AsnRepository .Where(p => p.Site == siteCode) .OrderByDescending(p => p.UID) .FirstOrDefaultAsync(); lastUid = x12?.UID ?? 0; if (lastUid < siteMinUid) { lastUid = siteMinUid; } Logger.LogInformation($"{siteCode}: Last UID is {lastUid}"); var scpAsns = await scpAsnManager.GetUnreadAsnsAsync(siteCode, lastUid, _options.BatchSize); Logger.LogInformation($"{siteCode}: {scpAsns.Count} ASNs were Found"); var baseUrl = _options.BaseUrl; var username = _options.Username; var password = _options.Password; foreach (var asn in scpAsns) { var barcodes = await scpAsnManager.GetBarcodesAsync(siteCode, asn.AsnBillNum); var noPoAsn = CreateNoPoAsn(asn, barcodes); asn.IsPort = 1; var apiUrl = ""; var jsonString = noPoAsn.JsonString; try { var result = await _postService.PostAsync(baseUrl, apiUrl, jsonString, username, password); if (result == null) { noPoAsn.SetError("Boomi", EnumExchangeDataErrorCode.None, "Boomi没有返回值","Boomi接口执行失败"); } if (result?.Status == "SUCCESS") { noPoAsn.SetSuccess("Boomi", "Boomi接口执行成功"); } else if (result?.Status == "EXCEPTION") { noPoAsn.SetError("Boomi", EnumExchangeDataErrorCode.Exception, "EXCEPTION" + result?.ErrorMessage, "Boomi接口执行失败"); } else if (result?.Status == "FAIL") { noPoAsn.SetError("Boomi", EnumExchangeDataErrorCode.FAIL, "FAIL" + result?.ErrorMessage, "Boomi接口执行失败"); } } catch (Exception e) { Logger.LogException(e); e = e.GetBaseException(); noPoAsn.SetError("Boomi", EnumExchangeDataErrorCode.Exception, "接口程序异常"+e.Message, "Boomi接口执行失败"); } finally { asnX12List.Add(noPoAsn); } //if (asn.AsnBillNum.StartsWith(_options.QadAsnPrefix))//ASN to QAD //{ // //埃驰要求不传托盘信息 @20220905 // barcodes.ForEach(p => p.PalletCode = ""); // //埃驰要求不传托盘信息 @20220905 // var asnX12 = CreateX12Asn(site, asn, barcodes); // asnX12List.Add(asnX12); //} Logger.LogInformation($"{siteCode}:{asn.Id} {asn.AsnBillNum} was loaded"); } } } } catch (Exception ex) { Logger.LogException(ex); } await AddX12AsnsAsync(asnX12List, x12AsnRepository); // await AddNoPoAsnsAsync(noPoAsnList,noPoAsnRepository); } Logger.LogInformation("Get ASN from SCP: Complete"); } private X12Asn CreateNoPoAsn(TB_ASN asn, List barcodes) { var asnMstr = new AsnMstr() { traceId = asn.Site+"-"+ asn.Id .ToString()+ "-"+ Guid.NewGuid().ToString(), uid = asn.Id, company = asn.Site, site = asn.Site, asnNbr = asn.AsnBillNum, rpNbr = asn.AskBillNum, poNbr = asn.PoBillNum, vendorCode = asn.VendId, contacts = asn.ReceiveUser, phone = "", truckNbr = asn.PlateNumber, whse = "", dock = asn.Dock, shipDate = asn.ShipTime, dueDate = asn.ReceiveTime, timeWindow = asn.ReceivedPort, remark = asn.Remark, subsite=asn.WebSubSite }; if (string.IsNullOrEmpty(asnMstr.timeWindow)) { asnMstr.timeWindow = "00:00-00:00"; } foreach (var barcode in barcodes) { var det = new AsnDet() { asnNbr = asn.AsnBillNum, poNbr = asn.PoBillNum, poLine = barcode.PoBillLine, partCode = barcode.PartCode, lot = barcode.Batch, qty = barcode.Qty, productionDate = barcode.ProduceDate, wareClass = "", wareCode = "", stdPackQty = barcode.PackQty, poUm = barcode.PoUnit, locUm = barcode.LocUnit, umConv = 1, partType = "", supplierlot = barcode.VendBatch, status = barcode.State.ToString(), labelCode = barcode.Extend2, entireBarCode = barcode.FullBarCode, palletLabelCode = barcode.PalletCode, remark = barcode.Remark, }; asnMstr.details.Add(det); } var jsonString = JsonSerializer.Serialize(asnMstr); var ediString = jsonString; var asnX12 = new X12Asn(asn.Id, asn.Site, asn.AsnBillNum, ScpWebApiConsts.NO_PO_ASN, jsonString, ediString, asn.ShipTime ?? DateTime.Today); return asnX12; } private static X12Asn CreateX12Asn(AsnOptions.Site site, TB_ASN asn, List barcodes) { var asnFactory = new AsnFactory(); var asnX128563060 = asnFactory.CreateAsnX128563060(site.Receiver, asn, barcodes); var jsonString = JsonSerializer.Serialize(asnX128563060); var ediString = asnX128563060.ToString(); var asnX12 = new X12Asn(asn.Id, asn.Site, asn.AsnBillNum, ScpWebApiConsts.ASN, jsonString, ediString, asn.ShipTime ?? DateTime.Today); return asnX12; } /* private async Task AddNoPoAsnsAsync(List noPoAsnList, IAsnRepository noPoAsnRepository) { foreach (var asn in noPoAsnList) { var exist = await noPoAsnRepository.FirstOrDefaultAsync( p => p.UID == asn.UID && p.Site == asn.Site); if (exist == null) { await noPoAsnRepository.InsertAsync(asn); } else { exist.RpNbr = asn.RpNbr; exist.Contacts = asn.Contacts; exist.Phone = asn.Phone; exist.TruckNbr = asn.TruckNbr; exist.Whse = asn.Whse; exist.Dock = asn.Dock; exist.ShipDate = asn.ShipDate; exist.DueDate = asn.DueDate; exist.TimeWindow = asn.TimeWindow; exist.Remark = asn.Remark; exist.Details = asn.Details; exist.SetEffectiveDate(asn.EffectiveDate); exist.Reset(); await noPoAsnRepository.UpdateAsync(exist); } } } */ private static async Task AddX12AsnsAsync(List asnX12List, IX12AsnRepository x12AsnRepository) { foreach (var x12Asn in asnX12List) { var exist = await x12AsnRepository.FirstOrDefaultAsync( p => p.UID == x12Asn.UID && p.Site == x12Asn.Site); if (exist == null) { await x12AsnRepository.InsertAsync(x12Asn); } else { exist.JsonString = x12Asn.JsonString; exist.EdiString = x12Asn.EdiString; if(x12Asn.Status== EnumExchangeDataStatus.Finish) { exist.SetSuccess(x12Asn.Reader); } else { exist.SetError(x12Asn.Reader, (EnumExchangeDataErrorCode) x12Asn.ErrorCode, x12Asn.ErrorMessage, x12Asn.Remark); } await x12AsnRepository.UpdateAsync(exist); } } } } }