title: Shopping Cart Estimate Tax Shipping - Issue with shipping totals collect
body: <p>I use <b>WebShopApps_MatrixRates</b> module on Magento 2 site and module is configured with one delivery method for the region and two other delivery methods for some cities in that region. 
  <br/>
  I've setup "Estimate Tax and Shipping" form on Cart Page to display region and city fields. preference for: <pre>Magento\Checkout\Block\Cart\LayoutProcessor</pre></p>
  
  <pre class="lang-php prettyprint-override"><code>    public function process($jsLayout)
      {
          $elements = [
              'city' =&gt; [
                  'visible' =&gt; true,
                  'formElement' =&gt; 'select',
                  'label' =&gt; __('City'),
                  'options' =&gt; $this-&gt;bcCitiesOptionsArray,
              ],
              'country_id' =&gt; [
                  'visible' =&gt; false,  //Remove the country
                  'formElement' =&gt; 'select',
                  'label' =&gt; __('Country'),
                  'options' =&gt; [],
                  'value' =&gt; null
              ],
              'region_id' =&gt; [
                  'visible' =&gt; true,
                  'formElement' =&gt; 'select',
                  'label' =&gt; __('State/Province'),
                  'options' =&gt; [],
                  'value' =&gt; null
              ],
              'postcode' =&gt; [
                  'visible' =&gt; false, //Remove Postal Code
                  'formElement' =&gt; 'input',
                  'label' =&gt; __('Zip/Postal Code'),
                  'value' =&gt; null
              ]
          ];
  
          if (!isset($jsLayout['components']['checkoutProvider']['dictionaries'])) {
              $jsLayout['components']['checkoutProvider']['dictionaries'] = [
                  'country_id' =&gt; $this-&gt;countryCollection-&gt;loadByStore()-&gt;toOptionArray(),
                  'region_id' =&gt; $this-&gt;regionCollection-&gt;addAllowedCountriesFilter()-&gt;toOptionArray(),
              ];
          }
  
          if (isset($jsLayout['components']['block-summary']['children']['block-shipping']['children']
              ['address-fieldsets']['children'])
          ) {
              $fieldSetPointer = &amp;$jsLayout['components']['block-summary']['children']['block-shipping']
              ['children']['address-fieldsets']['children'];
              $fieldSetPointer = $this-&gt;merger-&gt;merge($elements, 'checkoutProvider', 'shippingAddress', $fieldSetPointer);
              $fieldSetPointer['region_id']['config']['skipValidation'] = true;
          }
          return $jsLayout;
      }
  </code></pre>
  
  <p>and when i select a city with two methods, shipping form with correct methods and prices is loaded.</p>
  
  <p>But after the method is selected, <b>$addressInformation</b> parameter is passed to <b>calculate()</b> method in class:</p>
  
  <pre>Magento\Checkout\Model\TotalsInformationManagement</pre>
  
  <pre class="lang-php prettyprint-override"><code>public function calculate(
          $cartId,
          \Magento\Checkout\Api\Data\TotalsInformationInterface $addressInformation
      ) {
          /** @var \Magento\Quote\Model\Quote $quote */
          $quote = $this-&gt;cartRepository-&gt;get($cartId);
          $this-&gt;validateQuote($quote);
  
          if ($quote-&gt;getIsVirtual()) {
              $quote-&gt;setBillingAddress($addressInformation-&gt;getAddress());
          } else {
              $quote-&gt;setShippingAddress($addressInformation-&gt;getAddress());
              $quote-&gt;getShippingAddress()-&gt;setCollectShippingRates(true)-&gt;setShippingMethod(
                  $addressInformation-&gt;getShippingCarrierCode() . '_' . $addressInformation-&gt;getShippingMethodCode()
              );
          }
          $quote-&gt;collectTotals();
  
          return $this-&gt;cartTotalRepository-&gt;get($cartId);
      }
  </code></pre>
  
  <p>which does not contain information about city.
  <br/>
  Because of this, module MatrixRates loads the wrong shipping method from  database and we get two different <b>$this->getShippingMethod()</b> and <b>$rate->getGode()</b> codes here:</p>
  
  <pre>Magento\Quote\Model\Quote\Address</pre>
  
  <pre class="lang-php prettyprint-override"><code>    public function requestShippingRates(\Magento\Quote\Model\Quote\Item\AbstractItem $item = null)
      {
  
          /** @var $request \Magento\Quote\Model\Quote\Address\RateRequest */
          $request = $this-&gt;_rateRequestFactory-&gt;create();
          $request-&gt;setAllItems($item ? [$item] : $this-&gt;getAllItems());
          $request-&gt;setDestCountryId($this-&gt;getCountryId());
          $request-&gt;setDestRegionId($this-&gt;getRegionId());
          $request-&gt;setDestRegionCode($this-&gt;getRegionCode());
          $request-&gt;setDestStreet($this-&gt;getStreetFull());
          $request-&gt;setDestCity($this-&gt;getCity());
          $request-&gt;setDestPostcode($this-&gt;getPostcode());
          $request-&gt;setPackageValue($item ? $item-&gt;getBaseRowTotal() : $this-&gt;getBaseSubtotal());
          $packageWithDiscount = $item ? $item-&gt;getBaseRowTotal() -
              $item-&gt;getBaseDiscountAmount() : $this-&gt;getBaseSubtotalWithDiscount();
          $request-&gt;setPackageValueWithDiscount($packageWithDiscount);
          $request-&gt;setPackageWeight($item ? $item-&gt;getRowWeight() : $this-&gt;getWeight());
          $request-&gt;setPackageQty($item ? $item-&gt;getQty() : $this-&gt;getItemQty());
  
          /**
           * Need for shipping methods that use insurance based on price of physical products
           */
          $packagePhysicalValue = $item ? $item-&gt;getBaseRowTotal() : $this-&gt;getBaseSubtotal() -
              $this-&gt;getBaseVirtualAmount();
          $request-&gt;setPackagePhysicalValue($packagePhysicalValue);
  
          $request-&gt;setFreeMethodWeight($item ? 0 : $this-&gt;getFreeMethodWeight());
  
          /**
           * Store and website identifiers specified from StoreManager
           */
          $request-&gt;setQuoteStoreId($this-&gt;getQuote()-&gt;getStoreId());
          $request-&gt;setStoreId($this-&gt;storeManager-&gt;getStore()-&gt;getId());
          $request-&gt;setWebsiteId($this-&gt;storeManager-&gt;getWebsite()-&gt;getId());
          $request-&gt;setFreeShipping($this-&gt;getFreeShipping());
          /**
           * Currencies need to convert in free shipping
           */
          $request-&gt;setBaseCurrency($this-&gt;storeManager-&gt;getStore()-&gt;getBaseCurrency());
          $request-&gt;setPackageCurrency($this-&gt;storeManager-&gt;getStore()-&gt;getCurrentCurrency());
          $request-&gt;setLimitCarrier($this-&gt;getLimitCarrier());
          $baseSubtotalInclTax = $this-&gt;getBaseSubtotalTotalInclTax();
          $request-&gt;setBaseSubtotalInclTax($baseSubtotalInclTax);
  
          $result = $this-&gt;_rateCollector-&gt;create()-&gt;collectRates($request)-&gt;getResult();
  
          $found = false;
          if ($result) {
              $shippingRates = $result-&gt;getAllRates();
  
              foreach ($shippingRates as $shippingRate) {
                  $rate = $this-&gt;_addressRateFactory-&gt;create()-&gt;importShippingRate($shippingRate);
                  if (!$item) {
                      $this-&gt;addShippingRate($rate);
                  }
                  if($this-&gt;getShippingMethod() === "_" &amp;&amp; $this-&gt;getShippingMethod() === null){
                      $this-&gt;setShippingMethod($rate-&gt;getCode());
                  }
  
                  if ($this-&gt;getShippingMethod() == $rate-&gt;getCode()) {
                      if ($item) {
                          $item-&gt;setBaseShippingAmount($rate-&gt;getPrice());
                      } else {
  
                          /** @var \Magento\Store\Api\Data\StoreInterface */
                          $store = $this-&gt;storeManager-&gt;getStore();
                          $amountPrice = $store-&gt;getBaseCurrency()
                              -&gt;convert($rate-&gt;getPrice(), $store-&gt;getCurrentCurrencyCode());
                          $this-&gt;setBaseShippingAmount($rate-&gt;getPrice());
                          $this-&gt;setShippingAmount($amountPrice);
                      }
  
                      $found = true;
                  }
              }
          }
  </code></pre>
  
  <p>This condition</p>
  
  <pre class="lang-php prettyprint-override"><code> if ($this-&gt;getShippingMethod() == $rate-&gt;getCode()) {
                      if ($item) {
                          $item-&gt;setBaseShippingAmount($rate-&gt;getPrice());
                      } else {
  
                          /** @var \Magento\Store\Api\Data\StoreInterface */
                          $store = $this-&gt;storeManager-&gt;getStore();
                          $amountPrice = $store-&gt;getBaseCurrency()
                              -&gt;convert($rate-&gt;getPrice(), $store-&gt;getCurrentCurrencyCode());
                          $this-&gt;setBaseShippingAmount($rate-&gt;getPrice());
                          $this-&gt;setShippingAmount($amountPrice);
                      }
  
                      $found = true;
                  }
  </code></pre>
  
  <p>is not met and function returns <b>false</b></p>
  
  <p>This causes method <b>collectShippingRates()</b> in class</p>
  
  <pre>
  Magento\Quote\Model\Quote\Address
  </pre> 
  
  <p>set shipping method price to 0:</p>
  
  <pre class="lang-php prettyprint-override"><code>$found = $this-&gt;requestShippingRates();
          if (!$found) {
              $this-&gt;setShippingAmount(0)-&gt;setBaseShippingAmount(0)-&gt;setShippingMethod('')-&gt;setShippingDescription('');
          }
  </code></pre>
  
  <p>So, how can I add city to <b>$shippingInformation</b> variable?</p>