예제 #1
0
 /// <summary>
 /// Populates default fields on the first line item. Override to populate custom line item fields.
 /// </summary>
 protected virtual void PopulateMetaFields(
     ILineItem lineItem,
     IMarket market,
     SaleViewModel kachingSale,
     SaleLineItemViewModel kachingLineItem)
 {
 }
예제 #2
0
        protected virtual ILineItem CreateLineItem(
            IPurchaseOrder purchaseOrder,
            IShipment shipment,
            SaleViewModel kachingSale,
            SaleLineItemViewModel kachingLineItem)
        {
            ILineItem lineItem = _orderGroupFactory.CreateLineItem(
                kachingLineItem.VariantId.DesanitizeKey() ?? kachingLineItem.Id.DesanitizeKey(),
                purchaseOrder);

            decimal quantity = kachingLineItem.UnitCount ?? kachingLineItem.Quantity;

            lineItem.Quantity    = quantity;
            lineItem.PlacedPrice = kachingLineItem.RetailPrice / quantity;

            // Get the specific discount amount of this line item (discount that were applied directly to the line item).
            decimal lineItemDiscount =
                kachingLineItem.Discounts?
                .Where(d => !(d.Discount?.Application.Basket ?? false))
                .Sum(d => d.Amount) ?? 0;

            // Get the amount of the order level discount that this line item contributes
            // (the order level discount are spread out on all line items).
            decimal orderLevelDiscount =
                kachingLineItem.Discounts?
                .Where(d => d.Discount?.Application.Basket ?? false)
                .Sum(d => d.Amount) ?? 0;

            lineItem.SetEntryDiscountValue(lineItemDiscount);
            lineItem.SetOrderDiscountValue(orderLevelDiscount);

            return(lineItem);
        }
예제 #3
0
 /// <summary>
 /// Populates default fields on the first order form. Override to populate custom order form fields.
 /// </summary>
 protected virtual void PopulateMetaFields(
     IPurchaseOrder purchaseOrder,
     IOrderForm orderForm,
     IMarket market,
     SaleViewModel kachingSale)
 {
     orderForm.Name = purchaseOrder.Name;
 }
예제 #4
0
        /// <summary>
        /// Populates default fields on the purchase order. Override to populate custom purchase order fields.
        /// </summary>
        protected virtual void PopulateMetaFields(
            IPurchaseOrder purchaseOrder,
            IMarket market,
            SaleViewModel kachingSale)
        {
            purchaseOrder.Currency         = kachingSale.CurrencyCode;
            purchaseOrder.MarketId         = market.MarketId;
            purchaseOrder.MarketName       = market.MarketName;
            purchaseOrder.PricesIncludeTax = market.PricesIncludeTax;

            purchaseOrder.OrderNumber = _orderNumberGenerator.GenerateOrderNumber(kachingSale.SequenceNumber);
            // Default status is Completed. It will be changed when handling shipments, if there are pending line items.
            purchaseOrder.OrderStatus = OrderStatus.Completed;
            purchaseOrder.Properties["CustomerName"] = kachingSale.Summary.Customer?.Name;
        }
