WooCommerce connector for Tryton

Create a file called test_woo.py and put the following data into it:

from woocommerce import API

wcapi = API(
    url="https://[my-web-shop's-URL]",
    consumer_key="<your key>",
    consumer_secret="<your secret>",
    version="wc/v3"
)

r = wcapi.get("products")
print(r.status_code)
print(r.headers)
print(r.text)
print(r.json)

execute this file with python test_woo.py within your activated virtual environment. You should see some data with the print statements.

1 Like

This is what I get. “401” seems to be an authentification error. So I re-checked credentials with a browser as stated in message #16, but they are still working.

(tryton-5.6) wd@Simux-380:~/tryton-56-exp$ python test_woo.py
401
{'Server': 'nginx', 'Date': 'Tue, 13 Oct 2020 13:37:59 GMT', 'Content-Type': 'application/json; charset=UTF-8', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'X-Robots-Tag': 'noindex', 'Link': '<https://shop.komponentenkontor-berlin.de/wp-json/>; rel="https://api.w.org/"', 'X-Content-Type-Options': 'nosniff', 'Access-Control-Expose-Headers': 'X-WP-Total, X-WP-TotalPages, Link', 'Access-Control-Allow-Headers': 'Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type', 'Vary': 'Origin'}
{"code":"woocommerce_rest_cannot_view","message":"Entschuldigung, es k\u00f6nnen keine Ressourcen aufgelistet werden.","data":{"status":401}}

The messsage “sorry, no ressources can be listed” are the same as in tryton GUI.

So, no problem with the module, but with connection. You can search the internet for the woocommerce_rest_cannot_view and find https://stackoverflow.com/questions/42186757/woocommerce-woocommerce-rest-cannot-view-status-401.

You can try to change:

wcapi = API(
    url="https://[my-web-shop's-URL]",
    consumer_key="<your key>",
    consumer_secret="<your secret>",
    version="wc/v3"
)

to

wcapi = API(
    url="https://[my-web-shop's-URL]",
    consumer_key="<your key>",
    consumer_secret="<your secret>",
    version="wc/v3",
    query_string_auth=True
)

It seems for many people that solved their case. It’s because of using httpS.

But maybe the keys you have created are not sufficient enough and have the wrong rights, e.g. they are not allowed to show the products. Maybe @pokoli can also shed some light here with explaining his setup.

1 Like
wcapi = API(
    url="https://[my-web-shop's-URL]",
    consumer_key="[your key]",
    consumer_secret="[your secret]",
    version="wc/v3",
    query_string_auth="true"
)

Eddy the great! It works. Magician!

Yes. My homework now is to find out where I have to insert the line.
Already tried. Already failed… Sorry.

1 Like

Unfortunately you can’t, see web.py · master · kopen / web_shop_woocommerce · GitLab. @pokoli have to make some changes to the code so support this.

There is an API parameters property that can be overriden to match custom requirements.

Why not? The property can be overriden in custom module so you can pass any arguments to the API constructor and make it work for any use case.

I understand, but to create a new custom module to just add that one parameter seems a lot of work and was just thinking about it. It’s almost impossible to put this into the trytond.conf because you can have multiple shops.

When you look at the variables, you can see a pattern like <key>="<value>". What about doing that also in the module? Replacing all the woocommerce fields in the shop class with a text field and on each line you enter the key=value. The property then splits those based on the newline character, maybe add some checking if the key is allowed etc. With this, you are giving the user great flexibility but also the responsibility to add the right data correctly.

Was just thinking about it.

This may work but for us normally it’s easier to extend the code on a third party module instead of having configuration on the database because it may allow to hide the api internals to the end users.

With again very patient help by @edbo I could make it work partially. His (he said “hacky”) solution was:

  1. in (name-of-your-environment)/web_shop_woocommerce/build/lib/trytond/modules/web_shop_woocommerce/web.py,
    change:

@property
def woocommerce_api_parameters(self):
return {
‘url’: self.woocommerce_url,
‘consumer_key’: self.woocommerce_consumer_key,
‘consumer_secret’: self.woocommerce_consumer_secret,
‘timeout’: 30,
}

(which occurs around line 168) to

@property
def woocommerce_api_parameters(self):
    return {
        'url': self.woocommerce_url,
        'consumer_key': self.woocommerce_consumer_key,
        'consumer_secret': self.woocommerce_consumer_secret,
        'timeout': 30,
        'query_string_auth': True,
        }
  1. Reinstall the woocommerce module.

This at least made the “import orders” feature work; “import products” still does not.

