Mango.Nop.Plugins/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/FruitBankDbContext.cs

251 lines
11 KiB
C#

#nullable enable
using AyCode.Core.Loggers;
using AyCode.Utils.Extensions;
using FruitBank.Common.Entities;
using FruitBank.Common.Interfaces;
using FruitBank.Common.Models;
using FruitBank.Common.Server;
using LinqToDB;
using LinqToDB.Common;
using Mango.Nop.Core.Loggers;
using Mango.Nop.Core.Repositories;
using Nop.Core;
using Nop.Core.Caching;
using Nop.Core.ComponentModel;
using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Customers;
using Nop.Data;
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer.Interfaces;
using Nop.Plugin.Misc.FruitBankPlugin.Services;
using Nop.Services.Catalog;
using Nop.Services.Common;
using System.Transactions;
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
public class FruitBankDbContext : MgDbContextBase, IPartnerDbSet<PartnerDbTable>, IShippingDbSet<ShippingDbTable>, IShippingItemDbSet<ShippingItemDbTable>, IShippingDocumentDbSet<ShippingDocumentDbTable>
{
private readonly FruitBankAttributeService _fruitBankAttributeService;
private readonly IStoreContext _storeContext;
private readonly IProductService _productService;
private readonly IStaticCacheManager _staticCacheManager;
public PartnerDbTable Partners { get; set; }
public ShippingDbTable Shippings { get; set; }
public ShippingItemDbTable ShippingItems { get; set; }
public ShippingDocumentDbTable ShippingDocuments { get; set; }
public IRepository<Product> Products { get; set; }
public IRepository<Customer> Customers { get; set; }
public IRepository<CustomerRole> CustomerRoles { get; set; }
public IRepository<CustomerCustomerRoleMapping> CustomerRoleMappings { get; set; }
public FruitBankDbContext(INopDataProvider dataProvider, ILockService lockService, FruitBankAttributeService fruitBankAttributeService, IStoreContext storeContext,
PartnerDbTable partnerDbTable, ShippingDbTable shippingDbTable, ShippingItemDbTable shippingItemDbTable,
ShippingDocumentDbTable shippingDocumentDbTable, IProductService productService, IStaticCacheManager staticCacheManager,
IRepository<Product> productRepository,
IRepository<Customer> customerRepository,
IRepository<CustomerCustomerRoleMapping> customerCustomerRoleMappingRepository,
IRepository<CustomerRole> customerRoleRepository,
IEnumerable<IAcLogWriterBase> logWriters) : base(dataProvider, lockService, logWriters)
{
_storeContext = storeContext;
_productService = productService;
_staticCacheManager = staticCacheManager;
_fruitBankAttributeService = fruitBankAttributeService;
Partners = partnerDbTable;
Shippings = shippingDbTable;
ShippingItems = shippingItemDbTable;
ShippingDocuments = shippingDocumentDbTable;
Products = productRepository;
Customers = customerRepository;
CustomerRoles = customerRoleRepository;
CustomerRoleMappings = customerCustomerRoleMappingRepository;
}
public IQueryable<MeasuringModel> GetMeasuringModelByShippingId(int shippingId)
{
var query =
from p in Partners.Table
join s in Shippings.Table on p.Id equals s.PartnerId
where s.Id == shippingId
select new MeasuringModel(p.Name);
return query;
}
public IQueryable<Customer> GetCustomersBySystemRoleName(string systemRoleName)
{
if (systemRoleName.IsNullOrWhiteSpace()) throw new ArgumentException("systemRoleName.IsNullOrWhiteSpace()", nameof(systemRoleName));
var query =
from c in Customers.Table
join crm in CustomerRoleMappings.Table on c.Id equals crm.CustomerId
join cr in CustomerRoles.Table on crm.CustomerRoleId equals cr.Id
where c.Active && !c.Deleted && cr.SystemName == systemRoleName
select c;
return query.Distinct().OrderBy(o => o.Username);
}
public IQueryable<CustomerRole> GetCustomerRolesByCustomerId(int customerId)
{
var query =
from cr in CustomerRoles.Table
join crm in CustomerRoleMappings.Table on cr.Id equals crm.CustomerRoleId
where crm.CustomerId == customerId
select cr;
return query.Distinct();
}
public IQueryable<Product> GetAllProducts()
=> Products.Table.Where(p => !p.Deleted).OrderBy(o => o.Name);
public Task<bool> UpdateMeasuredShippingItemAsync(ShippingItem shippingItem)
{
if (shippingItem.IsValidMeasuringValues()) return UpdateShippingItemAsync(shippingItem);
Logger.Error("shippingItem.IsMeasurable && !shippingItem.IsValidMeasuringValues()");
return Task.FromResult(false);
}
public Task<bool> UpdateShippingItemAsync(ShippingItem shippingItem)
{
if (shippingItem == null)
{
Logger.Error("shippingItem == null");
return Task.FromResult(false);
}
return TransactionSafeAsync(async tr =>
{
try
{
//Mi van ha nem jött meg a termék? Nem fogják tudni menteni... - J.
if (shippingItem.MeasuredQuantity <= 0) shippingItem.MeasuredQuantity = null;
if (!shippingItem.IsMeasurable || shippingItem.MeasuredNetWeight <= 0) shippingItem.MeasuredNetWeight = null;
if (!shippingItem.IsMeasurable || shippingItem.MeasuredGrossWeight <= 0) shippingItem.MeasuredGrossWeight = null;
//Update előtt kivesszük a korábbi ShippingItem-et a db-ből! - J.
var dbShippingItem = await ShippingItems.GetByIdAsync(shippingItem.Id);
if (dbShippingItem == null)
{
throw new Exception("dbShippingItem == null");
}
Product product = null;
if (shippingItem.ProductId > 0)
{
product = await Products.GetByIdAsync(shippingItem.ProductId);
if (product == null)
{
throw new Exception($"shippingItem.ProductId > 0 && product == null; shippingItem.ProductId: {shippingItem.ProductId}");
//shippingItem.ProductId = null;
//if (!dbShippingItem.IsMeasured) shippingItem.ProductId = null;
//else return await Task.FromResult(false);
}
}
shippingItem.IsMeasured = product != null && shippingItem.IsValidMeasuringValues();
await ShippingItems.UpdateAsync(shippingItem);
if (shippingItem.ProductId != dbShippingItem.ProductId ||
shippingItem.IsMeasured != dbShippingItem.IsMeasured || shippingItem.IsMeasurable != dbShippingItem.IsMeasurable ||
shippingItem.MeasuredQuantity != dbShippingItem.MeasuredQuantity ||
shippingItem.MeasuredNetWeight != dbShippingItem.MeasuredNetWeight || shippingItem.MeasuredGrossWeight != dbShippingItem.MeasuredGrossWeight)
{
var productIdUnchanged = shippingItem.ProductId == dbShippingItem.ProductId;
if (shippingItem.IsMeasured)
{
product!.StockQuantity += shippingItem.MeasuredQuantity.GetValueOrDefault(0) - dbShippingItem.MeasuredQuantity.GetValueOrDefault(0);
//IsMeasurable
//TODO: ROUND!!!! - J.
var measuringValues = new MeasuringAttributeValues
{
NetWeight = shippingItem.MeasuredNetWeight - dbShippingItem.MeasuredNetWeight,
GrossWeight = shippingItem.MeasuredGrossWeight- dbShippingItem.MeasuredGrossWeight,
IsMeasurable = shippingItem.IsMeasurable
};
if (!await UpdateProductStockQuantityAsync(product))
{
throw new Exception($"UpdateProductStockQuantity() == false; shippingItem! id: {product.Id}");
}
//var measuringValues = new MeasuringAttributeValues(shippingItem.MeasuredNetWeight, shippingItem.MeasuredGrossWeight, shippingItem.IsMeasurable);
await _fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync<Product>(product.Id, measuringValues, true);
}
if (productIdUnchanged) return true;
if (dbShippingItem.IsMeasured)
{
product = await Products.GetByIdAsync(dbShippingItem.ProductId);
if (product != null)
{
product.StockQuantity -= dbShippingItem.MeasuredQuantity.GetValueOrDefault(0);
if (!await UpdateProductStockQuantityAsync(product))
{
throw new Exception($"UpdateProductStockQuantity() == false; dbShippingItem! id: {product.Id}");
//return await Task.FromResult(false);
}
var measuringValues = new MeasuringAttributeValues(-dbShippingItem.MeasuredNetWeight, -dbShippingItem.MeasuredGrossWeight, dbShippingItem.IsMeasurable);
await _fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync<Product>(product.Id, measuringValues, true);
}
else Logger.Warning($"product == null; dbShippingItem.ProductId: {dbShippingItem.ProductId}");
}
}
//else //TODO: productIdUnchanged-et lekezelni! - J.
return true;
}
catch (Exception ex)
{
throw new Exception($"UpdateShippingItemAsync Transaction ERROR! Id: {shippingItem?.Id}; ex: {ex.Message}", ex);
}
});
}
private async Task<bool> UpdateProductStockQuantityAsync(int productId)
{
var product = await Products.GetByIdAsync(productId);
if (product != null) return await UpdateProductStockQuantityAsync(product);
Logger.Error($"product == null; id: {productId}");
return await Task.FromResult(false);
}
private async Task<bool> UpdateProductStockQuantityAsync(Product product)
{
//Itt mi legyen? RollBack? - J.
if (product.StockQuantity < 0)
Logger.Error($"product.StockQuantity < 0; Id: {product.Id}; StockQuantity: {product.StockQuantity}");
await Products.UpdateAsync(product, true);
return await Task.FromResult(true);
//var updatedRowsCount = await DataProvider.ExecuteNonQueryAsync($"update product set {nameof(Product.StockQuantity)} = {product.StockQuantity} where {nameof(Product.Id)} = {product.Id}");
//if (updatedRowsCount == 1) return await Task.FromResult(true);
//Logger.Error($"Product updatedRowsCount != 1; id: {product.Id}");
//return await Task.FromResult(false);
}
}