Exemple #1
0
        /// <summary>
        /// Called by the workflow runtime to execute an activity.
        /// </summary>
        /// <param name="executionContext">The <see cref="T:Mediachase.Commerce.WorkflowCompatibility.ActivityExecutionContext"/> to associate with this <see cref="T:Mediachase.Commerce.WorkflowCompatibility.Activity"/> and execution.</param>
        /// <returns>
        /// The <see cref="T:Mediachase.Commerce.WorkflowCompatibility.ActivityExecutionStatus"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state.
        /// </returns>
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            // Check for multiple warehouses. In the default, we simply reject processing an order if the application has
            //  multiple warehouses. Any corresponding fulfillment process is the responsibility of the client.
            CheckMultiWarehouse();

            // Validate the properties at runtime
            ValidateRuntime();

            var orderForms = OrderGroup.OrderForms.Where(o => !OrderForm.IsReturnOrderForm(o));

            foreach (OrderForm orderForm in orderForms)
            {
                foreach (Shipment shipment in orderForm.Shipments)
                {
                    foreach (var lineItem in Shipment.GetShipmentLineItems(shipment))
                    {
                        AdjustStockItemQuantity(shipment, lineItem);
                    }
                }
            }

            // Retun the closed status indicating that this activity is complete.
            return(ActivityExecutionStatus.Closed);
        }
