using AyCode.Core.Loggers; using FruitBank.Common.Entities; using FruitBank.Common.Interfaces; using FruitBank.Common.Models; using Mango.Nop.Core.Loggers; using Mango.Nop.Core.Repositories; using Nop.Core.Caching; using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Customers; using Nop.Data; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer.Interfaces; using Nop.Services.Catalog; using NUglify.Helpers; using System.Transactions; using LinqToDB; using Nop.Core.ComponentModel; namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; public class FruitBankDbContext : MgDbContextBase, IPartnerDbSet, IShippingDbSet, IShippingItemDbSet, IShippingDocumentDbSet { 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 Products { get; set; } public IRepository Customers { get; set; } public IRepository CustomerRoles { get; set; } public IRepository CustomerRoleMappings { get; set; } public FruitBankDbContext(INopDataProvider dataProvider, PartnerDbTable partnerDbTable, ShippingDbTable shippingDbTable, ShippingItemDbTable shippingItemDbTable, ShippingDocumentDbTable shippingDocumentDbTable, IProductService productService, IStaticCacheManager staticCacheManager, IRepository productRepository, IRepository customerRepository, IRepository customerCustomerRoleMappingRepository, IRepository customerRoleRepository, IEnumerable logWriters) : base(dataProvider, logWriters) { _productService = productService; _staticCacheManager = staticCacheManager; Partners = partnerDbTable; Shippings = shippingDbTable; ShippingItems = shippingItemDbTable; ShippingDocuments = shippingDocumentDbTable; Products = productRepository; Customers = customerRepository; CustomerRoles = customerRoleRepository; CustomerRoleMappings = customerCustomerRoleMappingRepository; } public IQueryable 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 GetCustormersBySystemRoleName(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 GetAllProducts() => Products.Table.Where(p => !p.Deleted).OrderBy(o => o.Name); public Task UpdateMeasuredShippingItemAsync(ShippingItem shippingItem) { if (!shippingItem.IsMeasurable || shippingItem.IsValidMeasuringValues()) return UpdateShippingItemAsync(shippingItem); Logger.Error("shippingItem.IsMeasurable && !shippingItem.IsValidMeasuringValues()"); return Task.FromResult(false); } private static readonly ReaderWriterLockSlim _locker = new(LockRecursionPolicy.NoRecursion); public async Task UpdateShippingItemAsync(ShippingItem shippingItem) { if (shippingItem == null) { Logger.Error("shippingItem == null"); return await Task.FromResult(false); } //using (new ReaderWriteLockDisposable(_locker)) //_locker.EnterWriteLock(); //try //{ using var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled); 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) { Logger.Error("dbShippingItem == null"); return await Task.FromResult(false); } Product product = null; if (shippingItem.ProductId > 0) { product = await Products.GetByIdAsync(shippingItem.ProductId); if (product == null) { Logger.Error($"shippingItem.ProductId > 0 && product == null; shippingItem.ProductId: {shippingItem.ProductId}"); return await Task.FromResult(false); } } shippingItem.IsMeasured = product != null && shippingItem.IsValidMeasuringValues(); await ShippingItems.UpdateAsync(shippingItem); //TODO: a measuredweight-eket is! - J. 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); if (!await UpdateProductStockQuantityAsync(product)) { Logger.Error($"UpdateProductStockQuantity() == false; shippingItem! id: {product.Id}"); return await Task.FromResult(false); } } if (dbShippingItem.IsMeasured) { product = await Products.GetByIdAsync(dbShippingItem.ProductId); if (product != null) { product.StockQuantity -= dbShippingItem.MeasuredQuantity.GetValueOrDefault(0); if (!await UpdateProductStockQuantityAsync(product)) { Logger.Error($"UpdateProductStockQuantity() == false; dbShippingItem! id: {product.Id}"); return await Task.FromResult(false); } } else Logger.Warning($"product == null; dbShippingItem.ProductId: {dbShippingItem.ProductId}"); } } //else //TODO: productIdUnchanged-et lekezelni! - J. } catch (Exception ex) { Logger.Error($"UpdateShippingItemAsync Transaction ERROR! Id: {shippingItem?.Id}", ex); return await Task.FromResult(false); } transaction.Complete(); //} //finally //{ // _locker.ExitWriteLock(); //} return await Task.FromResult(true); } private async Task 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 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); } }