protected override void BaseSecure(Security config)
        {
            var created          = new PurchaseInvoiceStates(this.Session).Created;
            var awaitingApproval = new PurchaseInvoiceStates(this.Session).AwaitingApproval;
            var received         = new PurchaseInvoiceStates(this.Session).Received;
            var notPaid          = new PurchaseInvoiceStates(this.Session).NotPaid;
            var partiallyPaid    = new PurchaseInvoiceStates(this.Session).PartiallyPaid;
            var paid             = new PurchaseInvoiceStates(this.Session).Paid;
            var cancelled        = new PurchaseInvoiceStates(this.Session).Cancelled;
            var rejected         = new PurchaseInvoiceStates(this.Session).Rejected;

            var approve = this.Meta.Approve;
            var reject  = this.Meta.Reject;
            var confirm = this.Meta.Confirm;
            var cancel  = this.Meta.Cancel;
            var reopen  = this.Meta.Reopen;
            var delete  = this.Meta.Delete;
            var setPaid = this.Meta.SetPaid;

            config.Deny(this.ObjectType, created, approve, reject, reopen, setPaid);
            config.Deny(this.ObjectType, cancelled, approve, reject, confirm, cancel, setPaid, delete);
            config.Deny(this.ObjectType, rejected, approve, reject, confirm, cancel, setPaid, delete);
            config.Deny(this.ObjectType, awaitingApproval, confirm, cancel, reopen, setPaid, delete);
            config.Deny(this.ObjectType, notPaid, approve, confirm, reopen, delete);
            config.Deny(this.ObjectType, partiallyPaid, approve, confirm, reopen, delete);
            config.Deny(this.ObjectType, received, delete);

            config.Deny(this.ObjectType, notPaid, Operations.Write);
            config.Deny(this.ObjectType, partiallyPaid, Operations.Write);
            config.Deny(this.ObjectType, paid, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, cancelled, Operations.Write);
            config.Deny(this.ObjectType, rejected, Operations.Write, Operations.Execute);
        }
Example #2
0
        protected override void BaseSecure(Security config)
        {
            var created          = new PurchaseInvoiceStates(this.Session).Created;
            var awaitingApproval = new PurchaseInvoiceStates(this.Session).AwaitingApproval;
            var notPaid          = new PurchaseInvoiceStates(this.Session).NotPaid;
            var partiallyPaid    = new PurchaseInvoiceStates(this.Session).PartiallyPaid;
            var paid             = new PurchaseInvoiceStates(this.Session).Paid;
            var cancelled        = new PurchaseInvoiceStates(this.Session).Cancelled;
            var rejected         = new PurchaseInvoiceStates(this.Session).Rejected;
            var revising         = new PurchaseInvoiceStates(this.Session).Revising;

            var approve            = this.Meta.Approve;
            var reject             = this.Meta.Reject;
            var confirm            = this.Meta.Confirm;
            var cancel             = this.Meta.Cancel;
            var reopen             = this.Meta.Reopen;
            var createSalesInvoice = this.Meta.CreateSalesInvoice;
            var delete             = this.Meta.Delete;
            var setPaid            = this.Meta.SetPaid;
            var revise             = this.Meta.Revise;
            var finishRevising     = this.Meta.FinishRevising;

            config.Deny(this.ObjectType, created, approve, reject, reopen, createSalesInvoice, setPaid, revise, finishRevising);
            config.Deny(this.ObjectType, cancelled, approve, reject, confirm, cancel, setPaid, createSalesInvoice, delete, revise, finishRevising);
            config.Deny(this.ObjectType, rejected, approve, reject, confirm, cancel, setPaid, createSalesInvoice, delete, revise, finishRevising);
            config.Deny(this.ObjectType, awaitingApproval, confirm, cancel, reopen, setPaid, delete, revise, finishRevising);
            config.Deny(this.ObjectType, notPaid, cancel, reject, approve, confirm, reopen, createSalesInvoice, delete, finishRevising);
            config.Deny(this.ObjectType, partiallyPaid, cancel, reject, approve, confirm, reopen, createSalesInvoice, delete, finishRevising);
            config.Deny(this.ObjectType, paid, cancel, reject, approve, confirm, reopen, createSalesInvoice, delete, finishRevising);

            if (revising != null)
            {
                config.Deny(this.ObjectType, revising, cancel, reject, approve, confirm, reopen, createSalesInvoice, delete, setPaid, revise);
            }

            var except = new HashSet <IOperandType>
            {
                this.Meta.ElectronicDocuments.RoleType,
                this.Meta.Print,
            };

            config.DenyExcept(this.ObjectType, notPaid, except, Operations.Write);
            config.DenyExcept(this.ObjectType, partiallyPaid, except, Operations.Write);
            config.DenyExcept(this.ObjectType, paid, except, Operations.Write);
            config.DenyExcept(this.ObjectType, cancelled, except, Operations.Write);
            config.DenyExcept(this.ObjectType, rejected, except, Operations.Write);
        }
