using System; using InABox.Core; using PRSClasses; namespace Comal.Classes { [UserTracking("Product Management")] public class Product : DimensionedEntity, IPersistent, IRemotable, IIssues, ILicense, IExportable, IImportable, IMergeable { [UniqueCodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)] [EditorSequence(1)] public string Code { get; set; } [TextBoxEditor] [EditorSequence(2)] public string Name { get; set; } [EditorSequence(3)] public ProductStyleLink DefaultStyle { get; set; } [NullEditor] [Obsolete("Replaced with Dimensions", true)] // [DoubleEditor] // [EditorSequence(4)] public double UnitSize { get; set; } [NullEditor] [Obsolete("Replaced with Dimensions", false)] // [EditorSequence(5)] public ProductUOMLink Units { get; set; } [NullEditor] [Obsolete("Replaced with Dimensions", true)] // [DoubleEditor] // [EditorSequence(6)] // [Caption("Standard Weight")] public double Weight { get; set; } [EditorSequence(4)] [RequiredColumn] [DimensionsEditor(typeof(ProductDimensions))] public override ProductDimensions Dimensions { get; set; } [EditorSequence(7)] public ProductGroupLink Group { get; set; } [EditorSequence(8)] [DataModelTableName("Image")] public ImageDocumentLink Image { get; set; } [URLEditor] [EditorSequence(9)] public string URL { get; set; } [TimestampEditor] [EditorSequence(10)] public DateTime Expired { get; set; } [EnumLookupEditor(typeof(ProductPricingStrategy))] [EditorSequence("Pricing", 1)] public ProductPricingStrategy PricingStrategy { get; set; } [EditorSequence("Pricing", 2)] public SupplierProductLink Supplier { get; set; } [CheckBoxEditor] [EditorSequence("Pricing", 3)] public bool UseDefaultSupplierPricing { get; set; } [CurrencyEditor(Visible = Visible.Optional)] [EditorSequence("Pricing", 4)] public double BaseCost { get; set; } [Aggregate(typeof(ProductComponentCost))] [CurrencyEditor(Visible = Visible.Optional)] //, Editable = Editable.Disabled)] [EditorSequence("Pricing", 5)] public double ComponentCost { get; set; } [CurrencyEditor(Visible = Visible.Optional, Editable = Editable.Disabled)] [EditorSequence("Pricing", 6)] public double NettCost { get; set; } [CurrencyEditor(Visible = Visible.Optional, Editable = Editable.Disabled)] [EditorSequence("Pricing", 7)] [LoggableProperty] public double AverageCost { get; set; } [EditorSequence("Pricing", 8)] public TaxCodeLink TaxCode { get; set; } [EditorSequence("Pricing", 9)] public GLCodeLink PurchaseGL { get; set; } [EditorSequence("Pricing", 10)] public GLCodeLink SellGL { get; set; } [EditorSequence("Pricing", 11)] public CostCentreLink CostCentre { get; set; } [EditorSequence("Pricing", 12)] public CostSheetSectionLink CostSheetSection { get; set; } [ProductChargeEditor] [EditorSequence("Pricing", 13)] public ProductCharge Charge { get; set; } /// /// Flag to indicate whether stock movements are to be tracked for this item /// If set, no stock movements will be recorded, even if the Warehouse and/or default location are set /// [CheckBoxEditor] [EditorSequence("Warehousing", 1)] public bool NonStock { get; set; } /// /// The Warehouse that this item resides in. DefaultLocation Lookups are limited to this Warehouse only, although /// actual stock holdings can be anywhere (imperfect systems) /// [EditorSequence("Warehousing", 2)] public StockWarehouseLink Warehouse { get; set; } [IntegerEditor] [EditorSequence("Warehousing", 3)] public int MinimumStockLevel { get; set; } /// /// (Optional) The Location to be used when Purchase Orders / Consignments are received. /// If blank, the item will be received into the default location for the Warehouse assign to the product /// If that is also blank, then no stock movement will be recorded when receiving the item /// [EditorSequence("Warehousing", 4)] public StockLocationLink DefaultLocation { get; set; } [Caption("Incoming QA")] [EditorSequence("Warehousing", 5)] public DigitalFormLink DigitalForm { get; set; } [NullEditor] public string Barcodes { get; set; } [Aggregate(typeof(ProductUnitAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double UnitQty { get; set; } [Aggregate(typeof(ProductRemnantAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double RemnantQty { get; set; } [Aggregate(typeof(OnOrderAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double OnOrder { get; set; } [Aggregate(typeof(TotalStockAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double TotalStock { get; set; } [Formula(typeof(ReservedStockFormula))] [DoubleEditor(Editable = Editable.Hidden)] public double ReservedStock { get; set; } [Aggregate(typeof(FreeStockAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double FreeStock { get; set; } [Aggregate(typeof(TotalRequiredAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double Required { get; set; } [Aggregate(typeof(ProductReceivedAggregate))] [DateTimeEditor(Editable = Editable.Hidden)] public DateTime LastReceived { get; set; } [Aggregate(typeof(ProductIssuedAggregate))] [DateTimeEditor(Editable = Editable.Hidden)] public DateTime LastIssued { get; set; } [NullEditor] public string Issues { get; set; } public override string ToString() { return string.Format("{0}: {1} ({2})", Code, Name, Dimensions.UnitSize); } protected override void Init() { base.Init(); Supplier = new SupplierProductLink(); //UnitSize = 1.0F; Units = new ProductUOMLink(); Group = new ProductGroupLink(); CostCentre = new CostCentreLink(); PurchaseGL = new GLCodeLink(); SellGL = new GLCodeLink(); CostSheetSection = new CostSheetSectionLink(); PricingStrategy = ProductPricingStrategy.Standard; TaxCode = new TaxCodeLink(() => this); Image = new ImageDocumentLink(); Warehouse = new StockWarehouseLink(); DigitalForm = new DigitalFormLink(); DefaultLocation = new StockLocationLink(); DefaultStyle = new ProductStyleLink(); NonStock = false; UseDefaultSupplierPricing = true; Dimensions = new ProductDimensions(() => this); Charge = new ProductCharge(); } public static double CalculateNettCost(ProductPricingStrategy strategy, double basecost, double componentcost) { if (strategy == ProductPricingStrategy.Kit) return basecost + componentcost; if (strategy == ProductPricingStrategy.Subcontractor) return basecost - componentcost; // Standard or Assembly return basecost; } } public class ProductFormLookups : ILookupDefinition { public Filter DefineFilter(Product[] items) { // Get all FillableFormTypes where 2nd parameter is typeof(PurchaseOrder) return new Filter(x => x.Active).IsEqualTo(true).And(x => x.AppliesTo).IsEqualTo("PurchaseOrderItem"); } Columns ILookupDefinition.DefineFilterColumns() => new Columns(); } }