Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.0][MIG][ADD]-Migrated WooCommerce Module #44

Open
wants to merge 8 commits into
base: 11.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions connector_woocommerce/LICENSE/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

Tech-Receptives Solutions Pvt. Ltd.
Copyright (C) 2009-TODAY Tech-Receptives(<http://www.techreceptives.com>).

Serpent Consulting Services Pvt. Ltd.
Copyright (C) 2018-TODAY Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>).

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
62 changes: 62 additions & 0 deletions connector_woocommerce/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3

=====================
WooCommerce Connector
=====================

Connector between WooCommerce and Odoo

Usage
=====

#. Go to ...

.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/207/11.0


Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/OCA/connector-woocommerce/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.

Credits
=======

Images
------

* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.

Contributors
------------

* Tech-Receptives Solutions <https://techreceptives.com/>
* Serpent Consulting Services Pvt. Ltd.<http://www.serpentcs.com/>

Maintainer
----------

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

This module is maintained by the OCA.

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

To contribute to this module, please visit https://odoo-community.org.



.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
5 changes: 5 additions & 0 deletions connector_woocommerce/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import components
from . import models
from . import wizard
39 changes: 39 additions & 0 deletions connector_woocommerce/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# © 2009 Tech-Receptives Solutions Pvt. Ltd.
# © 2018 Serpent Consulting Services Pvt. Ltd.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# See LICENSE file for full copyright and licensing details.

{
'name': 'WooCommerce Connector',
'version': '11.0.1.0.1',
'category': 'Ecommerce',
'author': """Tech Receptives,
Serpent Consulting Services Pvt. Ltd.,
Odoo Community Association (OCA)""",
'contributors': """Tech Receptives,
Serpent Consulting Services Pvt. Ltd.""",
'license': 'AGPL-3',
'maintainer': 'Odoo Community Association (OCA)',
'website': 'https://github.com/OCA/connector-woocommerce',
'summary': """Imports the Product's Categories, Products, Customers and
Sale orders from WooCommerce, Meanwhile Exports from Odoo
To WooCommerce.""",
'depends': ['sale_stock', 'connector', 'connector_ecommerce'],
'installable': True,
'auto_install': False,
'data': [
"security/ir.model.access.csv",
"views/backend_view.xml",
"views/product_view.xml",
"views/res_partner_views.xml",
"views/sale_views.xml",
"wizard/woo_export_view.xml",
"wizard/woo_validation_view.xml",
"wizard/backend_instance.xml",
],
'external_dependencies': {
'python': ['woocommerce'],
},
'application': True,
"sequence": 3,
}
8 changes: 8 additions & 0 deletions connector_woocommerce/components/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import core
from . import backend_adapter
from . import binder
from . import importer
from . import exporter
from . import mapper
209 changes: 209 additions & 0 deletions connector_woocommerce/components/backend_adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# © 2009 Tech-Receptives Solutions Pvt. Ltd.
# © 2018 Serpent Consulting Services Pvt. Ltd.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# See LICENSE file for full copyright and licensing details.

import socket
import logging
import xmlrpc.client
from datetime import datetime
from odoo.addons.component.core import AbstractComponent
from odoo.addons.queue_job.exception import RetryableJobError
from odoo.addons.connector.exception import NetworkRetryableError
from odoo.addons.queue_job.exception import FailedJobError

_logger = logging.getLogger(__name__)

try:
from woocommerce import API
except ImportError:
_logger.debug("Cannot import 'woocommerce'")

WOO_DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'


class WooLocation(object):

def __init__(self, location, consumer_key, consumre_secret, version):
self._location = location
self.consumer_key = consumer_key
self.consumer_secret = consumre_secret
self.version = version

@property
def location(self):
location = self._location
return location


class WooAPI(object):

def __init__(self, location):
"""
:param location: Woo location
:type location: :class:`WooLocation`
"""
self._location = location
self._api = None

@property
def api(self):
return self._api

def __enter__(self):
# we do nothing, api is lazy
return self

def __exit__(self, type, value, traceback):
if self._api is not None:
return