Example #3
0
        protected override void AppsSecure(Security config)
        {
            base.AppsSecure(config);

            var inProcess = new PurchaseInvoiceStates(this.Session).InProcess;
            var received  = new PurchaseInvoiceStates(this.Session).Received;
            var paid      = new PurchaseInvoiceStates(this.Session).Paid;
            var cancelled = new PurchaseInvoiceStates(this.Session).Cancelled;
            var finished  = new PurchaseInvoiceStates(this.Session).Finished;

            var approve            = this.Meta.Approve;
            var createSalesInvoice = this.Meta.CreateSalesInvoice;

            config.Deny(this.ObjectType, inProcess, approve);
            config.Deny(this.ObjectType, received, createSalesInvoice);

            config.Deny(this.ObjectType, paid, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, cancelled, Operations.Write, Operations.Execute);
            config.Deny(this.ObjectType, finished, Operations.Write, Operations.Execute);
        }
Example #4
0
        public void BaseOnDerive(ObjectOnDerive method)
        {
            var derivation = method.Derivation;

            var internalOrganisations = new Organisations(this.Strategy.Session).Extent().Where(v => Equals(v.IsInternalOrganisation, true)).ToArray();

            if (!this.ExistBilledTo && internalOrganisations.Count() == 1)
            {
                this.BilledTo = internalOrganisations.First();
            }

            if (!this.ExistInvoiceNumber)
            {
                var year = this.InvoiceDate.Year;
                this.InvoiceNumber = this.BilledTo.NextPurchaseInvoiceNumber(year);

                var fiscalYearInternalOrganisationSequenceNumbers = this.BilledTo.FiscalYearsInternalOrganisationSequenceNumbers.FirstOrDefault(v => v.FiscalYear == year);
                var prefix = this.BilledTo.InvoiceSequence.IsEnforcedSequence ? this.BilledTo.PurchaseInvoiceNumberPrefix : fiscalYearInternalOrganisationSequenceNumbers.PurchaseInvoiceNumberPrefix;
                this.SortableInvoiceNumber = this.Session().GetSingleton().SortableNumber(prefix, this.InvoiceNumber, year.ToString());
            }

            if (this.BilledFrom is Organisation supplier)
            {
                if (!this.BilledTo.ActiveSuppliers.Contains(supplier))
                {
                    derivation.Validation.AddError(this, this.Meta.BilledFrom, ErrorMessages.PartyIsNotASupplier);
                }
            }

            if (this.PurchaseInvoiceState.IsCreated)
            {
                this.DerivedVatRegime  = this.AssignedVatRegime;
                this.DerivedIrpfRegime = this.AssignedIrpfRegime;
                this.DerivedCurrency   = this.AssignedCurrency ?? this.BilledTo?.PreferredCurrency;

                if (this.ExistInvoiceDate)
                {
                    this.DerivedVatRate  = this.DerivedVatRegime?.VatRates.First(v => v.FromDate <= this.InvoiceDate && (!v.ExistThroughDate || v.ThroughDate >= this.InvoiceDate));
                    this.DerivedIrpfRate = this.DerivedIrpfRegime?.IrpfRates.First(v => v.FromDate <= this.InvoiceDate && (!v.ExistThroughDate || v.ThroughDate >= this.InvoiceDate));
                }
            }

            if (this.ExistInvoiceDate &&
                this.ExistBilledTo &&
                this.DerivedCurrency != this.BilledTo.PreferredCurrency)
            {
                var exchangeRate = this.DerivedCurrency.ExchangeRatesWhereFromCurrency.Where(v => v.ValidFrom.Date <= this.InvoiceDate.Date && v.ToCurrency.Equals(this.BilledTo.PreferredCurrency)).OrderByDescending(v => v.ValidFrom).FirstOrDefault();

                if (exchangeRate == null)
                {
                    exchangeRate = this.BilledTo.PreferredCurrency.ExchangeRatesWhereFromCurrency.Where(v => v.ValidFrom.Date <= this.InvoiceDate.Date && v.ToCurrency.Equals(this.DerivedCurrency)).OrderByDescending(v => v.ValidFrom).FirstOrDefault();
                }

                if (exchangeRate == null)
                {
                    derivation.Validation.AddError(this, M.Quote.AssignedCurrency, ErrorMessages.CurrencyNotAllowed);
                }
            }

            this.PurchaseOrders = this.InvoiceItems.SelectMany(v => v.OrderItemBillingsWhereInvoiceItem).Select(v => v.OrderItem.OrderWhereValidOrderItem).ToArray();

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

            this.ValidInvoiceItems = validInvoiceItems;

            var purchaseInvoiceStates     = new PurchaseInvoiceStates(this.Strategy.Session);
            var purchaseInvoiceItemStates = new PurchaseInvoiceItemStates(this.Strategy.Session);

            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);
            }

            foreach (var invoiceItem in validInvoiceItems)
            {
                if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsRevising)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Revising;
                }
                else if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsCreated)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Created;
                }
                else if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsAwaitingApproval)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.AwaitingApproval;
                }
                else if (invoiceItem.AmountPaid == 0)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.NotPaid;
                }
                else if (invoiceItem.ExistAmountPaid && invoiceItem.AmountPaid >= invoiceItem.GrandTotal)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Paid;
                }
                else
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.PartiallyPaid;
                }
            }

            if (validInvoiceItems.Any())
            {
                if (!this.PurchaseInvoiceState.IsRevising &&
                    !this.PurchaseInvoiceState.IsCreated &&
                    !this.PurchaseInvoiceState.IsAwaitingApproval)
                {
                    if (this.PurchaseInvoiceItems.All(v => v.PurchaseInvoiceItemState.IsPaid))
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.Paid;
                    }
                    else if (this.PurchaseInvoiceItems.All(v => v.PurchaseInvoiceItemState.IsNotPaid))
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.NotPaid;
                    }
                    else
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.PartiallyPaid;
                    }
                }
            }

            // If disbursements are not matched at invoice level
            if (!this.PurchaseInvoiceState.IsRevising &&
                this.AmountPaid != 0)
            {
                if (this.AmountPaid >= decimal.Round(this.GrandTotal, 2))
                {
                    this.PurchaseInvoiceState = purchaseInvoiceStates.Paid;
                }
                else
                {
                    this.PurchaseInvoiceState = purchaseInvoiceStates.PartiallyPaid;
                }

                foreach (var invoiceItem in validInvoiceItems)
                {
                    if (this.AmountPaid >= decimal.Round(this.GrandTotal, 2))
                    {
                        invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Paid;
                    }
                    else
                    {
                        invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.PartiallyPaid;
                    }
                }
            }

            if (!this.PurchaseInvoiceState.IsRevising &&
                !this.PurchaseInvoiceState.IsCreated &&
                !this.PurchaseInvoiceState.IsAwaitingApproval)
            {
                foreach (var invoiceItem in validInvoiceItems)
                {
                    if (invoiceItem.ExistSerialisedItem &&
                        this.BilledTo.SerialisedItemSoldOns.Contains(new SerialisedItemSoldOns(this.Session()).PurchaseInvoiceConfirm))
                    {
                        if ((this.BilledFrom as InternalOrganisation)?.IsInternalOrganisation == false)
                        {
                            invoiceItem.SerialisedItem.Buyer = this.BilledTo;
                        }

                        //TODO: Martien , remove check on date and place it in custom derive
                        // who comes first?
                        // Item you purchased can be on sold via sales invoice even before purchase invoice is created and confirmed!!

                        if (this.InvoiceDate > new DateTime(2021, 07, 04) &&
                            !invoiceItem.SerialisedItem.SalesInvoiceItemsWhereSerialisedItem.Any(v => (v.SalesInvoiceWhereSalesInvoiceItem.BillToCustomer as Organisation)?.IsInternalOrganisation == false &&
                                                                                                 v.SalesInvoiceWhereSalesInvoiceItem.SalesInvoiceType.Equals(new SalesInvoiceTypes(this.Session()).SalesInvoice) &&
                                                                                                 !v.SalesInvoiceWhereSalesInvoiceItem.ExistSalesInvoiceWhereCreditedFromInvoice))
                        {
                            invoiceItem.SerialisedItem.OwnedBy   = this.BilledTo;
                            invoiceItem.SerialisedItem.Ownership = new Ownerships(this.Session()).Own;
                        }
                    }
                }
            }

            this.BaseOnDeriveInvoiceItems(derivation);
            this.BaseOnDeriveInvoiceTotals();

            this.DeriveWorkflow();

            var singleton = this.Session().GetSingleton();

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

            this.Sync(this.Session());

            this.ResetPrintDocument();
        }
        public void BaseOnDerive(ObjectOnDerive method)
        {
            var derivation = method.Derivation;

            var internalOrganisations = new Organisations(this.Strategy.Session).Extent().Where(v => Equals(v.IsInternalOrganisation, true)).ToArray();

            if (!this.ExistBilledTo && internalOrganisations.Count() == 1)
            {
                this.BilledTo = internalOrganisations.First();
            }

            if (!this.ExistInvoiceNumber)
            {
                this.InvoiceNumber = this.BilledTo.NextPurchaseInvoiceNumber(this.InvoiceDate.Year);
            }

            if (this.BilledFrom is Organisation supplier)
            {
                if (!this.BilledTo.ActiveSuppliers.Contains(supplier))
                {
                    derivation.Validation.AddError(this, this.Meta.BilledFrom, ErrorMessages.PartyIsNotASupplier);
                }
            }

            this.PurchaseOrders = this.InvoiceItems.SelectMany(v => v.OrderItemBillingsWhereInvoiceItem).Select(v => v.OrderItem.OrderWhereValidOrderItem).ToArray();

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

            this.ValidInvoiceItems = validInvoiceItems;

            var purchaseInvoiceStates     = new PurchaseInvoiceStates(this.Strategy.Session);
            var purchaseInvoiceItemStates = new PurchaseInvoiceItemStates(this.Strategy.Session);

            foreach (var invoiceItem in validInvoiceItems)
            {
                if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsCreated)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Created;
                }
                else if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsAwaitingApproval)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.AwaitingApproval;
                }
                else if (invoiceItem.AmountPaid == 0)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.NotPaid;
                }
                else if (invoiceItem.ExistAmountPaid && invoiceItem.AmountPaid >= invoiceItem.TotalIncVat)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Paid;
                }
                else
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.PartiallyPaid;
                }
            }

            if (validInvoiceItems.Any())
            {
                if (!this.PurchaseInvoiceState.IsCreated && !this.PurchaseInvoiceState.IsAwaitingApproval)
                {
                    if (this.PurchaseInvoiceItems.All(v => v.PurchaseInvoiceItemState.IsPaid))
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.Paid;
                    }
                    else if (this.PurchaseInvoiceItems.All(v => v.PurchaseInvoiceItemState.IsNotPaid))
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.NotPaid;
                    }
                    else
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.PartiallyPaid;
                    }
                }
            }

            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 disbursements are not matched at invoice level
            if (this.AmountPaid > 0)
            {
                if (this.AmountPaid >= this.TotalIncVat)
                {
                    this.PurchaseInvoiceState = purchaseInvoiceStates.Paid;
                }
                else
                {
                    this.PurchaseInvoiceState = purchaseInvoiceStates.PartiallyPaid;
                }

                foreach (var invoiceItem in validInvoiceItems)
                {
                    if (this.AmountPaid >= this.TotalIncVat)
                    {
                        invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Paid;
                    }
                    else
                    {
                        invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.PartiallyPaid;
                    }
                }
            }

            this.BaseOnDeriveInvoiceItems(derivation);
            this.BaseOnDeriveInvoiceTotals();

            this.DeriveWorkflow();

            var singleton = this.Session().GetSingleton();

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

            this.Sync(this.Session());

            this.ResetPrintDocument();
        }
