123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Comal.Classes;
- using InABox.Core;
- namespace Comal.Stores
- {
- public class BaseProductStore<T> : BaseStore<T> where T : Entity, new()
- {
- /// <summary>
- /// Update the ComponentCost and NettCost of any Product that contains this one
- /// as a component
- /// </summary>
- /// <param name="entity"></param>
- protected void UpdateProductComponentCost(Product entity)
- {
- // Extract all the Products that Contain this one as a component
- var products = Provider.Query(
- new Filter<ProductPriceComponent>(x => x.Component.ID).IsEqualTo(entity.ID),
- new Columns<ProductPriceComponent>(
- x => x.ID,
- x => x.Product.ID,
- x => x.Product.PricingStrategy,
- x => x.Product.BaseCost
- )
- );
- if (!products.Rows.Any())
- return;
- // All the info we need, we can extract from the product link, so we don't need to
- // go back to the database and incur another query penalty
- var infos = products.Rows.Select(x =>
- new ProdInfo
- {
- ProductID = x.Get<ProductPriceComponent, Guid>(c => c.Product.ID),
- Strategy = x.Get<ProductPriceComponent, ProductPricingStrategy>(c => c.Product.PricingStrategy),
- BaseCost = x.Get<ProductPriceComponent, double>(c => c.Product.BaseCost)
- }
- ).Distinct().ToArray();
- var ids = infos.Select(x => x.ProductID).ToArray();
- // Now get all the components that these products contain
- // We _could_ use the delta NettCost the for the entity (newvalue-oldvalue)
- // And skip this part, but then it will be hard to fix any errors that might creep in,
- // and we also will need to do this anyway for new products, etc
- var components = Provider.Query(
- new Filter<ProductPriceComponent>(x => x.Product.ID).InList(ids),
- new Columns<ProductPriceComponent>(
- x => x.Product.ID,
- x => x.NettCost
- )
- );
- // Now construct the required updates
- var updates = new List<Product>();
- foreach (var info in infos)
- {
- double compcost = 0.0F;
- components.Rows
- .Where(r => r.Get<ProductPriceComponent, Guid>(c => c.Product.ID).Equals(info.ProductID))
- .Select(r => r.Get<ProductPriceComponent, double>(c => c.NettCost))
- .ToList()
- .ForEach(x => compcost += x);
- if (info.Strategy != ProductPricingStrategy.Assembly)
- {
- var update = new Product
- {
- ID = info.ProductID,
- NettCost = Product.CalculateNettCost(info.Strategy, info.BaseCost, compcost)
- };
- updates.Add(update);
- }
- }
- Provider.Save(updates);
- }
- /// <summary>
- /// Update the Base Cost of any product that has this supplier price as its default
- /// </summary>
- /// <param name="entity"></param>
- protected void UpdateDefaultSupplierPricing(SupplierProduct entity)
- {
- var product = Provider.Query(
- new Filter<Product>(x => x.Supplier.ID).IsEqualTo(entity.ID).And(x => x.UseDefaultSupplierPricing).IsEqualTo(true),
- new Columns<Product>(
- x => x.ID,
- x => x.PricingStrategy,
- x => x.BaseCost,
- x => x.ComponentCost,
- x => x.NettCost
- )
- ).Rows.FirstOrDefault()?.ToObject<Product>();
- if (product != null)
- {
- product.BaseCost = entity.CostPrice;
- product.NettCost = Product.CalculateNettCost(product.PricingStrategy, product.BaseCost, product.ComponentCost);
- product.TaxCode.ID = entity.TaxCode.ID;
- if (product.IsChanged())
- {
- Provider.Save(product);
- UpdateProductComponentCost(product);
- }
- }
- }
- private struct ProdInfo
- {
- public Guid ProductID;
- public ProductPricingStrategy Strategy;
- public double BaseCost;
- }
- }
- }
|