912 lines
44 KiB
C#
912 lines
44 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using AyCode.Core.Extensions;
|
|
using AyCode.Core.Loggers;
|
|
using AyCode.Services.Nav.Ekaer;
|
|
using AyCode.Services.SignalRs;
|
|
using DocumentFormat.OpenXml.Office2010.Excel;
|
|
using FruitBank.Common.Dtos;
|
|
using FruitBank.Common.Entities;
|
|
using FruitBank.Common.Interfaces;
|
|
using FruitBank.Common.Loggers;
|
|
using FruitBank.Common.Models;
|
|
using FruitBank.Common.Server;
|
|
using FruitBank.Common.Server.Interfaces;
|
|
using FruitBank.Common.Server.Services.Ekaer;
|
|
using FruitBank.Common.Services.Ekaer;
|
|
using FruitBank.Common.SignalRs;
|
|
using LinqToDB;
|
|
using Mango.Nop.Core.Dtos;
|
|
using Mango.Nop.Core.Loggers;
|
|
using Mango.Nop.Core.Models;
|
|
using Nop.Core;
|
|
using Nop.Core.Domain.Customers;
|
|
using Nop.Core.Domain.Orders;
|
|
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
|
|
using Nop.Plugin.Misc.FruitBankPlugin.Factories;
|
|
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
|
using Nop.Services.Customers;
|
|
using Nop.Services.Localization;
|
|
using Nop.Web.Framework.Controllers;
|
|
using NUglify.Helpers;
|
|
|
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
|
{
|
|
//https://linq2db.github.io/articles/sql/Join-Operators.html
|
|
public class FruitBankDataController(
|
|
FruitBankDbContext ctx,
|
|
FruitBankAttributeService fruitBankAttributeService,
|
|
MeasurementService measurementService,
|
|
IWorkContext workContext,
|
|
ICustomerService customerService,
|
|
ICustomerRegistrationService customerRegistrationService,
|
|
ILocalizationService localizationService,
|
|
PreOrderConversionService preorderConversionService,
|
|
IFruitBankEkaerService fruitBankEkaerService,
|
|
IEkaerSettings ekaerSettings,
|
|
IEnumerable<IAcLogWriterBase> logWriters)
|
|
: BasePluginController, IFruitBankDataControllerServer
|
|
{
|
|
private const int LastShippingDays = 15;
|
|
private readonly ILogger _logger = new Logger<FruitBankDataController>(logWriters.ToArray());
|
|
|
|
[SignalR(SignalRTags.ProcessAndSaveFullShippingJson)]
|
|
public async Task<List<Partner>> ProcessAndSaveFullShippingJson(string fullShippingJson, int customerId)
|
|
{
|
|
return await measurementService.ProcessAndSaveFullShippingJson(fullShippingJson, customerId);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetGenericAttributeDtosByEntityIdAndKeyGroup)]
|
|
public async Task<List<GenericAttributeDto>> GetGenericAttributeDtosByEntityIdAndKeyGroup(int productId, string keyGroup, int storeId)
|
|
{
|
|
return await ctx.GetGenericAttributeDtosByEntityIdAndKeyGroup(productId, keyGroup, storeId);
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddGenericAttributeDto)]
|
|
public async Task<GenericAttributeDto> AddGenericAttributeDto(GenericAttributeDto genericAttributeDto)
|
|
{
|
|
await ctx.GenericAttributeDtos.InsertAsync(genericAttributeDto);
|
|
return await ctx.GenericAttributeDtos.GetByIdAsync(genericAttributeDto.Id);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateGenericAttributeDto)]
|
|
public async Task<GenericAttributeDto> UpdateGenericAttributeDto(GenericAttributeDto genericAttributeDto)
|
|
{
|
|
await ctx.GenericAttributeDtos.UpdateAsync(genericAttributeDto);
|
|
return await ctx.GenericAttributeDtos.GetByIdAsync(genericAttributeDto.Id);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetStockQuantityHistoryDtos)]
|
|
public async Task<List<StockQuantityHistoryDto>> GetStockQuantityHistoryDtos()
|
|
{
|
|
_logger.Detail($"GetStockQuantityHistoryDtos invoked; lastDaysCount: {LastShippingDays}");
|
|
|
|
var fromDateUtc = DateTime.UtcNow.Date.AddDays(-LastShippingDays);
|
|
return await ctx.StockQuantityHistoryDtos.GetAll(true).Where(sqh => sqh.CreatedOnUtc >= fromDateUtc).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetStockQuantityHistoryDtosByProductId)]
|
|
public async Task<List<StockQuantityHistoryDto>> GetStockQuantityHistoryDtosByProductId(int productId)
|
|
{
|
|
_logger.Detail($"GetStockQuantityHistoryDtosByProductId invoked; productId: {productId}; lastDaysCount: {LastShippingDays}");
|
|
|
|
var fromDateUtc = DateTime.UtcNow.Date.AddDays(-LastShippingDays);
|
|
return await ctx.StockQuantityHistoryDtos.GetByProductIdAsync(productId, true).Where(sqh => sqh.CreatedOnUtc >= fromDateUtc).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetMeasuringModels)]
|
|
public Task<List<MeasuringModel>> GetMeasuringModels()
|
|
{
|
|
throw new NotImplementedException("GetMeasuringModels");
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetPartners)]
|
|
public async Task<List<Partner>> GetPartners()
|
|
{
|
|
_logger.Detail($"GetPartners invoked");
|
|
|
|
// A telephelyeket is behúzzuk (CSAK a depókat, NEM a teljes GetAll(true) láncot) — a partnerek
|
|
// úgyis cache-eltek, így a ShippingDocument-grid telephely-legördülője kliens-oldalon kaszkádolhat.
|
|
return await ctx.Partners.GetAll().LoadWith(p => p.PartnerDepots).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetPartnerById)]
|
|
public async Task<Partner> GetPartnerById(int id)
|
|
{
|
|
_logger.Detail($"GetPartnerById invoked; id: {id}");
|
|
|
|
//var customers = await ctx.GetCustormersBySystemRoleName("Measuring").ToListAsync();
|
|
//_logger.Error($"COUNT: {customers.Count}");
|
|
|
|
return await ctx.Partners.GetByIdAsync(id, false);
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddPartner)]
|
|
public async Task<Partner> AddPartner(Partner partner)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(partner);
|
|
|
|
_logger.Detail($"AddPartner invoked; id: {partner.Id}");
|
|
|
|
await ctx.Partners.InsertAsync(partner);
|
|
return await ctx.Partners.GetByIdAsync(partner.Id, partner.ShippingDocuments != null);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdatePartner)]
|
|
public async Task<Partner> UpdatePartner(Partner partner)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(partner);
|
|
|
|
_logger.Detail($"UpdatePartner invoked; id: {partner.Id}");
|
|
|
|
await ctx.Partners.UpdateAsync(partner);
|
|
return await ctx.Partners.GetByIdAsync(partner.Id, partner.ShippingDocuments != null);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetCargoPartners)]
|
|
public async Task<List<CargoPartner>> GetCargoPartners()
|
|
{
|
|
_logger.Detail($"GetCargoPartners invoked");
|
|
|
|
return await ctx.CargoPartners.GetAll(true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetCargoPartnerById)]
|
|
public async Task<CargoPartner> GetCargoPartnerById(int id)
|
|
{
|
|
_logger.Detail($"GetCargoPartnerById invoked; id: {id}");
|
|
return await ctx.CargoPartners.GetByIdAsync(id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddCargoPartner)]
|
|
public async Task<CargoPartner> AddCargoPartner(CargoPartner cargoPartner)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(cargoPartner);
|
|
|
|
_logger.Detail($"AddCargoPartner invoked; id: {cargoPartner.Id}");
|
|
|
|
await ctx.CargoPartners.InsertAsync(cargoPartner);
|
|
return await ctx.CargoPartners.GetByIdAsync(cargoPartner.Id, cargoPartner.CargoTrucks != null);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateCargoPartner)]
|
|
public async Task<CargoPartner> UpdateCargoPartner(CargoPartner cargoPartner)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(cargoPartner);
|
|
|
|
_logger.Detail($"UpdateCargoPartner invoked; id: {cargoPartner.Id}");
|
|
|
|
await ctx.CargoPartners.UpdateAsync(cargoPartner);
|
|
return await ctx.CargoPartners.GetByIdAsync(cargoPartner.Id, cargoPartner.CargoTrucks != null);
|
|
}
|
|
|
|
|
|
[SignalR(SignalRTags.GetCargoTrucks)]
|
|
public async Task<List<CargoTruck>> GetCargoTrucks()
|
|
{
|
|
_logger.Detail($"GetCargoTrucks invoked");
|
|
|
|
return await ctx.CargoTrucks.GetAll(true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetCargoTruckById)]
|
|
public async Task<CargoTruck> GetCargoTruckById(int id)
|
|
{
|
|
_logger.Detail($"GetCargoTruckById invoked; id: {id}");
|
|
return await ctx.CargoTrucks.GetByIdAsync(id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetCargoTrucksByCargoPartnerId)]
|
|
public async Task<List<CargoTruck>> GetCargoTrucksByCargoPartnerId(int cargoPartnerId)
|
|
{
|
|
_logger.Detail($"GetCargoTrucksByCargoPartnerId invoked; cargoPartnerId: {cargoPartnerId}");
|
|
return await ctx.CargoTrucks.GetByCargoPartnerId(cargoPartnerId, true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddCargoTruck)]
|
|
public async Task<CargoTruck> AddCargoTruck(CargoTruck cargoTruck)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(cargoTruck);
|
|
|
|
_logger.Detail($"AddCargoTruck invoked; id: {cargoTruck.Id}");
|
|
|
|
await ctx.CargoTrucks.InsertAsync(cargoTruck);
|
|
return await ctx.CargoTrucks.GetByIdAsync(cargoTruck.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateCargoTruck)]
|
|
public async Task<CargoTruck> UpdateCargoTruck(CargoTruck cargoTruck)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(cargoTruck);
|
|
|
|
_logger.Detail($"UpdateCargoTruck invoked; id: {cargoTruck.Id}");
|
|
|
|
await ctx.CargoTrucks.UpdateAsync(cargoTruck);
|
|
return await ctx.CargoTrucks.GetByIdAsync(cargoTruck.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetPartnerDepots)]
|
|
public async Task<List<PartnerDepot>> GetPartnerDepots()
|
|
{
|
|
_logger.Detail($"GetPartnerDepots invoked");
|
|
|
|
return await ctx.PartnerDepots.GetAll(true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetPartnerDepotById)]
|
|
public async Task<PartnerDepot> GetPartnerDepotById(int id)
|
|
{
|
|
_logger.Detail($"GetPartnerDepotById invoked; id: {id}");
|
|
return await ctx.PartnerDepots.GetByIdAsync(id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetPartnerDepotsByPartnerId)]
|
|
public async Task<List<PartnerDepot>> GetPartnerDepotsByPartnerId(int partnerId)
|
|
{
|
|
_logger.Detail($"GetPartnerDepotsByPartnerId invoked; partnerId: {partnerId}");
|
|
return await ctx.PartnerDepots.GetByPartnerId(partnerId, true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddPartnerDepot)]
|
|
public async Task<PartnerDepot> AddPartnerDepot(PartnerDepot partnerDepot)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(partnerDepot);
|
|
|
|
_logger.Detail($"AddPartnerDepot invoked; id: {partnerDepot.Id}");
|
|
|
|
await ctx.PartnerDepots.InsertAsync(partnerDepot);
|
|
return await ctx.PartnerDepots.GetByIdAsync(partnerDepot.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdatePartnerDepot)]
|
|
public async Task<PartnerDepot> UpdatePartnerDepot(PartnerDepot partnerDepot)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(partnerDepot);
|
|
|
|
_logger.Detail($"UpdatePartnerDepot invoked; id: {partnerDepot.Id}");
|
|
|
|
await ctx.PartnerDepots.UpdateAsync(partnerDepot);
|
|
return await ctx.PartnerDepots.GetByIdAsync(partnerDepot.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetEkaerHistories)]
|
|
public async Task<List<EkaerHistory>> GetEkaerHistories(EkaerHistoryFilter ekaerHistoryFilter)
|
|
{
|
|
_logger.Detail($"GetEkaerHistories invoked; ekaerHistoryFilter: {ekaerHistoryFilter}");
|
|
return await ctx.EkaerHistories.GetByFilter(ekaerHistoryFilter, true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetEkaerHistoryCount)]
|
|
public async Task<int> GetEkaerHistoryCount(EkaerHistoryFilter ekaerHistoryFilter)
|
|
{
|
|
_logger.Detail($"GetEkaerHistoryCount invoked; ekaerHistoryFilter: {ekaerHistoryFilter}");
|
|
return await ctx.EkaerHistories.CountByFilterAsync(ekaerHistoryFilter);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetEkaerHistoryById)]
|
|
public async Task<EkaerHistory> GetEkaerHistoryById(int id)
|
|
{
|
|
_logger.Detail($"GetEkaerHistoryById invoked; id: {id}");
|
|
return await ctx.EkaerHistories.GetByIdAsync(id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetEkaerHistoriesByForeignKey)]
|
|
public async Task<List<EkaerHistory>> GetEkaerHistoriesByForeignKey(int foreignKey)
|
|
{
|
|
_logger.Detail($"GetEkaerHistoriesByForeignKey invoked; foreignKey: {foreignKey}");
|
|
|
|
// A forrás-rekordot (ShippingDocument/Order Id) lefedő EKÁER-deklaráció(k), a Mappings-szel betöltve — EGY query
|
|
// (EXISTS a mapping-táblára), nem kettő.
|
|
return await ctx.EkaerHistories.GetAll(true)
|
|
.Where(eh => ctx.EkaerHistoryMappings.Table.Any(m => m.EkaerHistoryId == eh.Id && m.ForeignKey == foreignKey))
|
|
.ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddEkaerHistory)]
|
|
public async Task<EkaerHistory> AddEkaerHistory(EkaerHistory ekaerHistory)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(ekaerHistory);
|
|
|
|
_logger.Detail($"AddEkaerHistory invoked; id: {ekaerHistory.Id}");
|
|
|
|
await ctx.EkaerHistories.InsertAsync(ekaerHistory);
|
|
return await ctx.EkaerHistories.GetByIdAsync(ekaerHistory.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateEkaerHistory)]
|
|
public async Task<EkaerHistory> UpdateEkaerHistory(EkaerHistory ekaerHistory)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(ekaerHistory);
|
|
|
|
_logger.Detail($"UpdateEkaerHistory invoked; id: {ekaerHistory.Id}");
|
|
|
|
await ctx.EkaerHistories.UpdateAsync(ekaerHistory);
|
|
return await ctx.EkaerHistories.GetByIdAsync(ekaerHistory.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GenerateEkaerXmlDocument)]
|
|
public async Task<EkaerHistory> GenerateEkaerXmlDocument(int ekaerHistoryId)
|
|
{
|
|
_logger.Detail($"GenerateEkaerXmlDocument invoked; ekaerHistoryId: {ekaerHistoryId}");
|
|
|
|
var ekaerHistory = await ctx.EkaerHistories.GetByIdAsync(ekaerHistoryId, true)
|
|
?? throw new ArgumentException($"EkaerHistory not found; id: {ekaerHistoryId}", nameof(ekaerHistoryId));
|
|
|
|
// A deklarációhoz tartozó forrás-rekordok a BETÖLTÖTT mappingből (bejövő: N szállítólevél; kimenő: 1 rendelés).
|
|
var foreignKeys = ekaerHistory.Mappings?.Select(m => m.ForeignKey).ToList() ?? [];
|
|
if (foreignKeys.Count == 0) throw new InvalidOperationException($"EkaerHistory #{ekaerHistoryId} has no mapped source records.");
|
|
|
|
if (!ekaerHistory.IsOutgoing)
|
|
{
|
|
// Bejövő: a csoport ÖSSZES szállítólevele EGY tradeCard-dá (összevont tömeg/érték); GetAll(true) = teljes gráf.
|
|
var documents = await ctx.ShippingDocuments.GetAll(true).Where(sd => foreignKeys.Contains(sd.Id)).ToListAsync();
|
|
if (documents.Count == 0) throw new InvalidOperationException($"EkaerHistory #{ekaerHistoryId}: no ShippingDocuments found for the mapped ids.");
|
|
ekaerHistory = fruitBankEkaerService.GenerateEkaerXmlDocument(documents, ekaerHistory);
|
|
|
|
// Összegző (ShippingDate + Partner) frissítése — a csoporton belül invariáns, így bármelyik dok jó.
|
|
fruitBankEkaerService.SetSummary(ekaerHistory, documents[0].ShippingDate, documents[0].Partner?.Name);
|
|
}
|
|
else
|
|
{
|
|
// Kimenő: egy rendelés (a GetByIdAsync(true) tölti a Customer-t, tételeket, palettákat (GrossWeight), ProductDto-t).
|
|
var order = await ctx.OrderDtos.GetByIdAsync(foreignKeys[0], true)
|
|
?? throw new ArgumentException($"Order not found; id: {foreignKeys[0]}");
|
|
ekaerHistory = fruitBankEkaerService.GenerateEkaerXmlDocument(order, ekaerHistory);
|
|
|
|
fruitBankEkaerService.SetSummary(ekaerHistory, order.DateOfReceipt, order.Customer?.Company);
|
|
}
|
|
|
|
await ctx.EkaerHistories.UpdateAsync(ekaerHistory);
|
|
// A friss sort adjuk vissza (frissített Modified + a betöltött Mappings); a sor biztosan létezik (épp updateltük).
|
|
return await ctx.EkaerHistories.GetByIdAsync(ekaerHistory.Id, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Idempotens rekord-létrehozás: ha a forrás-rekordra (foreignKey + isOutgoing) már van mapping → a hozzá tartozó
|
|
/// EkaerHistory-t adja vissza érintetlenül; különben új Pending rekordot + EGY mapping sort hoz létre (atomikusan).
|
|
/// A generálás (XmlDoc) külön lépés: GenerateEkaerXmlDocument(ekaerHistoryId).
|
|
/// </summary>
|
|
[SignalR(SignalRTags.CreateEkaerHistory)]
|
|
public async Task<EkaerHistory> CreateEkaerHistory(int foreignKey, bool isOutgoing)
|
|
{
|
|
_logger.Detail($"CreateEkaerHistory invoked; foreignKey: {foreignKey}; isOutgoing: {isOutgoing}");
|
|
|
|
// Idempotencia: a forrás-rekordra (azonos irányban) már létező mapping → a hozzá tartozó EkaerHistory,
|
|
// a Mappings-szel betöltve (GetAll(true)) — EGY query (EXISTS a mappingre), nincs külön újraolvasás.
|
|
var existing = await LinqToDB.AsyncExtensions.FirstOrDefaultAsync(
|
|
ctx.EkaerHistories.GetAll(true).Where(eh => eh.IsOutgoing == isOutgoing
|
|
&& ctx.EkaerHistoryMappings.Table.Any(m => m.EkaerHistoryId == eh.Id && m.ForeignKey == foreignKey)));
|
|
|
|
if (existing != null) return existing;
|
|
|
|
// A forrás-entitás létét ellenőrizzük és betöltjük (relations) az összegző mezőkhöz (ShippingDate + Partner).
|
|
var ekaerHistory = new EkaerHistory { IsOutgoing = isOutgoing, Status = EkaerStatus.Pending };
|
|
if (!isOutgoing)
|
|
{
|
|
var doc = await ctx.ShippingDocuments.GetByIdAsync(foreignKey, true) ?? throw new ArgumentException($"ShippingDocument not found; id: {foreignKey}", nameof(foreignKey));
|
|
fruitBankEkaerService.SetSummary(ekaerHistory, doc.ShippingDate, doc.Partner?.Name);
|
|
}
|
|
else
|
|
{
|
|
var order = await ctx.OrderDtos.GetByIdAsync(foreignKey, true) ?? throw new ArgumentException($"Order not found; id: {foreignKey}", nameof(foreignKey));
|
|
fruitBankEkaerService.SetSummary(ekaerHistory, order.DateOfReceipt, order.Customer?.Company);
|
|
}
|
|
|
|
// EGY EkaerHistory + EGY mapping sor (egyelemű csoport), atomikusan.
|
|
ekaerHistory = await ctx.AddEkaerHistoryWithMappingsAsync(ekaerHistory, [foreignKey]);
|
|
|
|
// A friss sort adjuk vissza, a betöltött Mappings-szel; a sor biztosan létezik (épp beszúrtuk).
|
|
return await ctx.EkaerHistories.GetByIdAsync(ekaerHistory.Id, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// A megadott dátumtól kezdődő, EKÁER-rekord nélküli szállítólevelekre Pending rekordot hoz létre.
|
|
/// User-vezérelt (toolbar gomb) — szándékosan NINCS automata rekord-érzékelés: a létrehozás explicit,
|
|
/// idempotens, és bármikor újrafuttatható (maga a gomb a "reconciliation").
|
|
/// </summary>
|
|
[SignalR(SignalRTags.CreateMissingEkaerHistories)]
|
|
public async Task<EkaerCreateResult> CreateMissingEkaerHistories(DateTime fromDate)
|
|
{
|
|
_logger.Detail($"CreateMissingEkaerHistories invoked; fromDate: {fromDate:yyyy-MM-dd}");
|
|
|
|
var toCreate = new List<(EkaerHistory History, List<int> ForeignKeys)>();
|
|
var messages = new HashSet<string>(); // dedup: ugyanaz a partner (pl. hiányzó országkód) több csoportban is előjöhet
|
|
|
|
// ── Bejövő ── Rekord nélküli szállítólevelek a dátumtól, Partnerrel + tételekkel betöltve a kötelezettség-kapuhoz.
|
|
// A bejelentés-egység (Shipping, Partner, PartnerDepot) = feladó(+telephely)→címzett→jármű: EGY EkaerHistory/csoport, a küszöb a csoport ÖSSZES dokumentumára aggregál.
|
|
var candidates = await ctx.ShippingDocuments.GetAll()
|
|
.Where(sd => sd.ShippingDate >= fromDate)
|
|
.Where(sd => !ctx.EkaerHistoryMappings.Table.Any(m => m.ForeignKey == sd.Id && ctx.EkaerHistories.Table.Any(eh => eh.Id == m.EkaerHistoryId && !eh.IsOutgoing)))
|
|
.LoadWith(sd => sd.Partner)
|
|
.LoadWith(sd => sd.ShippingItems)
|
|
.ToListAsync();
|
|
|
|
// Partner nélküli (még nincs rendesen felvett) szállítólevél CSENDBEN kihagyva — nincs feladó, nem kész;
|
|
// a mentes partner (IsEkaer=false) is. A maradék (Shipping, Partner, PartnerDepot) csoportban (a dokumentum mindig kap Shippinget).
|
|
foreach (var group in candidates.Where(sd => sd.Partner != null && sd.Partner.IsEkaer != false).GroupBy(sd => (sd.ShippingId, sd.PartnerId, sd.PartnerDepotId)))
|
|
{
|
|
var docs = group.ToList();
|
|
try
|
|
{
|
|
var result = fruitBankEkaerService.EvaluateObligation(docs);
|
|
if (result.Obligation == EkaerObligation.DataError) { messages.UnionWith(result.Errors); continue; }
|
|
if (result.Obligation == EkaerObligation.NotRequired) continue;
|
|
|
|
// Kötelező → EGY EkaerHistory a csoportra (összegző: ShippingDate + Partner — invariáns) + a dokumentumok mapping-foreignKey-ként.
|
|
var history = new EkaerHistory { IsOutgoing = false, StatusId = (int)EkaerStatus.Pending };
|
|
fruitBankEkaerService.SetSummary(history, docs[0].ShippingDate, docs[0].Partner?.Name);
|
|
toCreate.Add((history, docs.Select(d => d.Id).ToList()));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"CreateMissingEkaerHistories; inbound evaluate failed; ShippingId: {group.Key.ShippingId}; PartnerId: {group.Key.PartnerId}; PartnerDepotId: {group.Key.PartnerDepotId}", ex);
|
|
messages.Add($"Szállítólevél-csoport (Shipping #{group.Key.ShippingId}, Partner #{group.Key.PartnerId}, Telephely #{group.Key.PartnerDepotId?.ToString() ?? "—"}): a kötelezettség nem dönthető el — {ex.Message}");
|
|
}
|
|
}
|
|
|
|
// ── Kimenő ── Rekord nélküli, lezárt (Complete) rendelések a dátumtól; rendelésenként vizsgáljuk (nincs Shipping).
|
|
// Előbb csak az azonosítók (könnyű szűrés), majd EGY batch-betöltés a teljes gráffal (GetAllByIds) — nincs N+1.
|
|
var missingOrderIds = await ctx.OrderDtos.GetAllByOrderStatus(OrderStatus.Complete, false)
|
|
.Where(o => o.GenericAttributes.Any(ga => ga.Key == nameof(OrderDto.DateOfReceipt) && DateTime.Parse(ga.Value) >= fromDate.Date))
|
|
.Where(o => !ctx.EkaerHistoryMappings.Table.Any(m => m.ForeignKey == o.Id && ctx.EkaerHistories.Table.Any(eh => eh.Id == m.EkaerHistoryId && eh.IsOutgoing)))
|
|
.Select(o => o.Id)
|
|
.ToListAsync();
|
|
|
|
var missingOrders = missingOrderIds.Count == 0 ? [] : await ctx.OrderDtos.GetAllByIds(missingOrderIds, true).ToListAsync();
|
|
|
|
foreach (var order in missingOrders)
|
|
{
|
|
try
|
|
{
|
|
var result = fruitBankEkaerService.EvaluateObligation(order);
|
|
if (result.Obligation == EkaerObligation.DataError) { messages.UnionWith(result.Errors); continue; }
|
|
if (result.Obligation == EkaerObligation.NotRequired) continue;
|
|
|
|
var history = new EkaerHistory { IsOutgoing = true, StatusId = (int)EkaerStatus.Pending };
|
|
fruitBankEkaerService.SetSummary(history, order.DateOfReceipt, order.Customer?.Company);
|
|
toCreate.Add((history, [order.Id]));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"CreateMissingEkaerHistories; outbound evaluate failed; OrderId: {order.Id}", ex);
|
|
messages.Add($"Rendelés #{order.Id}: a kötelezettség nem dönthető el — {ex.Message}");
|
|
}
|
|
}
|
|
|
|
// ── Beszúrás ──
|
|
var createdCount = 0;
|
|
foreach (var (history, foreignKeys) in toCreate)
|
|
{
|
|
try
|
|
{
|
|
// EkaerHistory + a forrás-mapping sorok atomikusan (a junction tartja a kapcsolatot, nem a rendszer-tábla).
|
|
await ctx.AddEkaerHistoryWithMappingsAsync(history, foreignKeys);
|
|
createdCount++;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"CreateMissingEkaerHistories; insert failed; IsOutgoing: {history.IsOutgoing}; foreignKeys: [{string.Join(",", foreignKeys)}]", ex);
|
|
}
|
|
}
|
|
|
|
_logger.Info($"CreateMissingEkaerHistories; created: {createdCount}; messages: {messages.Count}; fromDate: {fromDate:yyyy-MM-dd}");
|
|
return new EkaerCreateResult { CreatedCount = createdCount, Messages = [.. messages.OrderBy(m => m)] };
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippings)]
|
|
public async Task<List<Shipping>> GetShippings()
|
|
{
|
|
_logger.Detail($"GetShippings invoked; lastDaysCount: {LastShippingDays}");
|
|
|
|
var fromDateUtc = DateTime.UtcNow.Date.AddDays(-LastShippingDays);
|
|
return await ctx.Shippings.GetAll(true).Where(s => s.ShippingDate >= fromDateUtc).ToListAsync();
|
|
//return await ctx.Shippings.Table.LoadWith(sd => sd.ShippingDocuments).ThenLoad(si => si.ShippingItems).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetNotMeasuredShippings)]
|
|
public async Task<List<Shipping>> GetNotMeasuredShippings()
|
|
{
|
|
_logger.Detail($"GetNotMeasuredShippings invoked; lastDaysCount: {LastShippingDays}");
|
|
|
|
var startTime = DateTime.Now;
|
|
var shippings = await ctx.Shippings.GetAllNotMeasured(true, LastShippingDays).ToListAsync();
|
|
|
|
_logger.Detail($"GetNotMeasuredShippings; shippingsCount: {shippings.Count}; dbResponse: {(DateTime.Now - startTime).TotalSeconds} sec.");
|
|
return shippings;
|
|
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingById)]
|
|
public async Task<Shipping> GetShippingById(int id)
|
|
{
|
|
_logger.Detail($"GetShippingById invoked; id: {id}");
|
|
|
|
return await ctx.Shippings.GetByIdAsync(id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddShipping)]
|
|
public async Task<Shipping> AddShipping(Shipping shipping)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shipping);
|
|
|
|
_logger.Detail($"AddShipping invoked; id: {shipping.Id}");
|
|
|
|
await ctx.Shippings.InsertAsync(shipping);
|
|
return await ctx.Shippings.GetByIdAsync(shipping.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateShipping)]
|
|
public async Task<Shipping> UpdateShipping(Shipping shipping)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shipping);
|
|
|
|
_logger.Detail($"UpdateShipping invoked; id: {shipping.Id}");
|
|
|
|
await ctx.Shippings.UpdateAsync(shipping);
|
|
return await ctx.Shippings.GetByIdAsync(shipping.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingItems)]
|
|
public async Task<List<ShippingItem>> GetShippingItems()
|
|
{
|
|
_logger.Detail($"GetShippingItems invoked; lastDaysCount: {LastShippingDays}");
|
|
|
|
var fromDateUtc = DateTime.UtcNow.Date.AddDays(-LastShippingDays);
|
|
return await ctx.ShippingItems.GetAll(true).Where(si => si.ShippingDocument.Shipping == null ||
|
|
si.ShippingDocument.Shipping.ShippingDate >= fromDateUtc).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingItemsByDocumentId)]
|
|
public async Task<List<ShippingItem>> GetShippingItemsByDocumentId(int shippingDocumentId)
|
|
{
|
|
_logger.Detail($"GetShippingItemsByDocumentId invoked");
|
|
|
|
return await ctx.ShippingItems.GetAllByShippingDocumentIdAsync(shippingDocumentId, true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingItemsByShippingId)]
|
|
public async Task<List<ShippingItem>> GetShippingItemsByShippingId(int shippingId)
|
|
{
|
|
_logger.Detail($"GetShippingItemsByShippingId invoked");
|
|
|
|
return await ctx.ShippingItems.GetAllByShippingIdAsync(shippingId, true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingItemsByPartnerId)]
|
|
public async Task<List<ShippingItem>> GetShippingItemsByPartnerId(int partnerId)
|
|
{
|
|
_logger.Detail($"GetShippingItemsByPartnerId invoked");
|
|
|
|
return await ctx.ShippingItems.GetAllByPartnerIdAsync(partnerId, true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingItemById)]
|
|
public async Task<ShippingItem> GetShippingItemById(int id)
|
|
{
|
|
_logger.Detail($"GetShippingItemById invoked; id: {id}");
|
|
|
|
var shippingItem = await ctx.ShippingItems.GetByIdAsync(id, true);
|
|
return shippingItem;
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddShippingItem)]
|
|
public async Task<ShippingItem> AddShippingItem(ShippingItem shippingItem)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingItem);
|
|
|
|
_logger.Detail($"AddShippingItem invoked; id: {shippingItem.Id}");
|
|
|
|
if (!await ctx.AddShippingItemAsync(shippingItem)) return null;
|
|
|
|
// Update IncomingQuantity — EventConsumer handles conversion separately
|
|
if (shippingItem.ProductId.HasValue && shippingItem.QuantityOnDocument > 0)
|
|
await preorderConversionService.SyncIncomingQuantityAsync(
|
|
shippingItem.ProductId.Value, 0, shippingItem.QuantityOnDocument);
|
|
|
|
return await ctx.ShippingItems.GetByIdAsync(shippingItem.Id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateShippingItem)]
|
|
public async Task<ShippingItem> UpdateShippingItem(ShippingItem shippingItem)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingItem);
|
|
|
|
_logger.Detail($"UpdateShippingItem invoked; id: {shippingItem.Id}");
|
|
|
|
// Load BEFORE the update to capture previous ProductId and QuantityOnDocument
|
|
var oldItem = await ctx.ShippingItems.GetByIdAsync(shippingItem.Id, false);
|
|
|
|
if (!await ctx.UpdateShippingItemSafeAsync(shippingItem)) return null;
|
|
|
|
if (oldItem != null)
|
|
{
|
|
var productChanged = oldItem.ProductId != shippingItem.ProductId;
|
|
var quantityChanged = oldItem.QuantityOnDocument != shippingItem.QuantityOnDocument;
|
|
|
|
if (productChanged && shippingItem.ProductId.HasValue)
|
|
{
|
|
// Full replacement: swap stock, order items, preorder items
|
|
await preorderConversionService.ReplaceShippingItemProductAsync(
|
|
shippingItem.Id, shippingItem.ProductId.Value, oldItem);
|
|
}
|
|
else if (quantityChanged && shippingItem.ProductId.HasValue)
|
|
{
|
|
// Only quantity changed: sync IncomingQuantity delta
|
|
await preorderConversionService.SyncIncomingQuantityAsync(
|
|
shippingItem.ProductId.Value,
|
|
oldItem.QuantityOnDocument,
|
|
shippingItem.QuantityOnDocument);
|
|
|
|
// If quantity increased, trigger conversion
|
|
// (EventConsumer also fires this, double-call is idempotent)
|
|
if (shippingItem.QuantityOnDocument > oldItem.QuantityOnDocument)
|
|
_ = Task.Run(async () => await preorderConversionService
|
|
.ConvertPreOrdersForProductsAsync(
|
|
new List<int> { shippingItem.ProductId.Value },
|
|
shippingItem.ShippingDocumentId));
|
|
}
|
|
}
|
|
|
|
return await ctx.ShippingItems.GetByIdAsync(shippingItem.Id, shippingItem.ShippingDocument != null);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateMeasuredShippingItem)]
|
|
public async Task<ShippingItem> UpdateMeasuredShippingItem(ShippingItem shippingItem)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingItem);
|
|
|
|
_logger.Detail($"UpdateMeasuredShippingItem invoked; id: {shippingItem.Id}");
|
|
|
|
if (!await ctx.UpdateMeasuredShippingItemSafeAsync(shippingItem)) return null;
|
|
return await ctx.ShippingItems.GetByIdAsync(shippingItem.Id, shippingItem.ShippingDocument != null);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingItemPallets)]
|
|
public async Task<List<ShippingItemPallet>> GetShippingItemPallets()
|
|
{
|
|
_logger.Detail($"GetShippingItemPallets invoked; lastDaysCount: {LastShippingDays}");
|
|
|
|
var fromDateUtc = DateTime.UtcNow.Date.AddDays(-LastShippingDays);
|
|
|
|
return await ctx.ShippingItemPallets.GetAll(true).Where(sip => sip.ShippingItem.ShippingDocument.Shipping == null ||
|
|
sip.ShippingItem.ShippingDocument.Shipping.ShippingDate >= fromDateUtc).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddShippingItemPallet)]
|
|
public async Task<ShippingItemPallet> AddShippingItemPallet(ShippingItemPallet shippingItemPallet)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingItemPallet);
|
|
|
|
_logger.Detail($"AddShippingItemPallet invoked; {shippingItemPallet}");
|
|
|
|
if (!await ctx.AddShippingItemPalletSafeAsync(shippingItemPallet)) return null;
|
|
return await ctx.ShippingItemPallets.GetByIdAsync(shippingItemPallet.Id, false);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateShippingItemPallet)]
|
|
public async Task<ShippingItemPallet> UpdateShippingItemPallet(ShippingItemPallet shippingItemPallet)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingItemPallet);
|
|
|
|
_logger.Detail($"UpdateShippingItemPallet invoked; {shippingItemPallet}");
|
|
|
|
if (!await ctx.UpdateShippingItemPalletSafeAsync(shippingItemPallet)) return null;
|
|
return await ctx.ShippingItemPallets.GetByIdAsync(shippingItemPallet.Id, false);
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddOrUpdateMeasuredShippingItemPallets)]
|
|
public async Task<ShippingItem> AddOrUpdateMeasuredShippingItemPallets(List<ShippingItemPallet> shippingItemPallets)
|
|
{
|
|
// ArgumentNullException.ThrowIfNull(shippingItemPallets);
|
|
|
|
// _logger.Detail($"AddOrUpdateMeasuredShippingItemPallets invoked; count: {shippingItemPallets.Count}");
|
|
|
|
// if (shippingItemPallets.Count == 0) return null;
|
|
|
|
// var shippingItemId = shippingItemPallets.FirstOrDefault()!.ShippingItemId;
|
|
// if (shippingItemId <= 0 || shippingItemPallets.Any(x => x.ShippingItemId != shippingItemId)) return null;
|
|
|
|
// var shippingItem = await ctx.ShippingItems.GetByIdAsync(shippingItemId, false);
|
|
// shippingItem.ShippingItemPallets = shippingItemPallets.Where(sip => sip.IsValidMeasuringValues(shippingItem.IsMeasurable)).ToList();
|
|
|
|
// return await UpdateMeasuredShippingItem(shippingItem);
|
|
|
|
return null;
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddOrUpdateMeasuredShippingItemPallet)]
|
|
public async Task<ShippingItemPallet> AddOrUpdateMeasuredShippingItemPallet(ShippingItemPallet shippingItemPallet)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingItemPallet);
|
|
|
|
_logger.Detail($"AddOrUpdateMeasuredShippingItemPallet invoked; {shippingItemPallet}");
|
|
|
|
if (!await ctx.AddOrUpdateShippingItemPalletSafeAsync(shippingItemPallet)) return null;
|
|
|
|
var savedShippingItemPallet = await ctx.ShippingItemPallets.GetByIdAsync(shippingItemPallet.Id, true);
|
|
//update average weight and quantity on Product
|
|
await measurementService.CalculateAndSetAverageWeight(savedShippingItemPallet);
|
|
|
|
//return await ctx.ShippingItemPallets.GetByIdAsync(shippingItemPallet.Id, false);
|
|
return shippingItemPallet;
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingDocuments)]
|
|
public async Task<List<ShippingDocument>> GetShippingDocuments()
|
|
{
|
|
_logger.Detail($"GetShippingDocuments invoked; lastDaysCount: {LastShippingDays}");
|
|
|
|
var fromDateUtc = DateTime.UtcNow.Date.AddDays(-LastShippingDays);
|
|
return await ctx.ShippingDocuments.GetAll(true).Where(sd => sd.Shipping == null || sd.Shipping.ShippingDate >= fromDateUtc).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingDocumentById)]
|
|
public async Task<ShippingDocument> GetShippingDocumentById(int id)
|
|
{
|
|
_logger.Detail($"GetShippingDocumentById invoked; id: {id}");
|
|
|
|
return await ctx.ShippingDocuments.GetByIdAsync(id, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetShippingDocumentsByShippingId)]
|
|
public async Task<List<ShippingDocument>> GetShippingDocumentsByShippingId(int shippingId)
|
|
{
|
|
_logger.Detail($"GetShippingDocumentsByShippingId invoked; shippingId: {shippingId}");
|
|
|
|
return await ctx.ShippingDocuments.GetAllByShippingIdAsync(shippingId, true).ToListAsync();
|
|
}
|
|
[SignalR(SignalRTags.GetShippingDocumentsByProductId)]
|
|
public async Task<List<ShippingDocument>> GetShippingDocumentsByProductId(int productId)
|
|
{
|
|
_logger.Detail($"GetShippingDocumentsByProductId invoked; productId: {productId}");
|
|
|
|
return await ctx.ShippingDocuments.GetAllByProductIdAsync(productId, true).ToListAsync();
|
|
}
|
|
[SignalR(SignalRTags.GetShippingDocumentsByPartnerId)]
|
|
public async Task<List<ShippingDocument>> GetShippingDocumentsByPartnerId(int partnerId)
|
|
{
|
|
_logger.Detail($"GetShippingDocumentsByPartnerId invoked; partnerId: {partnerId}");
|
|
|
|
return await ctx.ShippingDocuments.GetAllByPartnerIdAsync(partnerId, true).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.AddShippingDocument)]
|
|
public async Task<ShippingDocument> AddShippingDocument(ShippingDocument shippingDocument)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingDocument);
|
|
|
|
_logger.Detail($"AddShippingDocument invoked; id: {shippingDocument.Id}");
|
|
|
|
await ctx.ShippingDocuments.InsertAsync(shippingDocument);
|
|
|
|
if(shippingDocument.ShippingItems != null)
|
|
{
|
|
foreach (var item in shippingDocument.ShippingItems)
|
|
{
|
|
var product = await ctx.Products.GetByIdAsync(item.ProductId);
|
|
if(product != null)
|
|
{
|
|
product.ProductCost = Convert.ToDecimal(item.UnitPriceOnDocument);
|
|
}
|
|
}
|
|
}
|
|
|
|
return await ctx.ShippingDocuments.GetByIdAsync(shippingDocument.Id, shippingDocument.Shipping != null || shippingDocument.Partner != null);
|
|
}
|
|
|
|
[SignalR(SignalRTags.UpdateShippingDocument)]
|
|
public async Task<ShippingDocument> UpdateShippingDocument(ShippingDocument shippingDocument)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(shippingDocument);
|
|
|
|
_logger.Detail($"UpdateShippingDocument invoked; id: {shippingDocument.Id}");
|
|
|
|
await ctx.ShippingDocuments.UpdateAsync(shippingDocument);
|
|
return await ctx.ShippingDocuments.GetByIdAsync(shippingDocument.Id, shippingDocument.Shipping != null || shippingDocument.Partner != null);
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetMeasuringUsers)]
|
|
public async Task<List<CustomerDto>> GetMeasuringUsers()
|
|
{
|
|
_logger.Detail($"GetMeasuringUsers invoked");
|
|
|
|
var customers = await ctx.GetCustomersBySystemRoleName(FruitBankConst.MeasuringRoleSystemName).Select(c => new CustomerDto(c)).ToListAsync();
|
|
return customers; //.ToModelDto<CustomerDto>();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetCustomerRolesByCustomerId)]
|
|
public async Task<List<CustomerRole>> GetCustomerRolesByCustomerId(int customerId)
|
|
{
|
|
_logger.Detail($"GetCustomerRolesByCustomerId invoked; customerId: {customerId}");
|
|
return await ctx.GetCustomerRolesByCustomerId(customerId).ToListAsync();
|
|
}
|
|
|
|
[SignalR(SignalRTags.GetProductDtos)]
|
|
public async Task<List<ProductDto>> GetProductDtos()
|
|
{
|
|
_logger.Detail($"GetProductDtos invoked");
|
|
return await ctx.ProductDtos.GetAll(false).ToListAsync();
|
|
}
|
|
|
|
//[SignalR(SignalRTags.GetAllMeasuringProductDtos)]
|
|
//public async Task<List<MeasuringProductDto>> GetAllMeasuringProductDtos()
|
|
//{
|
|
// _logger.Detail($"GetAllMeasuringProductDtos invoked");
|
|
// return await ctx.GetAllMeasuringProductDtos(false).ToListAsync();
|
|
//}
|
|
|
|
[SignalR(SignalRTags.GetMeasuringProductDtoById)]
|
|
public async Task<ProductDto?> GetProductDtoById(int productId)
|
|
{
|
|
_logger.Detail($"GetProductDtoById invoked; productId: {productId}");
|
|
return await ctx.ProductDtos.GetByIdAsync(productId, true);
|
|
}
|
|
|
|
[SignalR(SignalRTags.AuthenticateUser)]
|
|
public async Task<MgLoginModelResponse> LoginMeasuringUser(MgLoginModelRequest loginModelRequest)
|
|
{
|
|
var customerEmail = loginModelRequest?.Email;
|
|
var customerPassword = loginModelRequest?.Password;
|
|
|
|
_logger.Detail($"LoginMeasuringUser invoked; customerEmail; {customerEmail}");
|
|
|
|
var resultLoginModel = new MgLoginModelResponse();
|
|
|
|
if (!customerEmail.IsNullOrWhiteSpace() && !customerPassword.IsNullOrWhiteSpace())
|
|
{
|
|
var loginResult = await customerRegistrationService.ValidateCustomerAsync(customerEmail, customerPassword);
|
|
|
|
switch (loginResult)
|
|
{
|
|
case CustomerLoginResults.Successful:
|
|
{
|
|
var customer = await customerService.GetCustomerByEmailAsync(customerEmail);
|
|
|
|
var isInMeasuringRole = await customerService.IsInCustomerRoleAsync(customer, FruitBankConst.MeasuringRoleSystemName);
|
|
if (!isInMeasuringRole)
|
|
{
|
|
resultLoginModel.ErrorMessage = "Is not in MeauringRole!";
|
|
break;
|
|
}
|
|
|
|
//var actionResult = await customerRegistrationService.SignInCustomerAsync(customer, returnUrl, loginModel.RememberMe);
|
|
|
|
//await _workContext.SetCurrentCustomerAsync(customer);
|
|
//await _authenticationService.SignInAsync(customer, isPersist);
|
|
////raise event
|
|
//await _eventPublisher.PublishAsync(new CustomerLoggedinEvent(customer));
|
|
|
|
resultLoginModel.CustomerDto = new CustomerDto(customer); //customer.ToModel<CustomerDto>();
|
|
break;
|
|
}
|
|
case CustomerLoginResults.CustomerNotExist:
|
|
resultLoginModel.ErrorMessage = await localizationService.GetResourceAsync("Account.Login.WrongCredentials.CustomerNotExist");
|
|
break;
|
|
case CustomerLoginResults.Deleted:
|
|
resultLoginModel.ErrorMessage = await localizationService.GetResourceAsync("Account.Login.WrongCredentials.Deleted");
|
|
break;
|
|
case CustomerLoginResults.NotActive:
|
|
resultLoginModel.ErrorMessage = await localizationService.GetResourceAsync("Account.Login.WrongCredentials.NotActive");
|
|
break;
|
|
case CustomerLoginResults.NotRegistered:
|
|
resultLoginModel.ErrorMessage = await localizationService.GetResourceAsync("Account.Login.WrongCredentials.NotRegistered");
|
|
break;
|
|
case CustomerLoginResults.LockedOut:
|
|
resultLoginModel.ErrorMessage = await localizationService.GetResourceAsync("Account.Login.WrongCredentials.LockedOut");
|
|
break;
|
|
case CustomerLoginResults.WrongPassword:
|
|
default:
|
|
resultLoginModel.ErrorMessage = await localizationService.GetResourceAsync("Account.Login.WrongCredentials");
|
|
break;
|
|
}
|
|
}
|
|
else resultLoginModel.ErrorMessage = await localizationService.GetResourceAsync("Account.Login.WrongCredentials");
|
|
|
|
if (!resultLoginModel.ErrorMessage.IsNullOrWhiteSpace()) _logger.Error($"{resultLoginModel.ErrorMessage}; email: {customerEmail}");
|
|
return resultLoginModel;
|
|
}
|
|
}
|
|
}
|