예제 #5
0
        protected virtual IPayment CreatePayment(
            IPurchaseOrder purchaseOrder,
            CustomerContact customerContact,
            SaleViewModel kachingSale,
            decimal amount)
        {
            IPayment payment = _orderGroupFactory.CreatePayment(purchaseOrder);

            payment.Amount          = amount;
            payment.CustomerName    = kachingSale.Summary.Customer?.Name;
            payment.Status          = PaymentStatus.Processed.ToString();
            payment.TransactionType = TransactionType.Sale.ToString();
            payment.PaymentType     = PaymentType.Other;

            return(payment);
        }
        public IHttpActionResult Post(IDictionary <string, SaleViewModel> sales)
        {
            SaleViewModel sale = sales?.Values.FirstOrDefault();

            if (sale == null)
            {
                Logger.Error("The request is missing one or more sales objects. Exiting.");

                return(BadRequest());
            }

            // Ignore returns and voided sales
            if (sale.Summary.IsReturn || sale.Voided)
            {
                return(StatusCode(HttpStatusCode.NoContent));
            }

            // Ignore sales without any non special line items
            var saleLines = sale.Summary.LineItems.Where(lineItem => lineItem.Behavior == null);

            if (!saleLines.Any())
            {
                return(StatusCode(HttpStatusCode.NoContent));
            }

            try
            {
                IPurchaseOrder purchaseOrder = _saleFactory.CreatePurchaseOrder(sale);
                _purchaseOrderProvider.Save(purchaseOrder);
            }
            catch (Exception ex)
            {
                Logger.Error("Error occurred while registering Ka-ching sale in Episerver.", ex);

                return(BadRequest());
            }

            return(StatusCode(HttpStatusCode.NoContent));
        }
예제 #7
0
        protected virtual IShipment CreateShipment(
            IPurchaseOrder purchaseOrder,
            IOrderForm orderForm,
            CustomerContact customerContact,
            SaleShippingViewModel kachingShipping,
            SaleViewModel kachingSale,
            SaleLineItemViewModel shippingLineItem)
        {
            IShipment shipment = _orderGroupFactory.CreateShipment(purchaseOrder);

            shipment.OrderShipmentStatus = kachingShipping != null
                ? OrderShipmentStatus.AwaitingInventory
                : OrderShipmentStatus.Shipped;

            if (kachingShipping != null)
            {
                // If this shipment is awaiting delivery, then the whole order is still in-progress.
                purchaseOrder.OrderStatus = OrderStatus.InProgress;
            }

            return(shipment);
        }
예제 #8
0
        /// <summary>
        /// Populates default fields on the first shipment. Override to populate custom shipment fields.
        /// </summary>
        protected virtual void PopulateMetaFields(
            IShipment shipment,
            IMarket market,
            SaleShippingViewModel kachingShipping,
            SaleViewModel kachingSale)
        {
            // By default, use the shipping address supplied by Ka-ching.
            // Override this method if you need to use the customer's registered address.
            if (kachingShipping?.Address != null)
            {
                shipment.ShippingAddress = ConvertToAddress(shipment.ParentOrderGroup, kachingShipping);
            }
            else if (kachingSale.Summary?.Customer != null)
            {
                shipment.ShippingAddress = ConvertToAddress(shipment.ParentOrderGroup, kachingSale.Summary.Customer);
            }

            if (kachingShipping?.MethodId != null &&
                Guid.TryParse(kachingShipping.MethodId, out Guid shippingMethodId))
            {
                shipment.ShippingMethodId = shippingMethodId;
            }
        }
예제 #9
0
 /// <summary>
 /// Sets the CreatorId and ModifierId properties to the initials of the seller for good records.
 /// Also sets the Created and Modified date properties to the exact date and time of the sale,
 /// regardless of the time it was received in Episerver.
 /// </summary>
 protected void SetCashier(
     IExtendedProperties entity,
     SaleViewModel sale)
 {
     SetCashier(entity, sale.Timing.Timestamp, sale.Source.CashierName);
 }
