magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.47k stars 9.28k forks source link

Products added to cart with REST API give total prices equal to zero #2991

Closed degaray closed 5 years ago

degaray commented 8 years ago

Preconditions (*)

  1. Magento 2.3.0(release), 2.3-develop, 2.2-develop

Steps to reproduce (*)

1.Execute:

endpoint="http://m2ce.conf/rest"
shippingEmail="earthworm.jim@gmail.com"

admin_token=$(curl -X POST "$endpoint/V1/integration/admin/token" \
--header "Content-Type: application/json" \
-d '{"username":"admin","password":"123123q"}') && echo $admin_token && admin_token=$(echo $admin_token | tr -d '"')

curl -X POST "$endpoint/V1/categories" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"category":{"parent_id":2,"name":"Category 1","is_active":true,"level":2,"path":"1/2/3","include_in_menu":true,"custom_attributes":[{"attribute_code":"is_anchor","value":"1"},{"attribute_code":"url_key","value":"category-1"},{"attribute_code":"url_path","value":"category-1"}]}}' | json_pp

curl -X POST "$endpoint/V1/categories" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"category":{"parent_id":2,"name":"Category 2","is_active":true,"level":2,"path":"1/2/4","include_in_menu":true,"custom_attributes":[{"attribute_code":"is_anchor","value":"1"},{"attribute_code":"url_key","value":"category-2"},{"attribute_code":"url_path","value":"category-1"}]}}' | json_pp

category_id="3"; productSKU="Simple Product SSM 1" && curl -X POST "$endpoint/V1/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"product":{"sku":"'"$productSKU"'","name":"'"$productSKU"'","attribute_set_id":4,"price":10,"status":1,"visibility":4,"type_id":"simple","created_at":"2018-01-01 00:00:01","updated_at":"2018-01-01 00:01:00","weight":1,"extension_attributes":{"category_links":[{"position":0,"category_id":"'"$category_id"'"}],"stock_item":{"qty":1000,"is_in_stock":true,"is_qty_decimal":false}}}}' | json_pp

category_id="3"; productSKU="Simple Product SSM 2" && curl -X POST "$endpoint/V1/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"product":{"sku":"'"$productSKU"'","name":"'"$productSKU"'","attribute_set_id":4,"price":10,"status":1,"visibility":4,"type_id":"simple","created_at":"2018-01-01 00:00:01","updated_at":"2018-01-01 00:01:00","weight":1,"extension_attributes":{"category_links":[{"position":0,"category_id":"'"$category_id"'"}],"stock_item":{"qty":1000,"is_in_stock":true,"is_qty_decimal":false}}}}' | json_pp

category_id="3"; productSKU="Simple Product SSM 3" && curl -X POST "$endpoint/V1/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"product":{"sku":"'"$productSKU"'","name":"'"$productSKU"'","attribute_set_id":4,"price":10,"status":1,"visibility":4,"type_id":"simple","created_at":"2018-01-01 00:00:01","updated_at":"2018-01-01 00:01:00","weight":1,"extension_attributes":{"category_links":[{"position":0,"category_id":"'"$category_id"'"}],"stock_item":{"qty":1000,"is_in_stock":true,"is_qty_decimal":false}}}}' | json_pp

category_id="4"; productSKU="Simple Product SSM 4" && curl -X POST "$endpoint/V1/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"product":{"sku":"'"$productSKU"'","name":"'"$productSKU"'","attribute_set_id":4,"price":10,"status":1,"visibility":4,"type_id":"simple","created_at":"2018-01-01 00:00:01","updated_at":"2018-01-01 00:01:00","weight":1,"extension_attributes":{"category_links":[{"position":0,"category_id":"'"$category_id"'"}],"stock_item":{"qty":1000,"is_in_stock":true,"is_qty_decimal":false}}}}' | json_pp

category_id="4"; productSKU="Simple Product SSM 5" && curl -X POST "$endpoint/V1/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"product":{"sku":"'"$productSKU"'","name":"'"$productSKU"'","attribute_set_id":4,"price":10,"status":1,"visibility":4,"type_id":"simple","created_at":"2018-01-01 00:00:01","updated_at":"2018-01-01 00:01:00","weight":1,"extension_attributes":{"category_links":[{"position":0,"category_id":"'"$category_id"'"}],"stock_item":{"qty":1000,"is_in_stock":true,"is_qty_decimal":false}}}}' | json_pp

