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

[MIG] 10.0 connector_magento_pricing #286

Open
wants to merge 1 commit into
base: 10.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
82 changes: 82 additions & 0 deletions connector_magento_pricing/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
===========================
Connector Magento - Pricing
===========================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fconnector--magento-lightgray.png?logo=github
:target: https://github.com/OCA/connector-magento/tree/10.0/connector_magento_pricing
:alt: OCA/connector-magento
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/connector-magento-10-0/connector-magento-10-0-connector_magento_pricing
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/107/10.0
:alt: Try me on Runbot

|badge1| |badge2| |badge3| |badge4| |badge5|

Extension for **Connector Magento**.

The prices of the products are managed in Odoo using pricelists and
are pushed to Magento.

You can push all prices when modifying the pricelist on the backend.

Each time a price is modified in Odoo, the price is pushed to Magento.

**Table of contents**

.. contents::
:local:

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/connector-magento/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/connector-magento/issues/new?body=module:%20connector_magento_pricing%0Aversion:%2010.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Camptocamp
* Akretion

Contributors
~~~~~~~~~~~~

Guewen Baconnier <[email protected]>
Pierrick Brun <[email protected]>

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

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

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.

This module is part of the `OCA/connector-magento <https://github.com/OCA/connector-magento/tree/10.0/connector_magento_pricing>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions connector_magento_pricing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-

from . import models
19 changes: 19 additions & 0 deletions connector_magento_pricing/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2013 Camptocamp SA
# Copyright 2018 Akretion
{
'name': 'Connector Magento - Pricing',
'version': '10.0.1.0.0',
'category': 'Connector',
'depends': [
'connector_magento',
],
'author': "Camptocamp, Akretion, Odoo Community Association (OCA)",
'license': 'AGPL-3',
'website': 'http://www.odoo-magento-connector.com',
'data': [
'views/magento_model_view.xml',
],
'installable': True,
'application': False,
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-

from . import magento_model
from . import magento
from . import product
from . import sale
103 changes: 103 additions & 0 deletions connector_magento_pricing/models/magento.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
# Copyright 2013 Camptocamp SA
# Copyright 2018 Akretion

from odoo import fields, models, api
from odoo.tools.translate import _


class MagentoBackend(models.Model):
_inherit = 'magento.backend'

def get_pricelist_id(self):
data_obj = self.env['ir.model.data']
ref = data_obj.get_object_reference('product', 'list0')
if ref:
return ref[1]
return False

pricelist_id = fields.Many2one(
'product.pricelist',
'Pricelist',
required=True,
default=get_pricelist_id,
help='The price list used to define '
'the prices of the products in '
'Magento.')

@api.onchange('pricelist_id')
def onchange_pricelist_id(self):
if not self.id: # new record
return {}
warning = {
'title': _('Warning'),
'message': _('If you change the pricelist of the backend, '
'the price of all the products will be updated '
'in Magento.')
}
return {'warning': warning}

def _update_default_prices(self):
""" Update the default prices of the products linked with
this backend.

The default prices are linked with the 'Admin' website (id: 0).
"""
websites = self.env['magento.website'].search([
('backend_id', 'in'),
('external_id', '=', '0')])
websites._update_all_prices()

def write(self, vals):
if 'pricelist_id' in vals:
self._update_default_prices()
return super(MagentoBackend, self).write(vals)


class MagentoWebsite(models.Model):
_inherit = 'magento.website'

pricelist_id = fields.Many2one(
'product.pricelist',
'Pricelist',
help='The pricelist used to define '
'the prices of the products in '
'Magento for this website.\n'
'Choose a pricelist only if the '
'prices are different for this '
'website.\n'
'When empty, the default price '
'will be used.')

def _update_all_prices(self):
""" Update the prices of all the products linked to the
website. """
for website in self:
if website.external_id == '0':
# 'Admin' website -> default values
# Update the default prices on all the products.
binding_ids = website.backend_id.product_binding_ids
else:
binding_ids = website.product_binding_ids
for binding in binding_ids:
binding.with_delay().export_product_price(
website_id=website.id)
break
return True

@api.onchange('pricelist_id')
def onchange_pricelist_id(self):
if not self.id: # new record
return {}
warning = {
'title': _('Warning'),
'message': _('If you change the pricelist of the website, '
'the price of all the products linked with this '
'website will be updated in Magento.')
}
return {'warning': warning}

def write(self, vals):
if 'pricelist_id' in vals:
self._update_all_prices()
return super(MagentoWebsite, self).write(vals)
130 changes: 130 additions & 0 deletions connector_magento_pricing/models/product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# -*- coding: utf-8 -*-
# Copyright 2013 Camptocamp SA
# Copyright 2018 Akretion


from odoo import api, models
from odoo.tools.translate import _
from odoo.addons.queue_job.job import job, related_action
from odoo.addons.queue_job.exception import JobError
from odoo.addons.component.core import Component
from odoo.addons.component_event import skip_if
from odoo.addons.connector.components.mapper import mapping, only_create


# TODO: replace a price mapper only, not the full mapper
class ProductImportMapper(Component):
_inherit = 'magento.product.product.import.mapper'

@only_create
@mapping
def price(self, record):
""" The price is imported at the creation of
the product, then it is only modified and exported
from Odoo """
return super(ProductImportMapper, self).price(record)


class ProductPriceExporter(Component):
""" Export the price of a product.

Use the pricelist configured on the backend for the
default price in Magento.
If different pricelists have been configured on the websites,
update the prices on the different websites.
"""
_name = 'magento.product.price.exporter'
_inherit = 'base.exporter'
_usage = 'price.exporter'
_apply_on = 'magento.product.product'

def _get_price(self, pricelist_id):
""" Return the raw Odoo data for ``self.binding_id`` """
if pricelist_id is None:
# a False value will set the 'Use default value' in Magento
return False
return self.env[self._apply_on].with_context(
{'pricelist': pricelist_id}).browse(self.binding_id.id).price

def _update(self, data, storeview_id=None):
self.backend_adapter.write(self.binding_id.external_id, data,
storeview_id=storeview_id)

def _run(self, binding, website_id=None):
""" Export the product inventory to Magento

:param website_id: if None, export on all websites,
or Odoo ID for the website to update
"""
# export of products is not implemented so we just raise
# if the export was existing, we would export it
assert binding.external_id, "Record has been deleted in Magento"
pricelist = binding.backend_id.pricelist_id
if not pricelist:
name = binding.backend_id.name
raise JobError.IDMissingInBackend(
'Configuration Error:\n'
'No pricelist configured on the backend %s.\n\n'
'Resolution:\n'
'Go to Connectors > Backends > %s.\n'
'Choose a pricelist.' % (name, name))
pricelist_id = pricelist.id

# export the price for websites if they have a different
# pricelist
storeview_binder = self.binder_for('magento.storeview')
for website in binding.backend_id.website_ids:
if website_id is not None and website.id != website_id:
continue
# 0 is the admin website, the update on this website
# set the default values in Magento, we use the default
# pricelist
site_pricelist_id = None
if website.external_id == '0':
site_pricelist_id = pricelist_id
elif website.pricelist_id:
site_pricelist_id = website.pricelist_id.id

# The update of the prices in Magento is very weird:
# - The price is different per website (if the option
# is active in the config), but is shared between
# the store views of a website.
# - BUT the Magento API expects a storeview id to modify
# a price on a website (and not a website id...)
# So we take the first storeview of the website to update.
storeview_ids = self.env['magento.storeview'].search(
[('store_id.website_id.id', '=', website.id)]).ids
if not storeview_ids:
continue
magento_storeview = storeview_binder.to_internal(storeview_ids[0])
self.binding_id = binding
price = self._get_price(site_pricelist_id)
self._update({'price': price}, storeview_id=magento_storeview.id)
self.binder.bind(binding.external_id, binding.id)
return _('Prices have been updated.')


class MagentoProductProduct(models.Model):
_inherit = 'magento.product.product'

@job(default_channel='root.magento')
@related_action(action='related_action_unwrap_binding')
@api.multi
def export_product_price(self, website_id=None):
""" Export the price of a product. """
self.ensure_one()
with self.backend_id.work_on(self._name) as work:
price_exporter = work.component(usage='price.exporter')
return price_exporter._run(self, website_id=website_id)


class MagentoProductPriceListener(Component):
_name = 'product.product.listener'
_inherit = 'base.event.listener'
_apply_on = ['product.product']

@skip_if(lambda self, record, **kwargs: self.no_connector_export(record))
def on_product_price_changed(self, record):
""" When a product.product price has been changed """
for binding in record.magento_bind_ids:
binding.with_delay(priority=5).export_product_price()
23 changes: 23 additions & 0 deletions connector_magento_pricing/models/sale.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Copyright 2013 Camptocamp SA
# Copyright 2018 Akretion

from odoo.addons.component.core import Component
from odoo.addons.connector.components.mapper import mapping


class SaleOrderImportMapper(Component):
_inherit = 'magento.sale.order.mapper'

@mapping
def pricelist_id(self, record):
""" Assign to the sale order the price list used on
the Magento Website or Backend """
website_binder = self.binder_for('magento.website')
oe_website_id = website_binder.to_internal(record['website_id'])
website = self.session.browse('magento.website', oe_website_id)
if website.pricelist_id:
pricelist_id = website.pricelist_id.id
else:
pricelist_id = self.backend_record.pricelist_id.id
return {'pricelist_id': pricelist_id}
2 changes: 2 additions & 0 deletions connector_magento_pricing/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Guewen Baconnier <[email protected]>
Pierrick Brun <[email protected]>
8 changes: 8 additions & 0 deletions connector_magento_pricing/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Extension for **Connector Magento**.

The prices of the products are managed in Odoo using pricelists and
are pushed to Magento.

You can push all prices when modifying the pricelist on the backend.

Each time a price is modified in Odoo, the price is pushed to Magento.
Loading