Answers.Body: <p>You're right that the shipping calculator API doesn't lend itself to different rates per lineItem as such, but I'm pretty sure you can still make it do what you want.  (But longer term I agree that <code>getLineItemRate(lineItem)</code> or similar should be an option!).</p>
  
  <p>Basically, for now, you can do anything you like in the getBaseRate() and return the total from that to the cart.  (Personally I implement all my shipping stuff as services so I can call them from controllers etc too (e.g. to do shipping quotes via a controller separate to the cart as such - but in this I'll do ti right here).  But you can also do stuff like save data to the order in here, which should be enough to make this work for you.</p>
  
  <p>Basically, you'd loop through the lineItems, looking at the value in the dropdown for each and using that to sum up your shipping costs.  You probably want to list out the chosen options and costs for each lineitem separately on that payment page, so you'll also need to save that data somewhere too...so create a holder variable <code>lineItemShippingOptions</code> in your order for that data and set it as part of the process so you can refer to it in the later templates.</p>
  
  <p>(I'd use a non-editable incognito field for that so your order processors can't accidentally change the data later - <a href="https://github.com/mmikkel/IncognitoField-Craft" rel="nofollow">https://github.com/mmikkel/IncognitoField-Craft</a> (I have PR-ed an improvement to that for just this sort of thing).</p>
  
  <p>(Obviously - this is untested sketch code!)</p>
  
  <pre><code>public function getBaseRate()
  {
     $shippingCost = 0;
     $dataToSave = [];
  
     $this-&gt;cart = craft()-&gt;commerce_cart-&gt;getCart();
     foreach ($cart-&gt;lineItems as $item){
          $shippingOptionChosen = item.options.whatever;
          if($shippingOptionChosen == "service1" ){
              $shippingCost = $20;
              $dataToSave[item.id] = ['chosenOption'=&gt;$shippingOptionChosen, 'chosenPrice'=&gt;20];   
          }
          elseif ($shippingOptionChosen == "service2"){
              etc 
          }
     }
     //Save this data in to the order
     $this-&gt;cart-&gt;setContentFromPost(['lineItemShippingOptions'=&gt;$dataToSave]);
  }
  </code></pre>
  
  <p>Then in your templates you can refer to <code>lineItemShippingOptions</code> to print the info out to the customer.  (That's probably not the ideal way to build the template data you're saving but should serve the purpose to demonstrate the idea...basically you can build any format array you like really).</p>
  
  <p>I use this same approach in a very complicated custom shipping calculator (crazily this is some 2000 lines of php!) - that deals with multiple services (including some table data ones and some live quote ones), plus grouping &amp; boxing services &amp; caching to make it all work as quickly as possible (live rates always being much slower of course...).  Because at times the checkout flow gets awkward relying on Commerce's template tags, I also have an <code>actionShippingOptions</code> controller that calls the same services and returns the quotes &amp; data that way (also very handy for debugging purposes!) - but you may well not need that.  But even with the existing API you can do damn near anything you like between setting the rate and saving data to the order and showing it later, basically.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-05-23T09:32:26.193Z
Answers.Text: Thanks Jeremy, that was just the ticket. Rather than store the shipping in options then move it over to an order field in `getBaseRate()`, I've decided to cut out the middleman. I need a controller to validate that they've chosen shipping for each item anyway, so I though there would be a good place to save the values straight to the Incognito'd order field. That way when the `getBaseRate()` is run, I'll just spin through what they chosen in the order field directly, saves having the values in two places.
Answers.UserDisplayName: Steve Holland
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-05-23T10:16:12.043Z
Answers.Text: Hey Steve... not quite following...getBaseRate saves it straight in to the order field, just one spot...but sounds like you're on to it anyway!
Answers.UserDisplayName: Jeremy Daalder
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-05-23T10:48:24.643Z
Answers.Text: Hi Jeremy, it's does yes, but prior to that I've gone through saving it to the options collection first, which seems a redundant step? Is it, or am I missing something?
Answers.UserDisplayName: Steve Holland
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-05-23T10:52:38.427Z
Answers.Text: No that makes sense ... in my case I calculate options and present to user for choice, but given your fixed options you've already got the choices so yeah, you can indeed cut out  the middle bit :)
Answers.UserDisplayName: Jeremy Daalder
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-05-23T10:53:43.690Z
Answers.Text: Thanks Jeremy, this is my first time working with Commerce, so I'm still finding my feet :)
Answers.UserDisplayName: Steve Holland
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-05-21T00:58:08.160Z
Answers.LastActivityDate: 2016-05-21T02:11:31.480Z
Answers.LastEditDate: 2016-05-21T02:11:31.480Z
Answers.UserDisplayName: Jeremy Daalder
Body: <p>Each Product is associated with a Merchant (a standard Craft User), who has 2-3 flat-rate Shipping Prices. There could be any number of Merchants and Products.</p>
  
  <p>What I would like to do is on the Shipping page of Checkout, allow the Customer to select a Shipping method from a drop-down per LineItem. Then when they progress to the Payment Page, these Shipping Costs are Totalled and applied to the overall Order. </p>
  
  <p>I've got everything up to the drop-downs on the Shipping page and I'm able to save the value the Customer has chosen to the LineItem via the <a href="https://craftcommerce.com/docs/add-to-cart#line-item-options-and-notes" rel="nofollow">Options</a> collection, but that's where I've hit a brick wall.</p>
  
  <p>I've had a look at <a href="https://craftcommerce.com/docs/adjusters" rel="nofollow">Adjusters</a> and I don't think that's the solution. It was suggested on the Craft Slack that Custom <a href="https://craftcommerce.com/docs/shipping-methods" rel="nofollow">Shipping Methods</a> might be a way forward, but they are very heavily geared towards applying the Shipping Method to the whole Order rather than having separate ones for each lineItem.</p>
  
  <p>Does anyone have any ideas on a suitable approach? Any help gratefully received.</p>
  
Tags: <plugin-craftcommerce><shipping>
Title: Add a shippingCost per lineItem rather than per Order
ThreadText: # Add a shippingCost per lineItem rather than per Order
  
  (Asked by: username_0 on 2016-05-20)
  
  Each Product is associated with a Merchant (a standard Craft User), who has 2-3 flat-rate Shipping Prices. There could be any number of Merchants and Products.
  
  What I would like to do is on the Shipping page of Checkout, allow the Customer to select a Shipping method from a drop-down per LineItem. Then when they progress to the Payment Page, these Shipping Costs are Totalled and applied to the overall Order.
  
  I've got everything up to the drop-downs on the Shipping page and I'm able to save the value the Customer has chosen to the LineItem via the [Options](https://craftcommerce.com/docs/add-to-cart#line-item-options-and-notes) collection, but that's where I've hit a brick wall.
  
  I've had a look at [Adjusters](https://craftcommerce.com/docs/adjusters) and I don't think that's the solution. It was suggested on the Craft Slack that Custom [Shipping Methods](https://craftcommerce.com/docs/shipping-methods) might be a way forward, but they are very heavily geared towards applying the Shipping Method to the whole Order rather than having separate ones for each lineItem.
  
  Does anyone have any ideas on a suitable approach? Any help gratefully received.
  
  **Tags:** plugin-craftcommerce, shipping
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2016-05-21. Score: 4 | Accepted answer
  
  You're right that the shipping calculator API doesn't lend itself to different rates per lineItem as such, but I'm pretty sure you can still make it do what you want. (But longer term I agree that `getLineItemRate(lineItem)` or similar should be an option!).
  
  Basically, for now, you can do anything you like in the getBaseRate() and return the total from that to the cart. (Personally I implement all my shipping stuff as services so I can call them from controllers etc too (e.g. to do shipping quotes via a controller separate to the cart as such - but in this I'll do ti right here). But you can also do stuff like save data to the order in here, which should be enough to make this work for you.
  
  Basically, you'd loop through the lineItems, looking at the value in the dropdown for each and using that to sum up your shipping costs. You probably want to list out the chosen options and costs for each lineitem separately on that payment page, so you'll also need to save that data somewhere too...so create a holder variable `lineItemShippingOptions` in your order for that data and set it as part of the process so you can refer to it in the later templates.
  
  (I'd use a non-editable incognito field for that so your order processors can't accidentally change the data later - <https://github.com/mmikkel/IncognitoField-Craft> (I have PR-ed an improvement to that for just this sort of thing).
  
  (Obviously - this is untested sketch code!)
  
  ```
  public function getBaseRate()
  {
     $shippingCost = 0;
     $dataToSave = [];
  
     $this->cart = craft()->commerce_cart->getCart();
     foreach ($cart->lineItems as $item){
          $shippingOptionChosen = item.options.whatever;
          if($shippingOptionChosen == "service1" ){
              $shippingCost = $20;
              $dataToSave[item.id] = ['chosenOption'=>$shippingOptionChosen, 'chosenPrice'=>20];   
          }
          elseif ($shippingOptionChosen == "service2"){
              etc 
          }
     }
     //Save this data in to the order
     $this->cart->setContentFromPost(['lineItemShippingOptions'=>$dataToSave]);
  }
  
  ```
  
  Then in your templates you can refer to `lineItemShippingOptions` to print the info out to the customer. (That's probably not the ideal way to build the template data you're saving but should serve the purpose to demonstrate the idea...basically you can build any format array you like really).
  
  I use this same approach in a very complicated custom shipping calculator (crazily this is some 2000 lines of php!) - that deals with multiple services (including some table data ones and some live quote ones), plus grouping & boxing services & caching to make it all work as quickly as possible (live rates always being much slower of course...). Because at times the checkout flow gets awkward relying on Commerce's template tags, I also have an `actionShippingOptions` controller that calls the same services and returns the quotes & data that way (also very handy for debugging purposes!) - but you may well not need that. But even with the existing API you can do damn near anything you like between setting the rate and saving data to the order and showing it later, basically.
  
  > **Comments:**
  > **username_0**: Thanks username_1, that was just the ticket. Rather than store the shipping in options then move it over to an order field in `getBaseRate()`, I've decided to cut out the middleman. I need a controller to validate that they've chosen shipping for each item anyway, so I though there would be a good place to save the values straight to the Incognito'd order field. That way when the `getBaseRate()` is run, I'll just spin through what they chosen in the order field directly, saves having the values in two places.  
  > **username_1**: Hey username_0... not quite following...getBaseRate saves it straight in to the order field, just one spot...but sounds like you're on to it anyway!  
  > **username_0**: Hi username_1, it's does yes, but prior to that I've gone through saving it to the options collection first, which seems a redundant step? Is it, or am I missing something?  
  > **username_1**: No that makes sense ... in my case I calculate options and present to user for choice, but given your fixed options you've already got the choices so yeah, you can indeed cut out  the middle bit :)  
  > **username_0**: Thanks username_1, this is my first time working with Commerce, so I'm still finding my feet :)  
  
  ---
  
  