curl -X POST "$endpoint/V1/categories" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"category":{"parent_id":2,"name":"Category 3","is_active":true,"level":2,"path":"1/2/4","include_in_menu":true,"custom_attributes":[{"attribute_code":"is_anchor","value":"1"},{"attribute_code":"url_key","value":"category-3"},{"attribute_code":"url_path","value":"category-3"}]}}' | json_pp

category_id="5"; productSKU="Simple Product SSM 5" && curl -X POST "$endpoint/V1/products" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"product":{"sku":"'"$productSKU"'","name":"'"$productSKU"'","attribute_set_id":4,"price":10,"status":1,"visibility":4,"type_id":"simple","created_at":"2018-01-01 00:00:01","updated_at":"2018-01-01 00:01:00","weight":1,"extension_attributes":{"category_links":[{"position":0,"category_id":"'"$category_id"'"}],"stock_item":{"qty":1000,"is_in_stock":true,"is_qty_decimal":false}}}}' | json_pp

curl -X POST $endpoint/V1/customers \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $admin_token" \
-d '{"customer":{"default_billing":false,"default_shipping":true,"email":"'"$shippingEmail"'","firstname":"Jim","lastname":"Earthworm","store_id":1,"website_id":1,"addresses":[{"id":1,"region":{"region_code":"CA","region":"California","region_id":12},"region_id":12,"country_id":"US","street":["6161 West Centinela Avenue"],"company":"Magento","telephone":"555-55-555-55","postcode":"90230","city":"Culver City","firstname":"Jim","lastname":"Earthworm"}],"disable_auto_group_change":0,"extension_attributes":{"is_subscribed":false}},"password":"MetaFrame1"}' | json_pp

