private static void BaseCalculateTotalRevenue(this WorkEffort @this, WorkEffortCalculateTotalRevenue method) { if (!method.Result.HasValue) { ((WorkEffortDerivedRoles)@this).TotalLabourRevenue = Rounder.RoundDecimal(@this.BillableTimeEntries().Sum(v => v.BillingAmount), 2); ((WorkEffortDerivedRoles)@this).TotalMaterialRevenue = Rounder.RoundDecimal(@this.WorkEffortInventoryAssignmentsWhereAssignment.Where(v => v.DerivedBillableQuantity > 0).Sum(v => v.DerivedBillableQuantity * v.UnitSellingPrice), 2); ((WorkEffortDerivedRoles)@this).TotalSubContractedRevenue = Rounder.RoundDecimal(@this.WorkEffortPurchaseOrderItemAssignmentsWhereAssignment.Sum(v => v.Quantity * v.UnitSellingPrice), 2); var totalRevenue = Rounder.RoundDecimal(@this.TotalLabourRevenue + @this.TotalMaterialRevenue + @this.TotalSubContractedRevenue, 2); method.Result = true; ((WorkEffortDerivedRoles)@this).GrandTotal = totalRevenue; ((WorkEffortDerivedRoles)@this).TotalRevenue = @this.Customer.Equals(@this.ExecutedBy) ? 0M : totalRevenue; } }
public static decimal ConvertCurrency(decimal amount, DateTime validFrom, Currency fromCurrency, Currency toCurrency) { if (!fromCurrency.Equals(toCurrency)) { var exchangeRate = fromCurrency.ExchangeRatesWhereFromCurrency.Where(v => v.ValidFrom.Date <= validFrom.Date && v.ToCurrency.Equals(toCurrency)).OrderByDescending(v => v.ValidFrom).FirstOrDefault(); if (exchangeRate != null) { return(Rounder.RoundDecimal(amount * exchangeRate.Rate, 2)); } else { var invertedExchangeRate = toCurrency.ExchangeRatesWhereFromCurrency.Where(v => v.ValidFrom.Date <= validFrom.Date && v.ToCurrency.Equals(fromCurrency)).OrderByDescending(v => v.ValidFrom).FirstOrDefault(); if (invertedExchangeRate != null) { return(Rounder.RoundDecimal(amount * (1 / invertedExchangeRate.Rate), 2)); } } return(0); } return(amount); }
public void BaseOnDerive(ObjectOnDerive method) { var derivation = method.Derivation; var session = this.Session(); this.ValidQuoteItems = this.QuoteItems.Where(v => v.IsValid).ToArray(); var currentPriceComponents = new PriceComponents(session).CurrentPriceComponents(this.IssueDate); var quantityOrderedByProduct = this.ValidQuoteItems .Where(v => v.ExistProduct) .GroupBy(v => v.Product) .ToDictionary(v => v.Key, v => v.Sum(w => w.Quantity)); // First run to calculate price foreach (QuoteItem quoteItem in this.ValidQuoteItems) { decimal quantityOrdered = 0; if (quoteItem.ExistProduct) { quantityOrderedByProduct.TryGetValue(quoteItem.Product, out quantityOrdered); } foreach (QuoteItem featureItem in quoteItem.QuotedWithFeatures) { featureItem.Quantity = quoteItem.Quantity; this.CalculatePrices(derivation, featureItem, currentPriceComponents, quantityOrdered, 0); } this.CalculatePrices(derivation, quoteItem, currentPriceComponents, quantityOrdered, 0); } var totalBasePriceByProduct = this.QuoteItems .Where(v => v.ExistProduct) .GroupBy(v => v.Product) .ToDictionary(v => v.Key, v => v.Sum(w => w.TotalBasePrice)); // Second run to calculate price (because of order value break) foreach (QuoteItem quoteItem in this.ValidQuoteItems) { decimal quantityOrdered = 0; decimal totalBasePrice = 0; if (quoteItem.ExistProduct) { quantityOrderedByProduct.TryGetValue(quoteItem.Product, out quantityOrdered); totalBasePriceByProduct.TryGetValue(quoteItem.Product, out totalBasePrice); } foreach (QuoteItem featureItem in quoteItem.QuotedWithFeatures) { this.CalculatePrices(derivation, featureItem, currentPriceComponents, quantityOrdered, totalBasePrice); } this.CalculatePrices(derivation, quoteItem, currentPriceComponents, quantityOrdered, totalBasePrice); } // SalesOrderItem Derivations and Validations foreach (QuoteItem quoteItem in this.ValidQuoteItems) { var isSubTotalItem = quoteItem.ExistInvoiceItemType && (quoteItem.InvoiceItemType.IsProductItem || quoteItem.InvoiceItemType.IsPartItem); if (isSubTotalItem) { if (quoteItem.Quantity == 0) { derivation.Validation.AddError(quoteItem, M.QuoteItem.Quantity, "Quantity is Required"); } } else { if (quoteItem.UnitPrice == 0) { derivation.Validation.AddError(quoteItem, M.QuoteItem.UnitPrice, "Price is Required"); } } } // Calculate Totals this.TotalBasePrice = 0; this.TotalDiscount = 0; this.TotalSurcharge = 0; this.TotalExVat = 0; this.TotalFee = 0; this.TotalShippingAndHandling = 0; this.TotalExtraCharge = 0; this.TotalVat = 0; this.TotalIrpf = 0; this.TotalIncVat = 0; this.TotalListPrice = 0; this.GrandTotal = 0; foreach (QuoteItem quoteItem in this.ValidQuoteItems) { if (!quoteItem.ExistQuoteItemWhereQuotedWithFeature) { this.TotalBasePrice += quoteItem.TotalBasePrice; this.TotalDiscount += quoteItem.TotalDiscount; this.TotalSurcharge += quoteItem.TotalSurcharge; this.TotalExVat += quoteItem.TotalExVat; this.TotalVat += quoteItem.TotalVat; this.TotalIrpf += quoteItem.TotalIrpf; this.TotalIncVat += quoteItem.TotalIncVat; this.TotalListPrice += quoteItem.TotalExVat; this.GrandTotal += quoteItem.GrandTotal; } } var discount = 0M; var discountVat = 0M; var discountIrpf = 0M; var surcharge = 0M; var surchargeVat = 0M; var surchargeIrpf = 0M; var fee = 0M; var feeVat = 0M; var feeIrpf = 0M; var shipping = 0M; var shippingVat = 0M; var shippingIrpf = 0M; var miscellaneous = 0M; var miscellaneousVat = 0M; var miscellaneousIrpf = 0M; if (this.ExistIssueDate) { this.DerivedVatRate = this.DerivedVatRegime?.VatRates.First(v => v.FromDate <= this.IssueDate && (!v.ExistThroughDate || v.ThroughDate >= this.IssueDate)); this.DerivedIrpfRate = this.DerivedIrpfRegime?.IrpfRates.First(v => v.FromDate <= this.IssueDate && (!v.ExistThroughDate || v.ThroughDate >= this.IssueDate)); } foreach (OrderAdjustment orderAdjustment in this.OrderAdjustments) { if (orderAdjustment.GetType().Name.Equals(typeof(DiscountAdjustment).Name)) { discount = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalDiscount += discount; if (this.ExistDerivedVatRegime) { discountVat = discount * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { discountIrpf = discount * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(SurchargeAdjustment).Name)) { surcharge = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalSurcharge += surcharge; if (this.ExistDerivedVatRegime) { surchargeVat = surcharge * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { surchargeIrpf = surcharge * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(Fee).Name)) { fee = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalFee += fee; if (this.ExistDerivedVatRegime) { feeVat = fee * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { feeIrpf = fee * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(ShippingAndHandlingCharge).Name)) { shipping = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalShippingAndHandling += shipping; if (this.ExistDerivedVatRegime) { shippingVat = shipping * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { shippingIrpf = shipping * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(MiscellaneousCharge).Name)) { miscellaneous = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalExtraCharge += miscellaneous; if (this.ExistDerivedVatRegime) { miscellaneousVat = miscellaneous * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { miscellaneousIrpf = miscellaneous * this.DerivedIrpfRate.Rate / 100; } } } var totalExtraCharge = fee + shipping + miscellaneous; var totalExVat = this.TotalExVat - discount + surcharge + fee + shipping + miscellaneous; var totalVat = this.TotalVat - discountVat + surchargeVat + feeVat + shippingVat + miscellaneousVat; var totalIncVat = this.TotalIncVat - discount - discountVat + surcharge + surchargeVat + fee + feeVat + shipping + shippingVat + miscellaneous + miscellaneousVat; var totalIrpf = this.TotalIrpf + discountIrpf - surchargeIrpf - feeIrpf - shippingIrpf - miscellaneousIrpf; var grandTotal = totalIncVat - totalIrpf; if (this.ExistIssueDate && this.ExistDerivedCurrency && this.ExistIssuer) { this.TotalBasePriceInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalBasePrice, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalDiscountInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalDiscount, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalSurchargeInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalSurcharge, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalExtraChargeInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalExtraCharge, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalFeeInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalFee, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalShippingAndHandlingInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalShippingAndHandling, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalExVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalExVat, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalVat, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalIncVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalIncVat, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalIrpfInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalIrpf, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.GrandTotalInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(grandTotal, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); } this.TotalBasePrice = Rounder.RoundDecimal(this.TotalBasePrice, 2); this.TotalDiscount = Rounder.RoundDecimal(this.TotalDiscount, 2); this.TotalSurcharge = Rounder.RoundDecimal(this.TotalSurcharge, 2); this.TotalExtraCharge = Rounder.RoundDecimal(totalExtraCharge, 2); this.TotalFee = Rounder.RoundDecimal(this.TotalFee, 2); this.TotalShippingAndHandling = Rounder.RoundDecimal(this.TotalShippingAndHandling, 2); this.TotalExVat = Rounder.RoundDecimal(totalExVat, 2); this.TotalVat = Rounder.RoundDecimal(totalVat, 2); this.TotalIncVat = Rounder.RoundDecimal(totalIncVat, 2); this.TotalIrpf = Rounder.RoundDecimal(totalIrpf, 2); this.GrandTotal = Rounder.RoundDecimal(grandTotal, 2); //// Only take into account items for which there is data at the item level. //// Skip negative sales. decimal totalUnitBasePrice = 0; decimal totalListPrice = 0; foreach (QuoteItem item1 in this.ValidQuoteItems) { if (item1.TotalExVat > 0) { totalUnitBasePrice += item1.UnitBasePrice; totalListPrice += item1.UnitPrice; } } this.TotalListPriceInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(TotalListPrice, this.IssueDate, this.DerivedCurrency, this.Issuer.PreferredCurrency), 2); this.TotalListPrice = Rounder.RoundDecimal(this.TotalListPrice, 2); this.DeriveWorkflow(); this.Sync(this.Strategy.Session); this.ResetPrintDocument(); }
public void CalculatePrices( IDerivation derivation, QuoteItem quoteItem, PriceComponent[] currentPriceComponents, decimal quantityOrdered, decimal totalBasePrice) { var quoteItemDeriveRoles = (QuoteItemDerivedRoles)quoteItem; var currentGenericOrProductOrFeaturePriceComponents = Array.Empty <PriceComponent>(); if (quoteItem.ExistProduct) { currentGenericOrProductOrFeaturePriceComponents = quoteItem.Product.GetPriceComponents(currentPriceComponents); } else if (quoteItem.ExistProductFeature) { currentGenericOrProductOrFeaturePriceComponents = quoteItem.ProductFeature.GetPriceComponents(quoteItem.QuoteItemWhereQuotedWithFeature.Product, currentPriceComponents); } var priceComponents = currentGenericOrProductOrFeaturePriceComponents.Where( v => PriceComponents.BaseIsApplicable( new PriceComponents.IsApplicable { PriceComponent = v, Customer = this.Receiver, Product = quoteItem.Product, QuantityOrdered = quantityOrdered, ValueOrdered = totalBasePrice, })).ToArray(); var unitBasePrice = priceComponents.OfType <BasePrice>().Min(v => v.Price); // Calculate Unit Price (with Discounts and Surcharges) if (quoteItem.AssignedUnitPrice.HasValue) { quoteItemDeriveRoles.UnitBasePrice = unitBasePrice ?? quoteItem.AssignedUnitPrice.Value; quoteItemDeriveRoles.UnitDiscount = 0; quoteItemDeriveRoles.UnitSurcharge = 0; quoteItemDeriveRoles.UnitPrice = quoteItem.AssignedUnitPrice.Value; } else { quoteItemDeriveRoles.UnitBasePrice = unitBasePrice.Value; quoteItemDeriveRoles.UnitDiscount = priceComponents.OfType <DiscountComponent>().Sum( v => v.Percentage.HasValue ? quoteItem.UnitBasePrice * v.Percentage.Value / 100 : v.Price ?? 0); quoteItemDeriveRoles.UnitSurcharge = priceComponents.OfType <SurchargeComponent>().Sum( v => v.Percentage.HasValue ? quoteItem.UnitBasePrice * v.Percentage.Value / 100 : v.Price ?? 0); quoteItemDeriveRoles.UnitPrice = quoteItem.UnitBasePrice - quoteItem.UnitDiscount + quoteItem.UnitSurcharge; foreach (OrderAdjustment orderAdjustment in quoteItem.DiscountAdjustments) { quoteItemDeriveRoles.UnitDiscount += orderAdjustment.Percentage.HasValue ? quoteItem.UnitPrice * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; } foreach (OrderAdjustment orderAdjustment in quoteItem.SurchargeAdjustments) { quoteItemDeriveRoles.UnitSurcharge += orderAdjustment.Percentage.HasValue ? quoteItem.UnitPrice * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; } quoteItemDeriveRoles.UnitPrice = quoteItem.UnitBasePrice - quoteItem.UnitDiscount + quoteItem.UnitSurcharge; } foreach (QuoteItem featureItem in quoteItem.QuotedWithFeatures) { quoteItemDeriveRoles.UnitBasePrice += featureItem.UnitBasePrice; quoteItemDeriveRoles.UnitPrice += featureItem.UnitPrice; quoteItemDeriveRoles.UnitDiscount += featureItem.UnitDiscount; quoteItemDeriveRoles.UnitSurcharge += featureItem.UnitSurcharge; } quoteItemDeriveRoles.UnitVat = quoteItem.ExistVatRate ? quoteItem.UnitPrice * quoteItem.VatRate.Rate / 100 : 0; quoteItemDeriveRoles.UnitIrpf = quoteItem.ExistIrpfRate ? quoteItem.UnitPrice * quoteItem.IrpfRate.Rate / 100 : 0; // Calculate Totals quoteItemDeriveRoles.TotalBasePrice = quoteItem.UnitBasePrice * quoteItem.Quantity; quoteItemDeriveRoles.TotalDiscount = quoteItem.UnitDiscount * quoteItem.Quantity; quoteItemDeriveRoles.TotalSurcharge = quoteItem.UnitSurcharge * quoteItem.Quantity; quoteItemDeriveRoles.TotalPriceAdjustment = quoteItem.TotalSurcharge - quoteItem.TotalDiscount; if (quoteItem.TotalBasePrice > 0) { quoteItemDeriveRoles.TotalDiscountAsPercentage = Rounder.RoundDecimal(quoteItem.TotalDiscount / quoteItem.TotalBasePrice * 100, 2); quoteItemDeriveRoles.TotalSurchargeAsPercentage = Rounder.RoundDecimal(quoteItem.TotalSurcharge / quoteItem.TotalBasePrice * 100, 2); } else { quoteItemDeriveRoles.TotalDiscountAsPercentage = 0; quoteItemDeriveRoles.TotalSurchargeAsPercentage = 0; } quoteItemDeriveRoles.TotalExVat = quoteItem.UnitPrice * quoteItem.Quantity; quoteItemDeriveRoles.TotalVat = quoteItem.UnitVat * quoteItem.Quantity; quoteItemDeriveRoles.TotalIncVat = quoteItem.TotalExVat + quoteItem.TotalVat; quoteItemDeriveRoles.TotalIrpf = quoteItem.UnitIrpf * quoteItem.Quantity; quoteItemDeriveRoles.GrandTotal = quoteItem.TotalIncVat - quoteItem.TotalIrpf; }
public void BaseOnDerive(ObjectOnDerive method) { var derivation = method.Derivation; derivation.Validation.AssertExists(this, this.Meta.TimeSheetWhereTimeEntry); derivation.Validation.AssertAtLeastOne(this, this.Meta.WorkEffort, this.Meta.EngagementItem); var useInternalRate = this.WorkEffort?.Customer is Organisation organisation && organisation.IsInternalOrganisation; var rateType = useInternalRate ? new RateTypes(this.Session()).InternalRate : this.RateType; if (this.ExistTimeSheetWhereTimeEntry) { this.Worker = this.TimeSheetWhereTimeEntry.Worker; } //if (this.ExistWorker) //{ // var otherActiveTimeEntry = this.Worker.TimeEntriesWhereWorker.FirstOrDefault(v => // v.Id != this.Id // && ((v.FromDate < this.FromDate && (!v.ExistThroughDate || v.ThroughDate > this.FromDate)) // || (v.FromDate > this.FromDate && v.FromDate < this.ThroughDate))); // if (otherActiveTimeEntry != null) // { // derivation.Validation.AddError(this, this.Meta.Worker, ErrorMessages.WorkerActiveTimeEntry.Replace("{0}", otherActiveTimeEntry.WorkEffort?.WorkEffortNumber)); // } //} var billingRate = 0M; if (this.AssignedBillingRate.HasValue) { billingRate = this.AssignedBillingRate.Value; } else { if (this.ExistWorkEffort) { var workEffortAssignmentRate = this.WorkEffort.WorkEffortAssignmentRatesWhereWorkEffort.FirstOrDefault(v => v.RateType.Equals(this.RateType) && v.Frequency.Equals(this.BillingFrequency)); if (workEffortAssignmentRate != null) { billingRate = workEffortAssignmentRate.Rate; } } if (billingRate == 0 && this.ExistWorkEffort && this.WorkEffort.ExistCustomer && (this.WorkEffort.Customer as Organisation)?.IsInternalOrganisation == false) { var partyRate = this.WorkEffort.Customer.PartyRates.FirstOrDefault(v => v.RateType.Equals(rateType) && v.Frequency.Equals(this.BillingFrequency) && v.FromDate <= this.FromDate && (!v.ExistThroughDate || v.ThroughDate >= this.FromDate)); if (partyRate != null) { billingRate = partyRate.Rate; } } if (billingRate == 0 && this.ExistWorker && this.ExistRateType) { var partyRate = this.Worker.PartyRates.FirstOrDefault(v => v.RateType.Equals(rateType) && v.Frequency.Equals(this.BillingFrequency) && v.FromDate <= this.FromDate && (!v.ExistThroughDate || v.ThroughDate >= this.FromDate)); if (partyRate != null) { billingRate = partyRate.Rate; } } if (billingRate == 0 && this.ExistWorkEffort && this.WorkEffort.ExistExecutedBy) { var partyRate = this.WorkEffort.ExecutedBy.PartyRates.FirstOrDefault(v => v.RateType.Equals(rateType) && v.Frequency.Equals(this.BillingFrequency) && v.FromDate <= this.FromDate && (!v.ExistThroughDate || v.ThroughDate >= this.FromDate)); if (partyRate != null) { billingRate = partyRate.Rate; } } } // rate before uplift var costRate = billingRate; if (useInternalRate && this.WorkEffort.Customer != this.WorkEffort.ExecutedBy) { billingRate = Rounder.RoundDecimal(billingRate * (1 + this.strategy.Session.GetSingleton().Settings.InternalLabourSurchargePercentage / 100), 2); } this.BillingRate = billingRate; if (this.ExistBillingRate) { derivation.Validation.AssertExists(this, this.Meta.BillingFrequency); } // calculate AmountOfTime Or ThroughDate var frequencies = new TimeFrequencies(this.Strategy.Session); this.AmountOfTime = null; if (this.ThroughDate != null) { var timeSpan = this.ThroughDate - this.FromDate; this.AmountOfTimeInMinutes = (decimal)timeSpan.Value.TotalMinutes; var amount = frequencies.Minute.ConvertToFrequency(this.AmountOfTimeInMinutes, this.TimeFrequency); if (amount == null) { this.RemoveAmountOfTime(); } else { this.AmountOfTime = Rounder.RoundDecimal((decimal)amount, 2); } } else if (this.ExistAssignedAmountOfTime) { this.AmountOfTimeInMinutes = (decimal)this.TimeFrequency.ConvertToFrequency((decimal)this.AssignedAmountOfTime, frequencies.Minute); var timeSpan = TimeSpan.FromMinutes((double)this.AmountOfTimeInMinutes); this.ThroughDate = new DateTime(this.FromDate.Ticks, this.FromDate.Kind) + timeSpan; this.AmountOfTime = this.AssignedAmountOfTime; } else { var timeSpan = this.Session().Now() - this.FromDate; this.AmountOfTimeInMinutes = (decimal)timeSpan.TotalMinutes; var amount = frequencies.Minute.ConvertToFrequency(this.AmountOfTimeInMinutes, this.TimeFrequency); if (amount == null) { this.RemoveAmountOfTime(); } else { this.AmountOfTime = Rounder.RoundDecimal((decimal)amount, 2); } } if (this.ExistBillingRate && this.ExistBillingFrequency) { if (this.BillableAmountOfTime.HasValue) { this.BillableAmountOfTimeInMinutes = (decimal)this.TimeFrequency.ConvertToFrequency((decimal)this.BillableAmountOfTime, frequencies.Minute); } else { this.BillableAmountOfTimeInMinutes = this.AmountOfTimeInMinutes; } var billableTimeInTimeEntryRateFrequency = Rounder.RoundDecimal((decimal)frequencies.Minute.ConvertToFrequency(this.BillableAmountOfTimeInMinutes, this.BillingFrequency), 2); this.BillingAmount = Rounder.RoundDecimal((decimal)(this.BillingRate * billableTimeInTimeEntryRateFrequency), 2); var timeSpendInTimeEntryRateFrequency = Rounder.RoundDecimal((decimal)frequencies.Minute.ConvertToFrequency(this.AmountOfTimeInMinutes, this.BillingFrequency), 2); this.Cost = Rounder.RoundDecimal((decimal)(costRate * timeSpendInTimeEntryRateFrequency), 2); } }
public void BaseOnDeriveInvoiceTotals() { this.TotalBasePrice = 0; this.TotalDiscount = 0; this.TotalSurcharge = 0; this.TotalVat = 0; this.TotalExVat = 0; this.TotalIncVat = 0; this.TotalIrpf = 0; this.TotalExtraCharge = 0; this.GrandTotal = 0; foreach (PurchaseInvoiceItem item in this.PurchaseInvoiceItems) { this.TotalBasePrice += item.TotalBasePrice; this.TotalSurcharge += item.TotalSurcharge; this.TotalIrpf += item.TotalIrpf; this.TotalVat += item.TotalVat; this.TotalExVat += item.TotalExVat; this.TotalIncVat += item.TotalIncVat; this.GrandTotal += item.GrandTotal; } var discount = 0M; var discountVat = 0M; var discountIrpf = 0M; var surcharge = 0M; var surchargeVat = 0M; var surchargeIrpf = 0M; var fee = 0M; var feeVat = 0M; var feeIrpf = 0M; var shipping = 0M; var shippingVat = 0M; var shippingIrpf = 0M; var miscellaneous = 0M; var miscellaneousVat = 0M; var miscellaneousIrpf = 0M; foreach (OrderAdjustment orderAdjustment in this.OrderAdjustments) { if (orderAdjustment.GetType().Name.Equals(typeof(DiscountAdjustment).Name)) { discount = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalDiscount += discount; if (this.ExistDerivedVatRegime) { discountVat = discount * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { discountIrpf = discount * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(SurchargeAdjustment).Name)) { surcharge = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalSurcharge += surcharge; if (this.ExistDerivedVatRegime) { surchargeVat = surcharge * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { surchargeIrpf = surcharge * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(Fee).Name)) { fee = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalFee += fee; if (this.ExistDerivedVatRegime) { feeVat = fee * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { feeIrpf = fee * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(ShippingAndHandlingCharge).Name)) { shipping = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalShippingAndHandling += shipping; if (this.ExistDerivedVatRegime) { shippingVat = shipping * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { shippingIrpf = shipping * this.DerivedIrpfRate.Rate / 100; } } if (orderAdjustment.GetType().Name.Equals(typeof(MiscellaneousCharge).Name)) { miscellaneous = orderAdjustment.Percentage.HasValue ? this.TotalExVat * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; this.TotalExtraCharge += miscellaneous; if (this.ExistDerivedVatRegime) { miscellaneousVat = miscellaneous * this.DerivedVatRate.Rate / 100; } if (this.ExistDerivedIrpfRegime) { miscellaneousIrpf = miscellaneous * this.DerivedIrpfRate.Rate / 100; } } } var totalExtraCharge = fee + shipping + miscellaneous; var totalExVat = this.TotalExVat - discount + surcharge + fee + shipping + miscellaneous; var totalVat = this.TotalVat - discountVat + surchargeVat + feeVat + shippingVat + miscellaneousVat; var totalIncVat = this.TotalIncVat - discount - discountVat + surcharge + surchargeVat + fee + feeVat + shipping + shippingVat + miscellaneous + miscellaneousVat; var totalIrpf = this.TotalIrpf + discountIrpf - surchargeIrpf - feeIrpf - shippingIrpf - miscellaneousIrpf; var grandTotal = totalIncVat - totalIrpf; if (this.ExistInvoiceDate && this.ExistDerivedCurrency && this.ExistBilledTo) { this.TotalBasePriceInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalBasePrice, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalDiscountInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalDiscount, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalSurchargeInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalSurcharge, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalExtraChargeInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalExtraCharge, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalFeeInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalFee, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalShippingAndHandlingInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalShippingAndHandling, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalExVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalExVat, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalVat, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalIncVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalIncVat, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.TotalIrpfInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(totalIrpf, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); this.GrandTotalInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(grandTotal, this.InvoiceDate, this.DerivedCurrency, this.BilledTo.PreferredCurrency), 2); } this.TotalBasePrice = Rounder.RoundDecimal(this.TotalBasePrice, 2); this.TotalDiscount = Rounder.RoundDecimal(this.TotalDiscount, 2); this.TotalSurcharge = Rounder.RoundDecimal(this.TotalSurcharge, 2); this.TotalExtraCharge = Rounder.RoundDecimal(totalExtraCharge, 2); this.TotalFee = Rounder.RoundDecimal(this.TotalFee, 2); this.TotalShippingAndHandling = Rounder.RoundDecimal(this.TotalShippingAndHandling, 2); this.TotalExVat = Rounder.RoundDecimal(totalExVat, 2); this.TotalVat = Rounder.RoundDecimal(totalVat, 2); this.TotalIncVat = Rounder.RoundDecimal(totalIncVat, 2); this.TotalIrpf = Rounder.RoundDecimal(totalIrpf, 2); this.GrandTotal = Rounder.RoundDecimal(grandTotal, 2); }
private static decimal BaseCatalogPrice( SalesOrder salesOrder, SalesInvoice salesInvoice, Product product, DateTime date) { var productBasePrice = 0M; var productDiscount = 0M; var productSurcharge = 0M; var baseprices = new PriceComponent[0]; if (product.ExistBasePrices) { baseprices = product.BasePrices; } var party = salesOrder != null ? salesOrder.ShipToCustomer : salesInvoice?.BillToCustomer; foreach (BasePrice priceComponent in baseprices) { if (priceComponent.FromDate <= date && (!priceComponent.ExistThroughDate || priceComponent.ThroughDate >= date)) { if (PriceComponents.BaseIsApplicable(new PriceComponents.IsApplicable { PriceComponent = priceComponent, Customer = party, Product = product, SalesOrder = salesOrder, SalesInvoice = salesInvoice, })) { if (priceComponent.ExistPrice) { if (productBasePrice == 0 || priceComponent.Price < productBasePrice) { productBasePrice = priceComponent.Price ?? 0; } } } } } var currentPriceComponents = new PriceComponents(product.Strategy.Session).CurrentPriceComponents(date); var priceComponents = product.GetPriceComponents(currentPriceComponents); foreach (var priceComponent in priceComponents) { if (priceComponent.Strategy.Class.Equals(M.DiscountComponent.ObjectType) || priceComponent.Strategy.Class.Equals(M.SurchargeComponent.ObjectType)) { if (PriceComponents.BaseIsApplicable(new PriceComponents.IsApplicable { PriceComponent = priceComponent, Customer = party, Product = product, SalesOrder = salesOrder, SalesInvoice = salesInvoice, })) { if (priceComponent.Strategy.Class.Equals(M.DiscountComponent.ObjectType)) { var discountComponent = (DiscountComponent)priceComponent; decimal discount; if (discountComponent.Price.HasValue) { discount = discountComponent.Price.Value; productDiscount += discount; } else { var percentage = discountComponent.Percentage ?? 0; discount = Rounder.RoundDecimal(productBasePrice * percentage / 100, 2); productDiscount += discount; } } if (priceComponent.Strategy.Class.Equals(M.SurchargeComponent.ObjectType)) { var surchargeComponent = (SurchargeComponent)priceComponent; decimal surcharge; if (surchargeComponent.Price.HasValue) { surcharge = surchargeComponent.Price.Value; productSurcharge += surcharge; } else { var percentage = surchargeComponent.Percentage ?? 0; surcharge = Rounder.RoundDecimal(productBasePrice * percentage / 100, 2); productSurcharge += surcharge; } } } } } return(productBasePrice - productDiscount + productSurcharge); }
public void BaseOnDerive(ObjectOnDerive method) { var derivation = method.Derivation; if (!this.ExistOrderNumber) { var year = this.OrderDate.Year; this.OrderNumber = this.OrderedBy.NextPurchaseOrderNumber(year); var fiscalYearInternalOrganisationSequenceNumbers = this.OrderedBy?.FiscalYearsInternalOrganisationSequenceNumbers.FirstOrDefault(v => v.FiscalYear == year); var prefix = this.OrderedBy.InvoiceSequence.IsEnforcedSequence ? this.OrderedBy?.PurchaseOrderNumberPrefix : fiscalYearInternalOrganisationSequenceNumbers.PurchaseOrderNumberPrefix; this.SortableOrderNumber = this.Session().GetSingleton().SortableNumber(prefix, this.OrderNumber, year.ToString()); } if (this.TakenViaSupplier is Organisation supplier) { if (!this.OrderedBy.ActiveSuppliers.Contains(supplier)) { derivation.Validation.AddError(this, this.Meta.TakenViaSupplier, ErrorMessages.PartyIsNotASupplier); } } if (this.TakenViaSubcontractor is Organisation subcontractor) { if (!this.OrderedBy.ActiveSubContractors.Contains(subcontractor)) { derivation.Validation.AddError(this, this.Meta.TakenViaSubcontractor, ErrorMessages.PartyIsNotASubcontractor); } } if (this.PurchaseOrderState.IsCreated) { this.DerivedLocale = this.Locale ?? this.OrderedBy?.Locale; this.DerivedCurrency = this.AssignedCurrency ?? this.OrderedBy?.PreferredCurrency; this.DerivedVatRegime = this.AssignedVatRegime; this.DerivedIrpfRegime = this.AssignedIrpfRegime; this.DerivedShipToAddress = this.AssignedShipToAddress ?? this.OrderedBy?.ShippingAddress; this.DerivedBillToContactMechanism = this.AssignedBillToContactMechanism ?? this.OrderedBy?.BillingAddress ?? this.OrderedBy?.GeneralCorrespondence; this.DerivedTakenViaContactMechanism = this.AssignedTakenViaContactMechanism ?? this.TakenViaSupplier?.OrderAddress; } derivation.Validation.AssertExistsAtMostOne(this, this.Meta.TakenViaSupplier, this.Meta.TakenViaSubcontractor); derivation.Validation.AssertAtLeastOne(this, this.Meta.TakenViaSupplier, this.Meta.TakenViaSubcontractor); if (this.ExistOrderDate && this.ExistOrderedBy && this.DerivedCurrency != this.OrderedBy.PreferredCurrency) { var exchangeRate = this.DerivedCurrency.ExchangeRatesWhereFromCurrency.Where(v => v.ValidFrom.Date <= this.OrderDate.Date && v.ToCurrency.Equals(this.OrderedBy.PreferredCurrency)).OrderByDescending(v => v.ValidFrom).FirstOrDefault(); if (exchangeRate == null) { exchangeRate = this.OrderedBy.PreferredCurrency.ExchangeRatesWhereFromCurrency.Where(v => v.ValidFrom.Date <= this.OrderDate.Date && v.ToCurrency.Equals(this.DerivedCurrency)).OrderByDescending(v => v.ValidFrom).FirstOrDefault(); } if (exchangeRate == null) { derivation.Validation.AddError(this, M.Quote.AssignedCurrency, ErrorMessages.CurrencyNotAllowed); } } var validOrderItems = this.PurchaseOrderItems.Where(v => v.IsValid).ToArray(); this.ValidOrderItems = validOrderItems; var purchaseOrderShipmentStates = new PurchaseOrderShipmentStates(this.Strategy.Session); var purchaseOrderPaymentStates = new PurchaseOrderPaymentStates(this.Strategy.Session); var purchaseOrderItemStates = new PurchaseOrderItemStates(derivation.Session); // PurchaseOrder Shipment State if (validOrderItems.Any()) { if (validOrderItems.Any(v => v.IsReceivable)) { if (validOrderItems.Where(v => v.IsReceivable).All(v => v.PurchaseOrderItemShipmentState.IsReceived)) { this.PurchaseOrderShipmentState = purchaseOrderShipmentStates.Received; } else if (validOrderItems.Where(v => v.IsReceivable).All(v => v.PurchaseOrderItemShipmentState.IsNotReceived)) { this.PurchaseOrderShipmentState = purchaseOrderShipmentStates.NotReceived; } else { this.PurchaseOrderShipmentState = purchaseOrderShipmentStates.PartiallyReceived; } } else { this.PurchaseOrderShipmentState = purchaseOrderShipmentStates.Na; } // PurchaseOrder Payment State if (validOrderItems.All(v => v.PurchaseOrderItemPaymentState.IsPaid)) { this.PurchaseOrderPaymentState = purchaseOrderPaymentStates.Paid; } else if (validOrderItems.All(v => v.PurchaseOrderItemPaymentState.IsNotPaid)) { this.PurchaseOrderPaymentState = purchaseOrderPaymentStates.NotPaid; } else { this.PurchaseOrderPaymentState = purchaseOrderPaymentStates.PartiallyPaid; } // PurchaseOrder OrderState if (this.PurchaseOrderState.IsSent && (this.PurchaseOrderShipmentState.IsReceived || this.PurchaseOrderShipmentState.IsNa)) { this.PurchaseOrderState = new PurchaseOrderStates(this.Strategy.Session).Completed; } if (this.PurchaseOrderState.IsCompleted && this.PurchaseOrderPaymentState.IsPaid) { this.PurchaseOrderState = new PurchaseOrderStates(this.Strategy.Session).Finished; } } // Derive Totals var quantityOrderedByPart = new Dictionary <Part, decimal>(); var totalBasePriceByPart = new Dictionary <Part, decimal>(); foreach (PurchaseOrderItem item in this.ValidOrderItems) { if (item.ExistPart) { if (!quantityOrderedByPart.ContainsKey(item.Part)) { quantityOrderedByPart.Add(item.Part, item.QuantityOrdered); totalBasePriceByPart.Add(item.Part, item.TotalBasePrice); } else { quantityOrderedByPart[item.Part] += item.QuantityOrdered; totalBasePriceByPart[item.Part] += item.TotalBasePrice; } } } this.TotalBasePrice = 0; this.TotalDiscount = 0; this.TotalSurcharge = 0; this.TotalVat = 0; this.TotalIrpf = 0; this.TotalExVat = 0; this.TotalExtraCharge = 0; this.TotalIncVat = 0; this.GrandTotal = 0; this.TotalShippingAndHandlingInPreferredCurrency = 0; this.TotalFeeInPreferredCurrency = 0; this.TotalExtraChargeInPreferredCurrency = 0; this.TotalListPriceInPreferredCurrency = 0; foreach (PurchaseOrderItem orderItem in this.ValidOrderItems) { this.TotalBasePrice += orderItem.TotalBasePrice; this.TotalDiscount += orderItem.TotalDiscount; this.TotalSurcharge += orderItem.TotalSurcharge; this.TotalVat += orderItem.TotalVat; this.TotalIrpf += orderItem.TotalIrpf; this.TotalExVat += orderItem.TotalExVat; this.TotalIncVat += orderItem.TotalIncVat; this.GrandTotal += orderItem.GrandTotal; } if (this.ExistOrderDate && this.ExistDerivedCurrency && this.ExistOrderedBy) { this.TotalBasePriceInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalBasePrice, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); this.TotalDiscountInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalDiscount, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); this.TotalSurchargeInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalSurcharge, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); this.TotalExVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalExVat, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); this.TotalVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalVat, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); this.TotalIncVatInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalIncVat, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); this.TotalIrpfInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.TotalIrpf, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); this.GrandTotalInPreferredCurrency = Rounder.RoundDecimal(Currencies.ConvertCurrency(this.GrandTotal, this.OrderDate, this.DerivedCurrency, this.OrderedBy.PreferredCurrency), 2); } this.TotalBasePrice = Rounder.RoundDecimal(this.TotalBasePrice, 2); this.TotalDiscount = Rounder.RoundDecimal(this.TotalDiscount, 2); this.TotalSurcharge = Rounder.RoundDecimal(this.TotalSurcharge, 2); this.TotalVat = Rounder.RoundDecimal(this.TotalVat, 2); this.TotalIrpf = Rounder.RoundDecimal(this.TotalIrpf, 2); this.TotalExVat = Rounder.RoundDecimal(this.TotalExVat, 2); this.TotalIncVat = Rounder.RoundDecimal(this.TotalIncVat, 2); this.GrandTotal = Rounder.RoundDecimal(this.GrandTotal, 2); this.PreviousTakenViaSupplier = this.TakenViaSupplier; // Derive Workflow this.WorkItemDescription = $"PurchaseOrder: {this.OrderNumber} [{this.TakenViaSupplier?.PartyName}]"; var openTasks = this.TasksWhereWorkItem.Where(v => !v.ExistDateClosed).ToArray(); if (this.PurchaseOrderState.IsAwaitingApprovalLevel1) { if (!openTasks.OfType <PurchaseOrderApprovalLevel1>().Any()) { new PurchaseOrderApprovalLevel1Builder(this.Session()).WithPurchaseOrder(this).Build(); } } if (this.PurchaseOrderState.IsAwaitingApprovalLevel2) { if (!openTasks.OfType <PurchaseOrderApprovalLevel2>().Any()) { new PurchaseOrderApprovalLevel2Builder(this.Session()).WithPurchaseOrder(this).Build(); } } this.Sync(derivation, validOrderItems); this.ResetPrintDocument(); }
public void BaseOnDerive(ObjectOnDerive method) { var derivation = method.Derivation; var quote = this.QuoteWhereQuoteItem; if (this.InvoiceItemType.IsPartItem || this.InvoiceItemType.IsProductFeatureItem || this.InvoiceItemType.IsProductItem) { derivation.Validation.AssertAtLeastOne(this, M.QuoteItem.Product, M.QuoteItem.ProductFeature, M.QuoteItem.SerialisedItem, M.QuoteItem.Deliverable, M.QuoteItem.WorkEffort); derivation.Validation.AssertExistsAtMostOne(this, M.QuoteItem.Product, M.QuoteItem.ProductFeature, M.QuoteItem.Deliverable, M.QuoteItem.WorkEffort); derivation.Validation.AssertExistsAtMostOne(this, M.QuoteItem.SerialisedItem, M.QuoteItem.ProductFeature, M.QuoteItem.Deliverable, M.QuoteItem.WorkEffort); } else { this.Quantity = 1; } if (this.ExistSerialisedItem && this.Quantity != 1) { derivation.Validation.AddError(this, this.Meta.Quantity, ErrorMessages.SerializedItemQuantity); } this.DerivedVatRegime = this.ExistAssignedVatRegime ? this.AssignedVatRegime : quote?.DerivedVatRegime; this.VatRate = this.DerivedVatRegime?.VatRates.First(v => v.FromDate <= quote.IssueDate && (!v.ExistThroughDate || v.ThroughDate >= quote.IssueDate)); this.DerivedIrpfRegime = this.ExistAssignedIrpfRegime ? this.AssignedIrpfRegime : quote?.DerivedIrpfRegime; this.IrpfRate = this.DerivedIrpfRegime?.IrpfRates.First(v => v.FromDate <= quote.IssueDate && (!v.ExistThroughDate || v.ThroughDate >= quote.IssueDate)); if (derivation.ChangeSet.IsCreated(this) && !this.ExistDetails) { this.DeriveDetails(); } if (this.ExistRequestItem) { this.RequiredByDate = this.RequestItem.RequiredByDate; } if (!this.ExistUnitOfMeasure) { this.UnitOfMeasure = new UnitsOfMeasure(this.Strategy.Session).Piece; } this.UnitVat = this.ExistVatRate ? this.UnitPrice * this.VatRate.Rate / 100 : 0; // Calculate Totals this.TotalBasePrice = this.UnitBasePrice * this.Quantity; this.TotalDiscount = this.UnitDiscount * this.Quantity; this.TotalSurcharge = this.UnitSurcharge * this.Quantity; if (this.TotalBasePrice > 0) { this.TotalDiscountAsPercentage = Rounder.RoundDecimal(this.TotalDiscount / this.TotalBasePrice * 100, 2); this.TotalSurchargeAsPercentage = Rounder.RoundDecimal(this.TotalSurcharge / this.TotalBasePrice * 100, 2); } else { this.TotalDiscountAsPercentage = 0; this.TotalSurchargeAsPercentage = 0; } this.TotalExVat = this.UnitPrice * this.Quantity; this.TotalVat = this.UnitVat * this.Quantity; this.TotalIncVat = this.TotalExVat + this.TotalVat; // CurrentVersion is Previous Version until PostDerive var previousSerialisedItem = this.CurrentVersion?.SerialisedItem; if (previousSerialisedItem != null && previousSerialisedItem != this.SerialisedItem) { previousSerialisedItem.DerivationTrigger = Guid.NewGuid(); } }
private void CalculatePrice(IDerivation derivation, SalesOrder salesOrder, bool useValueOrdered = false) { var sameProductItems = salesOrder.SalesOrderItems .Where(v => v.IsValid && v.ExistProduct && v.Product.Equals(this.Product)) .ToArray(); var quantityOrdered = sameProductItems.Sum(w => w.QuantityOrdered); var valueOrdered = useValueOrdered ? sameProductItems.Sum(w => w.TotalBasePrice) : 0; var orderPriceComponents = new PriceComponents(this.Session()).CurrentPriceComponents(salesOrder.OrderDate); var orderItemPriceComponents = Array.Empty <PriceComponent>(); if (this.ExistProduct) { orderItemPriceComponents = this.Product.GetPriceComponents(orderPriceComponents); } else if (this.ExistProductFeature) { orderItemPriceComponents = this.ProductFeature.GetPriceComponents(this.SalesOrderItemWhereOrderedWithFeature.Product, orderPriceComponents); } var priceComponents = orderItemPriceComponents.Where( v => PriceComponents.BaseIsApplicable( new PriceComponents.IsApplicable { PriceComponent = v, Customer = salesOrder.BillToCustomer, Product = this.Product, SalesOrder = salesOrder, QuantityOrdered = quantityOrdered, ValueOrdered = valueOrdered, })).ToArray(); var unitBasePrice = priceComponents.OfType <BasePrice>().Min(v => v.Price); // Calculate Unit Price (with Discounts and Surcharges) if (this.AssignedUnitPrice.HasValue) { this.UnitBasePrice = unitBasePrice ?? this.AssignedUnitPrice.Value; this.UnitDiscount = 0; this.UnitSurcharge = 0; this.UnitPrice = this.AssignedUnitPrice.Value; } else { if (!unitBasePrice.HasValue) { derivation.Validation.AddError(this, M.SalesOrderItem.UnitBasePrice, "No BasePrice with a Price"); return; } this.UnitBasePrice = unitBasePrice.Value; this.UnitDiscount = priceComponents.OfType <DiscountComponent>().Sum( v => v.Percentage.HasValue ? this.UnitBasePrice * v.Percentage.Value / 100 : v.Price ?? 0); this.UnitSurcharge = priceComponents.OfType <SurchargeComponent>().Sum( v => v.Percentage.HasValue ? this.UnitBasePrice * v.Percentage.Value / 100 : v.Price ?? 0); this.UnitPrice = this.UnitBasePrice - this.UnitDiscount + this.UnitSurcharge; foreach (OrderAdjustment orderAdjustment in this.DiscountAdjustments) { this.UnitDiscount += orderAdjustment.Percentage.HasValue ? this.UnitPrice * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; } foreach (OrderAdjustment orderAdjustment in this.SurchargeAdjustments) { this.UnitSurcharge += orderAdjustment.Percentage.HasValue ? this.UnitPrice * orderAdjustment.Percentage.Value / 100 : orderAdjustment.Amount ?? 0; } this.UnitPrice = this.UnitBasePrice - this.UnitDiscount + this.UnitSurcharge; } foreach (SalesOrderItem featureItem in this.OrderedWithFeatures) { this.UnitBasePrice += featureItem.UnitBasePrice; this.UnitPrice += featureItem.UnitPrice; this.UnitDiscount += featureItem.UnitDiscount; this.UnitSurcharge += featureItem.UnitSurcharge; } this.UnitVat = this.ExistVatRate ? this.UnitPrice * this.VatRate.Rate / 100 : 0; this.UnitIrpf = this.ExistIrpfRate ? this.UnitPrice * this.IrpfRate.Rate / 100 : 0; // Calculate Totals this.TotalBasePrice = this.UnitBasePrice * this.QuantityOrdered; this.TotalDiscount = this.UnitDiscount * this.QuantityOrdered; this.TotalSurcharge = this.UnitSurcharge * this.QuantityOrdered; this.TotalOrderAdjustment = this.TotalSurcharge - this.TotalDiscount; if (this.TotalBasePrice > 0) { this.TotalDiscountAsPercentage = Rounder.RoundDecimal(this.TotalDiscount / this.TotalBasePrice * 100, 2); this.TotalSurchargeAsPercentage = Rounder.RoundDecimal(this.TotalSurcharge / this.TotalBasePrice * 100, 2); } else { this.TotalDiscountAsPercentage = 0; this.TotalSurchargeAsPercentage = 0; } this.TotalExVat = this.UnitPrice * this.QuantityOrdered; this.TotalVat = this.UnitVat * this.QuantityOrdered; this.TotalIncVat = this.TotalExVat + this.TotalVat; this.TotalIrpf = this.UnitIrpf * this.QuantityOrdered; this.GrandTotal = this.TotalIncVat - this.TotalIrpf; }