def call(self, method=None, resource=None, arguments=None):
try:
location = self._location._location
cons_key = self._location.consumer_key
sec_key = self._location.consumer_secret
version = self._location.version or 'v3'
# WooCommerce API Connection
wcapi = API(
url=location, # Your store URL
consumer_key=cons_key, # Your consumer key
consumer_secret=sec_key, # Your consumer secret
wp_api=True,
version=version, # WooCommerce WP REST API version
query_string_auth=True # Force Basic Authentication as query
# string true and using under HTTPS
)
if wcapi:
if isinstance(arguments, list):
while arguments and arguments[-1] is None:
arguments.pop()
start = datetime.now()
try:
wooapi = getattr(wcapi, method)
res = wooapi(resource) if method not in ['put', 'post'] \
else wooapi(resource, arguments)
vals = res.json()
if not res.ok:
raise FailedJobError(vals)
result = vals
except Exception as e:
_logger.error("api.call(%s, %s, %s, %s) failed", method,
resource, arguments, e)
raise
else:
_logger.debug("api.call(%s, %s, %s) returned %s in %s\
seconds", method, resource, arguments, result,
(datetime.now() - start).seconds)
return result
except (socket.gaierror, socket.error, socket.timeout) as err:
raise NetworkRetryableError(
'A network error caused the failure of the job: '
'%s' % err)
except xmlrpc.client.ProtocolError as err:
if err.errcode in [502, # Bad gateway
503, # Service unavailable
504]: # Gateway timeout
raise RetryableJobError(
'A protocol error caused the failure of the job:\n'
'URL: %s\n'
'HTTP/HTTPS headers: %s\n'
'Error code: %d\n'
'Error message: %s\n' %
(err.url, err.headers, err.errcode, err.errmsg))
else:
raise


class WooCRUDAdapter(AbstractComponent):
""" External Records Adapter for Woo """

_name = 'woo.crud.adapter'
_inherit = ['base.backend.adapter', 'base.woo.connector']
_usage = 'backend.adapter'

def search(self, filters=None):
""" Search records according to some criterias
and returns a list of ids """
raise NotImplementedError

def read(self, id, attributes=None):
""" Returns the information of a record """
raise NotImplementedError

def search_read(self, filters=None):
""" Search records according to some criterias
and returns their information"""
raise NotImplementedError

def create(self, data):
""" Create a record on the external system """
raise NotImplementedError

def write(self, id, data):
""" Update records on the external system """
raise NotImplementedError

def delete(self, id):
""" Delete a record on the external system """
raise NotImplementedError

def _call(self, method, resource, arguments):
try:
woo_api = getattr(self.work, 'woo_api')
except AttributeError:
raise AttributeError(
'You must provide a woo_api attribute with a '
'WooAPI instance to be able to use the '
'Backend Adapter.'
)
return woo_api.call(method, resource, arguments)


class GenericAdapter(AbstractComponent):

_name = 'woo.adapter'
_inherit = 'woo.crud.adapter'

_woo_model = None
_admin_path = None

def search(self, filters=None):
""" Search records according to some criterias
and returns a list of ids

:rtype: list
"""
return self._call('%s.search' % self._woo_model,
[filters] if filters else [{}])

def read(self, id, attributes=None):
""" Returns the information of a record
:rtype: dict
"""
arguments = []
if attributes:
# Avoid to pass Null values in attributes. Workaround for
# is not installed, calling info() with None in attributes
# would return a wrong result (almost empty list of
# attributes). The right correction is to install the
# compatibility patch on WooCommerce.
arguments.append(attributes)
return self._call('get', '%s/' % self._woo_model + str(id), [])

def search_read(self, filters=None):
""" Search records according to some criterias
and returns their information"""
return self._call('%s.list' % self._woo_model, [filters])

def create(self, data):
""" Create a record on the external system """
return self._call('post', self._woo_model, data)

def write(self, id, data):
""" Update records on the external system """
return self._call('put', self._woo_model + "/" + str(id), data)

def delete(self, id):
""" Delete a record on the external system """
return self._call('%s.delete' % self._woo_model, [int(id)])
27 changes: 27 additions & 0 deletions connector_woocommerce/components/binder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# © 2009 Tech-Receptives Solutions Pvt. Ltd.
# © 2018 Serpent Consulting Services Pvt. Ltd.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# See LICENSE file for full copyright and licensing details.

from odoo.addons.component.core import Component


class WooModelBinder(Component):
""" Bind records and give odoo/woo ids correspondence

Binding models are models called ``woo.{normal_model}``,
like ``woo.res.partner`` or ``woo.product.product``.
They are ``_inherits`` of the normal models and contains
the Woo ID, the ID of the Woo Backend and the additional
fields belonging to the Woo instance.
"""
_name = 'woo.binder'
_inherit = ['base.binder', 'base.woo.connector']
_apply_on = [
'woo.res.partner',
'woo.product.category',
'woo.product.product',
'woo.sale.order',
'woo.sale.order.line',
'woo.shipping.zone',
]
16 changes: 16 additions & 0 deletions connector_woocommerce/components/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# © 2009 Tech-Receptives Solutions Pvt. Ltd.
# © 2018 Serpent Consulting Services Pvt. Ltd.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.addons.component.core import AbstractComponent


class BaseWooConnectorComponent(AbstractComponent):
""" Base Woo Connector Component

All components of this connector should inherit from it.
"""

_name = 'base.woo.connector'
_inherit = 'base.connector'
_collection = 'woo.backend'
Loading