protected override void BaseSecure(Security config)
        {
            var readyForPosting    = new SalesInvoiceItemStates(this.Session).ReadyForPosting;
            var notPaid            = new SalesInvoiceItemStates(this.Session).NotPaid;
            var paid               = new SalesInvoiceItemStates(this.Session).Paid;
            var writtenOff         = new SalesInvoiceItemStates(this.Session).WrittenOff;
            var cancelledByInvoice = new SalesInvoiceItemStates(this.Session).CancelledByInvoice;

            config.Deny(this.ObjectType, notPaid, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, paid, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, writtenOff, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, cancelledByInvoice, Operations.Write);
        }
Beispiel #2
0
        protected override void AppsSecure(Security config)
        {
            base.AppsSecure(config);

            ObjectState sent       = new SalesInvoiceItemStates(this.Session).Sent;
            ObjectState paid       = new SalesInvoiceItemStates(this.Session).Paid;
            ObjectState writtenOff = new SalesInvoiceItemStates(this.Session).WrittenOff;
            ObjectState cancelled  = new SalesInvoiceItemStates(this.Session).Cancelled;

            config.Deny(this.ObjectType, sent, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, paid, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, writtenOff, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, cancelled, Operations.Write, Operations.Execute);
        }
Beispiel #3
0
        public void BaseOnDerive(ObjectOnDerive method)
        {
            var derivation             = method.Derivation;
            var salesInvoice           = this.SalesInvoiceWhereSalesInvoiceItem;
            var salesInvoiceItemStates = new SalesInvoiceItemStates(derivation.Session);

            derivation.Validation.AssertExistsAtMostOne(this, M.SalesInvoiceItem.Product, M.SalesInvoiceItem.ProductFeatures, M.SalesInvoiceItem.Part);
            derivation.Validation.AssertExistsAtMostOne(this, M.SalesInvoiceItem.SerialisedItem, M.SalesInvoiceItem.ProductFeatures, M.SalesInvoiceItem.Part);

            if (!this.ExistDerivationTrigger)
            {
                this.DerivationTrigger = Guid.NewGuid();
            }

            if (this.ExistSerialisedItem && !this.ExistNextSerialisedItemAvailability && salesInvoice.SalesInvoiceType.Equals(new SalesInvoiceTypes(this.Session()).SalesInvoice))
            {
                derivation.Validation.AssertExists(this, this.Meta.NextSerialisedItemAvailability);
            }

            if (this.Part != null && this.Part.InventoryItemKind.IsSerialised && this.Quantity != 1)
            {
                derivation.Validation.AddError(this, M.SalesInvoiceItem.Quantity, ErrorMessages.InvalidQuantity);
            }

            if (this.Part != null && this.Part.InventoryItemKind.IsNonSerialised && this.Quantity == 0)
            {
                derivation.Validation.AddError(this, M.SalesInvoiceItem.Quantity, ErrorMessages.InvalidQuantity);
            }

            if (this.ExistInvoiceItemType && this.InvoiceItemType.MaxQuantity.HasValue && this.Quantity > this.InvoiceItemType.MaxQuantity.Value)
            {
                derivation.Validation.AddError(this, M.SalesInvoiceItem.Quantity, ErrorMessages.InvalidQuantity);
            }

            this.DerivedVatRegime = this.ExistAssignedVatRegime ? this.AssignedVatRegime : this.SalesInvoiceWhereSalesInvoiceItem?.DerivedVatRegime;
            this.VatRate          = this.DerivedVatRegime?.VatRates.First(v => v.FromDate <= salesInvoice.InvoiceDate && (!v.ExistThroughDate || v.ThroughDate >= salesInvoice.InvoiceDate));

            this.DerivedIrpfRegime = this.ExistAssignedIrpfRegime ? this.AssignedIrpfRegime : this.SalesInvoiceWhereSalesInvoiceItem?.DerivedIrpfRegime;
            this.IrpfRate          = this.DerivedIrpfRegime?.IrpfRates.First(v => v.FromDate <= salesInvoice.InvoiceDate && (!v.ExistThroughDate || v.ThroughDate >= salesInvoice.InvoiceDate));

            if (this.ExistInvoiceItemType && this.IsSubTotalItem().Result == true && this.Quantity <= 0)
            {
                derivation.Validation.AssertExists(this, this.Meta.Quantity);
            }

            this.AmountPaid = 0;
            foreach (PaymentApplication paymentApplication in this.PaymentApplicationsWhereInvoiceItem)
            {
                this.AmountPaid += paymentApplication.AmountApplied;
            }

            if (salesInvoice != null && salesInvoice.SalesInvoiceState.IsReadyForPosting && this.SalesInvoiceItemState.IsCancelledByInvoice)
            {
                this.SalesInvoiceItemState = salesInvoiceItemStates.ReadyForPosting;
            }

            // SalesInvoiceItem States
            if (salesInvoice != null && this.IsValid)
            {
                if (salesInvoice.SalesInvoiceState.IsWrittenOff)
                {
                    this.SalesInvoiceItemState = salesInvoiceItemStates.WrittenOff;
                }

                if (salesInvoice.SalesInvoiceState.IsCancelled)
                {
                    this.SalesInvoiceItemState = salesInvoiceItemStates.CancelledByInvoice;
                }
            }
        }
        public void BaseOnDerive(ObjectOnDerive method)
        {
            var derivation             = method.Derivation;
            var salesInvoice           = this.SalesInvoiceWhereSalesInvoiceItem;
            var salesInvoiceItemStates = new SalesInvoiceItemStates(derivation.Session);

            derivation.Validation.AssertExistsAtMostOne(this, M.SalesInvoiceItem.Product, M.SalesInvoiceItem.ProductFeatures, M.SalesInvoiceItem.Part);
            derivation.Validation.AssertExistsAtMostOne(this, M.SalesInvoiceItem.SerialisedItem, M.SalesInvoiceItem.ProductFeatures, M.SalesInvoiceItem.Part);

            if (!this.ExistDerivationTrigger)
            {
                this.DerivationTrigger = Guid.NewGuid();
            }

            if (this.ExistSerialisedItem && !this.ExistNextSerialisedItemAvailability && salesInvoice.SalesInvoiceType.Equals(new SalesInvoiceTypes(this.Session()).SalesInvoice))
            {
                derivation.Validation.AssertExists(this, this.Meta.NextSerialisedItemAvailability);
            }

            if (this.Part != null && this.Part.InventoryItemKind.IsSerialised && this.Quantity != 1)
            {
                derivation.Validation.AddError(this, M.SalesInvoiceItem.Quantity, ErrorMessages.InvalidQuantity);
            }

            if (this.Part != null && this.Part.InventoryItemKind.IsNonSerialised && this.Quantity == 0)
            {
                derivation.Validation.AddError(this, M.SalesInvoiceItem.Quantity, ErrorMessages.InvalidQuantity);
            }

            if (this.ExistInvoiceItemType && this.InvoiceItemType.MaxQuantity.HasValue && this.Quantity > this.InvoiceItemType.MaxQuantity.Value)
            {
                derivation.Validation.AddError(this, M.SalesInvoiceItem.Quantity, ErrorMessages.InvalidQuantity);
            }

            this.VatRegime = this.ExistAssignedVatRegime ? this.AssignedVatRegime : this.SalesInvoiceWhereSalesInvoiceItem?.VatRegime;
            this.VatRate   = this.VatRegime?.VatRate;

            this.IrpfRegime = this.ExistAssignedIrpfRegime ? this.AssignedIrpfRegime : this.SalesInvoiceWhereSalesInvoiceItem?.IrpfRegime;
            this.IrpfRate   = this.IrpfRegime?.IrpfRate;

            if (this.ExistInvoiceItemType && this.IsSubTotalItem().Result == true && this.Quantity <= 0)
            {
                derivation.Validation.AssertExists(this, this.Meta.Quantity);
            }

            this.AmountPaid = 0;
            foreach (PaymentApplication paymentApplication in this.PaymentApplicationsWhereInvoiceItem)
            {
                this.AmountPaid += paymentApplication.AmountApplied;
            }

            if (salesInvoice != null && salesInvoice.SalesInvoiceState.IsReadyForPosting && this.SalesInvoiceItemState.IsCancelledByInvoice)
            {
                this.SalesInvoiceItemState = salesInvoiceItemStates.ReadyForPosting;
            }

            // SalesInvoiceItem States
            if (salesInvoice != null && this.IsValid)
            {
                if (salesInvoice.SalesInvoiceState.IsWrittenOff)
                {
                    this.SalesInvoiceItemState = salesInvoiceItemStates.WrittenOff;
                }

                if (salesInvoice.SalesInvoiceState.IsCancelled)
                {
                    this.SalesInvoiceItemState = salesInvoiceItemStates.CancelledByInvoice;
                }
            }

            // TODO: Move to Custom
            if (derivation.ChangeSet.IsCreated(this) && !this.ExistDescription)
            {
                if (this.ExistSerialisedItem)
                {
                    var builder = new StringBuilder();
                    var part    = this.SerialisedItem.PartWhereSerialisedItem;

                    if (part != null && part.ExistManufacturedBy)
                    {
                        builder.Append($", Manufacturer: {part.ManufacturedBy.PartyName}");
                    }

                    if (part != null && part.ExistBrand)
                    {
                        builder.Append($", Brand: {part.Brand.Name}");
                    }

                    if (part != null && part.ExistModel)
                    {
                        builder.Append($", Model: {part.Model.Name}");
                    }

                    builder.Append($", SN: {this.SerialisedItem.SerialNumber}");

                    if (this.SerialisedItem.ExistManufacturingYear)
                    {
                        builder.Append($", YOM: {this.SerialisedItem.ManufacturingYear}");
                    }

                    foreach (SerialisedItemCharacteristic characteristic in this.SerialisedItem.SerialisedItemCharacteristics)
                    {
                        if (characteristic.ExistValue)
                        {
                            var characteristicType = characteristic.SerialisedItemCharacteristicType;
                            if (characteristicType.ExistUnitOfMeasure)
                            {
                                var uom = characteristicType.UnitOfMeasure.ExistAbbreviation
                                                ? characteristicType.UnitOfMeasure.Abbreviation
                                                : characteristicType.UnitOfMeasure.Name;
                                builder.Append(
                                    $", {characteristicType.Name}: {characteristic.Value} {uom}");
                            }
                            else
                            {
                                builder.Append($", {characteristicType.Name}: {characteristic.Value}");
                            }
                        }
                    }

                    var details = builder.ToString();

                    if (details.StartsWith(","))
                    {
                        details = details.Substring(2);
                    }

                    this.Description = details;
                }
                else if (this.ExistProduct && this.Product is UnifiedGood unifiedGood)
                {
                    var builder = new StringBuilder();

                    if (unifiedGood != null && unifiedGood.ExistManufacturedBy)
                    {
                        builder.Append($", Manufacturer: {unifiedGood.ManufacturedBy.PartyName}");
                    }

                    if (unifiedGood != null && unifiedGood.ExistBrand)
                    {
                        builder.Append($", Brand: {unifiedGood.Brand.Name}");
                    }

                    if (unifiedGood != null && unifiedGood.ExistModel)
                    {
                        builder.Append($", Model: {unifiedGood.Model.Name}");
                    }

                    foreach (SerialisedItemCharacteristic characteristic in unifiedGood.SerialisedItemCharacteristics)
                    {
                        if (characteristic.ExistValue)
                        {
                            var characteristicType = characteristic.SerialisedItemCharacteristicType;
                            if (characteristicType.ExistUnitOfMeasure)
                            {
                                var uom = characteristicType.UnitOfMeasure.ExistAbbreviation
                                                ? characteristicType.UnitOfMeasure.Abbreviation
                                                : characteristicType.UnitOfMeasure.Name;
                                builder.Append($", {characteristicType.Name}: {characteristic.Value} {uom}");
                            }
                            else
                            {
                                builder.Append($", {characteristicType.Name}: {characteristic.Value}");
                            }
                        }
                    }

                    var details = builder.ToString();

                    if (details.StartsWith(","))
                    {
                        details = details.Substring(2);
                    }

                    this.Description = details;
                }
            }
        }
        public void BaseOnDerive(ObjectOnDerive method)
        {
            var derivation = method.Derivation;
            var session    = this.Session();

            var internalOrganisations = new Organisations(session).InternalOrganisations();

            if (!this.ExistBilledFrom && internalOrganisations.Count() == 1)
            {
                this.BilledFrom = internalOrganisations.First();
            }

            if (!this.ExistStore && this.ExistBilledFrom)
            {
                var stores = new Stores(session).Extent();
                stores.Filter.AddEquals(M.Store.InternalOrganisation, this.BilledFrom);
                this.Store = stores.FirstOrDefault();
            }

            if (!this.ExistInvoiceNumber && this.ExistStore)
            {
                this.InvoiceNumber = this.Store.NextTemporaryInvoiceNumber();
            }

            if (!this.ExistBilledFromContactMechanism && this.ExistBilledFrom)
            {
                this.BilledFromContactMechanism = this.BilledFrom.ExistBillingAddress ? this.BilledFrom.BillingAddress : this.BilledFrom.GeneralCorrespondence;
            }

            if (!this.ExistBillToContactMechanism && this.ExistBillToCustomer)
            {
                this.BillToContactMechanism = this.BillToCustomer.BillingAddress;
            }

            if (!this.ExistBillToEndCustomerContactMechanism && this.ExistBillToEndCustomer)
            {
                this.BillToEndCustomerContactMechanism = this.BillToEndCustomer.BillingAddress;
            }

            if (!this.ExistShipToEndCustomerAddress && this.ExistShipToEndCustomer)
            {
                this.ShipToEndCustomerAddress = this.ShipToEndCustomer.ShippingAddress;
            }

            if (!this.ExistShipToAddress && this.ExistShipToCustomer)
            {
                this.ShipToAddress = this.ShipToCustomer.ShippingAddress;
            }

            if (!this.ExistCurrency && this.ExistBilledFrom)
            {
                if (this.ExistBillToCustomer && (this.BillToCustomer.ExistPreferredCurrency || this.BillToCustomer.ExistLocale))
                {
                    this.Currency = this.BillToCustomer.ExistPreferredCurrency ? this.BillToCustomer.PreferredCurrency : this.BillToCustomer.Locale.Country.Currency;
                }
                else
                {
                    this.Currency = this.BilledFrom.ExistPreferredCurrency ?
                                    this.BilledFrom.PreferredCurrency :
                                    session.GetSingleton().DefaultLocale.Country.Currency;
                }
            }

            this.VatRegime   = this.VatRegime ?? this.BillToCustomer?.VatRegime;
            this.IsRepeating = this.ExistRepeatingSalesInvoiceWhereSource;

            foreach (SalesInvoiceItem salesInvoiceItem in this.SalesInvoiceItems)
            {
                foreach (OrderItemBilling orderItemBilling in salesInvoiceItem.OrderItemBillingsWhereInvoiceItem)
                {
                    if (orderItemBilling.OrderItem is SalesOrderItem salesOrderItem && !this.SalesOrders.Contains(salesOrderItem.SalesOrderWhereSalesOrderItem))
                    {
                        this.AddSalesOrder(salesOrderItem.SalesOrderWhereSalesOrderItem);
                    }
                }

                foreach (WorkEffortBilling workEffortBilling in salesInvoiceItem.WorkEffortBillingsWhereInvoiceItem)
                {
                    if (!this.WorkEfforts.Contains(workEffortBilling.WorkEffort))
                    {
                        this.AddWorkEffort(workEffortBilling.WorkEffort);
                    }
                }

                foreach (TimeEntryBilling timeEntryBilling in salesInvoiceItem.TimeEntryBillingsWhereInvoiceItem)
                {
                    if (!this.WorkEfforts.Contains(timeEntryBilling.TimeEntry.WorkEffort))
                    {
                        this.AddWorkEffort(timeEntryBilling.TimeEntry.WorkEffort);
                    }
                }
            }

            this.IsRepeatingInvoice = this.ExistRepeatingSalesInvoiceWhereSource && (!this.RepeatingSalesInvoiceWhereSource.ExistFinalExecutionDate || this.RepeatingSalesInvoiceWhereSource.FinalExecutionDate.Value.Date >= this.Strategy.Session.Now().Date);

            this.SalesInvoiceItems = this.SalesInvoiceItems.ToArray();

            if (this.ExistBillToCustomer && this.BillToCustomer.ExistLocale)
            {
                this.Locale = this.BillToCustomer.Locale;
            }
            else
            {
                this.Locale = session.GetSingleton().DefaultLocale;
            }

            if (this.ExistSalesTerms)
            {
                foreach (AgreementTerm term in this.SalesTerms)
                {
                    if (term.TermType.Equals(new InvoiceTermTypes(session).PaymentNetDays))
                    {
                        if (int.TryParse(term.TermValue, out var netDays))
                        {
                            this.PaymentDays = netDays;
                        }
                    }
                }
            }
            else if (this.BillToCustomer?.PaymentNetDays().HasValue == true)
            {
                this.PaymentDays = this.BillToCustomer.PaymentNetDays().Value;
            }
            else if (this.ExistStore && this.Store.ExistPaymentNetDays)
            {
                this.PaymentDays = this.Store.PaymentNetDays;
            }

            if (!this.ExistPaymentDays)
            {
                this.PaymentDays = 0;
            }

            if (this.ExistInvoiceDate)
            {
                this.DueDate = this.InvoiceDate.AddDays(this.PaymentNetDays);
            }

            var validInvoiceItems = this.SalesInvoiceItems.Where(v => v.IsValid).ToArray();

            this.ValidInvoiceItems = validInvoiceItems;

            var currentPriceComponents = new PriceComponents(this.Strategy.Session).CurrentPriceComponents(this.InvoiceDate);

            var quantityByProduct = validInvoiceItems
                                    .Where(v => v.ExistProduct)
                                    .GroupBy(v => v.Product)
                                    .ToDictionary(v => v.Key, v => v.Sum(w => w.Quantity));

            // First run to calculate price
            foreach (var salesInvoiceItem in validInvoiceItems)
            {
                decimal quantityOrdered = 0;

                if (salesInvoiceItem.ExistProduct)
                {
                    quantityByProduct.TryGetValue(salesInvoiceItem.Product, out quantityOrdered);
                }

                this.CalculatePrices(derivation, salesInvoiceItem, currentPriceComponents, quantityOrdered, 0);
            }

            var totalBasePriceByProduct = validInvoiceItems
                                          .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 (var salesInvoiceItem in validInvoiceItems)
            {
                decimal quantityOrdered = 0;
                decimal totalBasePrice  = 0;

                if (salesInvoiceItem.ExistProduct)
                {
                    quantityByProduct.TryGetValue(salesInvoiceItem.Product, out quantityOrdered);
                    totalBasePriceByProduct.TryGetValue(salesInvoiceItem.Product, out totalBasePrice);
                }

                this.CalculatePrices(derivation, salesInvoiceItem, currentPriceComponents, quantityOrdered, totalBasePrice);
            }

            // Calculate Totals
            if (this.ExistSalesInvoiceItems)
            {
                this.TotalBasePrice           = 0;
                this.TotalDiscount            = 0;
                this.TotalSurcharge           = 0;
                this.TotalExVat               = 0;
                this.TotalFee                 = 0;
                this.TotalShippingAndHandling = 0;
                this.TotalVat                 = 0;
                this.TotalIncVat              = 0;
                this.TotalListPrice           = 0;

                foreach (var item in validInvoiceItems)
                {
                    this.TotalBasePrice += item.TotalBasePrice;
                    this.TotalDiscount  += item.TotalDiscount;
                    this.TotalSurcharge += item.TotalSurcharge;
                    this.TotalExVat     += item.TotalExVat;
                    this.TotalVat       += item.TotalVat;
                    this.TotalIncVat    += item.TotalIncVat;
                    this.TotalListPrice += item.UnitPrice;
                }

                if (this.ExistDiscountAdjustment)
                {
                    var discount = this.DiscountAdjustment.Percentage.HasValue ?
                                   Math.Round(this.TotalExVat * this.DiscountAdjustment.Percentage.Value / 100, 2) :
                                   this.DiscountAdjustment.Amount ?? 0;

                    this.TotalDiscount += discount;
                    this.TotalExVat    -= discount;

                    if (this.ExistVatRegime)
                    {
                        var vat = Math.Round(discount * this.VatRegime.VatRate.Rate / 100, 2);

                        this.TotalVat    -= vat;
                        this.TotalIncVat -= discount + vat;
                    }
                }

                if (this.ExistSurchargeAdjustment)
                {
                    var surcharge = this.SurchargeAdjustment.Percentage.HasValue ?
                                    Math.Round(this.TotalExVat * this.SurchargeAdjustment.Percentage.Value / 100, 2) :
                                    this.SurchargeAdjustment.Amount ?? 0;

                    this.TotalSurcharge += surcharge;
                    this.TotalExVat     += surcharge;

                    if (this.ExistVatRegime)
                    {
                        var vat = Math.Round(surcharge * this.VatRegime.VatRate.Rate / 100, 2);
                        this.TotalVat    += vat;
                        this.TotalIncVat += surcharge + vat;
                    }
                }

                if (this.ExistFee)
                {
                    var fee = this.Fee.Percentage.HasValue ?
                              Math.Round(this.TotalExVat * this.Fee.Percentage.Value / 100, 2) :
                              this.Fee.Amount ?? 0;

                    this.TotalFee   += fee;
                    this.TotalExVat += fee;

                    if (this.Fee.ExistVatRate)
                    {
                        var vat1 = Math.Round(fee * this.Fee.VatRate.Rate / 100, 2);
                        this.TotalVat    += vat1;
                        this.TotalIncVat += fee + vat1;
                    }
                }

                if (this.ExistShippingAndHandlingCharge)
                {
                    var shipping = this.ShippingAndHandlingCharge.Percentage.HasValue ?
                                   Math.Round(this.TotalExVat * this.ShippingAndHandlingCharge.Percentage.Value / 100, 2) :
                                   this.ShippingAndHandlingCharge.Amount ?? 0;

                    this.TotalShippingAndHandling += shipping;
                    this.TotalExVat += shipping;

                    if (this.ShippingAndHandlingCharge.ExistVatRate)
                    {
                        var vat2 = Math.Round(shipping * this.ShippingAndHandlingCharge.VatRate.Rate / 100, 2);
                        this.TotalVat    += vat2;
                        this.TotalIncVat += shipping + vat2;
                    }
                }

                //// Only take into account items for which there is data at the item level.
                //// Skip negative sales.
                decimal totalUnitBasePrice = 0;
                decimal totalListPrice     = 0;

                foreach (var item1 in validInvoiceItems)
                {
                    if (item1.TotalExVat > 0)
                    {
                        totalUnitBasePrice += item1.UnitBasePrice;
                        totalListPrice     += item1.UnitPrice;
                    }
                }
            }

            var salesInvoiceItemStates = new SalesInvoiceItemStates(derivation.Session);
            var salesInvoiceStates     = new SalesInvoiceStates(derivation.Session);

            foreach (var invoiceItem in validInvoiceItems)
            {
                if (!invoiceItem.SalesInvoiceItemState.Equals(salesInvoiceItemStates.ReadyForPosting))
                {
                    if (invoiceItem.AmountPaid == 0)
                    {
                        invoiceItem.SalesInvoiceItemState = salesInvoiceItemStates.NotPaid;
                    }
                    else if (invoiceItem.ExistAmountPaid && invoiceItem.AmountPaid > 0 && invoiceItem.AmountPaid >= invoiceItem.TotalIncVat)
                    {
                        invoiceItem.SalesInvoiceItemState = salesInvoiceItemStates.Paid;
                    }
                    else
                    {
                        invoiceItem.SalesInvoiceItemState = salesInvoiceItemStates.PartiallyPaid;
                    }
                }
            }

            if (validInvoiceItems.Any() && !this.SalesInvoiceState.Equals(salesInvoiceStates.ReadyForPosting))
            {
                if (this.SalesInvoiceItems.All(v => v.SalesInvoiceItemState.IsPaid))
                {
                    this.SalesInvoiceState = salesInvoiceStates.Paid;
                }
                else if (this.SalesInvoiceItems.All(v => v.SalesInvoiceItemState.IsNotPaid))
                {
                    this.SalesInvoiceState = salesInvoiceStates.NotPaid;
                }
                else
                {
                    this.SalesInvoiceState = salesInvoiceStates.PartiallyPaid;
                }
            }

            this.AmountPaid  = this.AdvancePayment;
            this.AmountPaid += this.PaymentApplicationsWhereInvoice.Sum(v => v.AmountApplied);

            //// Perhaps payments are recorded at the item level.
            if (this.AmountPaid == 0)
            {
                this.AmountPaid = this.InvoiceItems.Sum(v => v.AmountPaid);
            }

            // If receipts are not matched at invoice level
            if (this.AmountPaid > 0)
            {
                if (this.AmountPaid >= this.TotalIncVat)
                {
                    this.SalesInvoiceState = salesInvoiceStates.Paid;
                }
                else
                {
                    this.SalesInvoiceState = salesInvoiceStates.PartiallyPaid;
                }

                foreach (var invoiceItem in validInvoiceItems)
                {
                    if (!invoiceItem.SalesInvoiceItemState.Equals(salesInvoiceItemStates.CancelledByInvoice) &&
                        !invoiceItem.SalesInvoiceItemState.Equals(salesInvoiceItemStates.WrittenOff))
                    {
                        if (this.AmountPaid >= this.TotalIncVat)
                        {
                            invoiceItem.SalesInvoiceItemState = salesInvoiceItemStates.Paid;
                        }
                        else
                        {
                            invoiceItem.SalesInvoiceItemState = salesInvoiceItemStates.PartiallyPaid;
                        }
                    }
                }
            }

            if (this.ExistVatRegime && this.VatRegime.ExistVatClause)
            {
                this.DerivedVatClause = this.VatRegime.VatClause;
            }
            else
            {
                if (Equals(this.VatRegime, new VatRegimes(session).ServiceB2B))
                {
                    this.DerivedVatClause = new VatClauses(session).ServiceB2B;
                }
                else if (Equals(this.VatRegime, new VatRegimes(session).IntraCommunautair))
                {
                    this.DerivedVatClause = new VatClauses(session).Intracommunautair;
                }
            }

            this.DerivedVatClause = this.ExistAssignedVatClause ? this.AssignedVatClause : this.DerivedVatClause;

            this.BaseOnDeriveCustomers(derivation);

            if (this.ExistBillToCustomer && !this.BillToCustomer.BaseIsActiveCustomer(this.BilledFrom, this.InvoiceDate))
            {
                derivation.Validation.AddError(this, M.SalesInvoice.BillToCustomer, ErrorMessages.PartyIsNotACustomer);
            }

            if (this.ExistShipToCustomer && !this.ShipToCustomer.BaseIsActiveCustomer(this.BilledFrom, this.InvoiceDate))
            {
                derivation.Validation.AddError(this, M.SalesInvoice.ShipToCustomer, ErrorMessages.PartyIsNotACustomer);
            }

            this.PreviousBillToCustomer = this.BillToCustomer;
            this.PreviousShipToCustomer = this.ShipToCustomer;

            // this.BaseOnDeriveRevenues(derivation);
            var singleton = this.Session().GetSingleton();

            this.AddSecurityToken(new SecurityTokens(this.Session()).DefaultSecurityToken);

            this.Sync(this.Session());

            this.ResetPrintDocument();
        }