/// <summary> /// Save changes back to models /// </summary> public void CommitHeaderChanges() { if (this.Validated) { // First check if a pickup code was configured on the back end and exists in the DB string pickupCode = LSRetailPosis.Settings.ApplicationSettings.Terminal.PickupDeliveryModeCode; if (string.IsNullOrWhiteSpace(pickupCode)) { // "Pickup cannot be used for delivery because a pickup delivery code was not found." string errorMessage = LSRetailPosis.ApplicationLocalizer.Language.Translate(56382); SalesOrder.LogMessage(errorMessage, LSRetailPosis.LogTraceLevel.Error); throw new InvalidOperationException(errorMessage); } this.transaction.RequestedDeliveryDate = this.PickupDate.Value; this.transaction.StoreId = this.SelectedStore.Number; this.transaction.WarehouseId = this.SelectedStore.Warehouse; this.transaction.DeliveryMode = storeDataManager.GetDeliveryMode(ApplicationSettings.Terminal.PickupDeliveryModeCode); this.transaction.ShippingAddress = GetStoreAddress(this.selectedStore); // Remove any header level charge var headerCharge = transaction.MiscellaneousCharges.FirstOrDefault(m => string.Equals(m.ChargeCode, LSRetailPosis.Settings.ApplicationSettings.Terminal.ShippingChargeCode, StringComparison.Ordinal)); if (headerCharge != null) { transaction.MiscellaneousCharges.Remove(headerCharge); } // Clear any line item delivery options and duplicate the pickup store on each line foreach (var item in this.transaction.SaleItems) { ClearLineDeliveryOptions(item); item.DeliveryStoreNumber = this.transaction.StoreId; item.DeliveryWarehouse = this.transaction.WarehouseId; item.ShippingAddress = this.transaction.ShippingAddress; if (this.transaction.RequestedDeliveryDate != default(DateTime)) { item.DeliveryDate = this.transaction.RequestedDeliveryDate; } } } }
internal static CustomerOrderTransaction GetTransactionFromInfo(CustomerOrderInfo orderInfo, SalesOrder salesOrderService) { CustomerOrderTransaction transaction = (CustomerOrderTransaction)SalesOrder.InternalApplication.BusinessLogic.Utility.CreateCustomerOrderTransaction( ApplicationSettings.Terminal.StoreId, ApplicationSettings.Terminal.StoreCurrency, ApplicationSettings.Terminal.TaxIncludedInPrice, SalesOrder.InternalApplication.Services.Rounding, salesOrderService); // Get all the defaults SalesOrder.InternalApplication.BusinessLogic.TransactionSystem.LoadTransactionStatus(transaction); // General header properties transaction.OrderId = orderInfo.Id; transaction.OrderType = orderInfo.OrderType; if (orderInfo.OrderType == CustomerOrderType.Quote) { transaction.QuotationId = orderInfo.Id; } transaction.OriginalOrderType = orderInfo.OrderType; switch (orderInfo.OrderType) { case CustomerOrderType.Quote: transaction.OrderStatus = GetSalesStatus((SalesQuotationStatus)orderInfo.Status); break; case CustomerOrderType.SalesOrder: transaction.OrderStatus = GetSalesStatus((SalesOrderStatus)orderInfo.Status, (DocumentStatus)orderInfo.DocumentStatus); break; default: transaction.OrderStatus = SalesStatus.Unknown; NetTracer.Information("SalesOrder::CustomerOrderTransaction: CustomerOrderInfo OrderType is unknown: {0}", orderInfo.OrderType); break; } transaction.LockPrices = true; transaction.ExpirationDate = ParseDateString(orderInfo.ExpiryDateString, DateTime.Today); // RequestedDeliveryDate is directly input from user. It is stored in the local timezone transaction.RequestedDeliveryDate = ParseDateString(orderInfo.RequestedDeliveryDateString, DateTime.Today); // CreationDate is stored in UTC. It needs to be converted to local time zone where order is accessed. ((IPosTransactionV2)transaction).BeginDateTime = ParseDateString(orderInfo.CreationDateString, DateTime.UtcNow, DateTimeStyles.AdjustToUniversal).ToLocalTime(); transaction.LocalHourOfDay = orderInfo.LocalHourOfDay; ((IPosTransactionV2)transaction).Comment = orderInfo.Comment; // Header delivery DM.StoreDataManager storeDataManager = new DM.StoreDataManager( SalesOrder.InternalApplication.Settings.Database.Connection, SalesOrder.InternalApplication.Settings.Database.DataAreaID); transaction.WarehouseId = orderInfo.WarehouseId; transaction.DeliveryMode = storeDataManager.GetDeliveryMode(orderInfo.DeliveryMode); transaction.CurrencyCode = orderInfo.CurrencyCode; foreach (var code in orderInfo.DiscountCodes) { transaction.DiscountCodes.AddLast(code); } // Header affiliation DM.AffiliationDataManager affiliationDataManager = new DM.AffiliationDataManager( SalesOrder.InternalApplication.Settings.Database.Connection, SalesOrder.InternalApplication.Settings.Database.DataAreaID); if (orderInfo.Affiliations != null && orderInfo.Affiliations.Any()) { foreach (AffiliationInfo affiliationInfo in orderInfo.Affiliations) { transaction.AffiliationLines.AddLast( new AffiliationItem() { RecId = affiliationInfo.AffiliationId, LoyaltyTier = affiliationInfo.LoyaltyTierId, AffiliationType = affiliationInfo.AffiliationType }); } } // Customer info ICustomerSystem customerSystem = SalesOrder.InternalApplication.BusinessLogic.CustomerSystem; DM.CustomerDataManager customerDataManager = new DM.CustomerDataManager( SalesOrder.InternalApplication.Settings.Database.Connection, SalesOrder.InternalApplication.Settings.Database.DataAreaID); DE.ICustomer customer = customerSystem.GetCustomerInfo(orderInfo.CustomerAccount); // try to get the customer from transaction service if (customer == null || customer.IsEmptyCustomer()) { DE.ICustomer tempCustomer = SalesOrder.GetCustomerFromAX(orderInfo.CustomerAccount, customerSystem, customerDataManager); if (tempCustomer != null) { customer = tempCustomer; } } DE.ICustomer invoicedCustomer = customerSystem.GetCustomerInfo(customer.InvoiceAccount); // try to get the invoicedCustomer from transaction service if (invoicedCustomer == null || invoicedCustomer.IsEmptyCustomer()) { DE.ICustomer tempinvoicedCustomer = SalesOrder.GetCustomerFromAX(customer.InvoiceAccount, customerSystem, customerDataManager); if (tempinvoicedCustomer != null) { invoicedCustomer = tempinvoicedCustomer; } } // If InvoiceCustomer is *still* blank/empty then fallback to Customer so that the UI fields are populated. if (invoicedCustomer == null || invoicedCustomer.IsEmptyCustomer()) { invoicedCustomer = customer; } customerSystem.SetCustomer(transaction, customer, invoicedCustomer); if (transaction.DeliveryMode != null && !string.IsNullOrWhiteSpace(orderInfo.AddressRecordId)) { DE.IAddress shippingAddress = customerDataManager.GetAddress(Int64.Parse(orderInfo.AddressRecordId)); customerSystem.SetShippingAddress(transaction, shippingAddress); } if (!string.IsNullOrEmpty(orderInfo.SalespersonStaffId)) { // Sets the sales person id and name according to AX values // This is done because we do not know whether the sales person information is available on this store transaction.SalesPersonId = orderInfo.SalespersonStaffId; transaction.SalesPersonName = orderInfo.SalespersonName; DM.EmployeeDataManager employees = new DM.EmployeeDataManager( SalesOrder.InternalApplication.Settings.Database.Connection, SalesOrder.InternalApplication.Settings.Database.DataAreaID); Employee employee = employees.GetEmployee(ApplicationSettings.Terminal.StoreId, orderInfo.SalespersonStaffId); if (employee != null) { transaction.SalesPersonId = employee.StaffId; transaction.SalesPersonName = employee.Name; transaction.SalesPersonNameOnReceipt = employee.NameOnReceipt; } } transaction.ChannelReferenceId = orderInfo.ChannelReferenceId; if (transaction.LoyaltyItem != null && !string.IsNullOrEmpty(orderInfo.LoyaltyCardId)) { transaction.LoyaltyItem.LoyaltyCardNumber = orderInfo.LoyaltyCardId; } transaction.ReceiptEmailAddress = orderInfo.Email; transaction.TotalManualDiscountAmount = orderInfo.TotalManualDiscountAmount; transaction.TotalManualPctDiscount = orderInfo.TotalManualDiscountPercentage; DateTime earliestDeliveryDate = DateTime.MaxValue; // Items foreach (ItemInfo item in orderInfo.Items) { Collection <Tax.MiscellaneousCharge> lineCharges = new Collection <Tax.MiscellaneousCharge>(); foreach (ChargeInfo charge in item.Charges) { Tax.MiscellaneousCharge lineCharge = (Tax.MiscellaneousCharge)SalesOrder.InternalApplication.BusinessLogic.Utility.CreateMiscellaneousCharge( charge.Amount, charge.SalesTaxGroup, charge.TaxGroup, charge.Code, string.Empty, transaction); lineCharges.Add(lineCharge); } // add item SaleLineItem lineItem = (SaleLineItem)SalesOrder.InternalApplication.BusinessLogic.Utility.CreateSaleLineItem( ApplicationSettings.Terminal.StoreCurrency, SalesOrder.InternalApplication.Services.Rounding, transaction); lineItem.Found = true; lineItem.OrderLineRecordId = item.RecId; lineItem.ItemId = item.ItemId; lineItem.Quantity = item.Quantity; lineItem.ReturnQtyAllowed = item.Quantity; lineItem.SalesOrderUnitOfMeasure = item.Unit; lineItem.Price = item.Price; lineItem.NetAmount = item.NetAmount; lineItem.QuantityOrdered = item.Quantity; lineItem.QuantityPickedUp = item.QuantityPicked; lineItem.DeliveryMode = storeDataManager.GetDeliveryMode(item.DeliveryMode); lineItem.DeliveryDate = ParseDateString(item.RequestedDeliveryDateString, DateTime.Today); lineItem.DeliveryStoreNumber = item.StoreId; lineItem.DeliveryWarehouse = item.WarehouseId; lineItem.SerialId = item.SerialId; lineItem.BatchId = item.BatchId; lineItem.HasBeenRecalled = true; lineItem.SalesMarkup = item.SalesMarkup; lineItem.Comment = string.IsNullOrEmpty(item.Comment) ? string.Empty : item.Comment; lineItem.LineStatus = GetSalesStatus((SalesOrderStatus)item.Status); lineItem.LineDiscount = item.LineDscAmount; lineItem.PeriodicDiscount = item.PeriodicDiscount; lineItem.PeriodicPctDiscount = item.PeriodicPercentageDiscount; lineItem.LineManualDiscountAmount = item.LineManualDiscountAmount; lineItem.LineManualDiscountPercentage = item.LineManualDiscountPercentage; lineItem.TotalDiscount = item.TotalDiscount; lineItem.TotalPctDiscount = item.TotalPctDiscount; foreach (Tax.MiscellaneousCharge charge in lineCharges) { lineItem.MiscellaneousCharges.Add(charge); } if (lineItem.DeliveryMode != null && !string.IsNullOrWhiteSpace(item.AddressRecordId)) { lineItem.ShippingAddress = customerDataManager.GetAddress(Int64.Parse(item.AddressRecordId)); } lineItem.Dimension.VariantId = item.VariantId; lineItem.Dimension.ColorId = item.ColorId; lineItem.Dimension.StyleId = item.StyleId; lineItem.Dimension.SizeId = item.SizeId; lineItem.Dimension.ConfigId = item.ConfigId; lineItem.Dimension.ColorName = item.ColorName; lineItem.Dimension.StyleName = item.StyleName; lineItem.Dimension.SizeName = item.SizeName; lineItem.Dimension.ConfigName = item.ConfigName; if (!string.IsNullOrEmpty(lineItem.Dimension.VariantId)) { Dimensions dimension = (Dimensions)SalesOrder.InternalApplication.BusinessLogic.Utility.CreateDimension(); dimension.VariantId = lineItem.Dimension.VariantId; SalesOrder.InternalApplication.Services.Dimension.GetDimensionForVariant(dimension); lineItem.Dimension = dimension; } if (item.Discounts.Count > 0) { lineItem.QuantityDiscounted = item.Quantity; lineItem.LinePctDiscount = lineItem.CalculateLinePercentDiscount(); } // create discount line from discount info object foreach (DiscountInfo discountInfo in item.Discounts) { DiscountItem discountItem = ConvertToDiscountItem( discountInfo.DiscountOriginType, discountInfo.ManualDiscountType, discountInfo.CustomerDiscountType, discountInfo.EffectiveAmount, discountInfo.DealPrice, discountInfo.DiscountAmount, discountInfo.Percentage, discountInfo.PeriodicDiscountOfferId, discountInfo.OfferName, discountInfo.DiscountCode); SalesOrder.InternalApplication.Services.Discount.AddDiscountLine(lineItem, discountItem); } // Set other default properties for this item SalesOrder.InternalApplication.Services.Item.ProcessItem(lineItem, bypassSerialNumberEntry: true); // Set tax info after defaults, as it may have been overridden. lineItem.SalesTaxGroupId = item.SalesTaxGroup; lineItem.SalesTaxGroupIdOriginal = item.SalesTaxGroup; lineItem.TaxGroupId = item.ItemTaxGroup; lineItem.TaxGroupIdOriginal = item.ItemTaxGroup; // Add it to the transaction transaction.Add(lineItem); if (lineItem.DeliveryDate < earliestDeliveryDate) { earliestDeliveryDate = lineItem.DeliveryDate.HasValue ? lineItem.DeliveryDate.Value : earliestDeliveryDate; } } // Once Items are populated - Reset Customer Tax Group //GRW Linea comentada para poder recoger la orden de venta en una tienda distinta a la configurada en AX //customerSystem.ResetCustomerTaxGroup(transaction); // The order can be created through some other channel other than POS which has set header delivery date as NoDate. // This must not be interpreted as a valid date. Instead the earliestDeliveryDate is used. if (transaction.RequestedDeliveryDate == NoDate) { transaction.RequestedDeliveryDate = earliestDeliveryDate; } // Charges foreach (ChargeInfo charge in orderInfo.Charges) { // add charges Tax.MiscellaneousCharge newCharge = (Tax.MiscellaneousCharge)SalesOrder.InternalApplication.BusinessLogic.Utility.CreateMiscellaneousCharge( charge.Amount, charge.SalesTaxGroup, charge.TaxGroup, charge.Code, string.Empty, transaction); transaction.Add(newCharge); } SalesOrder.InternalApplication.BusinessLogic.ItemSystem.CalculatePriceTaxDiscount(transaction); transaction.CalculateAmountDue(); // Payments // - total up amounts // - add history entries transaction.PrepaymentAmountPaid = decimal.Zero; transaction.PrepaymentAmountInvoiced = decimal.Zero; decimal nonPrepayments = decimal.Zero; PaymentInfo pinfo = new PaymentInfo(); pinfo.Amount = -111; pinfo.Currency = "MXN"; orderInfo.Payments.Add(pinfo); foreach (PaymentInfo payment in orderInfo.Payments) { // sum up payments decimal amount = (string.IsNullOrWhiteSpace(payment.Currency)) ? payment.Amount : (SalesOrder.InternalApplication.Services.Currency.CurrencyToCurrency( payment.Currency, ApplicationSettings.Terminal.StoreCurrency, payment.Amount)); if (payment.Prepayment) { // Sum prepayments to track total deposits paid transaction.PrepaymentAmountPaid += amount; } else { // Sum non-prepayments as base for calculating deposits applied to pickups nonPrepayments += amount; } CustomerOrderPaymentHistory paymentHistory = (CustomerOrderPaymentHistory)SalesOrder.InternalApplication.BusinessLogic.Utility.CreateCustomerOrderPaymentHistory(); paymentHistory.Amount = payment.Amount; paymentHistory.Currency = payment.Currency; paymentHistory.Date = ParseDateString(payment.DateString, DateTime.MinValue); paymentHistory.Balance = transaction.NetAmountWithTaxAndCharges - transaction.PrepaymentAmountPaid; transaction.PaymentHistory.Add(paymentHistory); } // Prepayment/Deposit override info transaction.PrepaymentAmountOverridden = orderInfo.PrepaymentAmountOverridden; if (transaction.PrepaymentAmountOverridden) { transaction.PrepaymentAmountRequired = transaction.PrepaymentAmountPaid; } // Amount that has been previously invoiced (picked-up) transaction.PreviouslyInvoicedAmount = orderInfo.PreviouslyInvoicedAmount; // Portion of the prepayment that has been applied to invoices. // If .PrepaymentAmountApplied is non-NULL then use the explicit amount, otherwise fall back to computing the amount based on payment history. transaction.PrepaymentAmountInvoiced = orderInfo.PrepaymentAmountApplied ?? (transaction.PreviouslyInvoicedAmount - nonPrepayments); transaction.HasLoyaltyPayment = orderInfo.HasLoyaltyPayment; return(transaction); }
/// <summary> /// Save changes back to models /// </summary> public void CommitHeaderChanges() { SalesOrder.InternalApplication.BusinessLogic.CustomerSystem.SetShippingAddress(transaction, this.ShippingAddress); // Delivery date this.transaction.RequestedDeliveryDate = this.DeliveryDate.Value; // Shipping method this.transaction.DeliveryMode = storeDataManager.GetDeliveryMode(this.ShippingMethod.Code); // Shipping warehouse this.transaction.WarehouseId = LSRetailPosis.Settings.ApplicationSettings.Terminal.InventLocationIdForCustomerOrder; // Clear any line item delivery options foreach (var item in this.transaction.SaleItems) { ClearLineDeliveryOptions(item); item.ShippingAddress = this.transaction.ShippingAddress; item.DeliveryMode = this.transaction.DeliveryMode; if (this.transaction.RequestedDeliveryDate != default(DateTime)) { item.DeliveryDate = this.transaction.RequestedDeliveryDate; } SalesOrder.InternalApplication.BusinessLogic.CustomerSystem.ResetCustomerTaxGroup(item); } // // Shipping charge // // First check if a shipping charge code was configured on the back end and exists in the DB string shippingChargeCode = LSRetailPosis.Settings.ApplicationSettings.Terminal.ShippingChargeCode; if (this.ShippingCharge.HasValue && string.IsNullOrWhiteSpace(shippingChargeCode)) { // "A shipping charge cannot be added because a shipping charge code was not found." string errorMessage = LSRetailPosis.ApplicationLocalizer.Language.Translate(56302); SalesOrder.LogMessage(errorMessage, LSRetailPosis.LogTraceLevel.Error); throw new InvalidOperationException(errorMessage); } Tax.MiscellaneousCharge mc = this.Transaction.MiscellaneousCharges.SingleOrDefault(m => m.ChargeCode == LSRetailPosis.Settings.ApplicationSettings.Terminal.ShippingChargeCode); // See if there's an existing charge if (mc == null) { if (this.ShippingCharge.HasValue) { // No charge exists, so we add it // Get Cancellation charge properties from DB DM.StoreDataManager store = new DM.StoreDataManager( SalesOrder.InternalApplication.Settings.Database.Connection, SalesOrder.InternalApplication.Settings.Database.DataAreaID); DataEntity.MiscellaneousCharge chargeProperties = store.GetMiscellaneousCharge(LSRetailPosis.Settings.ApplicationSettings.Terminal.ShippingChargeCode); if (chargeProperties != null) { mc = new Tax.MiscellaneousCharge( this.ShippingCharge.Value, this.transaction.Customer.SalesTaxGroup, chargeProperties.TaxItemGroup, chargeProperties.MarkupCode, string.Empty, this.Transaction); // Set the proper SalesTaxGroup based on the store/customer settings SalesOrder.InternalApplication.BusinessLogic.CustomerSystem.ResetCustomerTaxGroup(mc); this.Transaction.MiscellaneousCharges.Add(mc); } else { // "A shipping charge cannot be added because no information was found for shipping charge code: {0}." string errorMessage = string.Format(LSRetailPosis.ApplicationLocalizer.Language.Translate(56304), shippingChargeCode); SalesOrder.LogMessage(errorMessage, LSRetailPosis.LogTraceLevel.Error); throw new InvalidOperationException(errorMessage); } } } else // Charge exists { if (this.ShippingCharge.HasValue) { if (mc.Amount != this.ShippingCharge.Value) { // Update amount mc.Amount = this.ShippingCharge.Value; } } else { // No charge, so remove this.Transaction.MiscellaneousCharges.Remove(mc); } } // Trigger new price,tax and discount for the customer // We should preserve any existing Price Overrides SalesOrder.InternalApplication.BusinessLogic.ItemSystem.RecalcPriceTaxDiscount(this.Transaction, false); this.Transaction.CalcTotals(); }