예제 #1
0
        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;
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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();
        }
예제 #4
0
        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;
        }
예제 #5
0
파일: TimeEntry.cs 프로젝트: Allors/allors2
        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);
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
파일: Products.cs 프로젝트: Allors/allors2
        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);
        }
예제 #8
0
        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();
        }
예제 #9
0
        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();
            }
        }
예제 #10
0
        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;
        }