示例#1
0
        public OrderDetailsViewModel(
            CustomerOrderTransaction customerOrderTransaction,
            OrderDetailsSelection selectedMode)
        {
            this.SetTransaction(customerOrderTransaction);

            this.mode = selectedMode;

            DM.StoreDataManager storeDataManager = new DM.StoreDataManager(
                SalesOrder.InternalApplication.Settings.Database.Connection,
                SalesOrder.InternalApplication.Settings.Database.DataAreaID);

            DM.EmployeeDataManager employeeDataManager = new DM.EmployeeDataManager(
                SalesOrder.InternalApplication.Settings.Database.Connection,
                SalesOrder.InternalApplication.Settings.Database.DataAreaID);

            // Collection of all employees
            employees = new ReadOnlyCollection <DataEntity.Employee>(employeeDataManager.GetEmployees(ApplicationSettings.Terminal.StoreId));

            // Set the default minimum expiration date to tomorrow (but do not overwrite the current expiration date already set on the transaction)
            this.MinimumOrderExpirationDate = DateTime.Today.AddDays(1);

            // Use the actual, recalled, expiration date if it is older.
            // This is needed to prevent the UI from forcing the older date to snap to the minimum.
            if (this.MinimumOrderExpirationDate > this.OrderExpirationDate)
            {
                this.MinimumOrderExpirationDate = this.OrderExpirationDate;
            }

            // Set the default sales person to the currently logged in operator
            if (string.IsNullOrWhiteSpace(this.SalesPersonId))
            {
                this.SalesPersonId = LSRetailPosis.Settings.ApplicationSettings.Terminal.TerminalOperator.OperatorId;
            }
        }
示例#2
0
        public PickupInformationViewModel(CustomerOrderTransaction custTransaction)
        {
            this.transaction = custTransaction;

            // Get list of addresses
            storeDataManager = new DM.StoreDataManager(
                SalesOrder.InternalApplication.Settings.Database.Connection,
                SalesOrder.InternalApplication.Settings.Database.DataAreaID);

            customerDataManager = new DM.CustomerDataManager(
                SalesOrder.InternalApplication.Settings.Database.Connection,
                SalesOrder.InternalApplication.Settings.Database.DataAreaID);

            // Create a read-only collection
            stores = new ReadOnlyCollection <DataEntity.Store>(storeDataManager.GetStoresForPickup(SalesOrder.InternalApplication.Settings.Database.DataAreaID));

            // Load date
            if (custTransaction.RequestedDeliveryDate > DateTime.MinValue)
            {
                this.pickUpDate = custTransaction.RequestedDeliveryDate;
            }

            // Load store
            if (!string.IsNullOrWhiteSpace(custTransaction.WarehouseId))
            {
                this.selectedStore = storeDataManager.GetWarehouseStore(custTransaction.WarehouseId);
            }
            else
            {
                this.selectedStore = storeDataManager.GetStore(LSRetailPosis.Settings.ApplicationSettings.Terminal.StoreId);
            }
        }
示例#3
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="custTransaction">Transaction for this view model</param>
        /// <param name="saleLineItem">Sale line item for this view model if applicable</param>
        /// <remarks>If saleLineItem is not null then view model wraps line not transaction</remarks>
        public ShippingInformationViewModel(CustomerOrderTransaction custTransaction, SaleLineItem saleLineItem)
        {
            this.transaction     = custTransaction;
            this.lineItem        = saleLineItem;
            this.ShippingAddress = (saleLineItem == null) ? custTransaction.ShippingAddress : saleLineItem.ShippingAddress;

            // Load delivery date and set DeliveryDate property so validation is checked
            if (saleLineItem == null)
            {
                if (custTransaction.RequestedDeliveryDate > DateTime.MinValue)
                {
                    this.DeliveryDate = custTransaction.RequestedDeliveryDate;
                }
            }
            else
            {
                if (saleLineItem.DeliveryDate.HasValue && saleLineItem.DeliveryDate.Value > DateTime.MinValue)
                {
                    this.DeliveryDate = saleLineItem.DeliveryDate.Value;
                }
            }

            // Load delivery charge
            string shippingChargeCode = LSRetailPosis.Settings.ApplicationSettings.Terminal.ShippingChargeCode;

            Tax.MiscellaneousCharge mc = (saleLineItem == null)
                ? custTransaction.MiscellaneousCharges.SingleOrDefault(m => m.ChargeCode == shippingChargeCode)
                : lineItem.MiscellaneousCharges.SingleOrDefault(m => m.ChargeCode == shippingChargeCode);

            if (mc != null)
            {
                this.shippingCharge = mc.Price;
            }

            // Get list of addresses
            storeDataManager = new DM.StoreDataManager(
                SalesOrder.InternalApplication.Settings.Database.Connection,
                SalesOrder.InternalApplication.Settings.Database.DataAreaID);

            // Create a read-only collection
            GetValidDeliveryModes();
            //deliveryModes = new ReadOnlyCollection<DeliveryModeExploded>(storeDataManager.GetDeliveryModes());

            // Load delivery method and set ShippingMethod property so validation is checked
            //this.ShippingMethod = (DeliveryMode)((saleLineItem == null) ? custTransaction.DeliveryMode : saleLineItem.DeliveryMode);
            this.ShippingMethod = new DeliveryModeExploded((DeliveryMode)((saleLineItem == null) ? custTransaction.DeliveryMode : saleLineItem.DeliveryMode));
        }
        public void ExecuteSelectCurrency()
        {
            DM.StoreDataManager dm = new DM.StoreDataManager(
                CS.InternalApplication.Settings.Database.Connection,
                CS.InternalApplication.Settings.Database.DataAreaID);

            var list = dm.GetCurrencies();

            if (list.Count > 0)
            {
                string code;
                var    dialogResult = CS.InternalApplication.Services.Dialog.GenericLookup(
                    (System.Collections.IList)list, "Code", CaptionCurrency, "Code", out code, this.Currency);
                if (dialogResult == DialogResult.OK && code != null)
                {
                    this.Currency = code;
                }
            }
        }
示例#5
0
        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);
        }
示例#6
0
        /// <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();
        }