customer_token=$(curl -X POST "$endpoint/V1/integration/customer/token" \
 -H "Content-Type: application/json" \
 -d '{"username":"'"$shippingEmail"'","password":"MetaFrame1"}') && echo $customer_token && customer_token=$(echo $customer_token | tr -d '"')

 cart_id=$(curl -X POST "$endpoint/V1/carts/mine" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $customer_token") && echo $cart_id && cart_id=$(echo $cart_id | tr -d '"')

curl -X GET "$endpoint/V1/customers/me" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $customer_token" | grep -i customer_id

curl -X GET "$endpoint/V1/carts/mine/items" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $customer_token"

curl -X POST "$endpoint/V1/carts/mine/items" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $customer_token" \
-d '{"cartItem":{"sku":"'"$productSKU"'","qty": 1,"name": "'"$productSKU"'","price":10,"product_type":"simple","quote_id":"'"$cart_id"'"}}' | json_pp

curl -X POST "$endpoint/V1/carts/mine/items" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $customer_token" \
-d '{"cartItem":{"sku":"'"$productSKU"'","qty": 1,"name": "'"$productSKU"'","price":10,"product_type":"simple","quote_id":"'"$cart_id"'"}}' | json_pp

Expected result (*)

  1. Price is present in both last two responses and is not equal to zero or is equal to real price whatever price was specified in the request payload.
  2. No side-effects on Storefront

Actual result (*)

  1. Fresh cart always has no price property. Submit an order and you will be able to reproduce again.
  2. Zero price in the Cart on Storefront report

Information from reporter

I have created a Product with a prize of $24 using the backend of Magento2. When I check it in the backent it is fine. However, when I add one unit of it to an existent cart using the REST API I get a price of zero. For that I call [POST] /carts/mine/items with body:

{
    "cart_item": {
        "quote_id": "2",
        "sku": "MY_SKU",
        "qty": 1
    }
}

I get the following response:

{
  "item_id": 2,
  "sku": "MY_SKU",
  "qty": 2,
  "name": "My Product",
  "price": 0,
  "product_type": "virtual",
  "quote_id": "2"
}

Also when I call [GET] /products I get the right price in the response, this is the response I get:

{
  "items": [
    {
      "id": 1,
      "sku": "MY_SKU",
      "name": "My Product",
      "attribute_set_id": 9,
      "price": 24,
      "status": 1,
      "visibility": 4,
      "type_id": "virtual",
      "created_at": "2016-01-11 19:17:10",
      "updated_at": "2016-01-13 17:49:11",
      "product_links": [],
      "options": [],
      "tier_prices": [],
      "custom_attributes": [
        {
          "attribute_code": "meta_title",
          "value": "My Product"
        },
        {
          "attribute_code": "meta_keyword",
          "value": "My Product"
        },
        {
          "attribute_code": "meta_description",
          "value": "My Product"
        },
        {
          "attribute_code": "options_container",
          "value": "container2"
        },
        {
          "attribute_code": "required_options",
          "value": "0"
        },
        {
          "attribute_code": "has_options",
          "value": "0"
        },
        {
          "attribute_code": "url_key",
          "value": "my-product"
        },
        {
          "attribute_code": "tax_class_id",
          "value": "0"
        },
        {
          "attribute_code": "custom_time",
          "value": "2016-01-11 00:00:00"
        }
      ]
    }
  ],
  "search_criteria": {
    "filter_groups": [
      {
        "filters": [
          {
            "field": "custom_time",
            "value": "2015-11-19",
            "condition_type": "gt"
          }
        ]
      }
    ]
  },
  "total_count": 1
}

Any guesses why this might be?

degaray commented 8 years ago

The problem comes here: Magento\Quote\Model\Quote\TotalsCollector::collect because all totals are set to zero and then all totals are calculated per address set. Since no address is set, then no totals are calculated, and as result, it does not calculate any total.

ishakhsuvarov commented 8 years ago

@degaray Could you please provide more detailed steps to reproduce the issue? How did you create your quote and customer? A set of empty addresses should be created together with the quote, allowing normal totals calculation for this case.

degaray commented 8 years ago

1.- I create a new instance of Magento2 using git clone --recursive https://github.com/rgranadino/mage2_vagrant.git to get a fresh install. Then I follow all the steps to install it using composer, etc. 2.- I oath login as admin using /integration/admin/token:

    {
        "username": "admin",
        "password": "password123"
    }

I get an auth token.

3.- I create a product calling: [POST] /products:

    {
      "product": {
        "sku": "MY_SKU",
        "name": "My Product",
        "attributeSetId": "4",
        "price": 20,
        "status": 1,
        "visibility": 4,
        "typeId": "virtual",
        "weight": 0,
        "extensionAttributes": {
          "stockItem": {
            "stockId": 1,
            "qty": 20,
            "isInStock": true,
            "isQtyDecimal": false,
            "useConfigMinQty": true,
            "minQty": 0,
            "useConfigMinSaleQty": 0,
            "minSaleQty": 0,
            "useConfigMaxSaleQty": true,
            "maxSaleQty": 0,
            "useConfigBackorders": false,
            "backorders": 0,
            "useConfigNotifyStockQty": true,
            "notifyStockQty": 20,
            "useConfigQtyIncrements": false,
            "qtyIncrements": 0,
            "useConfigEnableQtyInc": false,
            "enableQtyIncrements": false,
            "useConfigManageStock": true,
            "manageStock": true,
            "lowStockDate": "string",
            "isDecimalDivided": true,
            "stockStatusChangedAuto": 0,
            "extensionAttributes": {}
          }
        },
        "options": [],
        "tierPrices": [],
        "customAttributes": [
        ]
      },
      "saveOptions": true
    }

4.- I create a user using [POST] /customers:

    {
        "customer": {
            "email": "my@email.com",
            "firstname": "My Name",
            "lastname": "Last Name",
            "storeId": 1,
            "websiteId": 1,
            "extension_attributes": {
            },
            "addresses": [
                {
                    "country_id": "MX",
                    "street": [
                        "Some address 23"
                    ],
                    "telephone": "5555555558",
                    "postcode": "10200",
                    "city": "México",
                    "firstname": "My Name",
                    "lastname": "Last Name",
                    "default_shipping": true,
                    "default_billing": true
                }
            ]
        },
        "password": "{{customer_password}}"
    }

4.1- I login using /integration/customer/token and get an oath token.

5.- I create a cart using: [POST] /carts/mine with a blank body

6.- I add an item to the cart using: [POST] /carts/mine/items

    {
        "cart_item": {
            "quote_id": "1",
            "sku": "MY_SKU",
            "qty": 1
        }
    }

7.- I finally call [GET] /carts/mine/payment-information and I get this:

    {
      "payment_methods": [
        {
          "code": "checkmo",
          "title": "Check / Money order"
        },
        {
          "code": "free",
          "title": "No Payment Information Required"
        }
      ],
      "totals": {
        "grand_total": 0,
        "weee_tax_applied_amount": null,
        "base_currency_code": "USD",
        "quote_currency_code": "USD",
        "items_qty": 1,
        "items": [
          {
            "item_id": 1,
            "price": 0,
            "base_price": 0,
            "qty": 1,
            "row_total": 0,
            "base_row_total": 0,
            "row_total_with_discount": 0,
            "tax_amount": 0,
            "base_tax_amount": 0,
            "tax_percent": 0,
            "discount_amount": 0,
            "base_discount_amount": 0,
            "discount_percent": 0,
            "options": "[]",
            "weee_tax_applied_amount": null,
            "weee_tax_applied": null,
            "name": "My Product"
          }
        ],
        "total_segments": [
          {
            "code": "subtotal",
            "title": "Subtotal",
            "value": null
          },
          {
            "code": "shipping",
            "title": "Shipping & Handling",
            "value": null
          },
          {
            "code": "grand_total",
            "title": "Grand Total",
            "value": null,
            "area": "footer"
          }
        ]
      }
    }
degaray commented 8 years ago

You can find further reference to this issue in this question:

http://magento.stackexchange.com/questions/97373/items-added-to-cart-with-no-price-on-magento2

sdzhepa commented 8 years ago

@degaray Thank you for reporting this issue. We have created an internal ticket MAGETWO-48570 to fix the problem.

ishakhsuvarov commented 8 years ago

@degaray Closing this ticket, since the fix is already delivered with the linked commits. Please feel free to reopen if you have any additional questions regarding this.

degaray commented 8 years ago

This issue is not fixed! I have tried 2.0.5 and it did not work. I added the extra line as in bdd8d3bf7b72f2686d99b900a46d9cd4273a3e9b and the bug still appears. This is a VERY serious bug. As I cannot collect the value of the cart, thus I cannot get the list of payment methods, use coupons, or update the cart information from the server.

manuelDistefano commented 8 years ago

Same here. I have tried 2.0.7 and it did not work.

manuelDistefano commented 8 years ago

Update. You can user rest/V1/carts/mine/billing-address to add address to cart. Then add item to cart so you can have item with the correct price.

POST /index.php/rest/V1/carts/mine/billing-address HTTP/1.1
Host: 127.0.0.41:8082
Content-Type: application/json
Accept: application/json
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
Authorization: Bearer 3ewcbeoxh1x52b9wf5aapaib0qm8hrbk
Cache-Control: no-cache
Postman-Token: 5ad87a49-68ec-6b0a-1002-88ed0f1bbbac

{
  "address": {
    "region": "Roma",
    "regionId": 0,
    "regionCode": "Roma",
    "countryId": "IT",
    "street": [
      "Via Toscana 16"
    ],
    "company": "Manuel Di Stefano",
    "telephone": "3333333",
    "fax": "33333333",
    "postcode": "00013",
    "city": "Fonte Nuova",
    "firstname": "First Name",
    "lastname": "Last name",
    "middlename": "string",
    "customerId": 21,
    "email": "string",
    "sameAsBilling": 1,
    "saveInAddressBook": 0
  },
  "useForShipping": true
}
degaray commented 8 years ago

Yes @manuelDistefano however, don't you think that is a bug? Specially if you are selling virtual products?

manuelDistefano commented 8 years ago

Yes @degaray, it's a problem for sure, and i'm selling virtual products too.

But i can use this "workaround" until they fix it.

RUjmiak commented 8 years ago

@ishakhsuvarov Can you reopen ticket? Bug is not fixed...

qwerty7869 commented 8 years ago

@ishakhsuvarov Please tell me how to extend model Repository.php from core file to my project. I tried extending the model but than add to product api is giving error as below.

message": "Source class \"%1\" for \"%2\" generation does not exist.", "parameters": [ "\project\ExtendQuote\Model\Quote\ItemInterface", "project\ExtendQuote\Model\Quote\Item\Repository"

tejashp77 commented 8 years ago

Any one has a solution of this issue? i am using 2.1.0 and 0 price issue which degaray mentioned above is still there

NisaKH commented 8 years ago

@tejashp77
For this issue, You can use an observer to auto add an empty address to cart.

use this event >> sales_quote_save_before and use the code below

public function execute( Observer $observer ) {
    $quote = $observer->getEvent()->getQuote();
    $this->logger->debug("Cart Observer is trigged.");

    if ($quote->hasItems() && $quote->getSubtotal() == 0) {
        $this->logger->debug("Set address to cart");
        $quote
            ->setShippingAddress($this->getEmptyAddress())
            ->setBillingAddress($this->getEmptyAddress());
    }
    $shippingAddress
        ->setCollectShippingRates(true)
        ->collectShippingRates();

}

private function getEmptyAddress() {
    $address = $this->addressFactory->create();
    $address->setRegionId(1);
    $address->setRegion(" ");
    $address->setRegionCode(" ");
    $address->setCountryId("EN");
    $address->setStreet([" "]);
    $address->setTelephone(" ");
    $address->setPostcode(" ");
    $address->setCity(" ");
    $address->setFirstname(" ");
    $address->setLastname(" ");
    return $address;
}

Please note that the region id must not be null

\ For virtual products, you don't need to set shipping address

tejashp77 commented 8 years ago

from API call it not goes to 'sales_quote_save_before' event. i have tried by put events.xml in etc folder and etc/frontend both.

NisaKH commented 8 years ago

@tejashp77

just put it in etc/events.xml should be enough.

This is how i put the event. `

` It should be tricked when your customer add a product to cart. please check again :)
SerhiyShkolyarenko commented 7 years ago

Reopened the ticket due to several reports of reproducing the issue.

degaray commented 7 years ago

I have sent a pull request for this issue.

Enviado desde Yahoo Mail para Android

El jue. 17 17e nov. 17e 2016 a las 7:20 AM, Serhiy Shkolyarenkonotifications@github.com escribió:
Reopened the ticket due to several reports of reproducing the issue.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

degaray commented 7 years ago

Find my pull request here: https://github.com/magento/magento2/pull/4532

SerhiyShkolyarenko commented 7 years ago

@degaray @manuelDistefano @RUjmiak could you please confirm the issue is reproducible on 2.0.10? Have anybody reproduced it on 2.1.2? Magento 2.0.10 and 2.1.2 were security releases, so the issue could be fixed there.

manuelDistefano commented 7 years ago

@SerhiyShkolyarenko i can't try it at the moment. Bu this should be ok in 2.1.1. I upgraded to 2.1.2 some days ago and it was ok.

I dont know in 2.0.*

degaray commented 7 years ago

I have tried it in 2.0.10 and it is now fixed. However there is an issue with payment method "free" showing as an available method even though the cart total is not zero

degaray commented 7 years ago

No It is not fixed as of 2.0.10 I can confirm it is not fixed yet! This bug has been around for more than a year, please give a higher importance.

RUjmiak commented 7 years ago

@degaray @SerhiyShkolyarenko This bug is still in 2.1.3. For products which are in stock prices are calculating, but for products which are on backorder price is 0

  1. Magento 2.1.3
  2. REST API login to get bearer token
  3. REST API create cart
  4. Add backorder product to cart
  5. get carts/mine/totals

{ "grand_total": 0, "weee_tax_applied_amount": null, "base_currency_code": "EUR", "quote_currency_code": "EUR", "items_qty": 1, "items": [ { "item_id": 4994081, "price": 0, "base_price": 0, "qty": 1, "row_total": 0, "base_row_total": 0, "row_total_with_discount": 0, "tax_amount": 0, "base_tax_amount": 0, "tax_percent": 0, "discount_amount": 0, "base_discount_amount": 0, "discount_percent": 0, "options": "[]", "weee_tax_applied_amount": null, "weee_tax_applied": null, "name": "Dámske čierne tričko Mustang Maja XS" } ], "total_segments": [ { "code": "subtotal", "title": "Subtotal", "value": 0 }, { "code": "shipping", "title": "Shipping & Handling", "value": null }, { "code": "tax", "title": "Tax", "value": 0, "extension_attributes": { "tax_grandtotal_details": [] } }, { "code": "grand_total", "title": "Grand Total", "value": null, "area": "footer" } ] }

allamgr commented 7 years ago

Im having the same issue after adding the first product to the cart via REST api the price is zero, then after update the product via REST api the price is normal.

davidverholen commented 7 years ago

same problem here when adding items using the service layer (Magento\Quote\Api\CartRepositoryInterface)

currently trying with

$quote = $this->checkoutSession->getQuote();
$quote->addProduct($product, $productData[self::PRODUCT_AMOUNT]);
$quote->collectTotals();
$this->cartRepository->save($quote);
$this->checkoutSession->replaceQuote($quote);
magentodeveloperankit commented 7 years ago

Magento ver. 2.1.3 Serious Issue on Cart Api

http://localhost/magento2/magento-2-ce/rest/V1/carts/33/items

BODY {
"cartItem":{
"sku":"24-MB01", "qty":1,

         "quote_id":"34"
         }
}

Same issue i am facing while creating cart & adding first product to cart price is showing zero its working for for 2nd Products

Api GET : http://localhost/magento2/magento-2-ce/rest/V1/carts/34 cart id : 34 Response after adding first product to cart page & i am trying to fetch cart data

{ "id": 34, "created_at": "2017-02-02 11:10:36", "updated_at": "2017-02-02 11:11:02", "is_active": true, "is_virtual": false, "items": [ { "item_id": 31, "sku": "24-MB01", "qty": 1, "name": "Joust Duffle Bag", "price": 0, "product_type": "simple", "quote_id": "34" } ], "items_count": 1, "items_qty": 1, "customer": { "id": 13, "group_id": 1, "created_at": "2017-02-02 11:00:15", "updated_at": "2017-02-02 11:00:16", "created_in": "Default Store View", "email": "a12@test.com", "firstname": "a12", "lastname": "asa", "store_id": 1, "website_id": 1, "addresses": [], "disable_auto_group_change": 0 }, "billing_address": { "id": 64, "region": null, "region_id": null, "region_code": null, "country_id": null, "street": [ "" ], "telephone": null, "postcode": null, "city": null, "firstname": null, "lastname": null, "customer_id": 13, "email": "a12@test.com", "same_as_billing": 0, "save_in_address_book": 0 }, "orig_order_id": 0, "currency": { "global_currency_code": "USD", "base_currency_code": "USD", "store_currency_code": "USD", "quote_currency_code": "USD", "store_to_base_rate": 0, "store_to_quote_rate": 0, "base_to_global_rate": 1, "base_to_quote_rate": 1 }, "customer_is_guest": false, "customer_note_notify": true, "customer_tax_class_id": 3, "store_id": 1, "extension_attributes": { "shipping_assignments": [ { "shipping": { "address": { "region": null, "region_id": null, "region_code": null, "country_id": null, "street": [ "" ], "telephone": null, "postcode": null, "city": null, "firstname": null, "lastname": null, "email": "a12@test.com" }, "method": null }, "items": [ { "item_id": 31, "sku": "24-MB01", "qty": 1, "name": "Joust Duffle Bag", "price": 0, "product_type": "simple", "quote_id": "34" } ] } ] } }

thomas-burko commented 7 years ago

Problem still occurring with Magento 2.1.4

nikhilzoom commented 7 years ago

Issue still not fixed with Magento 2.1.5

Here are the details

  1. I have two websites on my magento installation.
  2. Using OAuth1.0 for authentication in REST API.
  3. http://localhost/magento/rest/V1/ is my api URL.
  4. Want to add an item into cart which is assigned in another website not the default website.

Sequence of Calling of API 1. Create cart API: http://localhost/magento/rest/V1/customers/{customerId}/carts Method: POST Data Type: JSON Request: Response: "11" (cart id)

  1. Add billing address API: http://localhost/magento/rest/V1/carts/{cartId}/billing-address Method: POST Data Type: JSON Request: { "address": { "city": "xxxxxx", "company": "xxxxxxxx", "countryId": "IN", "email": "xxxxxxxxx@gmail.com", "firstname": "N", "lastname": "J", "postcode": "123456", "region": "GJ", "saveInAddressBook": 1, "street": ["D-84"], "telephone": "9876543210" }, "useForShipping": true } Response: "21" (address id)

  2. Add cart to item API: http://localhost/magento/rest/V1/carts/{cartId}/items Method: POST Data Type: JSON Request: { "cartItem":{ "sku":"ssp-product", "qty":1, "name":"ssp product", "price": 10, "product_type":"simple", "quote_id":"1" } } Response: { "item_id": 4, "sku": "ssp-product", "qty": 2, "name": "ssp product", "price": 0, "product_type": "virtual", "quote_id": "1" }

HemalAmbab commented 7 years ago

A Major work arround for the solution 1) Create User Account 2) Create A Cart for User. [POST] /rest/V1/carts/mine 2) Add product to cart [POST] /rest/V1/carts/mine/items 3) Recall Create Cart For User. [POST] /rest/V1/carts/mine 4) Now Get the Totals [POST] /rest/V1/carts/mine/totals

