Exemplo n.º 1
0
            /// <summary>
            /// Populates the adapter configuration for each delivery mode identifier key in the passed in dictionary.
            /// </summary>
            /// <param name="context">The request context.</param>
            /// <param name="deliveryModeIdMapper">The delivery mode identifier mapper.</param>
            private static void PopulateAdapterConfig(RequestContext context, Dictionary <string, TrackingConfig> deliveryModeIdMapper)
            {
                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                if (deliveryModeIdMapper == null)
                {
                    throw new ArgumentNullException("deliveryModeIdMapper");
                }

                List <string> nonDuplicateDeliveryIds = new List <string>(deliveryModeIdMapper.Keys);

                // Fetch adapter configuration table for all the delivery mode ids.
                var dataServiceRequest  = new GetShippingAdapterConfigurationDataRequest(nonDuplicateDeliveryIds, QueryResultSettings.AllRecords);
                var dataServiceResponse = context.Execute <EntityDataServiceResponse <ShippingAdapterConfig> >(dataServiceRequest);

                var shippingAdapterConfigTable = dataServiceResponse.PagedEntityCollection.Results;

                // Consolidate adapter config entries by having separate property bags per deliveryModeId.
                foreach (var adapterConfigLine in shippingAdapterConfigTable)
                {
                    var    trackingConfig = deliveryModeIdMapper[adapterConfigLine.DeliveryModeId];
                    string keyName        = adapterConfigLine.KeyName;
                    string keyValue       = adapterConfigLine.KeyValue;

                    trackingConfig.AdapterConfig[keyName] = keyValue;
                }
            }
Exemplo n.º 2
0
            /// <summary>
            /// Validates the address.
            /// </summary>
            /// <param name="shippingRequest">The shipping request.</param>
            /// <returns>The response.</returns>
            /// <remarks>Throws an exception if the address field in the request is null.</remarks>
            private static ValidateShippingAddressServiceResponse ValidateShippingAddress(ValidateShippingAddressServiceRequest shippingRequest)
            {
                if (shippingRequest.AddressToValidate == null)
                {
                    throw new ArgumentNullException("shippingRequest", "shippingRequest.AddressToValidate");
                }

                if (shippingRequest.DeliveryModeId == null)
                {
                    throw new ArgumentNullException("shippingRequest", "shippingRequest.DeliveryModeId");
                }

                var dataServiceRequest  = new GetShippingAdapterConfigurationDataRequest(new[] { shippingRequest.DeliveryModeId }, QueryResultSettings.AllRecords);
                var dataServiceResponse = shippingRequest.RequestContext.Execute <EntityDataServiceResponse <ShippingAdapterConfig> >(dataServiceRequest);

                var shippingAdapterConfigLines = dataServiceResponse.PagedEntityCollection.Results;

                ParameterSet adapterConfig = ExtractAdapterConfigForSpecificDeliveryMode(shippingRequest.DeliveryModeId, shippingAdapterConfigLines);

                var             carrierServiceRequest = new ValidateShippingAddressCarrierServiceRequest(adapterConfig, shippingRequest.AddressToValidate, shippingRequest.SuggestAddress);
                IRequestHandler carrierAdapterHandler = GetCarrierAdapterService(shippingRequest.RequestContext, carrierServiceRequest.GetType(), adapterConfig);

                bool isAddressValid = true;
                IEnumerable <Address> addressSuggestions = null;

                if (carrierAdapterHandler != null)
                {
                    // Call the adapter's validation method
                    var carrierServiceResponse = shippingRequest.RequestContext.Runtime.Execute <ValidateShippingAddressCarrierServiceResponse>(carrierServiceRequest, shippingRequest.RequestContext, carrierAdapterHandler);
                    isAddressValid     = carrierServiceResponse.IsAddressValid;
                    addressSuggestions = carrierServiceResponse.RecommendedAddresses;
                }
                else
                {
                    NetTracer.Warning("No registered shipping carrier is found.");
                }

                return(new ValidateShippingAddressServiceResponse(isAddressValid, addressSuggestions));
            }
Exemplo n.º 3
0
            /// <summary>
            /// Gets the shipping adapter configuration.
            /// </summary>
            /// <param name="request">The request.</param>
            /// <returns>The response with the shipping adapter configuration.</returns>
            private EntityDataServiceResponse <ShippingAdapterConfig> GetShippingAdapterConfiguration(GetShippingAdapterConfigurationDataRequest request)
            {
                var shippingDataManager  = this.GetDataManagerInstance(request.RequestContext);
                var adapterConfiguration = shippingDataManager.GetShippingAdapterConfiguration(request.DeliveryModeIds, request.QueryResultSettings.ColumnSet);

                return(new EntityDataServiceResponse <ShippingAdapterConfig>(adapterConfiguration));
            }
Exemplo n.º 4
0
            /// <summary>
            /// Gets the shipping rate from the external carriers.
            /// </summary>
            /// <param name="request">Contains the sales line item details for which the shipping rate needs to be computed.</param>
            /// <returns>The response containing the shipping response.</returns>
            /// <remarks>
            /// No exception is thrown if the delivery mode identifier is empty for a sales line.
            /// </remarks>
            private static GetExternalShippingRateServiceResponse GetExternalShippingRate(GetExternalShippingRateServiceRequest request)
            {
                // Check each salesLine for:
                //  1) an item id (used for getting dimensions,
                //  2) delivery mode id (used for determining shipping adapter to use)
                //  3) InventoryLocationId (used to determine ShippFromAddress)
                //  4) ShippingAddress(use to determine ShipToAddress)
                // Create a list of item ids for contacting database for item dimensions
                List <string> itemIds = new List <string>();

                // Create a list of warehouse ids for contacting database for warehouse addresses
                List <string> warehouseIds = new List <string>();

                // Create a list of delivery mode ids for contacting database for adapter configurations
                List <string> deliverModeIds = new List <string>();

                // Divide sales lines into groups that have the same delivery mode id and origin and destination shipping addresses.
                Dictionary <int, List <SalesLine> > groupedSalesLines = new Dictionary <int, List <SalesLine> >();

                bool isValidSalesLine;
                Collection <string> linesWithoutDeliveryModeId      = new Collection <string>();
                Collection <string> linesWithoutShippingAddress     = new Collection <string>();
                Collection <string> linesWithoutInventoryLocationId = new Collection <string>();

                foreach (var salesLine in request.SalesLines)
                {
                    // Assume that a sales line is valid until found otherwise.
                    isValidSalesLine = true;

                    if (salesLine == null)
                    {
                        throw new ArgumentNullException("request", "salesLine is not set in sales lines");
                    }

                    if (string.IsNullOrWhiteSpace(salesLine.ItemId))
                    {
                        throw new ArgumentNullException("request", "salesLine.ItemId");
                    }

                    if (string.IsNullOrWhiteSpace(salesLine.InventoryLocationId))
                    {
                        linesWithoutInventoryLocationId.Add(salesLine.LineId);
                        isValidSalesLine = false;
                    }

                    if (string.IsNullOrWhiteSpace(salesLine.DeliveryMode))
                    {
                        linesWithoutDeliveryModeId.Add(salesLine.LineId);
                        isValidSalesLine = false;
                    }

                    if (salesLine.ShippingAddress == null)
                    {
                        linesWithoutShippingAddress.Add(salesLine.LineId);
                        isValidSalesLine = false;
                    }

                    if (isValidSalesLine)
                    {
                        itemIds.Add(salesLine.ItemId);
                        warehouseIds.Add(salesLine.InventoryLocationId);
                        deliverModeIds.Add(salesLine.DeliveryMode);

                        // Group all sales line with the same delivery mode, warehouse id and destination shipping address together
                        int key = (salesLine.DeliveryMode + salesLine.InventoryLocationId + salesLine.ShippingAddress.GetHashCode()).GetHashCode();
                        if (!groupedSalesLines.ContainsKey(key))
                        {
                            groupedSalesLines.Add(key, new List <SalesLine>());
                        }

                        groupedSalesLines[key].Add(salesLine);
                    }
                }

                RaiseNotificationForInvalidLines(request.RequestContext, linesWithoutDeliveryModeId, linesWithoutInventoryLocationId, linesWithoutShippingAddress);

                var getWarehouseDataRequest  = new GetWarehouseDetailsDataRequest(warehouseIds, QueryResultSettings.AllRecords);
                var getWarehouseDataResponse = request.RequestContext.Execute <EntityDataServiceResponse <WarehouseDetails> >(getWarehouseDataRequest);

                var warehouseDetailsRecords = getWarehouseDataResponse.PagedEntityCollection.Results;

                Dictionary <string, Address> warehouseAddresses = warehouseDetailsRecords.ToDictionary(key => key.InventoryLocationId.ToUpperInvariant(), value => (Address)value);

                // Validate that a warehouse address was retrieved for each inventory location id.
                foreach (var warehouseId in warehouseIds)
                {
                    if (!warehouseAddresses.ContainsKey(warehouseId.ToUpperInvariant()))
                    {
                        throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_InvalidShippingAddress, string.Format(CultureInfo.InvariantCulture, "Address for inventory location id {0} could not be found", warehouseId));
                    }
                }

                var getItemDimensionsDataRequest  = new GetItemDimensionsDataRequest(itemIds, QueryResultSettings.AllRecords);
                var getItemDimensionsDataResponse = request.RequestContext.Execute <EntityDataServiceResponse <ItemDimensions> >(getItemDimensionsDataRequest);

                var itemDimensionsRecords = getItemDimensionsDataResponse.PagedEntityCollection.Results;
                Dictionary <string, decimal> itemGrossWeights = itemDimensionsRecords.ToDictionary(key => key.ItemId.ToUpperInvariant(), value => value.GrossWeight);

                // Validate that a weight value was retrieved for each item id.
                foreach (var itemId in itemIds)
                {
                    if (!itemGrossWeights.ContainsKey(itemId.ToUpperInvariant()))
                    {
                        throw new DataValidationException(DataValidationErrors.Microsoft_Dynamics_Commerce_Runtime_GrossWeightForItemNotFound, string.Format(CultureInfo.InvariantCulture, "Gross Weight for item id {0} could not be found", itemId));
                    }
                }

                var shippingAdapterConfigDataRequest  = new GetShippingAdapterConfigurationDataRequest(deliverModeIds, QueryResultSettings.AllRecords);
                var shippingAdapterConfigDataResponse = request.RequestContext.Execute <EntityDataServiceResponse <ShippingAdapterConfig> >(shippingAdapterConfigDataRequest);

                var shippingAdapterConfigRecords = shippingAdapterConfigDataResponse.PagedEntityCollection.Results;

                var salesLineShippingRates = CalculateShippingRates(
                    groupedSalesLines, warehouseAddresses, itemGrossWeights, shippingAdapterConfigRecords, request.RequestContext);

                return(new GetExternalShippingRateServiceResponse(salesLineShippingRates.AsPagedResult()));
            }