From 114526d880037b5e83936091471f953d4c8395ef Mon Sep 17 00:00:00 2001 From: liufu <809388027@qq.com> Date: Wed, 10 Jan 2024 17:43:03 +0800 Subject: [PATCH] WMS 1.0 final version --- .../Controller/BaseController.cs | 2 +- .../Extentions/StartupExtensions.cs | 115 ++++++++-- backend/ModernWMS.Core/Job/IJob.cs | 24 ++ backend/ModernWMS.Core/Job/TestJob.cs | 61 +++++ .../Models/LoginInputViewModel.cs | 4 +- .../Models/MultiLanguage.en-us.resx | 9 + .../Models/MultiLanguage.zh-cn.resx | 15 ++ backend/ModernWMS.Core/ModernWMS.Core.csproj | 5 +- .../Controllers/Asn/AsnController.cs | 34 +++ .../Dispatchlist/DispatchlistController.cs | 18 ++ .../Controllers/Stock/StockController.cs | 147 ++++++------ .../Stockprocess/StockprocessController.cs | 31 ++- .../Controllers/user/UserController.cs | 23 +- .../ViewModels/Asn/AsnExcelImportViewModel.cs | 161 +++++++++++++ .../Asn/Flow/AsnPendingPutawayViewModel.cs | 58 +++++ .../DispatchlistImportViewModel.cs | 44 ++++ .../Dispatchlist/DispatchlistViewModel.cs | 102 ++++----- .../LocationStockForPhoneSearchViewModel.cs | 44 ++++ .../Stock/LocationStockManagementViewModel.cs | 12 +- .../StockprocessImportViewModel.cs | 54 +++++ .../IServices/Asn/IAsnService.cs | 17 ++ .../Dispatchlist/IDispatchlistService.cs | 13 +- .../IServices/Stock/IStockService.cs | 50 ++-- .../Stockprocess/IStockprocessService.cs | 6 + .../ModernWMS.WMS/Services/Asn/AsnService.cs | 187 ++++++++++++--- .../Dispatchlist/DispatchlistService.cs | 215 ++++++++++++++---- .../Goodslocation/GoodslocationService.cs | 4 +- .../Services/Stock/StockService.cs | 206 +++++++++++++---- .../Services/Stockmove/StockmoveService.cs | 208 +++++++++-------- .../Stockprocess/StockprocessService.cs | 208 +++++++++++++++-- .../Services/user/UserService.cs | 78 ++++--- backend/ModernWMS/wms.db-shm | Bin 0 -> 32768 bytes backend/ModernWMS/wms.db-wal | Bin 0 -> 115392 bytes 33 files changed, 1717 insertions(+), 438 deletions(-) create mode 100644 backend/ModernWMS.Core/Job/IJob.cs create mode 100644 backend/ModernWMS.Core/Job/TestJob.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnExcelImportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPendingPutawayViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistImportViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockForPhoneSearchViewModel.cs create mode 100644 backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessImportViewModel.cs create mode 100644 backend/ModernWMS/wms.db-shm create mode 100644 backend/ModernWMS/wms.db-wal diff --git a/backend/ModernWMS.Core/Controller/BaseController.cs b/backend/ModernWMS.Core/Controller/BaseController.cs index e213965..39d4f55 100644 --- a/backend/ModernWMS.Core/Controller/BaseController.cs +++ b/backend/ModernWMS.Core/Controller/BaseController.cs @@ -10,7 +10,7 @@ namespace ModernWMS.Core.Controller /// /// base controller /// - //[Authorize] + [Authorize] [Produces("application/json")] public class BaseController : ControllerBase { diff --git a/backend/ModernWMS.Core/Extentions/StartupExtensions.cs b/backend/ModernWMS.Core/Extentions/StartupExtensions.cs index 0eb616d..113ae43 100644 --- a/backend/ModernWMS.Core/Extentions/StartupExtensions.cs +++ b/backend/ModernWMS.Core/Extentions/StartupExtensions.cs @@ -30,6 +30,9 @@ using ModernWMS.Core.DI; using Microsoft.Extensions.Localization; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; using Microsoft.EntityFrameworkCore.Migrations.Internal; +using System.Security.AccessControl; +using Hangfire; +using Hangfire.MemoryStorage; namespace ModernWMS.Core.Extentions { @@ -43,6 +46,7 @@ namespace ModernWMS.Core.Extentions var sharedLocalizer = sp.GetRequiredService>(); return sharedLocalizer; }); + services.AddHttpClient(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(factory => @@ -50,25 +54,27 @@ namespace ModernWMS.Core.Extentions var cache = new MemoryCache(new MemoryCacheOptions()); return cache; }); + var database_config = configuration.GetSection("Database")["db"]; services.AddDbContextPool(t => { - if (database_config == "SqlLite") + if (database_config.ToUpper() == "SQLLITE") { var SqlLite_connection = configuration.GetConnectionString("SqlLiteConn"); t.UseSqlite(SqlLite_connection, b => b.MigrationsAssembly("ModernWMS")); } - else if (database_config == "MySql") + else if (database_config.ToUpper() == "MYSQL") { var Mysql_connection = configuration.GetConnectionString("MySqlConn"); t.UseMySql(Mysql_connection, new MySqlServerVersion(new Version(8, 0, 26))); } - else if (database_config == "SqlServer") + else if (database_config.ToUpper() == "SQLSERVER") { var SqlServer_connection = configuration.GetConnectionString("SqlServerConn"); t.UseSqlServer(SqlServer_connection); } - else if (database_config == "PostGres") + + else if (database_config.ToUpper() == "POSTGRES") { var Postgre_connection = configuration.GetConnectionString("PostGresConn"); t.UseNpgsql(Postgre_connection); @@ -79,7 +85,7 @@ namespace ModernWMS.Core.Extentions t.UseLoggerFactory(new LoggerFactory(new[] { new DebugLoggerProvider() })); }, 100); ; services.AddMemoryCache(); - services.AddScoped(); + services.AddScoped(); services.AddSwaggerService(configuration, AppContext.BaseDirectory); services.AddTokenGeneratorService(configuration); services.RegisterAssembly(); @@ -98,13 +104,20 @@ namespace ModernWMS.Core.Extentions options.SerializerSettings.Converters.Add(new JsonStringTrimConverter()); options.SerializerSettings.Formatting = Formatting.Indented; options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(); - }).AddDataAnnotationsLocalization(options => - { + }).AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(ModernWMS.Core.MultiLanguage)); - }); ; - } + }); + // Hangfire + services.AddHangfire(x => x.SetDataCompatibilityLevel(CompatibilityLevel.Version_170) + .UseSimpleAssemblyNameTypeSerializer() + .UseRecommendedSerializerSettings() + .UseStorage(new MemoryStorage())); + services.AddHangfireServer(); + + + } public static void UseExtensionsConfigure(this IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider, IConfiguration configuration) { if (env.IsDevelopment()) @@ -118,20 +131,28 @@ namespace ModernWMS.Core.Extentions app.UseTokenGeneratorConfigure(configuration); app.UseAuthorization(); app.UseMiddleware(); - var support_languages = new[] { "zh-cn", "en-us" }; + var support_languages = new[] { "zh-cn", "en-us" }; var localization_options = new RequestLocalizationOptions() .SetDefaultCulture(support_languages[0]) .AddSupportedCultures(support_languages) .AddSupportedUICultures(support_languages); app.UseRequestLocalization(localization_options); + + var option = new BackgroundJobServerOptions + { + ServerName = String.Format("{0}.{1}", Environment.MachineName, Guid.NewGuid().ToString()), + WorkerCount = Environment.ProcessorCount * 5, + Queues = new[] { "wms" } + }; + app.UseHangfireServer(option); + app.UseHangfireDashboard(); + AddHangfireJob(serviceProvider); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } - #region Swagger - /// /// Swagger /// @@ -163,6 +184,7 @@ namespace ModernWMS.Core.Extentions }); }); + if (settings.XmlFiles != null && settings.XmlFiles.Count > 0) { settings.XmlFiles.ForEach(fileName => @@ -178,6 +200,7 @@ namespace ModernWMS.Core.Extentions c.OperationFilter(); c.OperationFilter(); + c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme { Description = "please input Bearer {token}", @@ -186,10 +209,10 @@ namespace ModernWMS.Core.Extentions Type = SecuritySchemeType.ApiKey }); c.SwaggerGeneratorOptions.DescribeAllParametersInCamelCase = false; + }); } } - /// /// register Swagger /// @@ -197,6 +220,7 @@ namespace ModernWMS.Core.Extentions /// 配置文件 private static void UseSwaggerConfigure(this IApplicationBuilder app, IConfiguration configuration) { + var swaggerSettings = configuration.GetSection("SwaggerSettings"); if (swaggerSettings != null && swaggerSettings["Name"].Equals("ModernWMS")) @@ -212,14 +236,14 @@ namespace ModernWMS.Core.Extentions c.IndexStream = () => Assembly.GetExecutingAssembly().GetManifestResourceStream("ModernWMS.Core.Swagger.index.html"); c.RoutePrefix = ""; + }); + } } - - #endregion Swagger + #endregion #region JWT - /// /// register JWT /// @@ -227,6 +251,7 @@ namespace ModernWMS.Core.Extentions /// configuration private static void AddTokenGeneratorService(this IServiceCollection services, IConfiguration configuration) { + if (services == null) { throw new ArgumentNullException(nameof(services)); @@ -239,7 +264,7 @@ namespace ModernWMS.Core.Extentions { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = nameof(ApiResponseHandler); + options.DefaultChallengeScheme = nameof(ApiResponseHandler); options.DefaultForbidScheme = nameof(ApiResponseHandler); } ) @@ -258,23 +283,24 @@ namespace ModernWMS.Core.Extentions }; }) .AddScheme(nameof(ApiResponseHandler), o => { }); + } private static void UseTokenGeneratorConfigure(this IApplicationBuilder app, IConfiguration configuration) { app.UseAuthentication(); } + #endregion - #endregion JWT - - #region dynamic injection - + #region dynamic injection /// - /// judge the dll to be injected by IDependency + /// judge the dll to be injected by IDependency /// /// services private static IServiceCollection RegisterAssembly(this IServiceCollection services) { + + var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; var referencedAssemblies = System.IO.Directory.GetFiles(path, "ModernWMS*.dll").Select(Assembly.LoadFrom).ToArray(); @@ -292,9 +318,50 @@ namespace ModernWMS.Core.Extentions } services.AddScoped(); + + // Register Job + var typeJobs = referencedAssemblies + .SelectMany(a => a.DefinedTypes) + .Select(type => type.AsType()) + .Where(x => x != typeof(Job.IJob) && typeof(Job.IJob).IsAssignableFrom(x)).ToArray(); + if (types != null && types.Length > 0) + { + var implementJobs = typeJobs.Where(x => x.IsClass).ToArray(); + foreach (var implementType in implementJobs) + { + services.AddScoped(implementType); + } + } + return services; } + /// + /// AddHangfireJob + /// + /// + private static void AddHangfireJob(IServiceProvider serviceProvider) + { + var baseType = typeof(Core.Job.IJob); + var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; + var referencedAssemblies = System.IO.Directory.GetFiles(path, "ModernWMS*.dll").Select(Assembly.LoadFrom).ToArray(); + var types = referencedAssemblies + .SelectMany(a => a.DefinedTypes) + .Select(type => type.AsType()) + .Where(x => x != baseType && baseType.IsAssignableFrom(x)).ToArray(); + if (types != null && types.Length > 0) + { + var implementTypes = types.Where(x => x.IsClass).ToArray(); + foreach (var implementType in implementTypes) + { + var job = serviceProvider.GetService(implementType) as Core.Job.IJob; + if (job != null) + { + Hangfire.RecurringJob.AddOrUpdate(() => job.Execute(), job.CronExpression, TimeZoneInfo.Local, "wms"); + } + } + } + } + #endregion - #endregion dynamic injection } -} \ No newline at end of file +} diff --git a/backend/ModernWMS.Core/Job/IJob.cs b/backend/ModernWMS.Core/Job/IJob.cs new file mode 100644 index 0000000..a48ae88 --- /dev/null +++ b/backend/ModernWMS.Core/Job/IJob.cs @@ -0,0 +1,24 @@ +/* + * date:2023-02-08 + * developer:AMo + */ + +namespace ModernWMS.Core.Job +{ + /// + /// base interface + /// + public interface IJob + { + /// + /// cron + /// + string CronExpression { get; } + + /// + /// Execute + /// + /// + Task Execute(); + } +} diff --git a/backend/ModernWMS.Core/Job/TestJob.cs b/backend/ModernWMS.Core/Job/TestJob.cs new file mode 100644 index 0000000..cfd5930 --- /dev/null +++ b/backend/ModernWMS.Core/Job/TestJob.cs @@ -0,0 +1,61 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Json; +using System.Net; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.Core.Job +{ + /// + /// + /// + public class TestJob : IJob + { + /// + /// + /// + private IHttpClientFactory _httpClient; + + /// + /// + /// + /// + public TestJob(IHttpClientFactory httpClient) { + this._httpClient = httpClient; + } + + /// + /// + /// + public string CronExpression => Hangfire.Cron.Hourly(3); + + /// + /// + /// + /// + /// + public async Task Execute() + { + using (HttpClient httpClient = new HttpClient()) + { + + httpClient.DefaultRequestHeaders.Add("Method", "Post"); + await httpClient.PostAsync("https://wmsonline.ikeyly.com:20011/hello-world?culture=zh-cn", null); + + //HttpResponseMessage response = await httpClient.PostAsync("https://wmsonline.ikeyly.com:20011/hello-world?culture=zh-cn", null); + //if (response.StatusCode == HttpStatusCode.OK) + //{ + // var data = await response.Content.ReadAsStringAsync(); + + //} + + } + } + + + } +} diff --git a/backend/ModernWMS.Core/Models/LoginInputViewModel.cs b/backend/ModernWMS.Core/Models/LoginInputViewModel.cs index c8829e9..2e851a8 100644 --- a/backend/ModernWMS.Core/Models/LoginInputViewModel.cs +++ b/backend/ModernWMS.Core/Models/LoginInputViewModel.cs @@ -13,12 +13,12 @@ namespace ModernWMS.Core.Models /// [Required(ErrorMessage ="Required")] [Display(Name = "user_name")] - [MaxLength(128, ErrorMessage = "MaxLength")] + [MaxLength(128,ErrorMessage = "MaxLength")] public string user_name { get; set; } = string.Empty; + /// /// password /// - [Required(ErrorMessage ="Required")] [Display(Name = "password")] [MaxLength(64, ErrorMessage = "MaxLength")] diff --git a/backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx b/backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx index f2e7d2c..329fb43 100644 --- a/backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx +++ b/backend/ModernWMS.Core/Models/MultiLanguage.en-us.resx @@ -645,4 +645,13 @@ User name already exists + + present stock is not sufficient. + + + Job Number + + + Processing details cannot all be source products or target products. + \ No newline at end of file diff --git a/backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx b/backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx index 64d50ec..c0a9902 100644 --- a/backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx +++ b/backend/ModernWMS.Core/Models/MultiLanguage.zh-cn.resx @@ -645,4 +645,19 @@ 用户名已存在 + + 目标库位被冻结 + + + 可用数量不足 + + + 当前库存不足 + + + 加工序号 + + + 加工明细不能全部为来源商品也不能全部为目标商品 + \ No newline at end of file diff --git a/backend/ModernWMS.Core/ModernWMS.Core.csproj b/backend/ModernWMS.Core/ModernWMS.Core.csproj index 4d183d4..8ec17c8 100644 --- a/backend/ModernWMS.Core/ModernWMS.Core.csproj +++ b/backend/ModernWMS.Core/ModernWMS.Core.csproj @@ -23,7 +23,7 @@ - + all @@ -45,6 +45,9 @@ + + + diff --git a/backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs b/backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs index 8e67187..ec2a9fb 100644 --- a/backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs +++ b/backend/ModernWMS.WMS/Controllers/Asn/AsnController.cs @@ -301,6 +301,19 @@ namespace ModernWMS.WMS.Controllers } } + /// + /// get pending putaway data by asn_id + /// + /// + /// + [HttpGet("pending-putaway")] + public async Task>> GetPendingPutawayDataAsync(int id) + { + var data = await _asnService.GetPendingPutawayDataAsync(id); + data ??= new List(); + return ResultModel>.Success(data); + } + /// /// PutAway /// @@ -321,6 +334,27 @@ namespace ModernWMS.WMS.Controllers } #endregion + + #region excel import + /// + /// excel import + /// + /// excel data + /// + [HttpPost("excel-import")] + public async Task>> ImportAsync(List excelData) + { + var (flag, msg, errList) = await _asnService.ImportAsync(excelData, CurrentUser); + if (flag) + { + return ResultModel>.Success(errList); + } + else + { + return ResultModel>.Error(msg, 400, errList); + } + } + #endregion } } diff --git a/backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs b/backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs index ddf9ab1..72611ec 100644 --- a/backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs +++ b/backend/ModernWMS.WMS/Controllers/Dispatchlist/DispatchlistController.cs @@ -336,6 +336,24 @@ namespace ModernWMS.WMS.Controllers } } + /// + /// Excel Import + /// + /// viewModels + /// + [HttpPost("import")] + public async Task> Import(List viewModels) + { + var (flag, msg) = await _dispatchlistService.Import(viewModels, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } #endregion } diff --git a/backend/ModernWMS.WMS/Controllers/Stock/StockController.cs b/backend/ModernWMS.WMS/Controllers/Stock/StockController.cs index 4ecf4f8..85d0f60 100644 --- a/backend/ModernWMS.WMS/Controllers/Stock/StockController.cs +++ b/backend/ModernWMS.WMS/Controllers/Stock/StockController.cs @@ -2,69 +2,75 @@ * date:2022-12-22 * developer:NoNo */ - using Microsoft.AspNetCore.Mvc; - using ModernWMS.Core.Controller; - using ModernWMS.Core.Models; - using ModernWMS.WMS.Entities.ViewModels; - using ModernWMS.WMS.IServices; - using Microsoft.Extensions.Localization; - - namespace ModernWMS.WMS.Controllers - { - /// - /// stock controller - /// - [Route("stock")] - [ApiController] - [ApiExplorerSettings(GroupName = "WMS")] - public class StockController : BaseController - { - #region Args - - /// - /// stock Service - /// - private readonly IStockService _stockService; - - /// - /// Localizer Service - /// - private readonly IStringLocalizer _stringLocalizer; - #endregion - - #region constructor - /// - /// constructor - /// - /// stock Service + +using Microsoft.AspNetCore.Mvc; +using ModernWMS.Core.Controller; +using ModernWMS.Core.Models; +using ModernWMS.WMS.Entities.ViewModels; +using ModernWMS.WMS.IServices; +using Microsoft.Extensions.Localization; + +namespace ModernWMS.WMS.Controllers +{ + /// + /// stock controller + /// + [Route("stock")] + [ApiController] + [ApiExplorerSettings(GroupName = "WMS")] + public class StockController : BaseController + { + #region Args + + /// + /// stock Service + /// + private readonly IStockService _stockService; + + /// + /// Localizer Service + /// + private readonly IStringLocalizer _stringLocalizer; + + #endregion Args + + #region constructor + + /// + /// constructor + /// + /// stock Service /// Localizer - public StockController( - IStockService stockService - , IStringLocalizer stringLocalizer - ) - { - this._stockService = stockService; - this._stringLocalizer= stringLocalizer; - } - #endregion - - #region Api - /// - /// stock details page search - /// - /// args - /// - [HttpPost("stock-list")] - public async Task>> StockPageAsync(PageSearch pageSearch) - { - var (data, totals) = await _stockService.StockPageAsync(pageSearch, CurrentUser); - - return ResultModel>.Success(new PageData - { - Rows = data, - Totals = totals - }); - } + public StockController( + IStockService stockService + , IStringLocalizer stringLocalizer + ) + { + this._stockService = stockService; + this._stringLocalizer = stringLocalizer; + } + + #endregion constructor + + #region Api + + /// + /// stock details page search + /// + /// args + /// + [HttpPost("stock-list")] + public async Task>> StockPageAsync(PageSearch pageSearch) + { + var (data, totals) = await _stockService.StockPageAsync(pageSearch, CurrentUser); + + return ResultModel>.Success(new PageData + { + Rows = data, + Totals = totals + }); + } + /// /// location stock page search /// @@ -115,8 +121,19 @@ Totals = totals }); } - #endregion + /// + /// get stock infomation by phone + /// + /// input + /// + [HttpPost("qrcode-list")] + public async Task>> LocationStockForPhoneAsync(LocationStockForPhoneSearchViewModel input) + { + var datas = await _stockService.LocationStockForPhoneAsync(input, CurrentUser); + return ResultModel>.Success(datas); + } + + #endregion Api } - } - +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs b/backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs index 818431b..7a7df95 100644 --- a/backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs +++ b/backend/ModernWMS.WMS/Controllers/Stockprocess/StockprocessController.cs @@ -8,12 +8,11 @@ using ModernWMS.WMS.Entities.ViewModels; using ModernWMS.WMS.IServices; using Microsoft.Extensions.Localization; - - namespace ModernWMS.WMS.Controllers - { - /// - /// stockprocess controller - /// +namespace ModernWMS.WMS.Controllers +{ + /// + /// stockprocess controller + /// [Route("stockprocess")] [ApiController] [ApiExplorerSettings(GroupName = "WMS")] @@ -194,6 +193,26 @@ return ResultModel.Error(msg); } } + + + /// + /// Excel Import + /// + /// viewModels + /// + [HttpPost("import")] + public async Task> Import(List viewModels) + { + var (flag, msg) = await _stockprocessService.Import(viewModels, CurrentUser); + if (flag) + { + return ResultModel.Success(msg); + } + else + { + return ResultModel.Error(msg); + } + } #endregion } diff --git a/backend/ModernWMS.WMS/Controllers/user/UserController.cs b/backend/ModernWMS.WMS/Controllers/user/UserController.cs index 4cd02e9..319807a 100644 --- a/backend/ModernWMS.WMS/Controllers/user/UserController.cs +++ b/backend/ModernWMS.WMS/Controllers/user/UserController.cs @@ -2,6 +2,7 @@ * date:2022-12-20 * developer:NoNo */ + using Microsoft.AspNetCore.Mvc; using ModernWMS.Core.Controller; using ModernWMS.Core.Models; @@ -31,9 +32,11 @@ namespace ModernWMS.WMS.Controllers /// Localizer Service /// private readonly IStringLocalizer _stringLocalizer; - #endregion + + #endregion Args #region constructor + /// /// constructor /// @@ -47,9 +50,11 @@ namespace ModernWMS.WMS.Controllers this._userService = userService; this._stringLocalizer = stringLocalizer; } - #endregion + + #endregion constructor #region Api + /// /// get select items /// @@ -60,6 +65,7 @@ namespace ModernWMS.WMS.Controllers var datas = await _userService.GetSelectItemsAsnyc(CurrentUser); return ResultModel>.Success(datas); } + /// /// page search /// @@ -112,6 +118,7 @@ namespace ModernWMS.WMS.Controllers return ResultModel.Error(_stringLocalizer["not_exists_entity"]); } } + /// /// add a new record /// @@ -124,13 +131,14 @@ namespace ModernWMS.WMS.Controllers var (id, msg) = await _userService.AddAsync(viewModel, CurrentUser); if (id > 0) { - return ResultModel.Success(id); + return ResultModel.Success(id, msg); } else { return ResultModel.Error(msg); } } + /// /// register a new tenant /// @@ -150,6 +158,7 @@ namespace ModernWMS.WMS.Controllers return ResultModel.Error(msg); } } + /// /// import users by excel /// @@ -168,6 +177,7 @@ namespace ModernWMS.WMS.Controllers return ResultModel.Error(msg); } } + /// /// update a record /// @@ -205,6 +215,7 @@ namespace ModernWMS.WMS.Controllers return ResultModel.Error(msg); } } + /// /// reset password /// @@ -223,6 +234,7 @@ namespace ModernWMS.WMS.Controllers return ResultModel.Error(msg); } } + /// /// change password /// @@ -241,8 +253,7 @@ namespace ModernWMS.WMS.Controllers return ResultModel.Error(msg); } } - #endregion + #endregion Api } -} - +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnExcelImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnExcelImportViewModel.cs new file mode 100644 index 0000000..844c609 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/AsnExcelImportViewModel.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// asn excel import view model + /// + public class AsnExcelImportViewModel + { + #region constructor + /// + /// constructor + /// + public AsnExcelImportViewModel() + { + + } + #endregion + + #region Property + + /// + /// asn_no + /// + [Display(Name = "asn_no")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string asn_no { get; set; } = string.Empty; + + + /// + /// spu_id + /// + [Display(Name = "spu_id")] + [Required(ErrorMessage = "Required")] + public int spu_id { get; set; } = 0; + + /// + /// spu_code + /// + [Display(Name = "spu_code")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string spu_code { get; set; } = string.Empty; + + /// + /// spu_name + /// + [Display(Name = "spu_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string spu_name { get; set; } = string.Empty; + + /// + /// sku_id + /// + [Display(Name = "sku_id")] + public int sku_id { get; set; } = 0; + + /// + /// sku_code + /// + [Display(Name = "sku_code")] + [Required(ErrorMessage = "Required")] + [MaxLength(32, ErrorMessage = "MaxLength")] + public string sku_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + [Display(Name = "sku_name")] + [MaxLength(200, ErrorMessage = "MaxLength")] + public string sku_name { get; set; } = string.Empty; + + /// + /// origin + /// + [Display(Name = "origin")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string origin { get; set; } = string.Empty; + + /// + /// length_unit (0=毫米、1=厘米、2=分米、3=米) + /// + [Display(Name = "length_unit")] + public byte length_unit { get; set; } = 0; + + /// + /// volume_unit (0=立方厘米、1=立方分米、2=立方米) + /// + [Display(Name = "volume_unit")] + public byte volume_unit { get; set; } = 0; + + /// + /// weight_unit (0=毫克、1=克、2=千克) + /// + [Display(Name = "weight_unit")] + public byte weight_unit { get; set; } = 0; + + /// + /// asn_qty + /// + [Display(Name = "asn_qty")] + public int asn_qty { get; set; } = 0; + + /// + /// weight + /// + [Display(Name = "weight")] + public decimal weight { get; set; } = 0; + + /// + /// volume + /// + [Display(Name = "volume")] + public decimal volume { get; set; } = 0; + + /// + /// supplier_id + /// + [Display(Name = "supplier_id")] + public int supplier_id { get; set; } = 0; + + /// + /// supplier_name + /// + [Display(Name = "supplier_name")] + [Required(ErrorMessage = "Required")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string supplier_name { get; set; } = string.Empty; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_owner_name + /// + [Display(Name = "goods_owner_name")] + [MaxLength(256, ErrorMessage = "MaxLength")] + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// + /// + public string _X_ROW_KEY { get; set; } = string.Empty; + + /// + /// + /// + public string error_msg { get; set; } = string.Empty; + #endregion + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPendingPutawayViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPendingPutawayViewModel.cs new file mode 100644 index 0000000..e0e29fc --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Asn/Flow/AsnPendingPutawayViewModel.cs @@ -0,0 +1,58 @@ +/* + * date:2023-09-05 + * developer:AMo + */ +using System.ComponentModel.DataAnnotations; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// pending putwaay viewModel + /// + public class AsnPendingPutawayViewModel + { + #region constructor + /// + /// constructor + /// + public AsnPendingPutawayViewModel() + { + + } + #endregion + + #region Property + + /// + /// asn_id + /// + [Display(Name = "asn_id")] + public int asn_id { get; set; } = 0; + + /// + /// goods_owner_id + /// + [Display(Name = "goods_owner_id")] + public int goods_owner_id { get; set; } = 0; + + /// + /// goods_owner_name + /// + [Display(Name = "goods_owner_name")] + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// series_number + /// + [Display(Name = "series_number")] + public string series_number { get; set; } = string.Empty; + + /// + /// sorted_qty + /// + [Display(Name = "sorted_qty")] + public int sorted_qty { get; set; } = 0; + + #endregion + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistImportViewModel.cs new file mode 100644 index 0000000..f2fa0e8 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistImportViewModel.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// ImportViewModel + /// + public class DispatchlistImportViewModel + { + /// + /// import_group + /// + public int import_group { get; set; } = 0; + + /// + /// customer_name + /// + public string customer_name { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// qty + /// + public int qty { get; set; } = 0; + } +} diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs index e82e10b..58612a9 100644 --- a/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Dispatchlist/DispatchlistViewModel.cs @@ -14,104 +14,104 @@ namespace ModernWMS.WMS.Entities.ViewModels public class DispatchlistViewModel { - #region constructor - /// - /// constructor - /// - public DispatchlistViewModel() - { - - } - #endregion + #region constructor + /// + /// constructor + /// + public DispatchlistViewModel() + { + + } + #endregion #region Property /// /// id /// [Display(Name = "id")] - public int id { get; set; } = 0; + public int id { get; set; } = 0; /// /// dispatch_no /// [Display(Name = "dispatch_no")] - [MaxLength(32, ErrorMessage = "MaxLength")] - public string dispatch_no { get; set; } = string.Empty; + [MaxLength(32,ErrorMessage = "MaxLength")] + public string dispatch_no { get; set; } = string.Empty; /// /// dispatch_status /// [Display(Name = "dispatch_status")] - public byte dispatch_status { get; set; } = 0; + public byte dispatch_status { get; set; } = 0; /// /// customer_id /// [Display(Name = "customer_id")] - public int customer_id { get; set; } = 0; + public int customer_id { get; set; } = 0; /// /// customer_name /// [Display(Name = "customer_name")] - [MaxLength(256, ErrorMessage = "MaxLength")] - public string customer_name { get; set; } = string.Empty; + [MaxLength(256,ErrorMessage = "MaxLength")] + public string customer_name { get; set; } = string.Empty; /// /// sku_id /// [Display(Name = "sku_id")] - public int sku_id { get; set; } = 0; + public int sku_id { get; set; } = 0; /// /// qty /// [Display(Name = "qty")] - public int qty { get; set; } = 0; + public int qty { get; set; } = 0; /// /// weight /// [Display(Name = "weight")] - public decimal weight { get; set; } = 0; + public decimal weight { get; set; } = 0; /// /// volume /// [Display(Name = "volume")] - public decimal volume { get; set; } = 0; + public decimal volume { get; set; } = 0; /// /// creator /// [Display(Name = "creator")] - [MaxLength(64, ErrorMessage = "MaxLength")] - public string creator { get; set; } = string.Empty; + [MaxLength(64,ErrorMessage = "MaxLength")] + public string creator { get; set; } = string.Empty; /// /// create_time /// [Display(Name = "create_time")] - [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] - public DateTime create_time { get; set; } = UtilConvert.MinDate; + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime create_time { get; set; } = UtilConvert.MinDate; /// /// damage_qty /// [Display(Name = "damage_qty")] - public int damage_qty { get; set; } = 0; + public int damage_qty { get; set; } = 0; /// /// lock_qty /// [Display(Name = "lock_qty")] - public int lock_qty { get; set; } = 0; + public int lock_qty { get; set; } = 0; /// /// picked_qty /// [Display(Name = "picked_qty")] - public int picked_qty { get; set; } = 0; + public int picked_qty { get; set; } = 0; /// /// unpicked_qty @@ -123,13 +123,13 @@ namespace ModernWMS.WMS.Entities.ViewModels /// intrasit_qty /// [Display(Name = "intrasit_qty")] - public int intrasit_qty { get; set; } = 0; + public int intrasit_qty { get; set; } = 0; /// /// package_qty /// [Display(Name = "package_qty")] - public int package_qty { get; set; } = 0; + public int package_qty { get; set; } = 0; /// /// unpackage_qty @@ -141,7 +141,7 @@ namespace ModernWMS.WMS.Entities.ViewModels /// weighing_qty /// [Display(Name = "weighing_qty")] - public int weighing_qty { get; set; } = 0; + public int weighing_qty { get; set; } = 0; /// /// weighing_qty @@ -153,87 +153,87 @@ namespace ModernWMS.WMS.Entities.ViewModels /// actual_qty /// [Display(Name = "actual_qty")] - public int actual_qty { get; set; } = 0; + public int actual_qty { get; set; } = 0; /// /// sign_qty /// [Display(Name = "sign_qty")] - public int sign_qty { get; set; } = 0; + public int sign_qty { get; set; } = 0; /// /// package_no /// [Display(Name = "package_no")] - [MaxLength(32, ErrorMessage = "MaxLength")] - public string package_no { get; set; } = string.Empty; + [MaxLength(32,ErrorMessage = "MaxLength")] + public string package_no { get; set; } = string.Empty; /// /// package_person /// [Display(Name = "package_person")] - [MaxLength(64, ErrorMessage = "MaxLength")] - public string package_person { get; set; } = string.Empty; + [MaxLength(64,ErrorMessage = "MaxLength")] + public string package_person { get; set; } = string.Empty; /// /// package_time /// [Display(Name = "package_time")] - [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] - public DateTime package_time { get; set; } = UtilConvert.MinDate; + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime package_time { get; set; } = UtilConvert.MinDate; /// /// weighing_no /// [Display(Name = "weighing_no")] - [MaxLength(32, ErrorMessage = "MaxLength")] - public string weighing_no { get; set; } = string.Empty; + [MaxLength(32,ErrorMessage = "MaxLength")] + public string weighing_no { get; set; } = string.Empty; /// /// weighing_person /// [Display(Name = "weighing_person")] - [MaxLength(64, ErrorMessage = "MaxLength")] - public string weighing_person { get; set; } = string.Empty; + [MaxLength(64,ErrorMessage = "MaxLength")] + public string weighing_person { get; set; } = string.Empty; /// /// weighing_weight /// [Display(Name = "weighing_weight")] - public decimal weighing_weight { get; set; } = 0; + public decimal weighing_weight { get; set; } = 0; /// /// waybill_no /// [Display(Name = "waybill_no")] - [MaxLength(64, ErrorMessage = "MaxLength")] - public string waybill_no { get; set; } = string.Empty; + [MaxLength(64,ErrorMessage = "MaxLength")] + public string waybill_no { get; set; } = string.Empty; /// /// carrier /// [Display(Name = "carrier")] - [MaxLength(256, ErrorMessage = "MaxLength")] - public string carrier { get; set; } = string.Empty; + [MaxLength(256,ErrorMessage = "MaxLength")] + public string carrier { get; set; } = string.Empty; /// /// freightfee /// [Display(Name = "freightfee")] - public decimal freightfee { get; set; } = 0; + public decimal freightfee { get; set; } = 0; /// /// last_update_time /// [Display(Name = "last_update_time")] - [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] - public DateTime last_update_time { get; set; } = UtilConvert.MinDate; + [DataType(DataType.DateTime, ErrorMessage = "DataType_DateTime")] + public DateTime last_update_time { get; set; } = UtilConvert.MinDate; /// /// tenant_id /// [Display(Name = "tenant_id")] - public long tenant_id { get; set; } = 0; + public long tenant_id { get; set; } = 0; /// diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockForPhoneSearchViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockForPhoneSearchViewModel.cs new file mode 100644 index 0000000..79d3ada --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockForPhoneSearchViewModel.cs @@ -0,0 +1,44 @@ +/* +* date:2023-9-3 +* developer:NoNo +*/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// get stock infomation by phone api input viewmodel + /// + public class LocationStockForPhoneSearchViewModel + { + /// + /// sku_id + /// + public int sku_id { get; set; } = 0; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; + + /// + /// warehouse_id + /// + public int warehouse_id { get; set; } = 0; + + /// + /// spu name + /// + public string spu_name { get; set; } = string.Empty; + + /// + /// location name + /// + public string location_name { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs index 343148b..907f289 100644 --- a/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stock/LocationStockManagementViewModel.cs @@ -67,5 +67,15 @@ namespace ModernWMS.WMS.Entities.ViewModels /// quantity frozen /// public int qty_frozen { get; set; } = 0; + + /// + /// goods owner name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// goods_location_id + /// + public int goods_location_id { get; set; } = 0; } -} +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessImportViewModel.cs b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessImportViewModel.cs new file mode 100644 index 0000000..0f89799 --- /dev/null +++ b/backend/ModernWMS.WMS/Entities/ViewModels/Stockprocess/StockprocessImportViewModel.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ModernWMS.WMS.Entities.ViewModels +{ + /// + /// StockprocessImportViewModel + /// + public class StockprocessImportViewModel + { + /// + /// import_group + /// + public int import_group { get; set; } = 0; + + /// + /// spu_code + /// + public string spu_code { get; set; } = string.Empty; + + /// + /// sku_name + /// + public string sku_name { get; set; } = string.Empty; + + /// + /// sku_code + /// + public string sku_code { get; set; } = string.Empty; + + /// + /// location_name + /// + public string location_name { get; set; } = string.Empty; + + /// + /// goods_owner_name + /// + public string goods_owner_name { get; set; } = string.Empty; + + /// + /// qty + /// + public int qty { get; set; } = 0; + + /// + /// is origin + /// + public bool is_ori { get; set; } = false; + } +} diff --git a/backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs b/backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs index 92f8781..f29efdd 100644 --- a/backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs +++ b/backend/ModernWMS.WMS/IServices/Asn/IAsnService.cs @@ -115,6 +115,13 @@ namespace ModernWMS.WMS.IServices /// Task<(bool flag, string msg)> SortedCancelAsync(int id); + /// + /// get pending putaway data by asn_id + /// + /// + /// + Task> GetPendingPutawayDataAsync(int id); + /// /// PutAway /// @@ -123,6 +130,16 @@ namespace ModernWMS.WMS.IServices /// Task<(bool flag, string msg)> PutAwayAsync(AsnPutAwayInputViewModel viewModel, CurrentUser currentUser); #endregion + + #region excel import + /// + /// excel import + /// + /// excel data + /// current user + /// + Task<(bool flag, string msg, List errList)> ImportAsync(List excelData, CurrentUser currentUser); + #endregion } } diff --git a/backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs b/backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs index 0b05c11..d2a4f51 100644 --- a/backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs +++ b/backend/ModernWMS.WMS/IServices/Dispatchlist/IDispatchlistService.cs @@ -149,7 +149,16 @@ namespace ModernWMS.WMS.IServices /// dispatchlist_id /// Task<(bool flag, string msg)> CancelDispatchlistDetailOpration(int id); - #endregion - } + + + /// + /// Excel Import + /// + /// viewModels + /// currentUser + /// + Task<(bool flag, string msg)> Import(List viewModels, CurrentUser currentUser); + #endregion + } } diff --git a/backend/ModernWMS.WMS/IServices/Stock/IStockService.cs b/backend/ModernWMS.WMS/IServices/Stock/IStockService.cs index f97b0c8..d78394d 100644 --- a/backend/ModernWMS.WMS/IServices/Stock/IStockService.cs +++ b/backend/ModernWMS.WMS/IServices/Stock/IStockService.cs @@ -2,26 +2,30 @@ * date:2022-12-22 * developer:NoNo */ - using ModernWMS.Core.Services; - using ModernWMS.Core.Models; - using ModernWMS.Core.JWT; - using ModernWMS.WMS.Entities.Models; - using ModernWMS.WMS.Entities.ViewModels; + +using ModernWMS.Core.Services; +using ModernWMS.Core.Models; +using ModernWMS.Core.JWT; +using ModernWMS.WMS.Entities.Models; +using ModernWMS.WMS.Entities.ViewModels; + namespace ModernWMS.WMS.IServices { /// /// Interface of StockService /// - public interface IStockService : IBaseService - { - #region Api - /// - /// page search - /// - /// args - /// current user - /// - Task<(List data, int totals)> StockPageAsync(PageSearch pageSearch, CurrentUser currentUser); + public interface IStockService : IBaseService + { + #region Api + + /// + /// page search + /// + /// args + /// current user + /// + Task<(List data, int totals)> StockPageAsync(PageSearch pageSearch, CurrentUser currentUser); + /// /// location stock page search /// @@ -45,7 +49,15 @@ namespace ModernWMS.WMS.IServices /// currentUser /// Task<(List data, int totals)> SkuSelectPageAsync(PageSearch pageSearch, CurrentUser currentUser); - #endregion - } - } - + + /// + /// get stock infomation by phone + /// + /// input + /// current user + /// + Task> LocationStockForPhoneAsync(LocationStockForPhoneSearchViewModel input, CurrentUser currentUser); + + #endregion Api + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs b/backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs index fd7de78..6c32ec4 100644 --- a/backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs +++ b/backend/ModernWMS.WMS/IServices/Stockprocess/IStockprocessService.cs @@ -70,6 +70,12 @@ /// current user /// Task<(bool flag, string msg)> ConfirmAdjustment(int id, CurrentUser currentUser); + + /// + /// Excel Import + /// + /// + Task<(bool flag, string msg)> Import(List viewModels, CurrentUser currentUser); #endregion } } diff --git a/backend/ModernWMS.WMS/Services/Asn/AsnService.cs b/backend/ModernWMS.WMS/Services/Asn/AsnService.cs index 282b66d..2459a06 100644 --- a/backend/ModernWMS.WMS/Services/Asn/AsnService.cs +++ b/backend/ModernWMS.WMS/Services/Asn/AsnService.cs @@ -13,6 +13,7 @@ using ModernWMS.Core.Services; using ModernWMS.WMS.Entities.Models; using ModernWMS.WMS.Entities.ViewModels; using ModernWMS.WMS.IServices; +using System.Text; namespace ModernWMS.WMS.Services { @@ -66,20 +67,29 @@ namespace ModernWMS.WMS.Services queries.Add(s); }); } + var Asns = _dBContext.GetDbSet().AsNoTracking(); Byte asn_status = 255; - if (pageSearch.sqlTitle.ToLower().Contains("asn_status")) + bool isShowAllData = false; + if (pageSearch.sqlTitle.ToLower().Contains("asn_status:-1")) + { + isShowAllData = true; + } + else if (pageSearch.sqlTitle.ToLower().Contains("asn_status:alltodo")) + { + Asns = Asns.Where(t => t.asn_status <= 3); + } + else if (pageSearch.sqlTitle.ToLower().Contains("asn_status")) { asn_status = Convert.ToByte(pageSearch.sqlTitle.Trim().ToLower().Replace("asn_status","").Replace(":", "").Replace(":", "").Replace("=", "")); - asn_status = asn_status.Equals(4) ? (Byte)255 : asn_status; + //asn_status = asn_status.Equals(4) ? (Byte)255 : asn_status; + Asns = Asns.Where(t => t.asn_status == asn_status); } - var Spus = _dBContext.GetDbSet(); - var Skus = _dBContext.GetDbSet(); - var Asns = _dBContext.GetDbSet(); - var query = from m in Asns.AsNoTracking() - join p in Spus.AsNoTracking() on m.spu_id equals p.id - join k in Skus.AsNoTracking() on m.sku_id equals k.id + var Spus = _dBContext.GetDbSet().AsNoTracking(); + var Skus = _dBContext.GetDbSet().AsNoTracking(); + var query = from m in Asns + join p in Spus on m.spu_id equals p.id + join k in Skus on m.sku_id equals k.id where m.tenant_id == currentUser.tenant_id - && (asn_status == 255 || m.asn_status == asn_status) select new AsnViewModel { id = m.id, @@ -154,8 +164,8 @@ namespace ModernWMS.WMS.Services shortage_qty = m.shortage_qty, more_qty = m.more_qty, damage_qty = m.damage_qty, - weight = m.weight, - volume = m.volume, + weight = k.weight * m.asn_qty, + volume = k.volume * m.asn_qty, supplier_id = m.supplier_id, supplier_name = m.supplier_name, goods_owner_id = m.goods_owner_id, @@ -350,11 +360,11 @@ namespace ModernWMS.WMS.Services var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.asn_status > 0) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Delivery"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Delivery"]}"); } entity.asn_status = 1; var qty = await _dBContext.SaveChangesAsync(); @@ -378,11 +388,11 @@ namespace ModernWMS.WMS.Services var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.asn_status != (byte)1) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Delivery"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Delivery"]}"); } entity.asn_status = 0; var qty = await _dBContext.SaveChangesAsync(); @@ -408,11 +418,11 @@ namespace ModernWMS.WMS.Services var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.asn_status > 1) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Load"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Load"]}"); } entity.asn_status = 2; entity.last_update_time = DateTime.Now; @@ -439,11 +449,11 @@ namespace ModernWMS.WMS.Services var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.asn_status != (byte)2) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Load"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Load"]}"); } entity.asn_status = 1; entity.last_update_time = DateTime.Now; @@ -471,11 +481,11 @@ namespace ModernWMS.WMS.Services var entity = await Asns.FirstOrDefaultAsync(t => t.id == viewModel.asn_id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.asn_status != 2) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Sort"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Pre_Sort"]}"); } await Asnsorts.AddAsync(new AsnsortEntity { @@ -511,11 +521,11 @@ namespace ModernWMS.WMS.Services var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.sorted_qty < 1) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorting"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorting"]}"); } entity.asn_status = 3; if (entity.sorted_qty > entity.asn_qty) @@ -550,15 +560,15 @@ namespace ModernWMS.WMS.Services var entity = await Asns.FirstOrDefaultAsync(t => t.id == id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.actual_qty > 0) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Putaway"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Putaway"]}"); } else if (entity.sorted_qty < 1) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorting"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorting"]}"); } entity.asn_status = 2; entity.sorted_qty = 0; @@ -577,6 +587,32 @@ namespace ModernWMS.WMS.Services return (false, _stringLocalizer["save_failed"]); } } + + /// + /// get pending putaway data by asn_id + /// + /// + /// + public async Task> GetPendingPutawayDataAsync(int id) + { + var Asns = _dBContext.GetDbSet(); + var Asnsorts = _dBContext.GetDbSet(); + + var data = await (from m in Asns.AsNoTracking() + join s in Asnsorts.AsNoTracking() on m.id equals s.asn_id + where m.id == id + group new { m, s } by new { m.id, m.goods_owner_id, m.goods_owner_name, m.actual_qty } + into g + select new AsnPendingPutawayViewModel + { + asn_id = g.Key.id, + goods_owner_id = g.Key.goods_owner_id, + goods_owner_name = g.Key.goods_owner_name, + series_number = "", + sorted_qty = g.Sum(o => o.s.sorted_qty) - g.Key.actual_qty + }).ToListAsync(); + return data; + } /// /// PutAway /// @@ -591,21 +627,21 @@ namespace ModernWMS.WMS.Services var Location = await Goodslocations.FirstOrDefaultAsync(t => t.id.Equals(viewModel.goods_location_id)); if (Location == null) { - return (false, string.Format(_stringLocalizer["Required"], _stringLocalizer["location_name"])); + return (false, "[202]" + string.Format(_stringLocalizer["Required"], _stringLocalizer["location_name"])); } var entity = await Asns.FirstOrDefaultAsync(t => t.id == viewModel.asn_id); if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } else if (entity.asn_status != 3) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorted"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Status_Is_Not_Sorted"]}"); } else if (entity.actual_qty + viewModel.putaway_qty > entity.sorted_qty) { - return (false, $"{entity.asn_no}{_stringLocalizer["ASN_Total_PutAway_Qty_Greater_Than_Sorted_Qty"]}"); + return (false, "[202]" + $"{entity.asn_no}{_stringLocalizer["ASN_Total_PutAway_Qty_Greater_Than_Sorted_Qty"]}"); } entity.actual_qty += viewModel.putaway_qty; if (Location.warehouse_area_property.Equals(5)) @@ -651,6 +687,97 @@ namespace ModernWMS.WMS.Services } } #endregion + + #region excel import + /// + /// excel import + /// + /// excel data + /// current user + /// + public async Task<(bool flag, string msg, List errList)> ImportAsync(List excelData, CurrentUser currentUser) + { + var Spus = _dBContext.GetDbSet().AsNoTracking(); + var Skus = _dBContext.GetDbSet().AsNoTracking(); + + var ownerList = excelData.Where(e => e.goods_owner_name != "").Select(e => e.goods_owner_name).ToList(); + if (ownerList == null) + { + ownerList = new List(); + } + var goods_owner = await _dBContext.GetDbSet().AsNoTracking() + .Where(t => t.tenant_id == currentUser.tenant_id) + .Where(t => ownerList.Contains(t.goods_owner_name)) + .Select(t => new { t.id, t.goods_owner_name}).ToListAsync(); + + var dbSku = await (from m in Spus + join d in Skus on m.id equals d.spu_id + where m.tenant_id == currentUser.tenant_id + select new + { + spu_id = m.id, + m.spu_code, + m.spu_name, + m.supplier_id, + m.supplier_name, + sku_id = d.id, + d.sku_code, + d.sku_name + }).ToListAsync(); + StringBuilder sb = new StringBuilder(); + excelData.ForEach(ex => + { + var sku = dbSku.FirstOrDefault(t => t.spu_code == ex.spu_code && t.sku_code == ex.sku_code && t.supplier_name == ex.supplier_name); + if (sku != null) + { + ex.spu_id = sku.spu_id; + ex.sku_id = sku.sku_id; + ex.supplier_id = sku.supplier_id; + + var owner = goods_owner.FirstOrDefault(t => t.goods_owner_name == ex.goods_owner_name); + if (owner != null) + { + ex.goods_owner_id = owner.id; + } + } + else + { + string err = $"[{_stringLocalizer["spu_code"]}:{ex.spu_name},{_stringLocalizer["sku_code"]}:{ex.sku_code},{_stringLocalizer["supplier_name"]}:{ex.supplier_name}{_stringLocalizer["not_exists_entity"]}]"; + ex.error_msg = err; + sb.AppendLine(err); + } + }); + if (excelData.Any(t => t.error_msg.Length > 0)) + { + return (false, sb.ToString(), excelData.Where(t => t.error_msg.Length > 0).ToList()); + } + else + { + var DbSet = _dBContext.GetDbSet(); + var entities = excelData.Adapt>(); + foreach (var entity in entities) + { + entity.id = 0; + entity.creator = currentUser.user_name; + entity.create_time = DateTime.Now; + entity.last_update_time = DateTime.Now; + entity.tenant_id = currentUser.tenant_id; + entity.is_valid = true; + } + await DbSet.AddRangeAsync(entities); + int qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"], new List()); + } + else + { + return (false, _stringLocalizer["save_failed"], new List()); + } + } + } + + #endregion } } diff --git a/backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs b/backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs index 43bd958..1d446b7 100644 --- a/backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs +++ b/backend/ModernWMS.WMS/Services/Dispatchlist/DispatchlistService.cs @@ -2,6 +2,7 @@ * date:2022-12-27 * developer:NoNo */ + using Mapster; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -16,6 +17,7 @@ using ModernWMS.WMS.Entities.Models; using ModernWMS.WMS.Entities.ViewModels; using ModernWMS.WMS.IServices; using System.Collections.Generic; +using System.Linq; namespace ModernWMS.WMS.Services { @@ -25,6 +27,7 @@ namespace ModernWMS.WMS.Services public class DispatchlistService : BaseService, IDispatchlistService { #region Args + /// /// The DBContext /// @@ -34,9 +37,11 @@ namespace ModernWMS.WMS.Services /// Localizer Service /// private readonly IStringLocalizer _stringLocalizer; - #endregion + + #endregion Args #region constructor + /// ///Dispatchlist constructor /// @@ -50,9 +55,11 @@ namespace ModernWMS.WMS.Services this._dBContext = dBContext; this._stringLocalizer = stringLocalizer; } - #endregion + + #endregion constructor #region Api + /// /// page search /// @@ -136,6 +143,7 @@ namespace ModernWMS.WMS.Services { query = query.Where(t => t.picked_qty == t.qty && (t.dispatch_status.Equals(3) || t.dispatch_status.Equals(4) || t.dispatch_status.Equals(5))); } + int totals = await query.CountAsync(); var list = await query.OrderByDescending(t => t.create_time) .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) @@ -143,6 +151,7 @@ namespace ModernWMS.WMS.Services .ToListAsync(); return (list, totals); } + /// /// get dispatchlist by dispatch_no /// @@ -201,6 +210,7 @@ namespace ModernWMS.WMS.Services }).ToListAsync(); return datas; } + /// /// update dispatchlist with same dispatch_no /// @@ -218,7 +228,7 @@ namespace ModernWMS.WMS.Services var skus = await (_dBContext.GetDbSet().AsNoTracking().Where(t => sku_id_list.Contains(t.id))).ToListAsync(); if (entities.Any(t => t.dispatch_status != 1 && t.dispatch_status != 0)) { - return (false, _stringLocalizer["data_changed"]); + return (false,"[202]"+ _stringLocalizer["data_changed"]); } foreach (var vm in viewModels) { @@ -227,7 +237,7 @@ namespace ModernWMS.WMS.Services var entity = entities.FirstOrDefault(t => t.id == -vm.id); if (entity == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } DBSet.Remove(entity); delete_id_list.Add(entity.id); @@ -237,7 +247,7 @@ namespace ModernWMS.WMS.Services var entity = entities.FirstOrDefault(t => t.id == vm.id); if (entity == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } entity.sku_id = vm.sku_id; entity.qty = vm.qty; @@ -261,7 +271,6 @@ namespace ModernWMS.WMS.Services dispatch_status = dispatch_status, sku_id = vm.sku_id, qty = vm.qty - }; var sku = skus.FirstOrDefault(t => t.id == entity.sku_id); if (sku != null) @@ -291,9 +300,10 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["save_failed"]); + return (false, "[202]" + _stringLocalizer["save_failed"]); } } + /// /// get pick list by dispatch_id /// @@ -332,7 +342,7 @@ namespace ModernWMS.WMS.Services } /// - /// advanced dispatch order page search + /// advanced dispatch order page search /// /// args /// currentUser @@ -376,12 +386,18 @@ namespace ModernWMS.WMS.Services var dispatch_status = Convert.ToByte(pageSearch.sqlTitle.Trim().ToLower().Replace("dispatch_status", "").Replace(":", "").Replace(":", "").Replace("=", "")); query = query.Where(t => t.dispatch_status.Equals(dispatch_status)); } + else if (pageSearch.sqlTitle.Equals("todo")) + { + query = query.Where(t => t.dispatch_status >= 2 && t.dispatch_status <= 5); + } int totals = await query.CountAsync(); var list = await query.OrderByDescending(t => t.dispatch_no) .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) .Take(pageSearch.pageSize) .ToListAsync(); - #region sqlit cannot sum data of decimal type + + #region sqlit cannot sum data of decimal type + var dispatch_no_list = list.Select(t => t.dispatch_no).Distinct().ToList(); var d_datas = await (from d in DbSet.AsNoTracking() join sku in _dBContext.GetDbSet().AsNoTracking() on d.sku_id equals sku.id @@ -398,9 +414,12 @@ namespace ModernWMS.WMS.Services t.volume = d_datas.Where(d => d.dispatch_no == t.dispatch_no).Sum(t => t.volume); t.weight = d_datas.Where(d => d.dispatch_no == t.dispatch_no).Sum(t => t.weight); }); - #endregion + + #endregion sqlit cannot sum data of decimal type + return (list, totals); } + /// /// Get dispatchlist by dispatch_no /// @@ -455,7 +474,7 @@ namespace ModernWMS.WMS.Services } /// - /// add a new Dispatchlist + /// add a new Dispatchlist /// /// viewmodel /// current user @@ -490,7 +509,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["save_failed"]); + return (false, "[202]" + _stringLocalizer["save_failed"]); } } @@ -515,7 +534,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["delete_failed"]); + return (false, "[202]" + _stringLocalizer["delete_failed"]); } } @@ -685,7 +704,6 @@ namespace ModernWMS.WMS.Services } return res; - } /// @@ -718,7 +736,7 @@ namespace ModernWMS.WMS.Services var d = dispatchlist_datas.Where(t => t.id == vm.dispatchlist_id).FirstOrDefault(); if (d == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } if (vm.confirm == true) { @@ -824,7 +842,7 @@ namespace ModernWMS.WMS.Services select tp).Any(); if (if_not_stock) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } await pick_DBSet.AddRangeAsync(pick_datas); var dispatch_no = await GetOrderCode(currentUser); @@ -849,12 +867,12 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } /// - /// cancel order opration + /// cancel order opration /// /// viewmodel /// current user @@ -866,7 +884,7 @@ namespace ModernWMS.WMS.Services var entities = await DBSet.Where(t => t.dispatch_no == viewModel.dispatch_no && t.tenant_id == currentUser.tenant_id && t.dispatch_status == viewModel.dispatch_status).ToListAsync(); if (entities.Count == 0) { - return (false, _stringLocalizer["status_changed"]); + return (false, "[202]" + _stringLocalizer["status_changed"]); } var time = DateTime.Now; var dispatch_id_list = entities.Select(t => t.id).ToList(); @@ -914,7 +932,7 @@ namespace ModernWMS.WMS.Services var proposedValues = entry.CurrentValues; var databaseValues = entry.GetDatabaseValues(); if (UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != viewModel.dispatch_status) - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); // Refresh original values to bypass next concurrency check entry.OriginalValues.SetValues(databaseValues); } @@ -931,7 +949,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } @@ -947,7 +965,7 @@ namespace ModernWMS.WMS.Services var time = DateTime.Now; if (entity == null) { - return (false, _stringLocalizer["not_exists_entity"]); + return (false, "[202]" + _stringLocalizer["not_exists_entity"]); } if (entity.dispatch_status == 4) { @@ -981,7 +999,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["status_changed"]); + return (false, "[202]" + _stringLocalizer["status_changed"]); } entity.last_update_time = time; var qty = await _dBContext.SaveChangesAsync(); @@ -991,7 +1009,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } @@ -1026,7 +1044,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } @@ -1049,11 +1067,11 @@ namespace ModernWMS.WMS.Services var entity = entities.FirstOrDefault(t => t.id == vm.id && t.dispatch_status == vm.dispatch_status); if (entity == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } if ((entity.package_qty + vm.package_qty) > entity.picked_qty) { - return (false, _stringLocalizer["unpackgeqty_lessthen"]); + return (false, "[202]" + _stringLocalizer["unpackgeqty_lessthen"]); } entity.last_update_time = time; entity.package_person = currentUser.user_name; @@ -1083,11 +1101,11 @@ namespace ModernWMS.WMS.Services var t_vm = viewModels.FirstOrDefault(t => t.id == UtilConvert.ObjToInt(databaseValues["id"])); if (t_vm == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } if (UtilConvert.ObjToInt(databaseValues["package_qty"]) + t_vm.package_qty > t_vm.picked_qty) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } else { @@ -1114,7 +1132,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false,"[202]"+ _stringLocalizer["operation_failed"]); } } @@ -1137,11 +1155,11 @@ namespace ModernWMS.WMS.Services var entity = entities.FirstOrDefault(t => t.id == vm.id && t.dispatch_status == vm.dispatch_status); if (entity == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } if ((entity.weighing_qty + vm.weighing_qty) > entity.picked_qty) { - return (false, _stringLocalizer["unweightqty_lessthen"]); + return (false, "[202]" + _stringLocalizer["unweightqty_lessthen"]); } entity.last_update_time = time; entity.weighing_person = currentUser.user_name; @@ -1172,11 +1190,11 @@ namespace ModernWMS.WMS.Services var t_vm = viewModels.FirstOrDefault(t => t.id == UtilConvert.ObjToInt(databaseValues["id"])); if (t_vm == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } if (UtilConvert.ObjToInt(databaseValues["weighing_qty"]) + t_vm.weighing_qty > t_vm.picked_qty) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } else { @@ -1204,7 +1222,7 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } @@ -1227,7 +1245,7 @@ namespace ModernWMS.WMS.Services { if (entity.dispatch_status != 3 && entity.dispatch_status != 4 && entity.dispatch_status != 5) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } entity.last_update_time = time; entity.dispatch_status = 6; @@ -1240,14 +1258,14 @@ namespace ModernWMS.WMS.Services var picks_g = pick_sql.AsNoTracking().GroupBy(e => new { e.goods_location_id, e.sku_id, e.goods_owner_id }).Select(c => new { c.Key.goods_location_id, c.Key.sku_id, c.Key.goods_owner_id, picked_qty = c.Sum(t => t.picked_qty) }); var picks = await picks_g.ToListAsync(); var stocks = await (from stock in stock_DBSet - where picks_g.Any(t => t.goods_location_id == stock.goods_location_id && t.sku_id == stock.sku_id && t.goods_owner_id == stock.goods_owner_id) + where pick_sql.Any(t => t.goods_location_id == stock.goods_location_id && t.sku_id == stock.sku_id && t.goods_owner_id == stock.goods_owner_id) select stock).ToListAsync(); foreach (var pick in picks) { var s = stocks.FirstOrDefault(t => t.goods_location_id == pick.goods_location_id && t.sku_id == pick.sku_id && t.goods_owner_id == pick.goods_owner_id); if (s == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } s.qty -= pick.picked_qty; s.last_update_time = time; @@ -1258,6 +1276,7 @@ namespace ModernWMS.WMS.Services pick.is_update_stock = true; pick.last_update_time = DateTime.Now; } + pick_DBSet.UpdateRange(pick_datas); var saved = false; int res = 0; while (!saved) @@ -1278,7 +1297,7 @@ namespace ModernWMS.WMS.Services var databaseValues = entry.GetDatabaseValues(); if (UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != 3 && UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != 4 && UtilConvert.ObjToInt(databaseValues["dispatch_status"]) != 5) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } proposedValues["last_update_time"] = DateTime.Now; } @@ -1289,7 +1308,7 @@ namespace ModernWMS.WMS.Services var t_p = picks.FirstOrDefault(t => t.goods_location_id == UtilConvert.ObjToInt(databaseValues["goods_location_id"]) && t.sku_id == UtilConvert.ObjToInt(databaseValues["sku_id"]) && t.goods_owner_id == UtilConvert.ObjToInt(databaseValues["goods_owner_id"])); if (t_p == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } proposedValues["qty"] = UtilConvert.ObjToInt(databaseValues["qty"]) - t_p.picked_qty; proposedValues["last_update_time"] = DateTime.Now; @@ -1309,9 +1328,10 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } + /// /// set dispatchlist freightfee /// @@ -1354,9 +1374,10 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } + /// /// sign for arrival /// @@ -1372,7 +1393,7 @@ namespace ModernWMS.WMS.Services var vm = viewModels.FirstOrDefault(t => t.id == t.id && t.dispatch_status == entity.dispatch_status); if (vm == null) { - return (false, _stringLocalizer["data_changed"]); + return (false, "[202]" + _stringLocalizer["data_changed"]); } entity.sign_qty = entity.actual_qty - vm.damage_qty; entity.damage_qty = vm.damage_qty; @@ -1386,9 +1407,10 @@ namespace ModernWMS.WMS.Services } else { - return (false, _stringLocalizer["operation_failed"]); + return (false, "[202]" + _stringLocalizer["operation_failed"]); } } + /// /// get next order code number /// @@ -1432,7 +1454,106 @@ namespace ModernWMS.WMS.Services long timeStamp = Convert.ToInt32(DateTime.Now.Subtract(_dtStart).TotalSeconds); return date + timeStamp.ToString(); } - #endregion - } -} + /// + /// Excel Import + /// + /// viewModels + /// currentUser + /// + public async Task<(bool flag, string msg)> Import(List viewModels, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet(); + var import_sku_code = viewModels.Select(e => e.sku_code).ToList(); + var import_customer_name = viewModels.Select(e => e.customer_name).ToList(); + var sku_list = await (from sku in _dBContext.GetDbSet() + join spu in _dBContext.GetDbSet() on sku.spu_id equals spu.id + where spu.tenant_id == currentUser.tenant_id && import_sku_code.Contains(sku.sku_code) + select sku).ToListAsync(); + var customer_list = await _dBContext.GetDbSet().Where(t => t.tenant_id == currentUser.tenant_id && import_customer_name.Contains(t.customer_name)).ToListAsync(); + var entities = new List(); + var groups = viewModels.Select(t => t.import_group).Distinct().ToList(); + var groups_code = await GetOrderCodeList(currentUser, groups.Count()); + var group_code_dic = new Dictionary(); + for (int i = 0; i < groups.Count(); i++) + { + group_code_dic.Add(groups[i], groups_code[i]); + } + foreach (var vm in viewModels) + { + var customer = customer_list.FirstOrDefault(t => t.customer_name == vm.customer_name); + if (customer == null) + { + return (false, _stringLocalizer["customer_name"] + ":" + vm.customer_name + " " + _stringLocalizer["not_exists_entity"]); + } + var sku = sku_list.FirstOrDefault(t => t.sku_code == vm.sku_code); + if (sku == null) + { + return (false, _stringLocalizer["sku_name"] + ":" + vm.sku_name + "-" + _stringLocalizer["sku_code"] + ":" + vm.sku_code + " " + _stringLocalizer["not_exists_entity"]); + } + entities.Add(new DispatchlistEntity + { + customer_id = customer.id, + customer_name = vm.customer_name, + sku_id = sku.id, + qty = vm.qty, + creator = currentUser.user_name, + create_time = DateTime.Now, + last_update_time = DateTime.Now, + tenant_id = currentUser.tenant_id, + dispatch_no = group_code_dic[vm.import_group], + }); + } + await DbSet.AddRangeAsync(entities); + var qty = await _dBContext.SaveChangesAsync(); + if (qty > 0) + { + return (true, _stringLocalizer["save_success"]); + } + else + { + return (false, _stringLocalizer["save_failed"]); + } + } + /// + /// get next order code number + /// + /// + public async Task> GetOrderCodeList(CurrentUser currentUser, int cnt) + { + List code = new List(); + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await _dBContext.GetDbSet().Where(t => t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.dispatch_no); + if (maxNo == null) + { + for (int i = 1; i <= cnt; i++) + { + code.Add(date + "-" + i.ToString("0000")); + } + } + else + { + string maxDate = maxNo.Substring(0, 8); + string maxDateNo = maxNo.Substring(9, 4); + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + for (int i = 1; i <= cnt; i++) + { + code.Add(date + "-" + (dd + i).ToString("0000")); + } + } + else + { + for (int i = 1; i <= cnt; i++) + { + code.Add(date + "-" + i.ToString("0000")); + } + } + } + + return code; + } + #endregion Api + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs b/backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs index 1b7d32d..4973b5a 100644 --- a/backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs +++ b/backend/ModernWMS.WMS/Services/Goodslocation/GoodslocationService.cs @@ -212,12 +212,12 @@ /// public async Task<(bool flag, string msg)> DeleteAsync(int id) { - var exist_stock = await _dBContext.GetDbSet().AsNoTracking().Where(t => t.qty > 0 && t.goods_location_id == id).AnyAsync(); + var exist_stock =await _dBContext.GetDbSet().AsNoTracking().Where(t=>t.qty>0&&t.goods_location_id == id ).AnyAsync(); if (exist_stock) { return (false, _stringLocalizer["location_exist_stock_not_delete"]); } - var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)).ExecuteDeleteAsync(); if (qty > 0) { return (true, _stringLocalizer["delete_success"]); diff --git a/backend/ModernWMS.WMS/Services/Stock/StockService.cs b/backend/ModernWMS.WMS/Services/Stock/StockService.cs index d47d3d5..d63e5f0 100644 --- a/backend/ModernWMS.WMS/Services/Stock/StockService.cs +++ b/backend/ModernWMS.WMS/Services/Stock/StockService.cs @@ -2,6 +2,7 @@ * date:2022-12-22 * developer:NoNo */ + using Mapster; using Microsoft.EntityFrameworkCore; using ModernWMS.Core.DBContext; @@ -25,6 +26,7 @@ namespace ModernWMS.WMS.Services public class StockService : BaseService, IStockService { #region Args + /// /// The DBContext /// @@ -34,9 +36,11 @@ namespace ModernWMS.WMS.Services /// Localizer Service /// private readonly IStringLocalizer _stringLocalizer; - #endregion + + #endregion Args #region constructor + /// ///Stock constructor /// @@ -50,11 +54,11 @@ namespace ModernWMS.WMS.Services this._dBContext = dBContext; this._stringLocalizer = stringLocalizer; } - #endregion + + #endregion constructor #region Api - /// /// stock page search /// @@ -80,15 +84,15 @@ namespace ModernWMS.WMS.Services var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); var move_DBSet = _dBContext.GetDbSet(); var stock_group_datas = from stock in DbSet.AsNoTracking() - join gl in _dBContext.GetDbSet().AsNoTracking() on stock.goods_location_id equals gl.id - group new { stock ,gl} by stock.sku_id into sg + join gl in _dBContext.GetDbSet().AsNoTracking() on stock.goods_location_id equals gl.id + group new { stock, gl } by stock.sku_id into sg select new { sku_id = sg.Key, qty_frozen = sg.Where(t => t.stock.is_freeze == true).Sum(e => e.stock.qty), qty = sg.Sum(t => t.stock.qty), - qty_normal = sg.Where(t=>t.gl.warehouse_area_property != 5).Sum(t=>t.stock.qty), - qty_normal_frozen = sg.Where(t=>t.gl.warehouse_area_property != 5 && t.stock.is_freeze == true).Sum(t=>t.stock.qty), + qty_normal = sg.Where(t => t.gl.warehouse_area_property != 5).Sum(t => t.stock.qty), + qty_normal_frozen = sg.Where(t => t.gl.warehouse_area_property != 5 && t.stock.is_freeze == true).Sum(t => t.stock.qty), }; var asn_group_datas = from asn in asn_DBSet.AsNoTracking() group asn by asn.sku_id into ag @@ -111,7 +115,7 @@ namespace ModernWMS.WMS.Services var process_locked_group_datas = from pd in processdetail_DBSet join gl in _dBContext.GetDbSet().AsNoTracking() on pd.goods_location_id equals gl.id where pd.is_update_stock == false && pd.is_source == true - group new { pd , gl } by pd.sku_id into pdg + group new { pd, gl } by pd.sku_id into pdg select new { sku_id = pdg.Key, @@ -121,16 +125,16 @@ namespace ModernWMS.WMS.Services var move_locked_group_datas = from m in move_DBSet.AsNoTracking() join gl in _dBContext.GetDbSet().AsNoTracking() on m.orig_goods_location_id equals gl.id where m.move_status == 0 - group new { m , gl } by m.sku_id into mg + group new { m, gl } by m.sku_id into mg select new { sku_id = mg.Key, qty_locked = mg.Sum(t => t.m.qty), - qty_normal_locked = mg.Where(t=>t.gl.warehouse_area_property !=5).Sum(t => t.m.qty), + qty_normal_locked = mg.Where(t => t.gl.warehouse_area_property != 5).Sum(t => t.m.qty), }; var query = from sku in sku_DBSet - join ag in asn_group_datas on sku.id equals ag.sku_id into ag_left + join ag in asn_group_datas on sku.id equals ag.sku_id into ag_left from ag in ag_left.DefaultIfEmpty() join sg in stock_group_datas on sku.id equals sg.sku_id into sg_left from sg in sg_left.DefaultIfEmpty() @@ -141,24 +145,24 @@ namespace ModernWMS.WMS.Services join m in move_locked_group_datas on sku.id equals m.sku_id into m_left from m in m_left.DefaultIfEmpty() join spu in spu_DBSet on sku.spu_id equals spu.id - where spu.tenant_id == currentUser.tenant_id + where spu.tenant_id == currentUser.tenant_id select new StockManagementViewModel { sku_id = sku.id, spu_name = spu.spu_name, spu_code = spu.spu_code, sku_code = sku.sku_code, - qty_asn = ag.qty_asn == null ? 0: ag.qty_asn, - qty_available = (sg.qty_normal == null ? 0 : sg.qty_normal) - (sg.qty_normal_frozen == null ? 0 : sg.qty_normal_frozen) - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_normal_locked == null ? 0 : pl.qty_normal_locked) - (m.qty_normal_locked == null ? 0 : m.qty_normal_locked) , + qty_asn = ag.qty_asn == null ? 0 : ag.qty_asn, + qty_available = (sg.qty_normal == null ? 0 : sg.qty_normal) - (sg.qty_normal_frozen == null ? 0 : sg.qty_normal_frozen) - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_normal_locked == null ? 0 : pl.qty_normal_locked) - (m.qty_normal_locked == null ? 0 : m.qty_normal_locked), qty_frozen = sg.qty_frozen == null ? 0 : sg.qty_frozen, - qty_locked = (dp.qty_locked == null ? 0 : dp.qty_locked) + (pl.qty_locked == null ? 0 : pl.qty_locked) + (m.qty_locked == null ? 0:m.qty_locked), - qty_sorted = ag.qty_sorted==null?0:ag.qty_sorted, + qty_locked = (dp.qty_locked == null ? 0 : dp.qty_locked) + (pl.qty_locked == null ? 0 : pl.qty_locked) + (m.qty_locked == null ? 0 : m.qty_locked), + qty_sorted = ag.qty_sorted == null ? 0 : ag.qty_sorted, qty_to_sort = ag.qty_to_sort == null ? 0 : ag.qty_to_sort, shortage_qty = ag.shortage_qty == null ? 0 : ag.shortage_qty, qty_to_unload = ag.qty_to_unload == null ? 0 : ag.qty_to_unload, qty = sg.qty == null ? 0 : sg.qty, }; - query = query.Where(t=>t.qty_asn>0 || t.qty > 0).Where(queries.AsExpression()); + query = query.Where(t => t.qty_asn > 0 || t.qty > 0).Where(queries.AsExpression()); int totals = await query.CountAsync(); var list = await query.OrderBy(t => t.sku_code) .Skip((pageSearch.pageIndex - 1) * pageSearch.pageSize) @@ -195,11 +199,12 @@ namespace ModernWMS.WMS.Services var stock_group_datas = from stock in DbSet.AsNoTracking() where stock.tenant_id == currentUser.tenant_id - group stock by new { stock.sku_id, stock.goods_location_id } into sg + group stock by new { stock.sku_id, stock.goods_location_id, stock.goods_owner_id } into sg select new { sku_id = sg.Key.sku_id, goods_location_id = sg.Key.goods_location_id, + sg.Key.goods_owner_id, qty_frozen = sg.Where(t => t.is_freeze == true).Sum(e => e.qty), qty = sg.Sum(t => t.qty) }; @@ -207,38 +212,41 @@ namespace ModernWMS.WMS.Services var dispatch_group_datas = from dp in dispatch_DBSet.AsNoTracking() join dpp in dispatchpick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id where dp.dispatch_status > 1 && dp.dispatch_status < 6 - group dpp by new { dpp.sku_id, dpp.goods_location_id } into dg + group dpp by new { dpp.sku_id, dpp.goods_location_id, dpp.goods_owner_id } into dg select new { sku_id = dg.Key.sku_id, goods_location_id = dg.Key.goods_location_id, + dg.Key.goods_owner_id, qty_locked = dg.Sum(t => t.pick_qty) }; var process_locked_group_datas = from pd in processdetail_DBSet where pd.is_update_stock == false && pd.is_source == true - group pd by new { pd.sku_id, pd.goods_location_id } into pdg + group pd by new { pd.sku_id, pd.goods_location_id, pd.goods_owner_id } into pdg select new { sku_id = pdg.Key.sku_id, goods_location_id = pdg.Key.goods_location_id, + pdg.Key.goods_owner_id, qty_locked = pdg.Sum(t => t.qty) }; var move_locked_group_datas = from m in move_DBSet.AsNoTracking() where m.move_status == 0 - group m by new { m.sku_id, m.orig_goods_location_id } into mg + group m by new { m.sku_id, m.orig_goods_location_id, m.goods_owner_id } into mg select new { sku_id = mg.Key.sku_id, goods_location_id = mg.Key.orig_goods_location_id, + mg.Key.goods_owner_id, qty_locked = mg.Sum(t => t.qty) }; var query = from sg in stock_group_datas - join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { dp.sku_id, dp.goods_location_id } into dp_left + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { dp.sku_id, dp.goods_location_id, dp.goods_owner_id } into dp_left from dp in dp_left.DefaultIfEmpty() - join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { pl.sku_id, pl.goods_location_id } into pl_left + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { pl.sku_id, pl.goods_location_id, pl.goods_owner_id } into pl_left from pl in pl_left.DefaultIfEmpty() - join m in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { m.sku_id, m.goods_location_id } into m_left + join m in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { m.sku_id, m.goods_location_id, m.goods_owner_id } into m_left from m in m_left.DefaultIfEmpty() join sku in sku_DBSet on sg.sku_id equals sku.id join spu in spu_DBSet on sku.spu_id equals spu.id @@ -250,12 +258,13 @@ namespace ModernWMS.WMS.Services spu_code = spu.spu_code, sku_code = sku.sku_code, sku_name = sku.sku_name, - qty_available =gl.warehouse_area_property == 5?0:( sg.qty - sg.qty_frozen - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (m.qty_locked == null ? 0 : m.qty_locked)), + qty_available = gl.warehouse_area_property == 5 ? 0 : (sg.qty - sg.qty_frozen - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (m.qty_locked == null ? 0 : m.qty_locked)), qty_frozen = sg.qty_frozen, - qty_locked = (dp.qty_locked == null ? 0 : dp.qty_locked) + (pl.qty_locked == null ? 0 : pl.qty_locked)+ (m.qty_locked == null ? 0 : m.qty_locked), + qty_locked = (dp.qty_locked == null ? 0 : dp.qty_locked) + (pl.qty_locked == null ? 0 : pl.qty_locked) + (m.qty_locked == null ? 0 : m.qty_locked), qty = sg.qty, location_name = gl.location_name, warehouse_name = gl.warehouse_name, + goods_location_id = sg.goods_owner_id, }; query = query.Where(t => t.qty > 0).Where(queries.AsExpression()); int totals = await query.CountAsync(); @@ -336,8 +345,25 @@ namespace ModernWMS.WMS.Services join owner in _dBContext.GetDbSet().AsNoTracking() on sg.goods_owner_id equals owner.id into o_left from owner in o_left.DefaultIfEmpty() where sg.tenant_id == currentUser.tenant_id - group new {sg,dp,pl,m,sku,spu,gl} by new { sg.sku_id ,spu.spu_name , spu.spu_code, sku.sku_code,sku.sku_name,sg.goods_location_id,sg.goods_owner_id,owner.goods_owner_name - , sg.qty , gl.location_name, sg.is_freeze, gl.warehouse_name ,sg.id,sku.unit,sg.tenant_id} into g + group new { sg, dp, pl, m, sku, spu, gl } by new + { + sg.sku_id, + spu.spu_name, + spu.spu_code, + sku.sku_code, + sku.sku_name, + sg.goods_location_id, + sg.goods_owner_id, + owner.goods_owner_name + , + sg.qty, + gl.location_name, + sg.is_freeze, + gl.warehouse_name, + sg.id, + sku.unit, + sg.tenant_id + } into g select new StockViewModel { sku_id = g.Key.sku_id, @@ -345,9 +371,9 @@ namespace ModernWMS.WMS.Services spu_code = g.Key.spu_code, sku_code = g.Key.sku_code, sku_name = g.Key.sku_name, - qty_available = g.Key.is_freeze ? 0 : (g.Key.qty - g.Sum(t=>t.dp.qty_locked == null ? 0 : t.dp.qty_locked) - g.Sum(t => t.pl.qty_locked == null ? 0 : t.pl.qty_locked) - g.Sum(t=>(t.m.qty_locked == null ? 0 : t.m.qty_locked))), + qty_available = g.Key.is_freeze ? 0 : (g.Key.qty - g.Sum(t => t.dp.qty_locked == null ? 0 : t.dp.qty_locked) - g.Sum(t => t.pl.qty_locked == null ? 0 : t.pl.qty_locked) - g.Sum(t => (t.m.qty_locked == null ? 0 : t.m.qty_locked))), qty = g.Key.qty, - goods_location_id= g.Key.goods_location_id, + goods_location_id = g.Key.goods_location_id, goods_owner_id = g.Key.goods_owner_id, location_name = g.Key.location_name, warehouse_name = g.Key.warehouse_name, @@ -355,17 +381,16 @@ namespace ModernWMS.WMS.Services id = g.Key.id, tenant_id = g.Key.tenant_id, unit = g.Key.unit, - goods_owner_name = g.Key.goods_owner_name == null? "":g.Key.goods_owner_name, + goods_owner_name = g.Key.goods_owner_name == null ? "" : g.Key.goods_owner_name, }; - if(pageSearch.sqlTitle == "") + if (pageSearch.sqlTitle == "") { query = query.Where(t => t.qty_available > 0); } - else if(pageSearch.sqlTitle == "all") + else if (pageSearch.sqlTitle == "all") { - } - else if(pageSearch.sqlTitle == "frozen") + else if (pageSearch.sqlTitle == "frozen") { query = query.Where(t => t.is_freeze == true); } @@ -411,7 +436,7 @@ namespace ModernWMS.WMS.Services supplier_name = spu.supplier_name, brand = spu.brand, origin = spu.origin, - sku_id = sku.id + sku_id = sku.id, }; query = query.Where(queries.AsExpression()); int totals = await query.CountAsync(); @@ -421,7 +446,110 @@ namespace ModernWMS.WMS.Services .ToListAsync(); return (list, totals); } - #endregion - } -} + /// + /// get stock infomation by phone + /// + /// input + /// current user + /// + public async Task> LocationStockForPhoneAsync(LocationStockForPhoneSearchViewModel input, CurrentUser currentUser) + { + var DbSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var dispatchpick_DBSet = _dBContext.GetDbSet(); + var dispatch_DBSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); + var sku_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var spu_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var processdetail_DBSet = _dBContext.GetDbSet().AsNoTracking(); + var move_DBSet = _dBContext.GetDbSet(); + + var stock_group_datas = from stock in DbSet.AsNoTracking() + join gw in _dBContext.GetDbSet().AsNoTracking() on stock.goods_owner_id equals gw.id into gw_left + from gw in gw_left.DefaultIfEmpty() + join gl in _dBContext.GetDbSet().AsNoTracking() on stock.goods_location_id equals gl.id + join sku in _dBContext.GetDbSet().AsNoTracking() on stock.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + where stock.tenant_id == currentUser.tenant_id && (input.sku_id == 0 || stock.sku_id == input.sku_id) + && (input.goods_location_id == 0 || stock.goods_location_id == input.goods_location_id) + && (input.warehouse_id == 0 || gl.warehouse_id == input.warehouse_id) + && (input.spu_name == "" || spu.spu_name.Contains(input.spu_name)) + && (input.location_name == "" || gl.location_name.Contains(input.location_name)) + group new { stock, gw } by new { stock.sku_id, stock.goods_location_id, stock.goods_owner_id, gw.goods_owner_name } into sg + select new + { + sku_id = sg.Key.sku_id, + goods_location_id = sg.Key.goods_location_id, + goods_owner_id = sg.Key.goods_owner_id, + goods_owner_name = sg.Key.goods_owner_name, + qty_frozen = sg.Where(t => t.stock.is_freeze == true).Sum(e => e.stock.qty), + qty = sg.Sum(t => t.stock.qty) + }; + + var dispatch_group_datas = from dp in dispatch_DBSet.AsNoTracking() + join dpp in dispatchpick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id + where dp.dispatch_status > 1 && dp.dispatch_status < 6 + group dpp by new { dpp.sku_id, dpp.goods_location_id, dpp.goods_owner_id } into dg + select new + { + sku_id = dg.Key.sku_id, + goods_location_id = dg.Key.goods_location_id, + goods_owner_id = dg.Key.goods_owner_id, + qty_locked = dg.Sum(t => t.pick_qty) + }; + var process_locked_group_datas = from pd in processdetail_DBSet + where pd.is_update_stock == false && pd.is_source == true + group pd by new { pd.sku_id, pd.goods_location_id, pd.goods_owner_id } into pdg + select new + { + sku_id = pdg.Key.sku_id, + goods_location_id = pdg.Key.goods_location_id, + goods_owner_id = pdg.Key.goods_owner_id, + qty_locked = pdg.Sum(t => t.qty) + }; + + var move_locked_group_datas = from m in move_DBSet.AsNoTracking() + where m.move_status == 0 + group m by new { m.sku_id, m.orig_goods_location_id, m.goods_owner_id } into mg + select new + { + sku_id = mg.Key.sku_id, + goods_location_id = mg.Key.orig_goods_location_id, + goods_owner_id = mg.Key.goods_owner_id, + qty_locked = mg.Sum(t => t.qty) + }; + var query = from sg in stock_group_datas + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { dp.sku_id, dp.goods_location_id, dp.goods_owner_id } into dp_left + from dp in dp_left.DefaultIfEmpty() + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { pl.sku_id, pl.goods_location_id, pl.goods_owner_id } into pl_left + from pl in pl_left.DefaultIfEmpty() + join m in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { m.sku_id, m.goods_location_id, m.goods_owner_id } into m_left + from m in m_left.DefaultIfEmpty() + join sku in sku_DBSet on sg.sku_id equals sku.id + join spu in spu_DBSet on sku.spu_id equals spu.id + join gl in location_DBSet on sg.goods_location_id equals gl.id + select new LocationStockManagementViewModel + { + sku_id = sg.sku_id, + goods_owner_name = sg.goods_owner_name, + spu_name = spu.spu_name, + spu_code = spu.spu_code, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + qty_available = gl.warehouse_area_property == 5 ? 0 : (sg.qty - sg.qty_frozen - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (m.qty_locked == null ? 0 : m.qty_locked)), + qty_frozen = sg.qty_frozen, + qty_locked = (dp.qty_locked == null ? 0 : dp.qty_locked) + (pl.qty_locked == null ? 0 : pl.qty_locked) + (m.qty_locked == null ? 0 : m.qty_locked), + qty = sg.qty, + location_name = gl.location_name, + warehouse_name = gl.warehouse_name, + goods_location_id = sg.goods_location_id + }; + + var list = await query.OrderBy(t => t.sku_code) + .ToListAsync(); + return list; + } + + #endregion Api + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs b/backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs index 8e5c100..7e8097a 100644 --- a/backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs +++ b/backend/ModernWMS.WMS/Services/Stockmove/StockmoveService.cs @@ -2,6 +2,7 @@ * date:2022-12-27 * developer:NoNo */ + using Mapster; using Microsoft.EntityFrameworkCore; using ModernWMS.Core.DBContext; @@ -26,6 +27,7 @@ namespace ModernWMS.WMS.Services public class StockmoveService : BaseService, IStockmoveService { #region Args + /// /// The DBContext /// @@ -35,9 +37,11 @@ namespace ModernWMS.WMS.Services /// Localizer Service /// private readonly IStringLocalizer _stringLocalizer; - #endregion + + #endregion Args #region constructor + /// ///Stockmove constructor /// @@ -51,9 +55,11 @@ namespace ModernWMS.WMS.Services this._dBContext = dBContext; this._stringLocalizer = stringLocalizer; } - #endregion + + #endregion constructor #region Api + /// /// page search /// @@ -120,36 +126,36 @@ namespace ModernWMS.WMS.Services { var DbSet = _dBContext.GetDbSet(); var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); - var data = await(from m in DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)) - join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id - join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id - join orig_location in location_DBSet on m.orig_goods_location_id equals orig_location.id - join dest_location in location_DBSet on m.dest_googs_location_id equals dest_location.id - select new StockmoveViewModel - { - id = m.id, - job_code = m.job_code, - move_status = m.move_status, - sku_id = m.sku_id, - orig_goods_location_id = m.orig_goods_location_id, - dest_googs_location_id = m.dest_googs_location_id, - qty = m.qty, - goods_owner_id = m.goods_owner_id, - handler = m.handler, - handle_time = m.handle_time, - creator = m.creator, - create_time = m.create_time, - last_update_time = m.last_update_time, - tenant_id = m.tenant_id, - sku_code = sku.sku_code, - sku_name = sku.sku_name, - spu_code = spu.spu_code, - spu_name = spu.spu_name, - dest_googs_location_name = dest_location.location_name, - dest_googs_warehouse = dest_location.warehouse_name, - orig_goods_location_name = orig_location.location_name, - orig_goods_warehouse = orig_location.warehouse_name, - } + var data = await (from m in DbSet.AsNoTracking().Where(t => t.tenant_id.Equals(currentUser.tenant_id)) + join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join orig_location in location_DBSet on m.orig_goods_location_id equals orig_location.id + join dest_location in location_DBSet on m.dest_googs_location_id equals dest_location.id + select new StockmoveViewModel + { + id = m.id, + job_code = m.job_code, + move_status = m.move_status, + sku_id = m.sku_id, + orig_goods_location_id = m.orig_goods_location_id, + dest_googs_location_id = m.dest_googs_location_id, + qty = m.qty, + goods_owner_id = m.goods_owner_id, + handler = m.handler, + handle_time = m.handle_time, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + dest_googs_location_name = dest_location.location_name, + dest_googs_warehouse = dest_location.warehouse_name, + orig_goods_location_name = orig_location.location_name, + orig_goods_warehouse = orig_location.warehouse_name, + } ).ToListAsync(); return data.Adapt>(); } @@ -163,42 +169,43 @@ namespace ModernWMS.WMS.Services var DbSet = _dBContext.GetDbSet(); var location_DBSet = _dBContext.GetDbSet().AsNoTracking(); var data = await (from m in DbSet.AsNoTracking() - join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id - join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id - join orig_location in location_DBSet on m.orig_goods_location_id equals orig_location.id - join dest_location in location_DBSet on m.dest_googs_location_id equals dest_location.id - where m.id == id - select new StockmoveViewModel - { - id = m.id, - job_code = m.job_code, - move_status = m.move_status, - sku_id = m.sku_id, - orig_goods_location_id = m.orig_goods_location_id, - dest_googs_location_id = m.dest_googs_location_id, - qty = m.qty, - goods_owner_id = m.goods_owner_id, - handler = m.handler, - handle_time = m.handle_time, - creator = m.creator, - create_time = m.create_time, - last_update_time = m.last_update_time, - tenant_id = m.tenant_id, - sku_code = sku.sku_code, - sku_name = sku.sku_name, - spu_code = spu.spu_code, - spu_name = spu.spu_name, - dest_googs_location_name = dest_location.location_name, - dest_googs_warehouse = dest_location.warehouse_name, - orig_goods_location_name = orig_location.location_name, - orig_goods_warehouse = orig_location.warehouse_name, - }).FirstOrDefaultAsync(); + join sku in _dBContext.GetDbSet().AsNoTracking() on m.sku_id equals sku.id + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + join orig_location in location_DBSet on m.orig_goods_location_id equals orig_location.id + join dest_location in location_DBSet on m.dest_googs_location_id equals dest_location.id + where m.id == id + select new StockmoveViewModel + { + id = m.id, + job_code = m.job_code, + move_status = m.move_status, + sku_id = m.sku_id, + orig_goods_location_id = m.orig_goods_location_id, + dest_googs_location_id = m.dest_googs_location_id, + qty = m.qty, + goods_owner_id = m.goods_owner_id, + handler = m.handler, + handle_time = m.handle_time, + creator = m.creator, + create_time = m.create_time, + last_update_time = m.last_update_time, + tenant_id = m.tenant_id, + sku_code = sku.sku_code, + sku_name = sku.sku_name, + spu_code = spu.spu_code, + spu_name = spu.spu_name, + dest_googs_location_name = dest_location.location_name, + dest_googs_warehouse = dest_location.warehouse_name, + orig_goods_location_name = orig_location.location_name, + orig_goods_warehouse = orig_location.warehouse_name, + }).FirstOrDefaultAsync(); if (data == null) { return null; } return data; } + /// /// add a new record /// @@ -215,65 +222,72 @@ namespace ModernWMS.WMS.Services var dispatch_DBSet = _dBContext.GetDbSet().Where(t => t.tenant_id.Equals(currentUser.tenant_id)); var dispatch_group_datas = from dp in dispatch_DBSet.AsNoTracking() join dpp in dispatchpick_DBSet.AsNoTracking() on dp.id equals dpp.dispatchlist_id - where dp.dispatch_status > 1 && dp.dispatch_status < 6 - && dpp.goods_location_id == entity.orig_goods_location_id && dpp.sku_id == entity.sku_id - group dpp by new { dpp.sku_id, dpp.goods_location_id } into dg + where dp.dispatch_status > 1 && dp.dispatch_status < 6 + && dpp.goods_location_id == entity.orig_goods_location_id && dpp.sku_id == entity.sku_id + && dpp.goods_owner_id == entity.goods_owner_id + group dpp by new { dpp.sku_id, dpp.goods_location_id, dpp.goods_owner_id } into dg select new { sku_id = dg.Key.sku_id, goods_location_id = dg.Key.goods_location_id, + goods_owner_id = dg.Key.goods_location_id, qty_locked = dg.Sum(t => t.pick_qty) }; var process_locked_group_datas = from pd in processdetail_DBSet where pd.is_update_stock == false && pd.sku_id == entity.sku_id && pd.goods_location_id == entity.orig_goods_location_id - group pd by new { pd.sku_id, pd.goods_location_id } into pdg + && pd.goods_owner_id == entity.goods_owner_id + group pd by new { pd.sku_id, pd.goods_location_id, pd.goods_owner_id } into pdg select new { sku_id = pdg.Key.sku_id, goods_location_id = pdg.Key.goods_location_id, + pdg.Key.goods_owner_id, qty_locked = pdg.Sum(t => t.qty) }; var move_locked_group_datas = from sm in DbSet.AsNoTracking() where sm.move_status == 0 && sm.sku_id == entity.sku_id && sm.orig_goods_location_id == entity.orig_goods_location_id - group sm by new { sm.sku_id, goods_location_id = sm.orig_goods_location_id } into smg - select new { - smg.Key.sku_id, - smg.Key.goods_location_id, - qty_locked = smg.Sum(t => t.qty) + && sm.goods_owner_id == entity.goods_owner_id + group sm by new { sm.sku_id, goods_location_id = sm.orig_goods_location_id, sm.goods_owner_id } into smg + select new + { + smg.Key.sku_id, + smg.Key.goods_location_id, + smg.Key.goods_owner_id, + qty_locked = smg.Sum(t => t.qty) }; - var orig_stock =await + var orig_stock = await (from sg in stock_DBSet.AsNoTracking() - join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { dp.sku_id, dp.goods_location_id } into dp_left + join dp in dispatch_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { dp.sku_id, dp.goods_location_id, dp.goods_owner_id } into dp_left from dp in dp_left.DefaultIfEmpty() - join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id } equals new { pl.sku_id, pl.goods_location_id } into pl_left + join pl in process_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { pl.sku_id, pl.goods_location_id, pl.goods_owner_id } into pl_left from pl in pl_left.DefaultIfEmpty() - join sm in move_locked_group_datas on new {sg.sku_id,sg.goods_location_id} equals new {sm.sku_id, goods_location_id = sm.goods_location_id} into sm_left + join sm in move_locked_group_datas on new { sg.sku_id, sg.goods_location_id, sg.goods_owner_id } equals new { sm.sku_id, goods_location_id = sm.goods_location_id, sm.goods_owner_id } into sm_left from sm in sm_left.DefaultIfEmpty() - where sg.sku_id == entity.sku_id && sg.goods_location_id == entity.orig_goods_location_id + where sg.sku_id == entity.sku_id && sg.goods_location_id == entity.orig_goods_location_id && sg.goods_owner_id == entity.goods_owner_id select new { id = sg.id, - qty_available = sg.is_freeze ? 0 : (sg.qty - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (sm.qty_locked == null ? 0 : sm.qty_locked)) , + qty_available = sg.is_freeze ? 0 : (sg.qty - (dp.qty_locked == null ? 0 : dp.qty_locked) - (pl.qty_locked == null ? 0 : pl.qty_locked) - (sm.qty_locked == null ? 0 : sm.qty_locked)), } ).FirstOrDefaultAsync(); - var dest_stock = await stock_DBSet.FirstOrDefaultAsync(t => t.goods_location_id == entity.dest_googs_location_id && t.sku_id == entity.sku_id); - if(orig_stock == null || orig_stock.qty_available t.goods_location_id == entity.dest_googs_location_id && t.sku_id == entity.sku_id && t.goods_owner_id == entity.goods_owner_id); + if (orig_stock == null || orig_stock.qty_available < entity.qty) { return (0, _stringLocalizer["qty_not_available"]); } - if(dest_stock!=null && dest_stock.is_freeze == true) + if (dest_stock != null && dest_stock.is_freeze == true) { return (0, _stringLocalizer["dest_stock_freeze"]); } entity.id = 0; - entity.move_status= 0; + entity.move_status = 0; entity.create_time = DateTime.Now; entity.creator = currentUser.user_name; entity.last_update_time = DateTime.Now; entity.tenant_id = currentUser.tenant_id; - entity.job_code =await GetOrderCode(currentUser); + entity.job_code = await GetOrderCode(currentUser); await DbSet.AddAsync(entity); await _dBContext.SaveChangesAsync(); if (entity.id > 0) @@ -285,16 +299,17 @@ namespace ModernWMS.WMS.Services return (0, _stringLocalizer["save_failed"]); } } + /// /// confirm move /// /// id /// current user /// - public async Task<(bool flag, string msg)> Confirm(int id,CurrentUser currentUser) + public async Task<(bool flag, string msg)> Confirm(int id, CurrentUser currentUser) { var DbSet = _dBContext.GetDbSet(); - var stock_DBSet = _dBContext.GetDbSet(); + var stock_DBSet = _dBContext.GetDbSet(); var entity = await DbSet.FirstOrDefaultAsync(t => t.id.Equals(id)); if (entity == null) { @@ -304,21 +319,21 @@ namespace ModernWMS.WMS.Services entity.handle_time = DateTime.Now; entity.move_status = 1; entity.last_update_time = DateTime.Now; - var orig_stock = await stock_DBSet.FirstOrDefaultAsync(t => t.goods_location_id == entity.orig_goods_location_id && t.sku_id == entity.sku_id) ; - var dest_stock = await stock_DBSet.FirstOrDefaultAsync(t=>t.goods_location_id == entity.dest_googs_location_id && t.sku_id!= entity.sku_id); + var orig_stock = await stock_DBSet.FirstOrDefaultAsync(t => t.goods_location_id == entity.orig_goods_location_id && t.goods_owner_id == entity.goods_owner_id && t.sku_id == entity.sku_id); + var dest_stock = await stock_DBSet.FirstOrDefaultAsync(t => t.goods_location_id == entity.dest_googs_location_id && t.goods_owner_id == entity.goods_owner_id && t.sku_id == entity.sku_id); if (orig_stock != null) { - if(orig_stock.qty == entity.qty) + if (orig_stock.qty == entity.qty) { stock_DBSet.Remove(orig_stock); } else { orig_stock.qty -= entity.qty; - orig_stock.last_update_time=DateTime.Now; + orig_stock.last_update_time = DateTime.Now; } } - if(dest_stock == null) + if (dest_stock == null) { dest_stock = new StockEntity { @@ -361,7 +376,7 @@ namespace ModernWMS.WMS.Services { throw new NotSupportedException(_stringLocalizer["try_agin"]); } - else if(UtilConvert.ObjToInt(databaseValues["qty"]) - entity.qty==0) + else if (UtilConvert.ObjToInt(databaseValues["qty"]) - entity.qty == 0) { entry.State = EntityState.Deleted; } @@ -371,7 +386,7 @@ namespace ModernWMS.WMS.Services proposedValues["qty"] = UtilConvert.ObjToInt(databaseValues["qty"]) - entity.qty; } } - else if(UtilConvert.ObjToInt(proposedValues["id"]) == dest_stock.id) + else if (UtilConvert.ObjToInt(proposedValues["id"]) == dest_stock.id) { proposedValues["qty"] = UtilConvert.ObjToInt(databaseValues["qty"]) + entity.qty; } @@ -394,6 +409,7 @@ namespace ModernWMS.WMS.Services return (false, _stringLocalizer["operation_failed"]); } } + /// /// delete a record /// @@ -401,7 +417,7 @@ namespace ModernWMS.WMS.Services /// public async Task<(bool flag, string msg)> DeleteAsync(int id) { - var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id)&&t.move_status == 0).ExecuteDeleteAsync(); + var qty = await _dBContext.GetDbSet().Where(t => t.id.Equals(id) && t.move_status == 0).ExecuteDeleteAsync(); if (qty > 0) { return (true, _stringLocalizer["delete_success"]); @@ -420,7 +436,7 @@ namespace ModernWMS.WMS.Services { string code; string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); - string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t=>t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); + string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); if (maxNo == null) { code = date + "-0001"; @@ -443,7 +459,7 @@ namespace ModernWMS.WMS.Services return code; } - #endregion - } -} + #endregion Api + } +} \ No newline at end of file diff --git a/backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs b/backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs index cfc637f..da81f04 100644 --- a/backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs +++ b/backend/ModernWMS.WMS/Services/Stockprocess/StockprocessService.cs @@ -19,6 +19,7 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Mvc.Formatters.Xml; using Microsoft.AspNetCore.SignalR.Protocol; using System.Linq; +using Microsoft.CodeAnalysis; namespace ModernWMS.WMS.Services { @@ -150,7 +151,7 @@ namespace ModernWMS.WMS.Services spu_code = spu.spu_code, spu_name = spu.spu_name, unit = sku.unit, - location_name = gl.location_name == null?"":gl.location_name + location_name = gl.location_name == null ? "" : gl.location_name }).ToListAsync(); if (entity == null) { @@ -163,7 +164,7 @@ namespace ModernWMS.WMS.Services where a.job_type == 2 && d.stock_process_id == id select a ).AnyAsync(); - res.adjust_status =entity.process_status && adjusted; + res.adjust_status = entity.process_status && adjusted; res.source_detail_list = details.Where(t => t.is_source == true).ToList(); res.target_detail_list = details.Where(t => t.is_source == false).ToList(); return res; @@ -226,7 +227,7 @@ namespace ModernWMS.WMS.Services await DbSet.AddAsync(entity); foreach (var d in entity.detailList) { - d.tenant_id =currentUser.tenant_id; + d.tenant_id = currentUser.tenant_id; d.last_update_time = DateTime.Now; d.id = 0; var s = stocks.FirstOrDefault(t => t.sku_id == d.sku_id && t.goods_location_id == d.goods_location_id); @@ -295,7 +296,7 @@ namespace ModernWMS.WMS.Services public async Task<(bool flag, string msg)> DeleteAsync(int id) { var entity = await _dBContext.GetDbSet().Where(t => t.id.Equals(id) && t.process_status == false).Include(e => e.detailList).FirstOrDefaultAsync(); - _dBContext.GetDbSet().Remove(entity); + _dBContext.GetDbSet().Remove(entity); var qty = await _dBContext.SaveChangesAsync(); if (qty > 0) { @@ -359,7 +360,7 @@ namespace ModernWMS.WMS.Services foreach (var d in details) { var stock = stocks.FirstOrDefault(t => t.goods_location_id == d.goods_location_id && t.sku_id == d.sku_id && t.goods_owner_id == d.goods_owner_id); - d.is_update_stock= true; + d.is_update_stock = true; d.last_update_time = DateTime.Now; if (d.is_source) { @@ -372,16 +373,16 @@ namespace ModernWMS.WMS.Services } else { - if(stock == null) + if (stock == null) { await stock_DBSet.AddAsync(new StockEntity { - sku_id= d.sku_id, - goods_location_id= d.goods_location_id, - goods_owner_id= d.goods_owner_id, - is_freeze =false, - last_update_time =DateTime.Now, - qty= d.qty, + sku_id = d.sku_id, + goods_location_id = d.goods_location_id, + goods_owner_id = d.goods_owner_id, + is_freeze = false, + last_update_time = DateTime.Now, + qty = d.qty, tenant_id = currentUser.tenant_id }); } @@ -412,7 +413,7 @@ namespace ModernWMS.WMS.Services { var DBSet = _dBContext.GetDbSet(); var entity = await DBSet.FirstOrDefaultAsync(t => t.id == id); - if(entity == null) + if (entity == null) { return (false, _stringLocalizer["not_exists_entity"]); } @@ -440,8 +441,8 @@ namespace ModernWMS.WMS.Services { string code; string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); - string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t=>t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); - if (maxNo == null) + string maxNo = await _dBContext.GetDbSet().AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.job_code); + if (maxNo == null) { code = date + "-0001"; } @@ -460,7 +461,7 @@ namespace ModernWMS.WMS.Services code = date + "-0001"; } } - + return code; } /// @@ -494,6 +495,181 @@ namespace ModernWMS.WMS.Services return code; } + /// + /// get next order code number + /// + /// + public async Task> GetOrderCodeList(CurrentUser currentUser, int cnt) + { + List code = new List(); + string date = DateTime.Now.ToString("yyyy" + "MM" + "dd"); + string maxNo = await _dBContext.GetDbSet().Where(t => t.tenant_id == currentUser.tenant_id).MaxAsync(t => t.dispatch_no); + if (maxNo == null) + { + for (int i = 1; i <= cnt; i++) + { + code.Add(date + "-" + i.ToString("0000")); + } + } + else + { + string maxDate = maxNo.Substring(0, 8); + string maxDateNo = maxNo.Substring(9, 4); + if (date == maxDate) + { + int.TryParse(maxDateNo, out int dd); + for (int i = 1; i <= cnt; i++) + { + code.Add(date + "-" + (dd + i).ToString("0000")); + } + } + else + { + for (int i = 1; i <= cnt; i++) + { + code.Add(date + "-" + i.ToString("0000")); + } + } + } + + return code; + } + + + /// + /// Excel Import + /// + /// + public async Task<(bool flag, string msg)> Import(List viewModels, CurrentUser currentUser) + { + + var sku_code_list = viewModels.Select(t => t.sku_code).Distinct().ToList(); + var sku_list = await (from sku in _dBContext.GetDbSet().AsNoTracking() + join spu in _dBContext.GetDbSet().AsNoTracking() on sku.spu_id equals spu.id + where sku_code_list.Contains(sku.sku_code) && spu.tenant_id == currentUser.tenant_id + select sku).ToListAsync(); + var location_name_list = viewModels.Select(t => t.location_name).Distinct().ToList(); + var location_list = await (from l in _dBContext.GetDbSet().AsNoTracking() + where location_name_list.Contains(l.location_name) && l.tenant_id == currentUser.tenant_id + select new + { + l.id, + l.location_name + }).ToListAsync(); + var goods_owner_name_list = viewModels.Select(t => t.goods_owner_name).Distinct().ToList(); + var goods_owner_list = await _dBContext.GetDbSet().AsNoTracking().Where(t => goods_owner_name_list.Contains(t.goods_owner_name) && t.tenant_id == currentUser.tenant_id).ToListAsync(); + + var entities = new List(); + var vm_group = viewModels.GroupBy(t => t.import_group); + foreach(var vg in vm_group) + { + if (vg.All(t => t.is_ori==true) || vg.All(t=>t.is_ori == false)) + { + return (false,_stringLocalizer["job_number"]+": " +vg.Key.ToString() +" "+ _stringLocalizer["process_valid"]); + } + } + var groups = vm_group.Select(t => t.Key).ToList(); + var groups_code = await GetOrderCodeList(currentUser, groups.Count()); + var group_code_dic = new Dictionary(); + for (int i = 0; i < groups.Count(); i++) + { + group_code_dic.Add(groups[i], groups_code[i]); + } + var location_id_list = location_list.Select(t => t.id).ToList(); + var sku_id_list = sku_list.Select(t => t.id).ToList(); + + var check_details_all = new List(); + foreach (var vg in vm_group) + { + var ent = new StockprocessEntity(); + ent.creator = currentUser.user_name; + ent.create_time = DateTime.Now; + ent.last_update_time = DateTime.Now; + ent.tenant_id = currentUser.tenant_id; + ent.job_code = group_code_dic[vg.Key]; + ent.job_type = true; + foreach (var v in vg) + { + var sku = sku_list.FirstOrDefault(t => t.sku_code == v.sku_code); + if (sku == null) + { + return (false, _stringLocalizer["sku_name"] + ":" + v.sku_name + "-" + _stringLocalizer["sku_code"] + ":" + v.sku_code + " " + _stringLocalizer["not_exists_entity"]); + } + var area = location_list.FirstOrDefault(t => t.location_name == v.location_name); + if (area == null) + { + return (false, _stringLocalizer["location_name"] + ":" + v.location_name + " " + _stringLocalizer["not_exists_entity"]); + } + var goods_owner = goods_owner_list.FirstOrDefault(t => t.goods_owner_name == v.goods_owner_name); + ent.detailList.Add(new StockprocessdetailEntity + { + sku_id = sku.id, + is_source = v.is_ori, + last_update_time = DateTime.Now, + goods_owner_id = goods_owner == null ? 0 : goods_owner.id, + is_update_stock = false, + qty = v.qty, + goods_location_id = area.id, + tenant_id = currentUser.tenant_id, + + }); + if (v.is_ori) + check_details_all.Add(new StockprocessdetailViewModel + { + sku_id = sku.id, + sku_code = v.sku_code, + goods_location_id = area.id, + qty = v.qty, + goods_owner_id = goods_owner == null ? 0 : goods_owner.id, + location_name = v.location_name + + }); + } + entities.Add(ent); + } + + var check_details_sum = check_details_all.GroupBy(t => new { t.sku_id, t.goods_location_id, t.goods_owner_id, t.sku_code, t.location_name }).Select(t => new + { + t.Key.sku_id, + t.Key.sku_code, + t.Key.goods_location_id, + t.Key.location_name, + t.Key.goods_owner_id, + qty = t.Sum(e=>e.qty), + }).ToList(); + var stocks = await _dBContext.GetDbSet().Where(t => sku_id_list.Contains(t.sku_id) && location_id_list.Contains(t.goods_location_id)).ToListAsync(); + var lockeds = await (from d in _dBContext.GetDbSet().AsNoTracking() + where d.is_update_stock == false && location_id_list.Contains(d.goods_location_id) + && sku_id_list.Contains(d.sku_id) + group d by new { d.goods_location_id, d.sku_id } into lg + select new + { + sku_id = lg.Key.sku_id, + goods_location_id = lg.Key.goods_location_id, + qty_locked = lg.Sum(e => e.qty) + }).ToListAsync(); + foreach (var c in check_details_sum) + { + var s = stocks.FirstOrDefault(t => t.sku_id == c.sku_id && t.goods_location_id == c.goods_location_id); + if (s == null) + { + return (false, _stringLocalizer["sku_code"]+":"+c.sku_code + "-" + _stringLocalizer["location_name"] +c.location_name+" "+ _stringLocalizer["stock_insufficiency"]); + } + var locked = lockeds.FirstOrDefault(t => t.sku_id == c.sku_id && t.goods_location_id == c.goods_location_id ); + if ((s.qty - (locked == null ? 0 : locked.qty_locked)) < c.qty) + { + return (false, _stringLocalizer["sku_code"] + ":" + c.sku_code + "-" + _stringLocalizer["location_name"] + c.location_name + " " + _stringLocalizer["stock_insufficiency"]); + } + if (s.is_freeze == true) + { + return (false, _stringLocalizer["stock_frozen"]); + } + + } + await _dBContext.GetDbSet().AddRangeAsync(entities); + await _dBContext.SaveChangesAsync(); + return (true, ""); + } #endregion } } diff --git a/backend/ModernWMS.WMS/Services/user/UserService.cs b/backend/ModernWMS.WMS/Services/user/UserService.cs index 64ff44e..d7c788d 100644 --- a/backend/ModernWMS.WMS/Services/user/UserService.cs +++ b/backend/ModernWMS.WMS/Services/user/UserService.cs @@ -2,6 +2,7 @@ * date:2022-12-20 * developer:NoNo */ + using Mapster; using Microsoft.EntityFrameworkCore; using ModernWMS.Core.DBContext; @@ -26,6 +27,7 @@ namespace ModernWMS.WMS.Services public class UserService : BaseService, IUserService { #region Args + /// /// The DBContext /// @@ -35,9 +37,11 @@ namespace ModernWMS.WMS.Services /// Localizer Service /// private readonly IStringLocalizer _stringLocalizer; - #endregion + + #endregion Args #region constructor + /// ///User constructor /// @@ -51,9 +55,11 @@ namespace ModernWMS.WMS.Services this._dBContext = dBContext; this._stringLocalizer = stringLocalizer; } - #endregion + + #endregion constructor #region Api + /// /// get select items /// @@ -106,6 +112,7 @@ namespace ModernWMS.WMS.Services .ToListAsync(); return (list.Adapt>(), totals); } + /// /// Get all records /// @@ -113,7 +120,7 @@ namespace ModernWMS.WMS.Services public async Task> GetAllAsync(CurrentUser currentUser) { var DbSet = _dBContext.GetDbSet(); - var data = await DbSet.AsNoTracking().Where(t=>t.tenant_id == currentUser.tenant_id).ToListAsync(); + var data = await DbSet.AsNoTracking().Where(t => t.tenant_id == currentUser.tenant_id).ToListAsync(); return data.Adapt>(); } @@ -131,6 +138,7 @@ namespace ModernWMS.WMS.Services } return entity.Adapt(); } + /// /// add a new record /// @@ -146,7 +154,8 @@ namespace ModernWMS.WMS.Services } var entity = viewModel.Adapt(); entity.id = 0; - entity.auth_string = Md5Helper.Md5Encrypt32("pwd123456"); + var new_auth = GetRandomPassword(); + entity.auth_string = Md5Helper.Md5Encrypt32(new_auth); entity.create_time = DateTime.Now; entity.last_update_time = DateTime.Now; entity.tenant_id = currentUser.tenant_id; @@ -154,13 +163,14 @@ namespace ModernWMS.WMS.Services await _dBContext.SaveChangesAsync(); if (entity.id > 0) { - return (entity.id, _stringLocalizer["save_success"]); + return (entity.id, new_auth); } else { return (0, _stringLocalizer["save_failed"]); } } + /// /// update a record /// @@ -197,6 +207,7 @@ namespace ModernWMS.WMS.Services return (false, _stringLocalizer["save_failed"]); } } + /// /// delete a record /// @@ -214,27 +225,28 @@ namespace ModernWMS.WMS.Services return (false, _stringLocalizer["delete_failed"]); } } + /// /// import users by excel /// /// excel datas /// current user /// - public async Task<(bool flag,string msg)>ExcelAsync(List datas,CurrentUser currentUser) + public async Task<(bool flag, string msg)> ExcelAsync(List datas, CurrentUser currentUser) { StringBuilder sb = new StringBuilder(); var DbSet = _dBContext.GetDbSet(); - var user_num_repeat_excel = datas.GroupBy(t => t.user_num).Select(t=>new { user_num= t.Key,cnt = t.Count()}).Where(t=>t.cnt>1).ToList(); - foreach(var repeat in user_num_repeat_excel) + var user_num_repeat_excel = datas.GroupBy(t => t.user_num).Select(t => new { user_num = t.Key, cnt = t.Count() }).Where(t => t.cnt > 1).ToList(); + foreach (var repeat in user_num_repeat_excel) { sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["user_num"], repeat.user_num)); } if (user_num_repeat_excel.Count > 0) { - return (false,sb.ToString()); + return (false, sb.ToString()); } - var user_num_repeat_exists =await DbSet.Where(t=>t.tenant_id == currentUser.tenant_id).Where(t => datas.Select(t => t.user_num).ToList().Contains(t.user_num)).Select(t=>t.user_num).ToListAsync(); + var user_num_repeat_exists = await DbSet.Where(t => t.tenant_id == currentUser.tenant_id).Where(t => datas.Select(t => t.user_num).ToList().Contains(t.user_num)).Select(t => t.user_num).ToListAsync(); foreach (var repeat in user_num_repeat_exists) { sb.AppendLine(string.Format(_stringLocalizer["exists_entity"], _stringLocalizer["user_num"], repeat)); @@ -245,14 +257,15 @@ namespace ModernWMS.WMS.Services } var entities = datas.Adapt>(); - entities.ForEach(t => { + entities.ForEach(t => + { t.creator = currentUser.user_name; - t.tenant_id= currentUser.tenant_id; + t.tenant_id = currentUser.tenant_id; t.auth_string = Md5Helper.Md5Encrypt32("pwd123456"); t.create_time = DateTime.Now; - t.last_update_time= DateTime.Now; + t.last_update_time = DateTime.Now; t.is_valid = true; - }); + }); await DbSet.AddRangeAsync(entities); var res = await _dBContext.SaveChangesAsync(); if (res > 0) @@ -267,18 +280,18 @@ namespace ModernWMS.WMS.Services /// /// viewmodel /// - public async Task<(bool,string)> ResetPwd(BatchOperationViewModel viewModel) + public async Task<(bool, string)> ResetPwd(BatchOperationViewModel viewModel) { var DBSet = _dBContext.GetDbSet(); - var entities =await DBSet.Where(t => viewModel.id_list.Contains(t.id)).ToListAsync(); + var entities = await DBSet.Where(t => viewModel.id_list.Contains(t.id)).ToListAsync(); var newpassword = GetRandomPassword(); entities.ForEach(t => { t.auth_string = Md5Helper.Md5Encrypt32(newpassword); t.last_update_time = DateTime.Now; }); - var res = await _dBContext.SaveChangesAsync(); + var res = await _dBContext.SaveChangesAsync(); if (res > 0) { return (true, newpassword); } - return (false,_stringLocalizer["operation_failed"]); + return (false, _stringLocalizer["operation_failed"]); } /// @@ -286,21 +299,23 @@ namespace ModernWMS.WMS.Services /// /// viewmodel /// - public async Task<(bool flag,string msg)> ChangePwd(UserChangePwdViewModel viewModel) + public async Task<(bool flag, string msg)> ChangePwd(UserChangePwdViewModel viewModel) { var DBSet = _dBContext.GetDbSet(); - var entity =await DBSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); - if(entity == null) + var entity = await DBSet.FirstOrDefaultAsync(t => t.id.Equals(viewModel.id)); + if (entity == null) { return (false, _stringLocalizer["not_exists_entity"]); } - if (!entity.auth_string.Equals(viewModel.old_password)){ - return(false, _stringLocalizer["old_password"] + _stringLocalizer["is_incorrect"]); + if (!entity.auth_string.Equals(viewModel.old_password)) + { + return (false, _stringLocalizer["old_password"] + _stringLocalizer["is_incorrect"]); } entity.auth_string = viewModel.new_password; await _dBContext.SaveChangesAsync(); return (true, _stringLocalizer["save_success"]); } + /// /// register a new tenant /// @@ -329,7 +344,9 @@ namespace ModernWMS.WMS.Services if (entity.id > 0) { var tenant_id = entity.id; + #region menus + var menus = new List { new MenuEntity @@ -512,15 +529,17 @@ namespace ModernWMS.WMS.Services tenant_id = tenant_id } }; - #endregion + + #endregion menus + entity.tenant_id = tenant_id; entity.creator = entity.user_name; entity.user_role = "admin"; - var adminrole = new UserroleEntity {is_valid = true, last_update_time = time, create_time = time, role_name = "admin", tenant_id = tenant_id }; + var adminrole = new UserroleEntity { is_valid = true, last_update_time = time, create_time = time, role_name = "admin", tenant_id = tenant_id }; await _dBContext.GetDbSet().AddAsync(adminrole); await _dBContext.GetDbSet().AddRangeAsync(menus); await _dBContext.SaveChangesAsync(); - foreach(var menu in menus) + foreach (var menu in menus) { await _dBContext.GetDbSet().AddAsync(new RolemenuEntity { @@ -528,7 +547,7 @@ namespace ModernWMS.WMS.Services authority = 1, menu_id = menu.id, tenant_id = tenant_id, - last_update_time=time, + last_update_time = time, create_time = time, }); } @@ -559,7 +578,6 @@ namespace ModernWMS.WMS.Services return password; } - #endregion + #endregion Api } -} - +} \ No newline at end of file diff --git a/backend/ModernWMS/wms.db-shm b/backend/ModernWMS/wms.db-shm new file mode 100644 index 0000000000000000000000000000000000000000..a43d97a6f6a119abb38c32dbe45e448d4880c2f2 GIT binary patch literal 32768 zcmeI*J5Iwu5CG5#|33-ekkB9{N`Yu8XgCDtpywPEh+ELp(NH4J02M74fY~TQZjf+e z5#^0E-t~IyUB3hDcHhpT#7<@_qJ5n0FmrTseQ|pE@ie&qynF9F-#)&+T=hl|=iQq1 z`KfXA^ZHeZ$?#9Jn7y)wlgvS8xnG^MYuT1(Wvui|&2RnkZmBJG)vSK2j0*w;2oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBmlLZFrV$1UgnaGTMNUK10Vg8%^n1PBly zK!5;&#s!w*sPQ>XNZ@}6ti*b3MJM*-AP%D&{V2P=3jzcPOryYjY{d5XyoYIAy)_dc zK!5-N0tD&^EW~b|ax#q_ca~RKdJBt&=cPsn6Z%?POR9-k@Y*bS>N1{^^1(63v#a z>ZO#@k$DSjFg6m0k7=N^Yg4kYwXkJl&q=l_ z#WHrcSeBjd!&$bTll|w%{j#&$xTqNK8&{2a;}zqwd_qG20R#|0009ILKmY**5I_Kd zHWTRX)=a%PQSR>YzURwZI<-NyFg=;cWv0qzpQa7!8Xu9q^!Qes6Q&FsvUJf0Lw|oopdZ2wGzo?y5-=*@@xBITtL{v z;cL;MXL@C)YTQudK|=rm1Q0*~0R#|0009ILKmdVFD4=P&E~nM7zCh>k{_-RD&s6FN zdW`29))$aZX$T;I00IagfB*srAbxu}xwFf>tm5{Ox`2yda`@~ZZ{>6F9iwpRSGdJZ6$PO9; z2q1s}0tg_000IagfB*srv{bnf>yPtcUI)aV-;o;g5KmY** z5I_I{1Q0*~0R%RYz>+!wZ4K)P-Z=crCw?&SsU2QiKnv`x)Dg&UGz1Vp009ILKmY** z5I_I{1XdK78PFDU_Cui+*V=a$a`r7d=Kak(6%|X?+m|``R$5q5H=anwEqAqf`yak1 zWl={Uvk2;P1)A(f&`?JZj{o%9A3yf9e^%=Vjw{CT6>mE)KmY**5I_I{1Q0*~0R#|0 z0D)U8u)kVGAPWf0P}3@c#xjCiS4VKpj1*4(=09Jfj^NhbP<|T%2q1s}0tg_000Iag zfB*vjqrj3ng3dLpBiJ_gPI=F#Z+y~=3v~MD7U~G(4>SZ2KmY**5I_I{1Q0*~fwmHu z8R+~7Is37?oc)-Wv!807v+u;Caob9!Qi;{)>@U8@b*Uo|OP2n#H^zPh%J7Nn$F2-q zntkoB7hZepM{~QpxPa2HP)E>K|LVCI1Q0*~0R#|0009ILKmdW;M9Kph@S+v`c&|6Q7Z@&;1Q0*~0R#|0009ILKmY**5NNSLryTDN`BjSxZ2A4y zFP{0yv*}vCz@Zjj5yK&X00IagfB*srAbWEt=Q!xAQ)Q@@5`x zdPCQ*vmq`JFy|)9A3U<#ADCAI0tg_0 z00IagfB*srAb*?vxf|VyeRST-#`5kg14Rr*s+V2HMUg*tx zaRJqsQj96q7ii_pW-J5{KmY**5I_I{1Q0-A^#arptlp|!UO8iQZB=&q^suf5gP~F1 zLi76_zu%O{sBR0}5w>t6a<2ueSSn