Exemple #2
0
        /// <summary>
        /// Gets the taxes for order form
        /// </summary>
        /// <param name="form">The order form.</param>
        /// <param name="marketId">The order market Id.</param>
        /// <param name="currency">The order currency.</param>
        /// <returns>The total taxes for the order form.</returns>
        public static void CalculateTaxes(OrderForm form, MarketId marketId, Currency currency)
        {
            var market     = _marketService.Service.GetMarket(marketId);
            var totalTaxes = 0m;

            foreach (Shipment shipment in form.Shipments)
            {
                var shippingTax  = 0m;
                var shippingCost = shipment.ShippingSubTotal - shipment.ShippingDiscountAmount;
                var lineItems    = Shipment.GetShipmentLineItems(shipment);
                // Calculate sales and shipping taxes per items
                foreach (LineItem lineItem in lineItems)
                {
                    var taxes = GetTaxValues(market, shipment, lineItem);
                    if (!taxes.Any())
                    {
                        continue;
                    }

                    // calculate quantity of item in current shipment
                    var quantity = OrderForm.IsReturnOrderForm(form) ? lineItem.ReturnQuantity : Shipment.GetLineItemQuantity(shipment, lineItem.LineItemId);
                    // price exclude tax for 1 line item
                    var lineItemPricesExcTax           = GetPriceExcludingTax(lineItem, quantity);
                    var totalShipmentLineItemsQuantity = lineItems.Sum(l => Shipment.GetLineItemQuantity(shipment, lineItem.LineItemId));
                    var itemShippingCost = shipment.SubTotal == 0 ? quantity / totalShipmentLineItemsQuantity * shippingCost : lineItemPricesExcTax / shipment.SubTotal * shippingCost;

                    shippingTax += GetTaxesAmount(taxes, TaxType.ShippingTax, itemShippingCost);
                    totalTaxes  += GetTaxesAmount(taxes, TaxType.SalesTax, lineItemPricesExcTax);
                }

                shipment.ShippingTax = currency.Round(shippingTax);
                totalTaxes          += shipment.ShippingTax;
            }

            form.TaxTotal = currency.Round(totalTaxes);
        }
        /// <summary>
        /// Called by the workflow runtime to execute an activity.
        /// </summary>
        /// <param name="executionContext">The <see cref="T:Mediachase.Commerce.WorkflowCompatibility.ActivityExecutionContext"/> to associate with this <see cref="T:Mediachase.Commerce.WorkflowCompatibility.Activity"/> and execution.</param>
        /// <returns>
        /// The <see cref="T:Mediachase.Commerce.WorkflowCompatibility.ActivityExecutionStatus"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state.
        /// </returns>
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            // Check for multiple warehouses. In the default, we simply reject processing an order if the application has
            //  multiple warehouses. Any corresponding fulfillment process is the responsibility of the client.
            CheckMultiWarehouse();

            // Validate the properties at runtime
            ValidateRuntime();

            // Return close status if order group is Payment Plan
            if (OrderGroup is PaymentPlan)
            {
                return(ActivityExecutionStatus.Closed);
            }

            var orderGroupStatus  = OrderStatusManager.GetOrderGroupStatus(OrderGroup);
            var orderForms        = OrderGroup.OrderForms.Where(o => !OrderForm.IsReturnOrderForm(o));
            var inventoryRequests = new List <InventoryRequestItem>();

            foreach (OrderForm orderForm in orderForms)
            {
                foreach (Shipment shipment in orderForm.Shipments)
                {
                    if (!ValidateShipment(orderForm, shipment))
                    {
                        continue;
                    }

                    var  shipmentStatus  = OrderStatusManager.GetOrderShipmentStatus(shipment);
                    bool completingOrder = orderGroupStatus == OrderStatus.Completed || shipmentStatus == OrderShipmentStatus.Shipped;
                    bool cancellingOrder = orderGroupStatus == OrderStatus.Cancelled || shipmentStatus == OrderShipmentStatus.Cancelled;
                    _logger.Debug(string.Format("Adjusting inventory, got orderGroupStatus as {0} and shipmentStatus as {1}. completingOrder as {2} and cancellingOrder as {3}.", orderGroupStatus, shipmentStatus, completingOrder, cancellingOrder));

                    // When completing/cancelling an order or a shipment
                    if (completingOrder || cancellingOrder)
                    {
                        var requestType = completingOrder ? InventoryRequestType.Complete : InventoryRequestType.Cancel;
                        inventoryRequests.AddRange(GetRequestInventory(shipment, inventoryRequests.Count, requestType));
                        // When processed request, need to clear all operation keys from the shipment
                        shipment.ClearOperationKeys();
                    }
                    // When release a shipment, check if shipment contain a BackOrder then need to complete that BackOrder.
                    else if (shipmentStatus == OrderShipmentStatus.Released)
                    {
                        foreach (LineItem lineItem in Shipment.GetShipmentLineItems(shipment))
                        {
                            var lineItemIndex            = orderForm.LineItems.IndexOf(lineItem);
                            var completeBackOrderRequest = new List <InventoryRequestItem>();
                            var lineItemRequest          = GetLineItemRequestInventory(shipment, lineItemIndex, 0, InventoryRequestType.Complete);

                            // Only need to process complete BackOrder request type
                            foreach (var request in lineItemRequest)
                            {
                                InventoryRequestType requestType;
                                InventoryChange      change;
                                _operationKeySerializer.Service.TryDeserialize(request.OperationKey, out requestType, out change);
                                if (requestType == InventoryRequestType.Backorder)
                                {
                                    // Add BackOrder request to request list
                                    completeBackOrderRequest.Add(request);

                                    // Then remove BackOrder request operation key from shipment's operation key map
                                    shipment.RemoveOperationKey(lineItemIndex, request.OperationKey);
                                }
                            }

                            // Storage the response operation keys from complete BackOrder mapping with line item index
                            if (completeBackOrderRequest.Count > 0)
                            {
                                InventoryResponse response = _inventoryService.Service.Request(new InventoryRequest(DateTime.UtcNow, completeBackOrderRequest, null));
                                if (response != null && response.IsSuccess)
                                {
                                    shipment.InsertOperationKeys(lineItemIndex, response.Items.Select(c => c.OperationKey));
                                }
                            }
                        }
                    }
                    else if (orderGroupStatus == OrderStatus.InProgress || orderGroupStatus == OrderStatus.AwaitingExchange)
                    {
                        // When placing an order or creating an exchange order
                        bool placingOrder = shipmentStatus == OrderShipmentStatus.AwaitingInventory || shipmentStatus == OrderShipmentStatus.InventoryAssigned;
                        if (placingOrder)
                        {
                            var lineItems = Shipment.GetShipmentLineItems(shipment);

                            CancelOperationKeys(shipment);
                            foreach (LineItem lineItem in lineItems)
                            {
                                RequestInventory(orderForm, shipment, lineItem);
                            }
                        }
                    }
                }
            }

            if (inventoryRequests.Any())
            {
                _inventoryService.Service.Request(new InventoryRequest(DateTime.UtcNow, inventoryRequests, null));
            }

            // Retun the closed status indicating that this activity is complete.
            return(ActivityExecutionStatus.Closed);
        }