Now, I receive orders as “posted” ones. In my case, this is not the ideal solution. My customers often purchase one service from the web shop, but when I receive their items, I see that they did not choose the appropriate service, and have to change or enhance their order.

Therefore: Is it possible to introduce an option where I can choose:
plugin provides

  • posted order or
  • draft order

The orders are confirmed because normally the customer have paid for it and you can not modify them.

You should consider using the sale_amendment module to update the of details of the sale.

1 Like

This may be the case often. But I think not always. A customer

  • may ring me up of mail me after a purchase that he forgot something,
  • … or accidentally ordered too much or wrong
  • I notice that one of the items ran out of stock and I will not sell them any longer

There are so many cases of error, misunderstanding or whatever… I again would vote of an option to receive a “draft” status - which I can finish then. Legally, this always should be allright if both parties agree.

If that’s difficult to implement, only import parties from woocommerce would be a usable compromise.

With the “sale_amendment” module, I get an error when I try to change an article:

Traceback (most recent call last):
  File "/trytond/wsgi.py", line 110, in dispatch_request
    return endpoint(request, **request.view_args)
  File "/trytond/protocols/dispatcher.py", line 47, in rpc
    return methods.get(request.rpc_method, _dispatch)(
  File "/trytond/wsgi.py", line 77, in auth_required
    return wrapped(*args, **kwargs)
  File "/trytond/protocols/wrappers.py", line 131, in wrapper
    return func(request, pool, *args, **kwargs)
  File "/trytond/protocols/dispatcher.py", line 186, in _dispatch
    result = rpc.result(meth(inst, *c_args, **c_kwargs))
  File "/trytond/model/fields/field.py", line 116, in wrapper
    return func(self, *args, **kwargs)
  File "/trytond/modules/sale_amendment/sale.py", line 409, in on_change_with_product_uom_category
    return self.line.product_uom_category.id
AttributeError: 'NoneType' ob

NB: The “download products” still does not work in my setup.

Cheers,
Wolf

I am also very interested in this woocommerce connector.

I installed it like described here WooCommerce connector for Tryton

The method “Update WooCommerce Products” works fine, i can push my products from tryton to woocommerce - including stock, SKU, name. But the method “Download WooCommerce Orders” seems to have no effect. I get no error, but it also won’t download the orders. I manualy checked the API response and it’s fine. SKUs also seem to be identical (Although the difference between, and the naming of, “code” and “SKU” in Tryton is not clear to me)

What could i do next in order to identify whats going wrong?

Edit: Is it possible to execute “Download WooCommerce Orders” with trytond in a terminal, to get additional infos?

I also made a fork https://gitlab.com/Nemo123/web_shop_woocommerce where I added the line:

'query_string_auth': True,

As discussed earlier in this thread.

However this doesn’t change a thing for me. API response is fine both ways.

Did you have any confirmed order on the Woocommerce shop?

The module will raise an Error if there is some problem syncronizing.

Yes, i have a few orders with woocommerce status “completed”, “processing” and “cancelled”.

Hmm…? Where am i supposed to see the downloaded orders in tryton, under Sales > Sales?

What i did inside tryton is roughly the following: I set up one party and one product. I used Inventories to stock up the warehouse with the product. I created a webshop and asigned it to the party, the warehouse and the product. Now i can push the stock amount, price etc. from tryton to woocommerce but i don’t see the downloaded orders.

Only on-hold orders are downloaded and then it’s status is update to processing on Woocomerce.
Then when the goods are sent the order is marked as Completed on WooCommerce.

1 Like

It works :heart_eyes:

1 Like

I’ve updated the module documentation to explain how the module works. I hope this makes it easier for others to properly understand the behaviour of the module. Let me know if there is something else that need to be clarified.

Happy to read feedback from happy users!

2 Likes

New year, new attempt.

Sorry, still I’m not happy with an invoice I cannot change.

  • We’re on holidays. Orders came in, but we’re not working. So invoice date would be in the last year, although actual shipping happens next week, nearly mid of January. Not nice.
  • Customer purchased wrong shipment method - I cannot change that without hassle.

Sorry having to insist - but still it does not work for me this way.

In the meanwhile, I understood that products to be synced need to be added under
[menu] > sales > settings > webshops - articles
Actually, these are synced now.

I could not find how to achieve it the other way - download from woocommerce to tryton.

I do not know why you are having issues with invoices as the connector does anything with them.

For me the current workflow is correct. The connector downloads the sales order with the date of the customer order and leaves it as processing. Then invoice is created depending following your default invoice method but is always created in the draft state so you can adjust the invoice date to the previous fiscalyear if required.