Example #6
0
        public void BaseOnDerive(ObjectOnDerive method)
        {
            var derivation = method.Derivation;

            var internalOrganisations = new Organisations(this.Strategy.Session).Extent().Where(v => Equals(v.IsInternalOrganisation, true)).ToArray();

            if (!this.ExistBilledTo && internalOrganisations.Count() == 1)
            {
                this.BilledTo = internalOrganisations.First();
            }

            if (!this.ExistInvoiceNumber)
            {
                this.InvoiceNumber         = this.BilledTo.NextPurchaseInvoiceNumber(this.InvoiceDate.Year);
                this.SortableInvoiceNumber = this.Session().GetSingleton().SortableNumber(this.BilledTo.PurchaseInvoiceNumberPrefix, this.InvoiceNumber, this.InvoiceDate.Year.ToString());
            }

            if (this.BilledFrom is Organisation supplier)
            {
                if (!this.BilledTo.ActiveSuppliers.Contains(supplier))
                {
                    derivation.Validation.AddError(this, this.Meta.BilledFrom, ErrorMessages.PartyIsNotASupplier);
                }
            }

            this.VatRegime ??= this.BilledFrom?.VatRegime;
            this.IrpfRegime ??= (this.BilledFrom as Organisation)?.IrpfRegime;

            this.PurchaseOrders = this.InvoiceItems.SelectMany(v => v.OrderItemBillingsWhereInvoiceItem).Select(v => v.OrderItem.OrderWhereValidOrderItem).ToArray();

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

            this.ValidInvoiceItems = validInvoiceItems;

            var purchaseInvoiceStates     = new PurchaseInvoiceStates(this.Strategy.Session);
            var purchaseInvoiceItemStates = new PurchaseInvoiceItemStates(this.Strategy.Session);

            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);
            }

            foreach (var invoiceItem in validInvoiceItems)
            {
                if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsRevising)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Revising;
                }
                else if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsCreated)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Created;
                }
                else if (invoiceItem.PurchaseInvoiceWherePurchaseInvoiceItem.PurchaseInvoiceState.IsAwaitingApproval)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.AwaitingApproval;
                }
                else if (invoiceItem.AmountPaid == 0)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.NotPaid;
                }
                else if (invoiceItem.ExistAmountPaid && invoiceItem.AmountPaid >= invoiceItem.TotalIncVat)
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Paid;
                }
                else
                {
                    invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.PartiallyPaid;
                }
            }

            if (validInvoiceItems.Any())
            {
                if (!this.PurchaseInvoiceState.IsRevising &&
                    !this.PurchaseInvoiceState.IsCreated &&
                    !this.PurchaseInvoiceState.IsAwaitingApproval)
                {
                    if (this.PurchaseInvoiceItems.All(v => v.PurchaseInvoiceItemState.IsPaid))
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.Paid;
                    }
                    else if (this.PurchaseInvoiceItems.All(v => v.PurchaseInvoiceItemState.IsNotPaid))
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.NotPaid;
                    }
                    else
                    {
                        this.PurchaseInvoiceState = purchaseInvoiceStates.PartiallyPaid;
                    }
                }
            }

            if (!this.PurchaseInvoiceState.IsRevising &&
                !this.PurchaseInvoiceState.IsCreated &&
                !this.PurchaseInvoiceState.IsAwaitingApproval)
            {
                foreach (var invoiceItem in validInvoiceItems)
                {
                    if (invoiceItem.ExistSerialisedItem &&
                        this.BilledTo.SerialisedItemSoldOns.Contains(new SerialisedItemSoldOns(this.Session()).PurchaseInvoiceConfirm))
                    {
                        if ((this.BilledFrom as InternalOrganisation)?.IsInternalOrganisation == false)
                        {
                            invoiceItem.SerialisedItem.Buyer = this.BilledTo;
                        }

                        // who comes first?
                        // Item you purchased can be on sold via sales invoice even before purchase invoice is created and confirmed!!
                        if (!invoiceItem.SerialisedItem.SalesInvoiceItemsWhereSerialisedItem.Any(v => (v.SalesInvoiceWhereSalesInvoiceItem.BillToCustomer as Organisation)?.IsInternalOrganisation == false))
                        {
                            invoiceItem.SerialisedItem.OwnedBy   = this.BilledTo;
                            invoiceItem.SerialisedItem.Ownership = new Ownerships(this.Session()).Own;
                        }
                    }
                }
            }

            // If disbursements are not matched at invoice level
            if (!this.PurchaseInvoiceState.IsRevising &&
                this.AmountPaid != 0)
            {
                if (this.AmountPaid >= decimal.Round(this.TotalIncVat, 2))
                {
                    this.PurchaseInvoiceState = purchaseInvoiceStates.Paid;
                }
                else
                {
                    this.PurchaseInvoiceState = purchaseInvoiceStates.PartiallyPaid;
                }

                foreach (var invoiceItem in validInvoiceItems)
                {
                    if (this.AmountPaid >= decimal.Round(this.TotalIncVat, 2))
                    {
                        invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.Paid;
                    }
                    else
                    {
                        invoiceItem.PurchaseInvoiceItemState = purchaseInvoiceItemStates.PartiallyPaid;
                    }
                }
            }

            this.BaseOnDeriveInvoiceItems(derivation);
            this.BaseOnDeriveInvoiceTotals();

            this.DeriveWorkflow();

            var singleton = this.Session().GetSingleton();

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

            this.Sync(this.Session());

            this.ResetPrintDocument();
        }