using System; using System.Collections.Generic; using System.Linq; using InABox.Core; namespace Comal.Classes { public class BillLineLink : EntityLink { [PopupEditor(typeof(BillLine))] public override Guid ID { get; set; } [RequiredColumn] public BillLink BillLink { get; set; } } internal class BillLineLookups : EntityLookup { public override Filter? DefineFilter() => null; public override SortOrder? DefineSortOrder() => null; public override Columns DefineColumns() { return base.DefineColumns().Add(x => x.BillLink.Number).Add(x => x.Description); } public override string FormatLookup(Dictionary values, IEnumerable exclude) { return base.FormatLookup(values, exclude); } } [UserTracking(typeof(Bill))] public class BillLine : Entity, IPersistent, IRemotable, IOneToMany, ITaxable, ILicense, IPostableFragment, IEntityLookup { [RequiredColumn] [EntityRelationship(DeleteAction.Cascade)] [NullEditor] public BillLink BillLink { get; set; } private class PurchaseOrderItemLookup : LookupDefinitionGenerator { public override Filter DefineFilter(BillLine[] items) { if (!items.Any()) return new Filter().None(); var supplierID = items.Select(x => x.BillLink.SupplierLink.ID).Distinct().SingleOrDefault(); if(supplierID == Guid.Empty) return new Filter().None(); return new Filter(x => x.PurchaseOrderLink.SupplierLink.ID).IsEqualTo(supplierID) .And(x=>x.BillLine.ID).IsEqualTo(Guid.Empty); } public override Columns DefineFilterColumns() { return Columns.None().Add(x => x.BillLink.SupplierLink.ID); } } [LookupDefinition(typeof(PurchaseOrderItemLookup))] [EntityRelationship(DeleteAction.SetNull)] [EditorSequence(1)] public PurchaseOrderItemLink OrderItem { get; set; } private class ConsignmentLookup : LookupDefinitionGenerator { public override Filter DefineFilter(BillLine[] items) { if (!items.Any()) return new Filter().None(); var supplierID = items.Select(x => x.BillLink.SupplierLink.ID).Distinct().SingleOrDefault(); if(supplierID == Guid.Empty) return new Filter().None(); return new Filter(x => x.Supplier.ID).IsEqualTo(supplierID) .And(x=>x.BillLine.ID).IsEqualTo(Guid.Empty); } public override Columns DefineFilterColumns() { return Columns.None().Add(x => x.BillLink.SupplierLink.ID); } } [LookupDefinition(typeof(ConsignmentLookup))] [EntityRelationship(DeleteAction.SetNull)] [EditorSequence(2)] public ConsignmentLink Consignment { get; set; } private class ProductLookupGenerator : LookupDefinitionGenerator { public override Filter? DefineFilter(BillLine[] items) => new Filter(x => x.NonStock).IsEqualTo(true); } [EditorSequence(3)] [LookupDefinition(typeof(ProductLookupGenerator))] public ProductLink Product { get; set; } [EditorSequence(4)] public JobLink Job { get; set; } [MemoEditor] [EditorSequence(5)] public string Description { get; set; } [CurrencyEditor(Summary=Summary.Sum)] [EditorSequence(6)] public double ForeignCurrencyCost { get; set; } [CurrencyEditor(Summary = Summary.Sum)] [EditorSequence(7)] public double ExTax { get; set; } [RequiredColumn] [EditorSequence(8)] public TaxCodeLink TaxCode { get; set; } [CurrencyEditor(Summary = Summary.Sum)] [EditorSequence(9)] public double Tax { get; set; } [CurrencyEditor(Summary = Summary.Sum)] [EditorSequence(10)] public double IncTax { get; set; } [EditorSequence(11)] public PurchaseGLCodeLink PurchaseGL { get; set; } [EditorSequence(12)] public CostCentreLink CostCentre { get; set; } [NullEditor] public double TaxRate { get; set; } [NullEditor] public string PostedReference { get; set; } static BillLine() { // If we select a product for this bill line LinkedProperties.Register(x => x.Product, x => x.Name, x => x.Description); LinkedProperties.Register(x => x.OrderItem, x => x.ExTax, x => x.ExTax); LinkedProperties.Register(x => x.OrderItem.PurchaseGL, x => x.ID, x => x.PurchaseGL.ID); LinkedProperties.Register(x => x.OrderItem.CostCentre, x => x.ID, x => x.CostCentre.ID); LinkedProperties.Register(x => x.OrderItem.TaxCode, x => x.ID, x => x.TaxCode.ID); LinkedProperties.Register(x => x.OrderItem.TaxCode, x => x.Code, x => x.TaxCode.Code); LinkedProperties.Register(x => x.OrderItem.TaxCode, x => x.Description, x => x.TaxCode.Description); LinkedProperties.Register(x => x.OrderItem.TaxCode, x => x.Rate, x => x.TaxCode.Rate); LinkedProperties.Register(x => x.OrderItem, x => x.Tax, x => x.Tax); LinkedProperties.Register(x => x.OrderItem, x => x.IncTax, x => x.IncTax); LinkedProperties.Register(x => x.TaxCode, x => x.Rate, x => x.TaxRate); LinkedProperties.Register(x => x.Product.PurchaseGL, x => x.ID, x => x.PurchaseGL.ID); LinkedProperties.Register(x => x.Product.CostCentre, x => x.ID, x => x.CostCentre.ID); LinkedProperties.Register(x => x.Product.TaxCode, x => x.ID, x => x.TaxCode.ID); LinkedProperties.Register(x => x.Product.TaxCode, x => x.Code, x => x.TaxCode.Code); LinkedProperties.Register(x => x.Product.TaxCode, x => x.Description, x => x.TaxCode.Description); LinkedProperties.Register(x => x.Product.TaxCode, x => x.Rate, x => x.TaxCode.Rate); } private static readonly Column OrderItemColumn = new Column(x => x.OrderItem.ID); private static readonly Column ProductColumn = new Column(x => x.Product.ID); private static readonly Column JobColumn = new Column(x => x.Job.ID); private static readonly Column ForeignCurrencyColumn = new Column(x => x.ForeignCurrencyCost); private static readonly Column ExTaxColumn = new Column(x => x.ExTax); private static readonly Column IncTaxColumn = new Column(x => x.ExTax); private bool bChanging = false; protected override void DoPropertyChanged(string name, object? before, object? after) { if (bChanging) return; bChanging = true; try { base.DoPropertyChanged(name, before, after); if (OrderItemColumn.IsEqualTo(name) && after is Guid orderItemID && orderItemID != Guid.Empty) { Product.ID = Guid.Empty; Product.Clear(); Job.ID = Guid.Empty; Job.Clear(); } else if((ProductColumn.IsEqualTo(name) && after is Guid productID && productID != Guid.Empty) || (JobColumn.IsEqualTo(name) && after is Guid jobID && jobID != Guid.Empty)) { OrderItem.ID = Guid.Empty; OrderItem.Clear(); } else if (ForeignCurrencyColumn.IsEqualTo(name) && after is double fcc) { ExTax = fcc / (BillLink.SupplierLink.Currency.ExchangeRate.IsEffectivelyEqual(0.0) ? 1.0 : BillLink.SupplierLink.Currency.ExchangeRate); Tax = ExTax * TaxRate / 100.0; IncTax = ExTax + Tax; } else if (ExTaxColumn.IsEqualTo(name) && after is double etc) { ForeignCurrencyCost = etc * (BillLink.SupplierLink.Currency.ExchangeRate.IsEffectivelyEqual(0.0) ? 1.0 : BillLink.SupplierLink.Currency.ExchangeRate); } else if (IncTaxColumn.IsEqualTo(name) && after is double itc) { ForeignCurrencyCost = ExTax * (BillLink.SupplierLink.Currency.ExchangeRate.IsEffectivelyEqual(0.0) ? 1.0 : BillLink.SupplierLink.Currency.ExchangeRate); } } finally { bChanging = false; } } } }