public void AppsOnDerive(ObjectOnDerive method) { var derivation = method.Derivation; var internalOrganisations = new Organisations(this.strategy.Session).Extent().Where(v => Equals(v.IsInternalOrganisation, true)).ToArray(); if (!this.ExistBilledFrom && internalOrganisations.Count() == 1) { this.BilledFrom = internalOrganisations.First(); } if (!this.ExistStore && this.ExistBilledFrom) { var store = new Stores(this.strategy.Session).Extent().FirstOrDefault(v => Equals(v.InternalOrganisation, this.BilledFrom)); if (store != null) { this.Store = store; } } if (!this.ExistInvoiceNumber && this.ExistStore) { this.InvoiceNumber = this.Store.DeriveNextTemporaryInvoiceNumber(); } if (!this.ExistBilledFromContactMechanism) { 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) { 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 : this.Strategy.Session.GetSingleton().DefaultLocale.Country.Currency; } } foreach (SalesInvoiceItem salesInvoiceItem in this.SalesInvoiceItems) { foreach (OrderItemBilling orderItemBilling in salesInvoiceItem.OrderItemBillingsWhereInvoiceItem) { var salesOrder = orderItemBilling.OrderItem.SalesOrderWhereSalesOrderItem; if (this.SalesOrders.Contains(salesOrder)) { this.SalesOrders.Add(salesOrder); } } foreach (WorkEffortBilling workEffortBilling in salesInvoiceItem.WorkEffortBillingsWhereInvoiceItem) { if (this.SalesOrders.Contains(workEffortBilling.WorkEffort)) { this.SalesOrders.Add(workEffortBilling.WorkEffort); } } } this.IsRepeatingInvoice = this.ExistRepeatingSalesInvoiceWhereSource && (!this.RepeatingSalesInvoiceWhereSource.ExistFinalExecutionDate || this.RepeatingSalesInvoiceWhereSource.FinalExecutionDate.Value.Date >= this.strategy.Session.Now().Date); this.AppsOnDeriveInvoiceItems(derivation); this.SalesInvoiceItems = this.SalesInvoiceItems.ToArray(); this.AppsOnDeriveLocale(derivation); this.AppsOnDeriveInvoiceTotals(derivation); this.AppsOnDeriveCustomers(derivation); this.AppsOnDeriveSalesReps(derivation); this.AppsOnDeriveAmountPaid(derivation); if (this.ExistBillToCustomer && !this.BillToCustomer.AppsIsActiveCustomer(this.BilledFrom, this.InvoiceDate)) { derivation.Validation.AddError(this, M.SalesInvoice.BillToCustomer, ErrorMessages.PartyIsNotACustomer); } if (this.ExistShipToCustomer && !this.ShipToCustomer.AppsIsActiveCustomer(this.BilledFrom, this.InvoiceDate)) { derivation.Validation.AddError(this, M.SalesInvoice.ShipToCustomer, ErrorMessages.PartyIsNotACustomer); } this.DeriveCurrentPaymentStatus(derivation); this.DeriveCurrentObjectState(derivation); this.PreviousBillToCustomer = this.BillToCustomer; this.PreviousShipToCustomer = this.ShipToCustomer; //this.AppsOnDeriveRevenues(derivation); this.ResetPrintDocument(); }
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(); }
public void BaseOnBuild(ObjectOnBuild method) { if (!this.ExistSalesOrderState) { this.SalesOrderState = new SalesOrderStates(this.Strategy.Session).Provisional; } if (!this.ExistSalesOrderShipmentState) { this.SalesOrderShipmentState = new SalesOrderShipmentStates(this.Strategy.Session).NotShipped; } if (!this.ExistSalesOrderInvoiceState) { this.SalesOrderInvoiceState = new SalesOrderInvoiceStates(this.Strategy.Session).NotInvoiced; } if (!this.ExistSalesOrderPaymentState) { this.SalesOrderPaymentState = new SalesOrderPaymentStates(this.Strategy.Session).NotPaid; } if (!this.ExistOrderDate) { this.OrderDate = this.Session().Now(); } if (!this.ExistEntryDate) { this.EntryDate = this.Session().Now(); } if (!this.ExistPartiallyShip) { this.PartiallyShip = true; } if (!this.ExistTakenBy) { var internalOrganisations = new Organisations(this.Strategy.Session).InternalOrganisations(); if (internalOrganisations.Count() == 1) { this.TakenBy = internalOrganisations.First(); } } if (!this.ExistStore && this.ExistTakenBy) { var stores = new Stores(this.Strategy.Session).Extent(); stores.Filter.AddEquals(M.Store.InternalOrganisation, this.TakenBy); if (stores.Any()) { this.Store = stores.First; } } if (!this.ExistOriginFacility) { this.OriginFacility = this.ExistStore ? this.Store.DefaultFacility : this.Strategy.Session.GetSingleton().Settings.DefaultFacility; } if (!this.ExistOrderNumber && this.ExistStore) { this.OrderNumber = this.Store.NextSalesOrderNumber(this.OrderDate.Year); } }
public void GivenCustomerBuyingFromDifferentStores_WhenShipping_ThenPickListIsCreatedForEachStore() { var store1 = new Stores(this.Session).FindBy(M.Store.Name, "store"); var store2 = new StoreBuilder(this.Session).WithName("second store") .WithDefaultFacility(new Facilities(this.Session).Extent().First) .WithDefaultShipmentMethod(new ShipmentMethods(this.Session).Ground) .WithDefaultCarrier(new Carriers(this.Session).Fedex) .WithSalesOrderNumberPrefix("") .WithOutgoingShipmentNumberPrefix("") .WithIsImmediatelyPacked(true) .Build(); var good1 = new NonUnifiedGoods(this.Session).FindBy(M.Good.Name, "good1"); new InventoryItemTransactionBuilder(this.Session).WithQuantity(100).WithReason(new InventoryTransactionReasons(this.Session).PhysicalCount).WithPart(good1.Part).Build(); var mechelen = new CityBuilder(this.Session).WithName("Mechelen").Build(); var mechelenAddress = new PostalAddressBuilder(this.Session).WithPostalAddressBoundary(mechelen).WithAddress1("Haverwerf 15").Build(); var shipToMechelen = new PartyContactMechanismBuilder(this.Session) .WithContactMechanism(mechelenAddress) .WithContactPurpose(new ContactMechanismPurposes(this.Session).ShippingAddress) .WithUseAsDefault(true) .Build(); var customer = new PersonBuilder(this.Session).WithLastName("customer").WithPartyContactMechanism(shipToMechelen).Build(); new CustomerRelationshipBuilder(this.Session).WithFromDate(this.Session.Now()).WithCustomer(customer).Build(); this.Session.Derive(true); var order1 = new SalesOrderBuilder(this.Session) .WithStore(store1) .WithBillToCustomer(customer) .WithAssignedBillToContactMechanism(mechelenAddress) .WithShipToCustomer(customer) .Build(); var order1Item = new SalesOrderItemBuilder(this.Session).WithProduct(good1).WithQuantityOrdered(1).WithAssignedUnitPrice(15).Build(); order1.AddSalesOrderItem(order1Item); this.Session.Derive(true); order1.SetReadyForPosting(); this.Session.Derive(true); order1.Post(); this.Session.Derive(); order1.Accept(); this.Session.Derive(); Assert.Single(customer.ShipmentsWhereShipToParty); var order2 = new SalesOrderBuilder(this.Session) .WithStore(store1) .WithBillToCustomer(customer) .WithShipToCustomer(customer) .Build(); var order2Item = new SalesOrderItemBuilder(this.Session).WithProduct(good1).WithQuantityOrdered(2).WithAssignedUnitPrice(15).Build(); order2.AddSalesOrderItem(order2Item); this.Session.Derive(true); order2.SetReadyForPosting(); this.Session.Derive(true); order2.Post(); this.Session.Derive(); order2.Accept(); this.Session.Derive(); Assert.Single(customer.ShipmentsWhereShipToParty); var store1Shipment = (CustomerShipment)mechelenAddress.ShipmentsWhereShipToAddress.First(v => v.Store.Equals(store1)); store1Shipment.Pick(); this.Session.Derive(); var order3 = new SalesOrderBuilder(this.Session) .WithStore(store2) .WithBillToCustomer(customer) .WithShipToCustomer(customer) .Build(); var order3Item = new SalesOrderItemBuilder(this.Session).WithProduct(good1).WithQuantityOrdered(5).WithAssignedUnitPrice(15).Build(); order3.AddSalesOrderItem(order3Item); this.Session.Derive(true); order3.SetReadyForPosting(); this.Session.Derive(true); order3.Post(); this.Session.Derive(); order3.Accept(); this.Session.Derive(); var store2Shipment = (CustomerShipment)mechelenAddress.ShipmentsWhereShipToAddress.First(v => v.Store.Equals(store2)); store2Shipment.Pick(); this.Session.Derive(); var store1PickList = customer.PickListsWhereShipToParty.FirstOrDefault(v => v.Store.Equals(store1)); var store2PickList = customer.PickListsWhereShipToParty.FirstOrDefault(v => v.Store.Equals(store2)); Assert.Equal(2, customer.PickListsWhereShipToParty.Count); Assert.NotNull(store1PickList); Assert.Equal(3, store1PickList.PickListItems[0].Quantity); Assert.NotNull(store2PickList); Assert.Equal(5, store2PickList.PickListItems[0].Quantity); }