shubhamagarwal862 commented 7 years ago

This issue of getting 0 or null in add to cart API is fixed now after taking below steps - ( Note : This is for magento 2 or later version. )

  1. Open file 'vendor/magento/module-quote/Model/QuoteManagement.php'.
  2. Find function 'createEmptyCartForCustomer'.
  3. Add below code inside try{}, around line number 235 $quote->getBillingAddress(); $quote->getShippingAddress()->setCollectShippingRates(true);

After that it will work perfectly.

minlare commented 7 years ago

Does anyone have "Single Store Mode" enabled? I have a suspicion that disabling single store mode fixed the issue for me... Can anyone else confirm this?

magento-engcom-team commented 6 years ago

Hi @shubhamagarwal862 it would be great if you can submit a pull request with the fix. Looks like you already found the solution 👍

magento-engcom-team commented 6 years ago

@degaray, thank you for your report. We've created internal ticket(s) MAGETWO-48570 to track progress on the issue.

magento-team commented 6 years ago

Internal ticket to track issue progress: MAGETWO-81994

okorshenko commented 6 years ago

the issue has been fixed and delivered to 2.2-develop branch. WIll be available with 2.2.2 release

vkmunjpara commented 6 years ago

@okorshenko , @magento-team

I need to apply the solution in magento 2.1.3 version.

