Dolibarr / dolibarr

Dolibarr ERP CRM is a modern software package to manage your company or foundation's activity (contacts, suppliers, invoices, orders, stocks, agenda, accounting, ...). it's an open source Web application (written in PHP) designed for businesses of any sizes, foundations and freelancers.
https://www.dolibarr.org
GNU General Public License v3.0
5.47k stars 2.8k forks source link

Error on creating variant with the API #23136

Closed Franckapik closed 1 year ago

Franckapik commented 1 year ago

Bug

I try to make this api POST request to add variant of a product :

curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'DOLAPIKEY: myapikey' -d '{ \ 
   "weight_impact": 0, \ 
   "price_impact": 0, \ 
   "price_impact_is_percent": true, \ 
   "features": [ \ 
     "1 => 1" \ 
   ] \ 
 }' 'https://quadratikfr.saas2.doliondemand.fr/api/index.php/products/1/variants'

I have this error :

{
  "error": {
    "code": 401,
    "message": "Unauthorized"
  },
  "debug": {
    "source": "api_products.class.php:1741 at call stage",
    "stages": {
      "success": [
        "get",
        "route",
        "negotiate",
        "authenticate",
        "validate"
      ],
      "failure": [
        "call",
        "message"
      ]
    }
  }
}

Is this a syntax error or missing data or finally a bug from this endpoint api ? I have tested POST a product and it's working but this i have 401 error with variant request. We can't know more on the error report.

Talking about POST product, do i miss documentation about the required data to send or is there any information missing in the proposed model on the explorer page ? (only "request_data": ["string"] ? ) I suppose that the model should be too long probably but we don't really know what key:value we can use for it ...

Environment Version

16.0.0

Environment OS

Linux Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64

Environment Web server

Apache/2.4.38 (Debian)

Environment PHP

7.3.31-1~deb10u1

Environment Database

5.5.5-10.3.36-MariaDB-0+deb10u1

Environment URL(s)

No response

Expected and actual behavior

I would like to add a new variant by using the api. I have an 401 error. I don't know if i am wrong on the syntax or if there is a bug on the variant POST endpoint of the API. I have tested this on my server with dolibarr 16.0.0 and on online demo with 16.0.3 . Error 401 or 404.

Steps to reproduce the behavior

{ "weight_impact": 0, "price_impact": 0, "price_impact_is_percent": true, "features": [ "1=>1" ] }

Attached files

image

image

milenmk commented 1 year ago

So you have an attribute with ID=1 and what to set it's value to 1, correct? If so, try with:

"features": ["1" => 1]

For more than one feature, try with:

"features": ["id_1" => value_1, "id_2" => value_2]

And if the value is a string, not a number try with:

"features": ["id_1" => "value_1", "id_2" => "value_2"]

Franckapik commented 1 year ago

I have tried these without success :

"features": ["1" => 1] ===> "Bad Request: Error encoding/decoding JSON: Syntax error"

"features": ["id_1" => value_1, "id_2" => value_2] ===> "Bad Request: Error encoding/decoding JSON: Syntax error"

"features": ["id_1=>id_1"] ===> 401 error

"features": ["1=>1"] ===> 401 error

"features": ["string"] ===> 401 error

"features": ["id_1=>value_1"] ===> 401 error

