protected override void BaseSecure(Security config) { var notPaid = new SalesInvoiceStates(this.Session).NotPaid; var paid = new SalesInvoiceStates(this.Session).Paid; var partiallyPaid = new SalesInvoiceStates(this.Session).PartiallyPaid; var writtenOff = new SalesInvoiceStates(this.Session).WrittenOff; var cancelled = new SalesInvoiceStates(this.Session).Cancelled; var readyForPosting = new SalesInvoiceStates(this.Session).ReadyForPosting; var send = this.Meta.Send; var cancelInvoice = this.Meta.CancelInvoice; var writeOff = this.Meta.WriteOff; var reopen = this.Meta.Reopen; var credit = this.Meta.Credit; var setPaid = this.Meta.SetPaid; var delete = this.Meta.Delete; config.Deny(this.ObjectType, readyForPosting, reopen, credit, setPaid, writeOff); config.Deny(this.ObjectType, notPaid, send, cancelInvoice, reopen, delete); config.Deny(this.ObjectType, partiallyPaid, send, cancelInvoice, reopen, delete); config.Deny(this.ObjectType, paid, send, writeOff, cancelInvoice, reopen, setPaid, delete); config.Deny(this.ObjectType, writtenOff, send, cancelInvoice, writeOff, credit, setPaid, delete, reopen); config.Deny(this.ObjectType, cancelled, send, cancelInvoice, writeOff, credit, setPaid, 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, writtenOff, Operations.Write); config.Deny(this.ObjectType, cancelled, Operations.Write); }
protected override void AppsSecure(Security config) { base.AppsSecure(config); var sent = new SalesInvoiceStates(this.Session).Sent; var paid = new SalesInvoiceStates(this.Session).Paid; var partiallyPaid = new SalesInvoiceStates(this.Session).PartiallyPaid; var writtenOff = new SalesInvoiceStates(this.Session).WrittenOff; var cancelled = new SalesInvoiceStates(this.Session).Cancelled; var readyForPosting = new SalesInvoiceStates(this.Session).ReadyForPosting; var send = this.Meta.Send; var cancelInvoice = this.Meta.CancelInvoice; var writeOff = this.Meta.WriteOff; var reopen = this.Meta.Reopen; var credit = this.Meta.Credit; config.Deny(this.ObjectType, partiallyPaid, send, cancelInvoice, reopen); config.Deny(this.ObjectType, readyForPosting, reopen, credit); config.Deny(this.ObjectType, sent, Operations.Write); config.Deny(this.ObjectType, sent, send, cancelInvoice); config.Deny(this.ObjectType, paid, Operations.Write); config.Deny(this.ObjectType, paid, send, writeOff, cancelInvoice, reopen); config.Deny(this.ObjectType, writtenOff, Operations.Write); config.Deny(this.ObjectType, writtenOff, send, cancelInvoice, writeOff, credit); config.Deny(this.ObjectType, cancelled, Operations.Write); config.Deny(this.ObjectType, cancelled, send, cancelInvoice, writeOff, credit); }
protected override void BaseSecure(Security config) { var notPaid = new SalesInvoiceStates(this.Session).NotPaid; var paid = new SalesInvoiceStates(this.Session).Paid; var partiallyPaid = new SalesInvoiceStates(this.Session).PartiallyPaid; var writtenOff = new SalesInvoiceStates(this.Session).WrittenOff; var cancelled = new SalesInvoiceStates(this.Session).Cancelled; var readyForPosting = new SalesInvoiceStates(this.Session).ReadyForPosting; var send = this.Meta.Send; var cancelInvoice = this.Meta.CancelInvoice; var writeOff = this.Meta.WriteOff; var reopen = this.Meta.Reopen; var credit = this.Meta.Credit; var setPaid = this.Meta.SetPaid; var delete = this.Meta.Delete; config.Deny(this.ObjectType, readyForPosting, reopen, credit, setPaid, writeOff); config.Deny(this.ObjectType, notPaid, send, cancelInvoice, reopen, delete); config.Deny(this.ObjectType, partiallyPaid, send, cancelInvoice, reopen, delete); config.Deny(this.ObjectType, paid, send, writeOff, cancelInvoice, reopen, setPaid, delete); config.Deny(this.ObjectType, writtenOff, send, cancelInvoice, writeOff, credit, setPaid, delete, reopen); config.Deny(this.ObjectType, cancelled, send, cancelInvoice, writeOff, credit, setPaid, delete); var except = new HashSet <IOperandType> { this.Meta.ElectronicDocuments.RoleType, this.Meta.Print, this.Meta.Credit, }; config.DenyExcept(this.ObjectType, notPaid, except, Operations.Write); config.DenyExcept(this.ObjectType, partiallyPaid, except, Operations.Write); config.DenyExcept(this.ObjectType, paid, except, Operations.Write, Operations.Execute); config.DenyExcept(this.ObjectType, writtenOff, except, Operations.Write); config.DenyExcept(this.ObjectType, cancelled, except, Operations.Write); }
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(); }