Could you please give me just the name of files which can resolve this issue from 2.2.2 version ?

Thanks in advance..

davidverholen commented 6 years ago

@vkmunjpara there is a referenced pull request in this issue, it should be sufficient to apply the same change to 2.1: https://github.com/magento/magento2/pull/11458/files

magento-engcom-team commented 6 years ago

Hi @degaray. Thank you for your report. The issue has been fixed in magento-engcom/magento2ce#1351 by @magento-engcom-team in 2.3-develop branch Related commit(s):

The fix will be available with the upcoming 2.3.0 release.

ulftietze commented 5 years ago

Hey Guys,

is this really fixed? I can reproduce in 2.2.6 easily :/

Steps to reproduce this:

curl -X POST \
  https://url.de/rest/de/V1/integration/customer/token \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
"username": „{{USERNAME}}",
"password": „{{PASSWORT}}"
}'
curl -X POST \
  https://url.de/rest/de/V1/carts/mine/items \
  -H 'Authorization: Bearer {{CUSTOMER_TOKEN}}' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
    "cart_item": {
    "quote_id": {{QUOTE_ID}},
        "sku": "123456789",
        "qty": 1
}
}'

I can recognice, that the answer of that request the price is already missing here. As example:

{
    "item_id": 15840429,
    "sku": "123456789",
    "qty": 1,
    "name": "Fleischpeitsche",
    "product_type": "simple",
    "quote_id": "14393073"
}

If you cant reproduce, you have to do this more often and delete that item out of cart with following request. After that just add it again. Sometimes you have to do this like 2 or 3 times after this error occures.

curl -X DELETE \
  https://url.de/rest/de/V1/carts/mine/items/{{ITEM_ID}} \
  -H 'Authorization: Bearer {{CUSTOMER_TOKEN}}' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json'

I debugged a while in core and can definitly recognice a possible corebug here. In \Magento\Quote\Model\Quote\TotalsCollector::collect() on line 143 the function $quote->getAllAddresses() is called. This function just gives me back one single address, the billing address. Normally i expect that there are always two addresses, billing and shipping address.

If you look up to the select sql, which is executed to load this: SELECTmain_table.* FROMquote_addressASmain_tableWHERE (quote_id= '13162569'); This returns also just one address, the billing address. This is started at \Magento\Quote\Model\Quote::getAddressesCollection() on line 1116.

Dunno how the billing and shipping address are created, so im going to step more deeply in this to look why this is happening.

@magento-engcom-team @okorshenko can you probably take a look here?

Greetz, Ulf

ulftietze commented 5 years ago

Well, i can provide some more information about this now.

Preconditions:

1.) POST {{Host}}/rest/de/V1/carts/mine/items to add product 2.) Assumed that everything is correct, database shows us two entries for following query:

