Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Nathan Sleigh 109 posts 353 karma points
    Jan 07, 2016 @ 10:35
    Nathan Sleigh
    0

    Shipping Address and Shipments when creating Invoice/Order

    Hi Guys,

    I am having a little bit of trouble when creating an Invoice/Order. I can set a billing address using invoice.SetBillingAddress(billingAddress). But I don't see a way of setting the shipping one. Has anyone got any sample code for me to look at?

    Also how do I set it so I can change the status of the order from unfulfilled to fulfilled? I Assume this is something to do with the shipments tab, but I can't see anywhere to set this as well.

    Many Thanks,

    Nathan

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jan 07, 2016 @ 17:15
    Rusty Swayne
    0

    Hey Nathan,

    You should not have to create an order - that is pretty much done internally.

    Typically the process would go:

    Basket -> SalesPreparation -> Authorize/AuthorizeCapture payment.

    Authorize/AuthorizeCapture payment will actually save the invoice and set a flag to approve the order creation. Once the payment has been captured the order will be created and allow the order to be fulfilled. This is so warehouse staff don't have to be notified of an order to be fulfilled until the payment has been received.

    If you want an order created regardless of payment status, you can set the AlwaysApproveOrderCreation to true in the merchello.config.

          <!-- 
    Overrides the Payment Method's IPaymentResponse ApproveOrderCreation indicating an order should always be created no matter
    if the payment has been collected or not. 
    -->
    <setting alias="AlwaysApproveOrderCreation" value="false" />
    

    Checkout the Merchello.Bazaar code for an example:

    https://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Bazaar/Controllers/BazaarCheckoutConfirmController.cs

    There are methods to set both the ShippingAddress and BillingAddress in the SalesPreparation class. You can think of this class as a temporary stage to collect all of your information while you are building the sale (invoice).

  • Nathan Sleigh 109 posts 353 karma points
    Jan 08, 2016 @ 09:09
    Nathan Sleigh
    0

    Hi Rusty,

    Im not actually using Bazaar. Im doing it in a custom way. Here's the code im using:

    //Create Invoice
    var invoiceService = MerchelloContext.Current.Services.InvoiceService;
    var invoice = invoiceService.CreateInvoice(Merchello.Core.Constants.DefaultKeys.InvoiceStatus.Unpaid);
    
    var extendedData = new ExtendedDataCollection();
    
    //Set Invoice Products
    var customerContext = new CustomerContext(UmbracoContext);
    var basket = customerContext.CurrentCustomer.Basket();
    var basketModel = basket.ToBasketViewModel();
    foreach(var basketItem in basketModel.Items)
    {
        var content = Umbraco.TypedContent(basketItem.ContentId);
        decimal itemPrice = basketItem.UnitPrice;
        var title = content.Name;
        var quantity = basketItem.Quantity;
        var sku = basketItem.Sku;
    
        var orderLine = new InvoiceLineItem(LineItemType.Product, title, sku, quantity, itemPrice, extendedData);
                invoice.Items.Add(orderLine);
                invoice.Total += itemPrice * quantity;            
     }
    
     //Payment Method
     var cashProvider = MerchelloContext.Current.Gateways.Payment.GetProviderByKey(Constants.ProviderKeys.Payment.CashPaymentProviderKey);
     var cash = cashProvider.PaymentMethods.FirstOrDefault();
     invoice.AuthorizeCapturePayment(cash.Key);
    
     //Set Billing Address
     invoice.SetBillingAddress(billingDestination);
    
    //Set Customer
    ((Invoice)invoice).CustomerKey = customer.Key;
    
     invoiceService.Save(invoice);
    

    As you can see from the code i can set the billing address quite easily with .SetBillingAddress, but there isnt anything to set the shipping address and i cant find anyone that has done it.

    Does this make sense?

    Nathan

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jan 08, 2016 @ 14:33
    Rusty Swayne
    0

    @Nathan,

    OK - if you want to create an invoice manually, you will need to add the shipment line item yourself. A shipment line item is created by getting a shipment rate quote by quoting a shipment (which you'll have to "package" from your items) and then adding that (the quote) to the shipment line items extended data collection. The shipment itself has the shipping address as "destination address".

    The reason we do it this way, is there could be times when an order is broken up into multiple shipments that need to be sent to different destinations. In that case there would be multiple shipment line items.

    I can't post code at the moment, but there are a few integration tests in the Merchello repo that should give you an idea. Also, if I remember right, there was a thread on this forum a while back where we discussed creating invoices manually.

  • Nathan Sleigh 109 posts 353 karma points
    Jan 08, 2016 @ 15:34
    Nathan Sleigh
    0

    Rusty,

    I have looked into it a bit further, I have see the post before and have tried to work through it and get it to work but I haven't had any luck.

    This is what I have so far:

     //Set Shipping Address
     var warehouse = MerchelloContext.Current.Services.WarehouseService.GetDefaultWarehouse();
     var shipmentService = MerchelloContext.Current.Services.ShipmentService;
     var shipmentStatus = MerchelloContext.Current.Services.ShipmentService.GetShipmentStatusByKey(Constants.DefaultKeys.ShipmentStatus.Quoted);
     var shipment = shipmentService.CreateShipment(shipmentStatus, warehouse.AsAddress(), shippingDestination, invoice.Items);
    
     var key = Constants.ProviderKeys.Shipping.FixedRateShippingProviderKey;
     var rateTableProvider = (FixedRateShippingGatewayProvider)MerchelloContext.Current.Gateways.Shipping.GetProviderByKey(key);
     var quotes = rateTableProvider.QuoteShippingGatewayMethodsForShipment(shipment);
     if (quotes.Any())
     {
         invoice.Items.Add(quotes.FirstOrDefault().AsLineItemOf<InvoiceLineItem>());
     }
    

    Its currently not wokring and doesnt seem to actually be doing anything. Any ideas when you get a sec would be amazing thank you.

    Nathan

  • Nathan Sleigh 109 posts 353 karma points
    Jan 11, 2016 @ 11:59
    Nathan Sleigh
    0

    Hi Rusty,

    I have tried to get this working this morning by looking at this post: https://our.umbraco.org/projects/collaboration/merchello/merchello/67640-fulfilling-orders. It seems like in my code it inst finding a shipment country.

     //Preparing shipment
            var warehouseService = MerchelloContext.Current.Services.WarehouseService;
            var shipmentService = MerchelloContext.Current.Services.ShipmentService;
            var gatewayproviderService = MerchelloContext.Current.Services.GatewayProviderService;
    
    
            var warehouse = warehouseService.GetDefaultWarehouse();
            var shipmentStatus = shipmentService.GetShipmentStatusByKey(Constants.DefaultKeys.ShipmentStatus.Quoted);
            var shipment = shipmentService.CreateShipment(shipmentStatus, warehouse.AsAddress(), billingDestination, invoice.Items);
            var country = MerchelloContext.Current.Services.StoreSettingService.GetCountryByCode("GB").Key;
            var key = Constants.ProviderKeys.Shipping.FixedRateShippingProviderKey;
            var rateTableProvider = (FixedRateShippingGatewayProvider)MerchelloContext.Current.Gateways.Shipping.GetProviderByKey(key);
    
            var shipService = new Merchello.Core.Services.GatewayProviderService();
            //IShipCountry shipCountry = shipService.GetShipCountryByKey(country);
    
            var catalog = warehouseService.GetAllWarehouseCatalogs().FirstOrDefault();
            var shipCountry = gatewayproviderService.GetShipCountry(catalog.Key, "GB");
    
    
            var methods = rateTableProvider.ShipMethods.ToArray(); //Gets "GLS", "Post Danmark (Vary by Weigth)", "Ground (Vary by Weight)"
            var method = rateTableProvider.ShipMethods.Where(x => x.ShipCountryKey == shipCountry.Key).FirstOrDefault(); //Gets "Post Danmark (Vary by Weight)"
            shipment.ShipMethodKey = method.Key;
            var quote = rateTableProvider.QuoteShipMethodForShipment(shipment, rateTableProvider.GetShippingGatewayMethod(method.Key, shipCountry.Key));
    
            //Add shipping quotes to invoice
            invoice.Items.Add(quote.AsLineItemOf<InvoiceLineItem>());
    

    Im curious to know if you can spot anything just by looking at that bit of code?

    Nathan

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Jan 11, 2016 @ 17:03
    Rusty Swayne
    0

    @Nathan,

    Once you have your shipment, you should probably use the ShippingContext as it sort of looks like your trying to do a lot of work that is already done for you ...

     var shippingContext = MerchelloContext.Current.Gateways.Shipping;
    
     var quote = shippingContext.GetShipRateQuotesForShipment(shipment);
    

    Alternatively you could use the extension method off of the shipment.

     // Quote the shipment
     var shipmentRateQuotes = shipment.ShipmentRateQuotes().ToArray();
    
  • Nguyen Hien 52 posts 133 karma points
    Jan 14, 2016 @ 06:32
    Nguyen Hien
    0

    Rusty, why shipment rate quote with my shipping address alway set to null? How can I configure this?

    shipmentRateQuotes = shipment.ShipmentRateQuotes().ToArray();

    if (shipmentRateQuotes.Any() && !invoice.ShippingLineItems().Any()) {

    //// Assume the first selection. Customer will be able to update this later //// but this allows for a taxation calculation as well in the event shipping charges

    //// are taxable. preparation.SaveShipmentRateQuote(shipmentRateQuotes.First()); }

    shipmentRateQuotes.Any() && !invoice.ShippingLineItems().Any() always is false

Please Sign in or register to post replies

Write your reply to:

Draft