예제 #10
0
        public virtual IPurchaseOrder CreatePurchaseOrder(
            SaleViewModel kachingSale)
        {
            IMarket market = _marketService.GetMarket(kachingSale.Source.MarketId);

            if (market == null || !market.IsEnabled)
            {
                throw new InvalidOperationException(
                          $"The MarketId ('{kachingSale.Source.MarketId}') is not recognized in Episerver Commerce.");
            }

            CustomerContact customerContact = null;

            if (kachingSale.Summary.Customer?.Identifier != null)
            {
                customerContact = CustomerContext.Current.GetContactById(
                    Guid.Parse(kachingSale.Summary.Customer.Identifier));
                if (customerContact?.PrimaryKeyId == null)
                {
                    throw new InvalidOperationException(
                              $"The customer ('{kachingSale.Summary.Customer.Identifier}') is not recognized in Episerver Commerce.");
                }
            }

            IPurchaseOrder purchaseOrder = _purchaseOrderProvider.Create(
                customerContact?.PrimaryKeyId.Value ?? Guid.Empty,
                "Default");

            if (purchaseOrder == null)
            {
                throw new InvalidOperationException(
                          "The purchase order could not be initialized.");
            }

            PopulateMetaFields(purchaseOrder, market, kachingSale);
            SetCashier(purchaseOrder, kachingSale);

            IOrderForm orderForm = purchaseOrder.GetFirstForm();

            PopulateMetaFields(purchaseOrder, orderForm, market, kachingSale);
            SetCashier(orderForm, kachingSale);

            orderForm.Shipments.Clear();

            decimal orderTotal = 0;

            foreach (var groupedLineItems in kachingSale.Summary
                     .LineItems
                     .GroupBy(li => li.EcomId))
            {
                var shippingLineItem = groupedLineItems.FirstOrDefault(li => li.Behavior?.Shipping != null);
                var kachingShipping  = shippingLineItem?.Behavior?.Shipping;

                decimal shipmentTotal    = 0;
                decimal shippingFeeTotal = shippingLineItem?.Total ?? 0;

                IShipment shipment = CreateShipment(
                    purchaseOrder,
                    orderForm,
                    customerContact,
                    kachingShipping,
                    kachingSale,
                    shippingLineItem);
                orderForm.Shipments.Add(shipment);

                PopulateMetaFields(shipment, market, kachingShipping, kachingSale);
                SetCashier(shipment, kachingSale);

                foreach (var kachingLineItem in groupedLineItems)
                {
                    // Skip special behavior line items. These are:
                    // shipping - handled above
                    // giftcard or voucher purchase
                    // giftcard or voucher use (can be a line item if they are taxed at point of sale)
                    // expenses
                    // customer account deposit
                    // container deposit
                    //
                    // We could consider including container deposit behavior
                    // but for now we just skip that along with the rest.
                    if (kachingLineItem.Behavior != null)
                    {
                        continue;
                    }

                    ILineItem lineItem = CreateLineItem(purchaseOrder, shipment, kachingSale, kachingLineItem);
                    shipment.LineItems.Add(lineItem);

                    PopulateMetaFields(lineItem, market, kachingSale, kachingLineItem);
                    SetCashier(lineItem, kachingSale);

                    shipmentTotal += kachingLineItem.Total;
                }

                // Populate all shipment amount fields, even those that need casting to reach.
                if (shipment is IShipmentCalculatedAmount calculatedAmount)
                {
                    calculatedAmount.IsShippingCostUpToDate = true;
                    calculatedAmount.IsShippingTaxUpToDate  = true;
                    calculatedAmount.ShippingCost           = shippingLineItem?.Total ?? 0;
                    calculatedAmount.ShippingTax            = shippingLineItem?.TotalTax ?? 0;
                }

                if (shipment is Shipment shipment1)
                {
                    shipment1.ShippingSubTotal = shippingLineItem?.Total ?? 0;
                    shipment1.SubTotal         = shipmentTotal;
                }

                shipmentTotal += shippingFeeTotal;
                orderTotal    += shipmentTotal;
            }

            IPayment payment = CreatePayment(purchaseOrder, customerContact, kachingSale, orderTotal);

            PopulateMetaFields(payment, market, kachingSale);
            SetCashier(payment, kachingSale);

            orderForm.Payments.Add(payment);

            return(purchaseOrder);
        }
예제 #11
0
 /// <summary>
 /// Populates default fields on the payment. Override to populate custom payment fields.
 /// </summary>
 protected virtual void PopulateMetaFields(
     IPayment payment,
     IMarket market,
     SaleViewModel kachingSale)
 {
 }