SELECT `main_table`.* FROM `quote_address` AS `main_table` WHERE (`quote_id` = '13162569');

3.) DELETE {{Host}}/rest/de/V1/carts/mine/items/21728697 to remove that item again 4.) If you look back into database with the query of point 2, you'll see that here is just one address, the billing address 5.) Add Product just like in point 1 and you'll see that the price isn't calculated.

This bug sucks really hard :D Givin' up on this today, may i find a solution tomorrow.

Greetz, Ulf

ulftietze commented 5 years ago

Hey @dmanners, @benmarks,

we talked about this at the MageUC :) Thanks for listen to me here!

Greetz, Ulf

cyberkiller6 commented 5 years ago

Hey @dmanners, @benmarks,

we talked about this at the MageUC :) Thanks for listen to me here!

Greetz, Ulf

@ulftietze Have you found any solutions to this problem?

ulftietze commented 5 years ago

@cyberkiller6 nah not really, found a workaround which may breaks tons of stuff :D You may disable the plugin which is responsible to delete the address from quote:

<type name="Magento\Quote\Model\Quote">
        <plugin name="clear_addresses_after_product_delete" disabled="true" />
</type>

Problem here is, that this does not fix the issue with the initialize adding a product directly after creating the quote.

ulftietze commented 5 years ago

