贾荣国
3 years ago
77 changed files with 4363 additions and 41 deletions
@ -0,0 +1,41 @@ |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Volo.Abp; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Agent |
|||
{ |
|||
public class AgentHostedService : IHostedService |
|||
{ |
|||
private readonly IAbpApplicationWithExternalServiceProvider _application; |
|||
private readonly IServiceProvider _serviceProvider; |
|||
private readonly AgentService _agentService; |
|||
|
|||
public AgentHostedService( |
|||
IAbpApplicationWithExternalServiceProvider application, |
|||
IServiceProvider serviceProvider, |
|||
AgentService agentService) |
|||
{ |
|||
_application = application; |
|||
_serviceProvider = serviceProvider; |
|||
_agentService = agentService; |
|||
} |
|||
|
|||
public Task StartAsync(CancellationToken cancellationToken) |
|||
{ |
|||
_application.Initialize(_serviceProvider); |
|||
|
|||
_agentService.Start(); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
public Task StopAsync(CancellationToken cancellationToken) |
|||
{ |
|||
_application.Shutdown(); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.BackgroundJobs; |
|||
using Volo.Abp.BackgroundWorkers; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Volo.Abp.Modularity; |
|||
using Win_in.Sfs.Scp.v1.Domain; |
|||
using Win_in.Sfs.Scp.v1.EntityFrameworkCore; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Agent |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpAutoMapperModule), |
|||
typeof(AbpBackgroundJobsModule), |
|||
typeof(AbpBackgroundWorkersModule) |
|||
)] |
|||
[DependsOn( |
|||
typeof(V1ScpDomainModule), |
|||
typeof(V1ScpEntityFrameworkCoreModule) |
|||
)] |
|||
public class AgentModule : AbpModule |
|||
{ |
|||
|
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
var env = context.Services.GetSingletonInstance<IHostEnvironment>(); |
|||
|
|||
Configure<AbpDbContextOptions>(options => |
|||
{ |
|||
options.UseSqlServer(); |
|||
}); |
|||
|
|||
|
|||
Configure<AgentOptions>(configuration.GetSection("AgentOptions")); |
|||
|
|||
context.Services.AddHostedService<AgentHostedService>(); |
|||
|
|||
context.Services.AddAutoMapperObjectMapper<AgentModule>(); |
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddMaps<AgentModule>(validate: false); |
|||
}); |
|||
|
|||
|
|||
} |
|||
|
|||
public override void OnApplicationInitialization( |
|||
ApplicationInitializationContext context) |
|||
{ |
|||
context.AddBackgroundWorker<IncomingDataWorker>(); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,16 @@ |
|||
namespace Win_in.Sfs.Scp.WebApi.Agent |
|||
{ |
|||
public class AgentOptions |
|||
{ |
|||
public IncomingOptions IncomingOptions { get; set; } |
|||
} |
|||
|
|||
public class IncomingOptions |
|||
{ |
|||
public bool Active { get; set; } = false; |
|||
public int PeriodSeconds { get; set; } = 5 * 60; |
|||
public int RetryTimes { get; set; } = 3; |
|||
public int BatchSize { get; set; } = 100; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Agent |
|||
{ |
|||
public class AgentService : ITransientDependency |
|||
{ |
|||
public void Start() |
|||
{ |
|||
Console.WriteLine("Wms dataExchange service has started..."); |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
namespace Win_in.Sfs.Scp.WebApi.Agent |
|||
{ |
|||
public enum EnumExchangeDataErrorCode |
|||
{ |
|||
None = 0, |
|||
UnknownDataType = 1, |
|||
WrongDataFormat = 2, |
|||
Exception = 9, |
|||
} |
|||
} |
@ -0,0 +1,67 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.BackgroundWorkers; |
|||
using Volo.Abp.Threading; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Agent |
|||
{ |
|||
public class IncomingDataWorker : AsyncPeriodicBackgroundWorkerBase |
|||
{ |
|||
private readonly IOptions<AgentOptions> _options; |
|||
|
|||
public IncomingDataWorker( |
|||
AbpAsyncTimer timer, |
|||
IOptions<AgentOptions> options, |
|||
IServiceScopeFactory serviceScopeFactory |
|||
) : base(timer, serviceScopeFactory) |
|||
{ |
|||
_options = options; |
|||
Timer.Period = options.Value.IncomingOptions.PeriodSeconds * 1000; //default 5 minutes
|
|||
} |
|||
|
|||
[UnitOfWork] |
|||
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) |
|||
{ |
|||
Logger.LogInformation("Starting: Handling Incoming Exchange data..."); |
|||
if (!_options.Value.IncomingOptions.Active) |
|||
{ |
|||
Logger.LogInformation("Incoming Exchange is not active!"); |
|||
return; |
|||
} |
|||
//Resolve dependencies
|
|||
var incomingDataManager = workerContext |
|||
.ServiceProvider |
|||
.GetRequiredService<IIncomingDataManager>(); |
|||
//Do the work
|
|||
var incomingDataList = await incomingDataManager.GetReadyListAsync(); |
|||
|
|||
foreach (var incomingData in incomingDataList) |
|||
{ |
|||
|
|||
try |
|||
{ |
|||
await UpdateWmsAsync(incomingData); |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
e = e.GetBaseException(); |
|||
incomingData.SetError(EnumExchangeDataErrorCode.Exception, e.Message); |
|||
} |
|||
//归档并删除
|
|||
await incomingDataManager.FileAndDeleteAsync(incomingData); |
|||
|
|||
} |
|||
|
|||
Logger.LogInformation("Completed: Handling Incoming Exchange data..."); |
|||
} |
|||
|
|||
private async Task UpdateWmsAsync(object incomingData) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,57 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Serilog; |
|||
using Serilog.Events; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Agent |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static async Task<int> Main(string[] args) |
|||
{ |
|||
Log.Logger = new LoggerConfiguration() |
|||
#if DEBUG
|
|||
.MinimumLevel.Debug() |
|||
#else
|
|||
.MinimumLevel.Information() |
|||
#endif
|
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
|||
.Enrich.FromLogContext() |
|||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|||
.WriteTo.Async(c => c.Console()) |
|||
.CreateLogger(); |
|||
|
|||
try |
|||
{ |
|||
Log.Information("Starting console host."); |
|||
await CreateHostBuilder(args).RunConsoleAsync(); |
|||
return 0; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
|
|||
} |
|||
|
|||
internal static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.UseAutofac() |
|||
.UseSerilog() |
|||
.ConfigureAppConfiguration((context, config) => |
|||
{ |
|||
//setup your additional configuration sources
|
|||
}) |
|||
.ConfigureServices((hostContext, services) => |
|||
{ |
|||
services.AddApplication<AgentModule>(); |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,35 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.*" /> |
|||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.*" /> |
|||
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.1.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> |
|||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" /> |
|||
<PackageReference Include="Volo.Abp.EntityFrameworkCore.SqlServer" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.BackgroundJobs" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.BackgroundWorkers" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.AutoMapper" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.Autofac" Version="4.4.2" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<Content Include="appsettings.json"> |
|||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Win_in.Sfs.Scp.v1.Domain\Win_in.Sfs.Scp.v1.Domain.csproj" /> |
|||
<ProjectReference Include="..\Win_in.Sfs.Scp.v1.EntityFrameworkCore\Win_in.Sfs.Scp.v1.EntityFrameworkCore.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
|
|||
</Project> |
@ -0,0 +1,14 @@ |
|||
{ |
|||
"ConnectionStrings": { |
|||
"DataExchange": "Server=127.0.0.1;Database=DataExchange_Test;uid=sa;pwd=Microsoft2008;" |
|||
}, |
|||
|
|||
"AgentOptions": { |
|||
"IncomingOptions": { |
|||
"Active": false, |
|||
"PeriodSeconds": 300, |
|||
"RetryTimes": 3, |
|||
"BatchSize": 100 |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,22 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Validation; |
|||
using Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi |
|||
{ |
|||
/// <summary>
|
|||
/// Asn接口
|
|||
/// </summary>
|
|||
public interface IX12AsnAppService : IReadOnlyAppService<X12AsnDTO,Guid,RequestDTO> |
|||
{ |
|||
Task<ListResultDto<X12AsnDTO>> GetUnreadListAsync(int count); |
|||
|
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using Win_in.Sfs.Scp.WebApi.Asns; |
|||
using Win_in.Sfs.Scp.WebApi.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi; |
|||
|
|||
public class X12AsnDTO: EntityDtoBase<Guid> |
|||
{ |
|||
public long UID { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 单据号
|
|||
/// </summary>
|
|||
public string BillNum { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 备注
|
|||
/// </summary>
|
|||
public string Remark { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 数据内容
|
|||
/// </summary>
|
|||
public ASN_X12_856_3060 AsnX12 { get; set; } |
|||
|
|||
} |
@ -0,0 +1,97 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
using System.Text.Json; |
|||
using System.Threading.Tasks; |
|||
using System.Threading.Tasks.Dataflow; |
|||
using AutoMapper; |
|||
using AutoMapper.Configuration; |
|||
using FluentValidation; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Uow; |
|||
using Win_in.Sfs.Scp.v1.Domain; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Volo.Abp.Clients; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Validation; |
|||
using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration; |
|||
using Volo.Abp.TenantManagement; |
|||
using Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi |
|||
{ |
|||
/// <summary>
|
|||
/// 零件服务
|
|||
/// </summary>
|
|||
[Authorize] |
|||
[Route(RouteConsts.X12Asn)] |
|||
[ApiExplorerSettings(GroupName = SwaggerGroupConsts.ScpWebApi)] |
|||
|
|||
public class X12AsnAppService : ReadOnlyAppService<X12Asn, X12AsnDTO, Guid, RequestDTO>, IX12AsnAppService |
|||
{ |
|||
private readonly IX12AsnRepository _x12AsnRepository; |
|||
private readonly ITenantStore _tenantStore; |
|||
private readonly ITenantRepository _tenantRepository; |
|||
|
|||
public X12AsnAppService( |
|||
IX12AsnRepository repository |
|||
, ITenantStore tenantStore |
|||
, ITenantRepository tenantRepository |
|||
) : base(repository) |
|||
{ |
|||
_x12AsnRepository = repository; |
|||
_tenantStore = tenantStore; |
|||
_tenantRepository = tenantRepository; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 按ID获取零件 (Get X12Asn by ID)
|
|||
/// </summary>
|
|||
/// <param name="id">唯一ID(unique ID)</param>
|
|||
/// <returns></returns>
|
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public override async Task<X12AsnDTO> GetAsync(Guid id) |
|||
{ |
|||
return await base.GetAsync(id); |
|||
} |
|||
|
|||
|
|||
/// <summary>
|
|||
/// 按条件获取零件列表 (Get X12Asn list by request condition)
|
|||
/// </summary>
|
|||
/// <param name="requestDTO">请求条件DTO(Request condition DTO)</param>
|
|||
/// <returns></returns>
|
|||
[HttpGet] |
|||
[Route("")] |
|||
public override async Task<PagedResultDto<X12AsnDTO>> GetListAsync(RequestDTO requestDTO) |
|||
{ |
|||
return await base.GetListAsync(requestDTO); |
|||
} |
|||
|
|||
public async Task<ListResultDto<X12AsnDTO>> GetUnreadListAsync(int count) |
|||
{ |
|||
var entities = await _x12AsnRepository.GetUnreadListAsync(count); |
|||
|
|||
var dtos = entities.Select(entity => new X12AsnDTO() |
|||
{ |
|||
Id = entity.Id, |
|||
UID = entity.UID, |
|||
BillNum = entity.BillNum, |
|||
Remark = entity.Remark, |
|||
AsnX12 = JsonSerializer.Deserialize<ASN_X12_856_3060>(entity.DataContent) |
|||
}) |
|||
.ToList(); |
|||
|
|||
return new ListResultDto<X12AsnDTO>(dtos); |
|||
|
|||
} |
|||
} |
|||
} |
@ -1,9 +1,5 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Net; |
|||
using System.Reflection; |
|||
using static System.Net.Mime.MediaTypeNames; |
|||
using static AutoMapper.Internal.ExpressionFactory; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
@ -1,5 +1,4 @@ |
|||
using System.Text; |
|||
using Microsoft.AspNetCore.SignalR; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
@ -1,7 +1,4 @@ |
|||
using System.Collections.Generic; |
|||
using System.Runtime.CompilerServices; |
|||
using Microsoft.AspNetCore.SignalR; |
|||
|
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
public static class ShipmentExtensions |
@ -0,0 +1,9 @@ |
|||
namespace Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
public enum EnumExchangeDataErrorCode |
|||
{ |
|||
None = 0, |
|||
UnknownDataType = 1, |
|||
WrongDataFormat = 2, |
|||
Exception = 9, |
|||
} |
@ -0,0 +1,25 @@ |
|||
namespace Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
public enum EnumExchangeDataStatus |
|||
{ |
|||
/// <summary>
|
|||
/// 新增
|
|||
/// </summary>
|
|||
Ready = 0, |
|||
/// <summary>
|
|||
/// 处理中
|
|||
/// </summary>
|
|||
Processing = 1, |
|||
/// <summary>
|
|||
/// 完成
|
|||
/// </summary>
|
|||
Success = 2, |
|||
/// <summary>
|
|||
/// 搁置
|
|||
/// </summary>
|
|||
Hold = 9, |
|||
/// <summary>
|
|||
/// 错误
|
|||
/// </summary>
|
|||
Error = -1, |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
public interface IX12AsnRepository : IRepository<X12Asn, Guid> |
|||
{ |
|||
Task<List<X12Asn>> GetUnreadListAsync(int count); |
|||
|
|||
Task<X12Asn> UpdateStatusAsync(Guid id, EnumExchangeDataStatus status); |
|||
} |
@ -0,0 +1,138 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Services; |
|||
using Win_in.Sfs.Scp.WebApi.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
public class X12Asn: EntityBase<Guid> |
|||
{ |
|||
public long UID { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 单据号
|
|||
/// </summary>
|
|||
public string BillNum { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 数据类型
|
|||
/// </summary>
|
|||
public string DataType { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 生效日期
|
|||
/// </summary>
|
|||
public DateTime EffectiveDate { get; protected internal set; } = DateTime.Today; |
|||
|
|||
/// <summary>
|
|||
/// 数据状态
|
|||
/// </summary>
|
|||
public EnumExchangeDataStatus Status { get; protected internal set; } = 0; |
|||
|
|||
/// <summary>
|
|||
/// 数据内容
|
|||
/// </summary>
|
|||
public string DataContent { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 目标系统
|
|||
/// </summary>
|
|||
public string DestinationSystem { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 读取时间
|
|||
/// </summary>
|
|||
public DateTime? ReadTime { get; set; } |
|||
/// <summary>
|
|||
/// 读取者
|
|||
/// </summary>
|
|||
public string Reader { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 来源系统
|
|||
/// </summary>
|
|||
public string SourceSystem { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 写入时间
|
|||
/// </summary>
|
|||
public DateTime WriteTime { get; set; } = DateTime.Now; |
|||
/// <summary>
|
|||
/// 写入者
|
|||
/// </summary>
|
|||
public string Writer { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 备注
|
|||
/// </summary>
|
|||
public string Remark { get; set; } |
|||
|
|||
|
|||
public int RetryTimes { get; protected internal set; } = 0; |
|||
|
|||
|
|||
public X12Asn(long uid,string billNum,string dataContent,DateTime effectiveDate) |
|||
{ |
|||
UID = uid; |
|||
BillNum = billNum; |
|||
DataType = "ASN"; |
|||
DataContent = dataContent; |
|||
EffectiveDate = effectiveDate; |
|||
DestinationSystem = "QAD"; |
|||
SourceSystem = "SCP"; |
|||
Writer = "SCP"; |
|||
} |
|||
|
|||
|
|||
public void SetEffectiveDate(DateTime newDate) |
|||
{ |
|||
EffectiveDate = newDate; |
|||
} |
|||
|
|||
public void SetError(EnumExchangeDataErrorCode errorCode, string errorMessage, string remark = null) |
|||
{ |
|||
Status = EnumExchangeDataStatus.Error; |
|||
ErrorCode = (int)errorCode; |
|||
ErrorMessage = errorMessage; |
|||
Remark = remark; |
|||
RetryTimes++; |
|||
|
|||
} |
|||
|
|||
public void SetHold(string remark = null) |
|||
{ |
|||
Status = EnumExchangeDataStatus.Hold; |
|||
Remark = remark; |
|||
} |
|||
|
|||
public virtual void Reset(string remark = null) |
|||
{ |
|||
Status = EnumExchangeDataStatus.Ready; |
|||
ErrorCode = (int)EnumExchangeDataErrorCode.None; |
|||
ErrorMessage = ""; |
|||
Remark = remark; |
|||
RetryTimes = 0; |
|||
} |
|||
|
|||
|
|||
public void Take(string remark = null) |
|||
{ |
|||
Status = EnumExchangeDataStatus.Processing; |
|||
Remark = remark; |
|||
} |
|||
|
|||
public void SetSuccess(string remark = null) |
|||
{ |
|||
Status = EnumExchangeDataStatus.Success; |
|||
ErrorCode = (int)EnumExchangeDataErrorCode.None; |
|||
ErrorMessage = ""; |
|||
Remark = remark; |
|||
} |
|||
|
|||
public void SetProcessing(string remark =null) |
|||
{ |
|||
Status = EnumExchangeDataStatus.Processing; |
|||
Remark = remark; |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,70 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Migrations |
|||
{ |
|||
public partial class X12Asn : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.AlterColumn<string>( |
|||
name: "AsnNumber", |
|||
table: "WebApi_Receipt", |
|||
type: "nvarchar(64)", |
|||
maxLength: 64, |
|||
nullable: true, |
|||
oldClrType: typeof(string), |
|||
oldType: "nvarchar(64)", |
|||
oldMaxLength: 64); |
|||
|
|||
migrationBuilder.CreateTable( |
|||
name: "WebApi_X12Asn", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|||
BillNum = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: false), |
|||
DataType = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: false), |
|||
EffectiveDate = table.Column<DateTime>(type: "datetime2(7)", nullable: false), |
|||
Status = table.Column<int>(type: "int", nullable: false), |
|||
DataContent = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|||
DestinationSystem = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: false), |
|||
ReadTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|||
Reader = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: true), |
|||
SourceSystem = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: false), |
|||
WriteTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|||
Writer = table.Column<string>(type: "nvarchar(16)", maxLength: 16, nullable: true), |
|||
Remark = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|||
RetryTimes = table.Column<int>(type: "int", nullable: false), |
|||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true), |
|||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true), |
|||
TraceId = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|||
ErrorCode = table.Column<int>(type: "int", nullable: false), |
|||
ErrorMessage = table.Column<string>(type: "nvarchar(max)", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_WebApi_X12Asn", x => x.Id); |
|||
}); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "WebApi_X12Asn"); |
|||
|
|||
migrationBuilder.AlterColumn<string>( |
|||
name: "AsnNumber", |
|||
table: "WebApi_Receipt", |
|||
type: "nvarchar(64)", |
|||
maxLength: 64, |
|||
nullable: false, |
|||
defaultValue: "", |
|||
oldClrType: typeof(string), |
|||
oldType: "nvarchar(64)", |
|||
oldMaxLength: 64, |
|||
oldNullable: true); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.EntityFrameworkCore; |
|||
|
|||
public class X12AsnRepository : EfCoreRepository<WebApiDbContext, X12Asn, Guid>, IX12AsnRepository |
|||
{ |
|||
public X12AsnRepository(IDbContextProvider<WebApiDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public async Task<List<X12Asn>> GetUnreadListAsync(int count) |
|||
{ |
|||
var dbSet = await GetDbSetAsync(); |
|||
var list =await dbSet.Where(p => p.Status == EnumExchangeDataStatus.Ready) |
|||
.OrderBy(p => p.UID) |
|||
.Take(count) |
|||
.ToListAsync(); |
|||
|
|||
foreach (var entity in list) |
|||
{ |
|||
await UpdateStatusAsync(entity.Id, EnumExchangeDataStatus.Success); |
|||
} |
|||
|
|||
return list; |
|||
} |
|||
|
|||
|
|||
public async Task<X12Asn> UpdateStatusAsync(Guid id,EnumExchangeDataStatus status) |
|||
{ |
|||
var entity =await base.GetAsync(id); |
|||
switch (status) |
|||
{ |
|||
case EnumExchangeDataStatus.Ready: |
|||
entity.Reset(); |
|||
break; |
|||
case EnumExchangeDataStatus.Processing: |
|||
entity.SetProcessing(); |
|||
break; |
|||
case EnumExchangeDataStatus.Success: |
|||
entity.SetSuccess(); |
|||
break; |
|||
case EnumExchangeDataStatus.Hold: |
|||
entity.SetHold(); |
|||
break; |
|||
case EnumExchangeDataStatus.Error: |
|||
entity.SetError(EnumExchangeDataErrorCode.Exception,""); |
|||
break; |
|||
default: |
|||
throw new ArgumentOutOfRangeException(nameof(status), status, null); |
|||
} |
|||
return await UpdateAsync(entity); |
|||
} |
|||
} |
@ -0,0 +1,74 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text.Json; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.BackgroundWorkers; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Threading; |
|||
using Volo.Abp.Uow; |
|||
using Win_in.Sfs.Scp.v1.Domain; |
|||
using Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi; |
|||
|
|||
public class AsnBackgroundWorker : AsyncPeriodicBackgroundWorkerBase |
|||
{ |
|||
private readonly IOptions<AsnBgWorker> _options; |
|||
|
|||
public AsnBackgroundWorker( |
|||
AbpAsyncTimer timer, |
|||
IOptions<AsnBgWorker> options, |
|||
IServiceScopeFactory serviceScopeFactory |
|||
) : base(timer, serviceScopeFactory) |
|||
{ |
|||
_options = options; |
|||
Timer.Period = options.Value.PeriodSeconds * 1000; //default 5 minutes
|
|||
} |
|||
|
|||
[UnitOfWork] |
|||
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext) |
|||
{ |
|||
Logger.LogInformation("Starting: Handling Scp Asn data..."); |
|||
if (!_options.Value.Active) |
|||
{ |
|||
Logger.LogInformation("Scp Asn is not active!"); |
|||
return; |
|||
} |
|||
//Resolve dependencies
|
|||
var scpAsnManager = workerContext |
|||
.ServiceProvider |
|||
.GetRequiredService<IScpAsnManager>(); |
|||
|
|||
var x12AsnRepository = workerContext |
|||
.ServiceProvider |
|||
.GetRequiredService<IX12AsnRepository>(); |
|||
|
|||
//Do the work
|
|||
var maxUid = await x12AsnRepository.MaxAsync(p => p.UID); |
|||
var scpAsns = await scpAsnManager.GetUnreadAsnsAsync(maxUid, _options.Value.BatchSize); |
|||
Logger.LogInformation($"{scpAsns.Count} Scp ASN records were Found"); |
|||
|
|||
if (scpAsns.Count > 0) |
|||
{ |
|||
var asnX12List = new List<X12Asn>(); |
|||
foreach (var asn in scpAsns) |
|||
{ |
|||
var barcodes = await scpAsnManager.GetBarcodesAsync(asn.AsnBillNum); |
|||
|
|||
var asnFactory = new AsnFactory(); |
|||
var asnX128563060 = asnFactory.CreateAsnX128563060(asn, barcodes); |
|||
|
|||
var dataContent = JsonSerializer.Serialize(asnX128563060); |
|||
var asnX12 = new X12Asn(asn.UID, asn.AsnBillNum, dataContent,asn.ShipTime??DateTime.Today); |
|||
asnX12List.Add(asnX12); |
|||
} |
|||
await x12AsnRepository.InsertManyAsync(asnX12List); |
|||
} |
|||
|
|||
Logger.LogInformation("Completed: Handling Scp Asn data..."); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace Win_in.Sfs.Scp.WebApi; |
|||
|
|||
public class AsnBgWorker |
|||
{ |
|||
public bool Active { get; set; } = false; |
|||
public int PeriodSeconds { get; set; } = 60; |
|||
public int RetryTimes { get; set; } = 3; |
|||
public int BatchSize { get; set; } = 10; |
|||
} |
@ -0,0 +1,194 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Win_in.Sfs.Scp.v1.Domain.Asns; |
|||
using Win_in.Sfs.Scp.WebApi.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi |
|||
{ |
|||
public class AsnFactory |
|||
{ |
|||
public ASN_X12_856_3060 CreateAsnX128563060(TB_ASN scpAsn,List<TS_BARCODE> barcodes) |
|||
{ |
|||
|
|||
var asnCode = scpAsn.AsnBillNum; |
|||
var senderId = scpAsn.VendId; |
|||
var receiverId = "IACNA_ID"; |
|||
var shipTime = scpAsn.ShipTime ?? DateTime.Now; |
|||
|
|||
var envType = ISA.EnvType.P; |
|||
var authorization = ""; |
|||
var security = ""; |
|||
//初始化ASN单
|
|||
var asn = CreateAsn(asnCode,senderId,receiverId,shipTime,envType,authorization,security); |
|||
|
|||
var functionalGroupCode = "123456789"; |
|||
//初始化功能组
|
|||
var functionalGroup = CreateFunctionalGroup(senderId,receiverId,shipTime,functionalGroupCode); |
|||
|
|||
var shipNoticeCode = "0001"; |
|||
var datetimeType = "011"; |
|||
//初始化发货单
|
|||
var shipNotice = CreateShipNotice(shipNoticeCode,functionalGroupCode,shipTime,datetimeType); |
|||
|
|||
var gValue = 0; |
|||
var gUom = "KG"; |
|||
var nValue = 0; |
|||
var nUom = "KG"; |
|||
var routeSequenceCode = "B"; |
|||
var identificationCode = "PSTV"; |
|||
var mode = "LT"; |
|||
var equipmentCode = "TL"; |
|||
var equipmentNumber = "123456";//TODO 车牌号
|
|||
//初始化发货明细
|
|||
var shipment = CreateShipment(shipNotice,gValue,gUom,nValue,nUom,routeSequenceCode,identificationCode,mode, |
|||
equipmentCode,equipmentNumber,functionalGroupCode,functionalGroupCode,senderId,receiverId); |
|||
|
|||
|
|||
//计算与添加托盘和尾箱
|
|||
var palletCodes = barcodes.Select(p => p.Extend2).Distinct().ToList(); |
|||
foreach (var palletCode in palletCodes) |
|||
{ |
|||
var palletBarcodes = barcodes.Where(p => p.Extend2==palletCode).ToList(); |
|||
|
|||
var items = new List<Item>(); |
|||
var group = palletBarcodes |
|||
.GroupBy(p => new { p.PartCode, p.Qty, p.Batch, p.PoUnit, p.PoBillNum,p.PackQty}) |
|||
.Select(p => new |
|||
{ |
|||
p.Key.PartCode, |
|||
p.Key.Qty, |
|||
p.Key.Batch, |
|||
p.Key.PoUnit, |
|||
p.Key.PoBillNum, |
|||
p.Key.PackQty, |
|||
Labels = p.Select(p=>p.BarCode).ToList() |
|||
}) |
|||
.ToList(); |
|||
|
|||
foreach (var b in group) |
|||
{ |
|||
var accumQty = 0;//TODO 如何计算
|
|||
var loadQty = b.Labels.Count; |
|||
var unitQty = b.PackQty; |
|||
var item = CreateItem(b.PartCode, loadQty * unitQty, b.PoUnit, accumQty, b.PoBillNum, loadQty, unitQty,b.Labels); |
|||
items.Add(item); |
|||
} |
|||
|
|||
//如果托标签为空,当作尾箱处理
|
|||
if (string.IsNullOrEmpty(palletCode)) |
|||
{ |
|||
foreach (var item in items) |
|||
{ |
|||
shipment.AddOrphanItem(shipNotice,item); |
|||
} |
|||
} |
|||
//添加托盘
|
|||
else |
|||
{ |
|||
var tare = CreateTare(palletCode); |
|||
shipment.AddTare(shipNotice,tare); |
|||
foreach (var item in items) |
|||
{ |
|||
tare.AddItem(shipNotice, item); |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
//TODO 如何获取包装代码,或者规则是什么?
|
|||
var packagingCode = "PLT90"; |
|||
//装载量需要在添加托盘和尾箱后再计算
|
|||
var loadingQty = shipment.Tares.Count+shipment.OrphanItems.Count; |
|||
shipment.SetTD1(packagingCode, loadingQty); |
|||
|
|||
shipNotice |
|||
.AddShipment(shipment) //添加发货明细
|
|||
.SetCTT() //设置发货单汇总
|
|||
.SetSE(shipNoticeCode); //设置发货明细结尾
|
|||
//添加发货单
|
|||
functionalGroup |
|||
.AddShipNotice(shipNotice) |
|||
.SetGE(functionalGroupCode); |
|||
//添加功能组
|
|||
asn |
|||
.AddFunctionGroup(functionalGroup) |
|||
.SetIEA(asnCode); |
|||
return asn; |
|||
} |
|||
|
|||
private ASN_X12_856_3060 CreateAsn(string asnCode, string senderId, string receiverId, DateTime datetime, |
|||
ISA.EnvType envType = ISA.EnvType.P, string authorization = "", string security = "") |
|||
{ |
|||
var asn = new ASN_X12_856_3060(); |
|||
asn.SetISA(asnCode, senderId, receiverId, datetime, envType, authorization, security); |
|||
return asn; |
|||
} |
|||
|
|||
private FunctionalGroup CreateFunctionalGroup(string senderId, string receiverId, DateTime datetime, |
|||
string functionalGroupCode) |
|||
{ |
|||
var functionGroup = new FunctionalGroup(); |
|||
functionGroup.SetGS(senderId, receiverId, datetime, functionalGroupCode); |
|||
return functionGroup; |
|||
} |
|||
|
|||
private ShipNotice CreateShipNotice(string shipNoticeCode, string noticeNumber, DateTime datetime, |
|||
string datetimeType="011", string purpose = "00") |
|||
{ |
|||
var shipNotice = new ShipNotice(); |
|||
shipNotice |
|||
.SetST(shipNoticeCode) |
|||
.SetBSN(noticeNumber, datetime, purpose) |
|||
.SetDTM(datetime, datetimeType); |
|||
shipNotice.AddSegment(4); |
|||
return shipNotice; |
|||
} |
|||
|
|||
private Shipment CreateShipment(ShipNotice shipNotice, decimal gValue, string gUom, decimal nValue, string nUom, |
|||
string routeSequenceCode, string identificationCode, string mode, string equipmentCode, |
|||
string equipmentNumber, string bmRefValue, string pkRefValue, string senderId, string receiverId) |
|||
{ |
|||
var shipment = new Shipment(); |
|||
shipment |
|||
.SetHL() |
|||
.SetMEA_G(gValue, gUom) |
|||
.SetMEA_N(nValue, nUom) |
|||
.SetTD5(routeSequenceCode, identificationCode, mode) |
|||
.SetTD3(equipmentCode, equipmentNumber) |
|||
.SetREF_BM(bmRefValue) |
|||
.SetREF_PK(pkRefValue) |
|||
.SetN1_SF(senderId) |
|||
.SetN1_ST(receiverId) |
|||
; |
|||
shipNotice.AddSegment(10); |
|||
|
|||
return shipment; |
|||
} |
|||
|
|||
private Tare CreateTare(string tareLabelCode) |
|||
{ |
|||
var tare = new Tare(); |
|||
tare.SetHL() |
|||
.SetREF_LS(tareLabelCode); |
|||
|
|||
return tare; |
|||
} |
|||
|
|||
private Item CreateItem(string itemCode, decimal qty, string uom, int accumQty, |
|||
string poNumber, int loadQty, decimal unitQty, List<string> itemLabelCodes) |
|||
{ |
|||
|
|||
var item = new Item(); |
|||
item.SetHL() |
|||
.SetLIN(itemCode) |
|||
.SetSN1(qty, uom, accumQty) |
|||
.SetPRF(poNumber) |
|||
.SetCLD(loadQty, unitQty) |
|||
.SetREF_LSs(itemLabelCodes); |
|||
return item; |
|||
} |
|||
|
|||
|
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
namespace Win_in.Sfs.Scp.WebApi; |
|||
|
|||
public enum EnumExchangeDataErrorCode |
|||
{ |
|||
None = 0, |
|||
UnknownDataType = 1, |
|||
WrongDataFormat = 2, |
|||
Exception = 9, |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Services; |
|||
using Win_in.Sfs.Scp.v1.Domain.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.v1.Domain |
|||
{ |
|||
public interface IScpAsnManager:IDomainService |
|||
{ |
|||
Task<List<TB_ASN>> GetUnreadAsnsAsync(long uid, int batchSize); |
|||
Task<List<TS_BARCODE>> GetBarcodesAsync(string billNum); |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Win_in.Sfs.Scp.v1.Domain.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.v1.Domain |
|||
{ |
|||
public interface ITbAsnRepository : IRepository<TB_ASN>,ITransientDependency |
|||
{ |
|||
Task<List<TB_ASN>> GetUnreadListAsync(long uid,int batchSize); |
|||
} |
|||
} |
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Win_in.Sfs.Scp.v1.Domain.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.v1.Domain |
|||
{ |
|||
public interface ITsBarcodeRepository : IRepository<TS_BARCODE>, ITransientDependency |
|||
{ |
|||
Task<List<TS_BARCODE>> GetListByBillNumAsync(string billNum); |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Services; |
|||
using Win_in.Sfs.Scp.v1.Domain.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.v1.Domain |
|||
{ |
|||
public class ScpAsnManager : DomainService,IScpAsnManager |
|||
{ |
|||
private readonly ITbAsnRepository _tbAsnRepository; |
|||
private readonly ITsBarcodeRepository _tsBarcodeRepository; |
|||
|
|||
public ScpAsnManager(ITbAsnRepository tbAsnRepository |
|||
,ITsBarcodeRepository tsBarcodeRepository) |
|||
{ |
|||
_tbAsnRepository = tbAsnRepository; |
|||
_tsBarcodeRepository = tsBarcodeRepository; |
|||
} |
|||
public async Task<List<TB_ASN>> GetUnreadAsnsAsync(long uid, int batchSize) |
|||
{ |
|||
return await _tbAsnRepository.GetUnreadListAsync(uid, batchSize); |
|||
} |
|||
|
|||
public async Task<List<TS_BARCODE>> GetBarcodesAsync(string billNum) |
|||
{ |
|||
return await _tsBarcodeRepository.GetListByBillNumAsync(billNum); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Win_in.Sfs.Scp.v1.Domain; |
|||
using Win_in.Sfs.Scp.v1.Domain.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.v1.EntityFrameworkCore |
|||
{ |
|||
public class TbAsnRepository : EfCoreRepository<V1ScpDbContext, TB_ASN>, ITbAsnRepository |
|||
{ |
|||
public TbAsnRepository(IDbContextProvider<V1ScpDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public async Task<List<TB_ASN>> GetUnreadListAsync(long uid, int batchSize) |
|||
{ |
|||
var dbSet = await GetDbSetAsync(); |
|||
var list = await dbSet |
|||
.Where(p => p.UID > uid) |
|||
.OrderBy(p => p.UID) |
|||
.Take(batchSize) |
|||
.ToListAsync(); |
|||
return list; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
using Win_in.Sfs.Scp.v1.Domain; |
|||
using Win_in.Sfs.Scp.v1.Domain.Asns; |
|||
|
|||
namespace Win_in.Sfs.Scp.v1.EntityFrameworkCore |
|||
{ |
|||
public class TsBarcodeRepository : EfCoreRepository<V1ScpDbContext, TS_BARCODE>, ITsBarcodeRepository |
|||
{ |
|||
public TsBarcodeRepository(IDbContextProvider<V1ScpDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
|
|||
public async Task<List<TS_BARCODE>> GetListByBillNumAsync(string billNum) |
|||
{ |
|||
var dbSet = await GetDbSetAsync(); |
|||
var list = await dbSet |
|||
.Where(p => p.BillNum == billNum) |
|||
.ToListAsync(); |
|||
return list; |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue