2015-08-13 42 views
0

TransationLibrary.CreateShipment錯誤從VolumeShippingMethodService一把umbraco uCommerce - 非空屬性引用NHibernate的

返回航運價值時,使用一把umbraco V7,uCommerce V6.6,DotNetShipping (plugin)。請參見VolumeMethodShippingService課程中的註釋,方法CalculateShippingPrice(在帖子底部)。

錯誤: http://docs.ucommerce.net/ucommerce/v6.7/extending-ucommerce/shipping-method-service.html

我使用聯邦快遞API:

not-null property references a null or transient value UCommerce.EntitiesV2.ShippingMethodPrice.PriceGroup 
Line 20:   { 
Line 21:    TransactionLibrary.CreateShipment(newShipmentId, overwriteExisting: true); 
Line 22:    TransactionLibrary.ExecuteBasketPipeline(); // <------ error is here *************************** 
Line 23:    HttpContext.Current.Response.Redirect("/cart/payment"); 
Line 24:   } 

[PropertyValueException: not-null property references a null or transient value UCommerce.EntitiesV2.ShippingMethodPrice.PriceGroup] 
    NHibernate.Engine.Nullability.CheckNullability(Object[] values, IEntityPersister persister, Boolean isUpdate) +592 
    NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +832 
    NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +295 
    NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) +58 
    NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) +130 
    NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) +470 
    NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) +398 
    NHibernate.Impl.SessionImpl.SaveOrUpdate(String entityName, Object obj) +396 
    NHibernate.Engine.Cascade.CascadeToOne(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) +254 
    NHibernate.Engine.Cascade.CascadeCollectionElements(Object parent, Object child, CollectionType collectionType, CascadeStyle style, IType elemType, Object anything, Boolean isCascadeDeleteEnabled) +639 
    NHibernate.Engine.Cascade.CascadeCollection(Object parent, Object child, CascadeStyle style, Object anything, CollectionType type) +338 
    NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything) +697 
    NHibernate.Event.Default.AbstractFlushingEventListener.CascadeOnFlush(IEventSource session, IEntityPersister persister, Object key, Object anything) +178 
    NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource session) +426 
    NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) +307 
    NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) +214 
    NHibernate.Impl.SessionImpl.Flush() +516 
    UCommerce.Pipelines.Common.SavePurchaseOrderTask.Execute(PurchaseOrder purchaseOrder) +20 
    UCommerce.Pipelines.Pipeline`1.Execute(T subject) +286 

這裏描述我已經成功地添加了 「VolumeShippingMethodService」。當用戶進入Shipment視圖時,它會抓取可用的運輸方法,並根據當前的購物籃中的訂單項來確定該貨物的價值(價格)。我看到uCommerce有另一種方法,CalculateShippingPrice,它可以獲得運輸方法的價格。我當然不需要這個,但uCommerce會自動調用它,所以我不得不重新調用我的FedEx API來獲取價格並將其返回。一旦我返回這個價格,我收到有關的錯誤。如果我保留帶有文檔(ucommerce)的默認代碼,則不會收到錯誤。

在下面的服務代碼中,正如我所說的,費率恢復得很好,沒有錯誤。當我再次發送到/ cart/shipment時,它會爲籃子創建Shipment對象,當我收到錯誤時。


查看:

@using UCommerce 
@using UCommerce.EntitiesV2 
@using UCommerce.Api 
@using ExtendedUCommerceServices.Services 
@{ 
    if (HttpContext.Current.Request.HttpMethod == "POST" && HttpContext.Current.Request.Form.AllKeys.Any(x => x == "update-shipment")) 
    { 
     int newShipmentId; 
     if (int.TryParse(HttpContext.Current.Request.Form["shipping-method"], out newShipmentId)) 
     { 
      TransactionLibrary.CreateShipment(newShipmentId, overwriteExisting: true); 
      TransactionLibrary.ExecuteBasketPipeline(); 
      HttpContext.Current.Response.Redirect("/cart/payment"); 
     } 
    } 

    var basket = TransactionLibrary.GetBasket().PurchaseOrder; 
    var currentShippingMethod = TransactionLibrary.GetShippingMethod(); 
    var shippingCountry = TransactionLibrary.GetShippingInformation().Country; 
    var availableShippingMethods = new VolumeShippingMethodService().GetShippingRates(TransactionLibrary.GetShippingMethods(shippingCountry).ToList(), basket); 
} 

VolumeShippingethodService

public class VolumeShippingMethodService : IShippingMethodService 
{ 
    // TODO: check if key and password are the same for production account 
    public string fedexKey = ConfigurationManager.AppSettings["FedExKey"]; 
    public string fedexPassword = ConfigurationManager.AppSettings["FedExPassword"]; 
    // TODO: get actual production account number and meter number 
    public string fedexAccountNumber = ConfigurationManager.AppSettings["FedExAccountNumber"]; 
    public string fedexMeterNumber = ConfigurationManager.AppSettings["FedExMeterNumber"]; 
    // TODO: remove "false" from FedExProvider when in production ********************8 
    public bool fedexUseProduction = ConfigurationManager.AppSettings["FedExUseProduction"].ToLower().Equals("false") ? false : true; 

    /// <summary> 
    /// Gets shipping rates for FedEx (waiting on UPS) ********************************************* 
    /// </summary> 
    /// <param name="availableShippingMethods">available shipping methods for the catalog</param> 
    /// <param name="basket">user's current basket</param> 
    /// <returns>shipping methods with prices (rates)</returns> 
    public List<ShippingMethod> GetShippingRates(List<ShippingMethod> availableShippingMethods, PurchaseOrder basket) 
    { 
     // create package with weight and size dimensions 
     // TODO: get this from uCommerce ******************************** 
     var packages = new List<Package>(); 
     packages.Add(new Package(12, 12, 12, 35, 150)); 
     packages.Add(new Package(4, 4, 6, 15, 250)); 

     // TODO: get actual address 
     var origin = new DotNetShipping.Address("1202 Chalet Ln", "Do Not Delete - Test Account", string.Empty, "Harrison", "AR", "72601", "US"); 
     var destinationAddress = basket.Shipments.First().ShipmentAddress; 
     var destination = new DotNetShipping.Address(
        destinationAddress.Line1, 
        destinationAddress.Line2, 
        string.Empty, // Line3 
        destinationAddress.City, 
        string.Empty, // State (not needed when postal code and country code are applied) 
        destinationAddress.PostalCode, 
        "US" /* country code 
          * NOTE: if additional countries are added later, then need to get 
          * a webservice to get country codes from actual country name */ 
      ); 

     var rateManager = new RateManager(); 
     rateManager.AddProvider(new FedExProvider(fedexKey, fedexPassword, fedexAccountNumber, fedexMeterNumber, fedexUseProduction)); 
     DotNetShipping.Shipment shipment = rateManager.GetRates(origin, destination, packages); 

     foreach (var shippingMethod in availableShippingMethods) 
     { 
      var rateToAdd = shipment.Rates.FirstOrDefault(x => x.Name.Equals(shippingMethod.Name)); 
      if (rateToAdd != null) 
      { 
       // apparently you can have more than one shipping price..... 
       if (shippingMethod.ShippingMethodPrices.Count == 0) 
       { 
        shippingMethod.AddShippingMethodPrice(new ShippingMethodPrice 
         { 
          Currency = basket.BillingCurrency, 
          Price = rateToAdd.TotalCharges 
         }); 
       } 
       else 
       { 
        shippingMethod.ShippingMethodPrices.First().Price = rateToAdd.TotalCharges; 
       } 
      } 
     } 

     return availableShippingMethods; 
    } 

    /// <summary> 
    /// uCommerce automatically calls this method (built in) when creating a shipment (TransactionLibrary.CreateShipment). 
    /// In order to correctly get price (again), recall the GetShippingRates method and find 
    /// the appropriate shipping method by name, then retrive price 
    /// </summary> 
    /// <param name="shipment">current uCommerce shipment</param> 
    /// <returns>shipping price for the shipping method</returns> 
    public Money CalculateShippingPrice(UCommerce.EntitiesV2.Shipment shipment) 
    { 
     var rates = this.GetShippingRates(TransactionLibrary.GetShippingMethods(TransactionLibrary.GetShippingInformation().Country).ToList(), TransactionLibrary.GetBasket(false).PurchaseOrder); 
     var shippingPrice = rates.FirstOrDefault(x => x.Name.Equals(shipment.ShipmentName)).ShippingMethodPrices.First().Price; 

     // ************************************** 
     // If I keep the above lines uncommented, I receive the error. 
     // The variable "shippingPrice" above returns a decimal, 36.25 
     // If I uncomment the lines below, there is no error. 
     // ************************************** 

     //decimal totalWeight = 0; 
     //foreach (OrderLine orderline in shipment.OrderLines) 
     // totalWeight += orderline.Quantity * Convert.ToDecimal(orderline["Weight"]); 
     //decimal shippingPrice = 0; 
     //if (totalWeight > 10) 
     // shippingPrice = 100; 
     //else if (totalWeight > 20) 
     // shippingPrice = 200; 
     //else 
     // shippingPrice = 300; 


     return new Money(shippingPrice, shipment.PurchaseOrder.BillingCurrency); 
    } 
} 
+0

有人嗎?在umbraco論壇上也沒有任何運氣 –

回答

0

需與PriceGroup添加到出貨對象

shippingMethod.AddShippingMethodPrice(new ShippingMethodPrice 
{ 
     Currency = basket.BillingCurrency, 
     Price = rateToAdd.TotalCharges, 
     PriceGroup = PriceGroup.FirstOrDefault(x => x.Name.Equals("US Dollar")) 
});