"features": ["id_1 => 5", "id_2 => 10"] (5 and 10 are my values's names) ===> 401 error

//GET PRODUCT (/api/index.php/products?sortfield=t.ref&sortorder=ASC&limit=100) [ { "label": "mon_libelle", "description": "", "other": null, "type": "0", "price": "68.00000000", "price_ttc": "81.60000000", "price_min": "0.00000000", "price_min_ttc": "0.00000000", "price_base_type": "HT", "multiprices": [], "multiprices_ttc": [], "multiprices_base_type": [], "multiprices_min": [], "multiprices_min_ttc": [], "multiprices_tva_tx": [], "prices_by_qty": [], "prices_by_qty_list": [], "multilangs": [], "default_vat_code": null, "tva_tx": "20.000", "localtax1_tx": "0.000", "localtax2_tx": "0.000", "localtax1_type": "0", "localtax2_type": "0", "lifetime": null, "qc_frequency": null, "cost_price": null, "pmp": "0.00000000", "seuil_stock_alerte": "0", "desiredstock": "0", "duration_value": false, "duration_unit": "", "status": "1", "status_buy": "0", "finished": null, "fk_default_bom": null, "status_batch": "0", "batch_mask": "", "customcode": "", "url": null, "weight": null, "weight_units": "0", "length": null, "length_units": "0", "width": null, "width_units": "0", "height": null, "height_units": "0", "surface": null, "surface_units": "0", "volume": null, "volume_units": "0", "net_measure": null, "net_measure_units": null, "accountancy_code_sell": "", "accountancy_code_sell_intra": "", "accountancy_code_sell_export": "", "accountancy_code_buy": "", "accountancy_code_buy_intra": "", "accountancy_code_buy_export": "", "barcode": null, "barcode_type": null, "date_creation": "2022-12-07 07:23:36", "date_modification": "2022-12-07 07:23:36", "fk_default_warehouse": null, "fk_price_expression": null, "fk_unit": null, "price_autogen": "0", "is_object_used": null, "mandatory_period": "0", "id": "1", "entity": "1", "validateFieldsErrors": [], "import_key": null, "array_options": [], "array_languages": null, "contacts_ids": null, "linked_objects": null, "linkedObjectsIds": null, "linkedObjectsFullLoaded": [], "canvas": "", "fk_projet": null, "ref": "test", "ref_ext": null, "country_id": null, "country_code": "", "state_id": null, "region_id": null, "barcode_type_coder": null, "last_main_doc": null, "note_public": null, "note_private": "", "total_ht": null, "total_tva": null, "total_localtax1": null, "total_localtax2": null, "total_ttc": null, "date_validation": null, "date_cloture": null, "user_author": null, "user_creation": null, "user_creation_id": null, "user_valid": null, "user_validation": null, "user_validation_id": null, "user_closing_id": null, "user_modification": null, "user_modification_id": null, "specimen": 0, "duration": "" } ]

//GET ATTRIBUTES (/api/index.php/products/attributes?sortfield=t.ref&sortorder=ASC&limit=100) [ { "module": "variants", "id": "1", "ref": "LON", "ref_ext": "", "label": "Longueur", "position": "1", "line": null, "entity": "1", "validateFieldsErrors": [], "import_key": null, "array_options": [], "array_languages": null, "contacts_ids": null, "linked_objects": null, "linkedObjectsIds": null, "linkedObjectsFullLoaded": [], "canvas": null, "fk_projet": null, "status": null, "country_id": null, "country_code": null, "state_id": null, "region_id": null, "barcode_type": null, "barcode_type_coder": null, "last_main_doc": null, "note_public": null, "note_private": null, "total_ht": null, "total_tva": null, "total_localtax1": null, "total_localtax2": null, "total_ttc": null, "date_creation": null, "date_validation": null, "date_modification": null, "date_cloture": null, "user_author": null, "user_creation": null, "user_creation_id": null, "user_valid": null, "user_validation": null, "user_validation_id": null, "user_closing_id": null, "user_modification": null, "user_modification_id": null, "specimen": 0 } ]

//GET ATTRIBUTES BY ID 1 (/api/index.php/products/attributes/1) { "id": "1", "ref": "LON", "ref_ext": "", "label": "Longueur", "position": "1", "entity": 1, "is_used_by_products": 0 }

//GET VALUES FROM ATTRIBUTE ID 1 (/api/index.php/products/attributes/1/values) [ { "module": "variants", "id": "1", "fk_product_attribute": "1", "ref": "GRAND", "value": "10", "position": null, "rowid": null, "fk_unit": null, "date_debut_prevue": null, "date_debut_reel": null, "date_fin_prevue": null, "date_fin_reel": null, "weight": null, "weight_units": null, "width": null, "width_units": null, "height": null, "height_units": null, "length": null, "length_units": null, "surface": null, "surface_units": null, "volume": null, "volume_units": null, "multilangs": null, "product_type": null, "fk_product": null, "desc": null, "product": null, "product_ref": null, "product_label": null, "product_barcode": null, "product_desc": null, "fk_product_type": null, "qty": null, "duree": null, "remise_percent": null, "info_bits": null, "special_code": null, "entity": 1, "validateFieldsErrors": [], "import_key": null, "array_options": [], "array_languages": null, "contacts_ids": null, "linked_objects": null, "linkedObjectsIds": null, "linkedObjectsFullLoaded": [], "canvas": null, "fk_projet": null, "ref_ext": null, "status": null, "country_id": null, "country_code": null, "state_id": null, "region_id": null, "barcode_type": null, "barcode_type_coder": null, "last_main_doc": null, "note_public": null, "note_private": null, "total_ht": null, "total_tva": null, "total_localtax1": null, "total_localtax2": null, "total_ttc": null, "date_creation": null, "date_validation": null, "date_modification": null, "date_cloture": null, "user_author": null, "user_creation": null, "user_creation_id": null, "user_valid": null, "user_validation": null, "user_validation_id": null, "user_closing_id": null, "user_modification": null, "user_modification_id": null, "specimen": 0 }, { "module": "variants", "id": "2", "fk_product_attribute": "1", "ref": "PETIT", "value": "5", "position": null, "rowid": null, "fk_unit": null, "date_debut_prevue": null, "date_debut_reel": null, "date_fin_prevue": null, "date_fin_reel": null, "weight": null, "weight_units": null, "width": null, "width_units": null, "height": null, "height_units": null, "length": null, "length_units": null, "surface": null, "surface_units": null, "volume": null, "volume_units": null, "multilangs": null, "product_type": null, "fk_product": null, "desc": null, "product": null, "product_ref": null, "product_label": null, "product_barcode": null, "product_desc": null, "fk_product_type": null, "qty": null, "duree": null, "remise_percent": null, "info_bits": null, "special_code": null, "entity": 1, "validateFieldsErrors": [], "import_key": null, "array_options": [], "array_languages": null, "contacts_ids": null, "linked_objects": null, "linkedObjectsIds": null, "linkedObjectsFullLoaded": [], "canvas": null, "fk_projet": null, "ref_ext": null, "status": null, "country_id": null, "country_code": null, "state_id": null, "region_id": null, "barcode_type": null, "barcode_type_coder": null, "last_main_doc": null, "note_public": null, "note_private": null, "total_ht": null, "total_tva": null, "total_localtax1": null, "total_localtax2": null, "total_ttc": null, "date_creation": null, "date_validation": null, "date_modification": null, "date_cloture": null, "user_author": null, "user_creation": null, "user_creation_id": null, "user_valid": null, "user_validation": null, "user_validation_id": null, "user_closing_id": null, "user_modification": null, "user_modification_id": null, "specimen": 0 } ]

Thanks for having suggested some possible answers. I don't know what to try now ;)

Franckapik commented 1 year ago

I know now that the function add variant is on this line : https://github.com/Dolibarr/dolibarr/blob/develop/htdocs/product/class/api_products.class.php#L1705

We can see that there is a lot of way to have the 401 exception error ...

Do someone know if I could directly modify this file on my server or if I should compile or do something next ? (I only use node.js on JavaScript development... )

milenmk commented 1 year ago

401 error is returned if the product attribute with this ID is not found OR if the product attribute with this label is not found. The easiest way to find these values is to look at table llx_product_attribute

You can check your Dolibarr log to see what request is sent to the server.

As for the file code change, the changes will be lost when you update your Dolibarr version.

milenmk commented 1 year ago

After some digging, what you need for the API call is:

id_attribute - the value of column rowid from table llx_product_attribute id_value - the value of column rowid from table llx_product_attribute_value

So if the attribute is colour and the value is blue, you cannot use 'colour' => 'blue' or '1' => 'blue'

1

2

Franckapik commented 1 year ago

Thank you for your help @milenmk , but i have stil a 401 error. Here is my tables attributes (left) and values (right) .

image

I have tried this :

{ "weight_impact": 0, "price_impact": 0, "price_impact_is_percent": true, "features": ["5=>10"] }

Still continue the investigation ... If someone could help me on the requested syntax maybe ?

Franckapik commented 1 year ago

If i use the Dolibarr debug tool with Dolibarr administration, i can see the sames ids : image

Franckapik commented 1 year ago

Maybe the response for the syntax is the way to post an associative array here ... (https://stackoverflow.com/questions/14050812/how-to-post-an-associative-array-in-php)

We should make the link between this : image-1.png

And this : image-2.png

Franckapik commented 1 year ago

I finally found the syntax for writing features!!!

The only way to have key : value on a json was probably to use object {key : value}. So it works with this :

{ "weight_impact": 0, "price_impact": 0, "price_impact_is_percent": true, "features": { "5": "10", "6" : "16" } }

I don't know if i am a noob or if there is something misterious about the documentation but it could be nice to update this kind of array(), or [5=>10] in the example model.