/// <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) { }
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); }
/// <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; }
/// <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; }
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)); }
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); }
/// <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; } }
/// <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); }
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); }
/// <summary> /// Populates default fields on the payment. Override to populate custom payment fields. /// </summary> protected virtual void PopulateMetaFields( IPayment payment, IMarket market, SaleViewModel kachingSale) { }