Hey @benmarks @dmanners ,

here i am to annoy you :D you said to me i should do that if you dont react ^^ May @ishakhsuvarov can tell more here? :D

Greetz, Ulf

okorshenko commented 5 years ago

Hi @ulftietze Thank you for raising the issue again. We will double-check it

ulftietze commented 5 years ago

Hey Guys,

i've found a temporary workaround, which works at least in my scope to prevent this behavior. This should definitly not be the solution for the core but may this help others until Magento fix this the correct way ^^

In\Magento\Quote\Model\Quote\Item\Repositoryon line 87, add $quote->getShippingAddress(); to make sure, a shipping address exists. Your function should look like this:

   /**
     * {@inheritdoc}
     */
    public function save(\Magento\Quote\Api\Data\CartItemInterface $cartItem)
    {
        /** @var \Magento\Quote\Model\Quote $quote */
        $cartId = $cartItem->getQuoteId();
        $quote = $this->quoteRepository->getActive($cartId);
        $quote->getShippingAddress();

        $quoteItems = $quote->getItems();
        $quoteItems[] = $cartItem;
        $quote->setItems($quoteItems);
        $this->quoteRepository->save($quote);
        $quote->collectTotals();
        return $quote->getLastAddedItem();
    }

@okorshenko thanks for reopening this :+1:

have a nice week, Ulf

hoangtuan21193 commented 5 years ago

@ulftietze

Thank you for your suggestion but I can not make it work for me. Would you mind if I can see how you add item to cart.

I want to add shopping bag item to cart when customer click [Proceed to Checkout] in Cart page. Then redirect to confirm page.

This is my code, but it's always redirect to cart page again, I don't want that. If I try to not redirect to cart, the price will be 0.

public function addShoppingBag()
    {
        $shoppingBagSku = $this->helper->getShoppingBagSku();
        $shoppingBagProduct = $this->productRepository->get($shoppingBagSku);

        $params = array(
            'product' => $shoppingBagProduct->getId(),
            'qty' => 1
        );

        $request = new \Magento\Framework\DataObject();
        $request->setData($params);

        $this->cart->addProduct($shoppingBagProduct, $request);
        $this->cart->save();
        $this->cart->getQuote()->setTotalsCollectedFlag(false)->collectTotals()->save();

    }
ulftietze commented 5 years ago

Hey @hoangtuan21193,

i think this is the wrong point to discuss about custom errors here. The right point to place this would probably be stackoverflow. If we discuss such custom solution in here, we can't talk about the real problem and the solution in Magento Core about this.

Anyway, i'm not like a bad person :D If you take a look at the last fix in the core, also included in this issue. Dunno if this works, but make sure that before you save the quote, you call this function: $quote->getShippingAddress()->setCollectShippingRates(true);

If you have more problems on this, you may create an stackoverflow question and send me the link ^^

Have a nice day, Ulf