Skip to content

Commit

Permalink
[11.0][NEW] sale_order_secondary_unit: New module for sale in a secon…
Browse files Browse the repository at this point in the history
…dary product unit
  • Loading branch information
sergio-teruel committed Oct 10, 2018
1 parent 42c511b commit d7ac444
Show file tree
Hide file tree
Showing 14 changed files with 333 additions and 0 deletions.
1 change: 1 addition & 0 deletions oca_dependencies.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
server-tools
bank-payment
account-closing
product-attribute
86 changes: 86 additions & 0 deletions sale_order_secondary_unit/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
=========================
Sale Order Secondary Unit
=========================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! 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%2Fsale--workflow-lightgray.png?logo=github
:target: https://github.com/OCA/sale-workflow/tree/11.0/sale_order_secondary_unit
:alt: OCA/sale-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/sale-workflow-11-0/sale-workflow-11-0-sale_order_secondary_unit
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/167/11.0
:alt: Try me on Runbot

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

This module extends the functionality of sale orders to allow sale products in
secondary unit of distinct category.

**Table of contents**

.. contents::
:local:

Usage
=====

To use this module you need to:

#. Go to a *Product > General Information tab*.
#. Create any record in "Secondary unit of measure".
#. Set the conversion factor.
#. Go to *Sales > Quotation > Create*.
#. Change quantities in line and secondary unit (produc_qty will be change).

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/sale-workflow/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/sale-workflow/issues/new?body=module:%20sale_order_secondary_unit%0Aversion:%2011.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
~~~~~~~

* Tecnativa

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

* Carlos Dauden <carlos.dauden@tecnativa.com>
* Sergio Teruel <sergio.teruel@tecnativa.com>

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/sale-workflow <https://github.com/OCA/sale-workflow/tree/11.0/sale_order_secondary_unit>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions sale_order_secondary_unit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import models
22 changes: 22 additions & 0 deletions sale_order_secondary_unit/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2018 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
'name': 'Sale Order Secondary Unit',
'summary': 'Sale product in a secondary unit',
'version': '11.0.1.0.0',
'development_status': 'Beta',
'category': 'Sale',
'website': 'https://github.com/OCA/sale-workflow',
'author': 'Tecnativa, Odoo Community Association (OCA)',
'license': 'AGPL-3',
'application': False,
'installable': True,
'auto_install': True,
'depends': [
'sale',
'product_secondary_unit',
],
'data': [
'views/sale_order_views.xml',
],
}
33 changes: 33 additions & 0 deletions sale_order_secondary_unit/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * sale_order_secondary_unit
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 11.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-09-05 10:13+0000\n"
"PO-Revision-Date: 2018-09-05 12:16+0200\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.0.6\n"
"Last-Translator: \n"
"Language: es_ES\n"

#. module: sale_order_secondary_unit
#: model:ir.model,name:sale_order_secondary_unit.model_sale_order_line
msgid "Sales Order Line"
msgstr "Línea de pedido"

#. module: sale_order_secondary_unit
#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line_secondary_uom_qty
msgid "Secondary Qty"
msgstr "Cta. Ud. secundaria"

#. module: sale_order_secondary_unit
#: model:ir.model.fields,field_description:sale_order_secondary_unit.field_sale_order_line_secondary_uom_id
msgid "Secondary uom"
msgstr "Unidad Secundaria"
2 changes: 2 additions & 0 deletions sale_order_secondary_unit/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import sale_order
65 changes: 65 additions & 0 deletions sale_order_secondary_unit/models/sale_order.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright 2018 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.addons import decimal_precision as dp
from odoo.tools.float_utils import float_compare, float_round


class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'

secondary_uom_qty = fields.Float(
string='Secondary Qty',
digits=dp.get_precision('Product Unit of Measure'),
)
secondary_uom_id = fields.Many2one(
comodel_name='product.secondary.unit',
string='Secondary uom',
ondelete='restrict',
)

@api.onchange('secondary_uom_id', 'secondary_uom_qty')
def onchange_secondary_uom(self):
if not self.secondary_uom_id:
return
factor = self.secondary_uom_id.factor * self.product_uom.factor
qty = float_round(
self.secondary_uom_qty * factor,
precision_rounding=self.product_uom.rounding
)
if float_compare(
self.product_uom_qty, qty,
precision_rounding=self.product_uom.rounding) != 0:
self.product_uom_qty = qty

@api.onchange('product_uom_qty')
def onchange_secondary_unit_product_uom_qty(self):
if not self.secondary_uom_id:
return
factor = self.secondary_uom_id.factor * self.product_uom.factor
qty = float_round(
self.product_uom_qty / (factor or 1.0),
precision_rounding=self.secondary_uom_id.uom_id.rounding
)
if float_compare(
self.secondary_uom_qty, qty,
precision_rounding=self.secondary_uom_id.uom_id.rounding) != 0:
self.secondary_uom_qty = qty

@api.onchange('product_uom')
def onchange_product_uom_for_secondary(self):
if not self.secondary_uom_id:
return
factor = self.product_uom.factor * self.secondary_uom_id.factor
qty = float_round(
self.product_uom_qty / (factor or 1.0),
precision_rounding=self.product_uom.rounding
)
if float_compare(
self.secondary_uom_qty, qty,
precision_rounding=self.product_uom.rounding) != 0:
self.secondary_uom_qty = qty

@api.onchange('product_id')
def onchange_secondary_unit_product_id(self):
self.secondary_uom_id = self.product_id.sale_secondary_uom_id
2 changes: 2 additions & 0 deletions sale_order_secondary_unit/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Carlos Dauden <carlos.dauden@tecnativa.com>
* Sergio Teruel <sergio.teruel@tecnativa.com>
2 changes: 2 additions & 0 deletions sale_order_secondary_unit/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module extends the functionality of sale orders to allow sale products in
secondary unit of distinct category.
7 changes: 7 additions & 0 deletions sale_order_secondary_unit/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
To use this module you need to:

#. Go to a *Product > General Information tab*.
#. Create any record in "Secondary unit of measure".
#. Set the conversion factor.
#. Go to *Sales > Quotation > Create*.
#. Change quantities in line and secondary unit (produc_qty will be change).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions sale_order_secondary_unit/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import test_sale_order_secondary_unit
80 changes: 80 additions & 0 deletions sale_order_secondary_unit/tests/test_sale_order_secondary_unit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright 2018 Tecnativa - Carlos Dauden
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.tests import SavepointCase


class TestSaleOrderSecondaryUnit(SavepointCase):
at_install = False
post_install = True

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.product_uom_kg = cls.env.ref('product.product_uom_kgm')
cls.product_uom_gram = cls.env.ref('product.product_uom_gram')
cls.product_uom_unit = cls.env.ref('product.product_uom_unit')
cls.product = cls.env['product.product'].create({
'name': 'test',
'uom_id': cls.product_uom_kg.id,
'uom_po_id': cls.product_uom_kg.id,
'secondary_uom_ids': [
(0, 0, {
'name': 'unit-700',
'uom_id': cls.product_uom_unit.id,
'factor': 0.7,
})],
})
cls.secondary_unit = cls.env['product.secondary.unit'].search([
('product_tmpl_id', '=', cls.product.product_tmpl_id.id),
])
cls.product.sale_secondary_uom_id = cls.secondary_unit.id
cls.partner = cls.env['res.partner'].create({
'name': 'test - partner',
})
so = cls.env['sale.order'].new({
'partner_id': cls.partner.id,
'order_line': [(0, 0, {
'name': cls.product.name,
'product_id': cls.product.id,
'product_uom_qty': 1,
'product_uom': cls.product.uom_id.id,
'price_unit': 1000.00,
})],
'pricelist_id': cls.env.ref('product.list0').id,
})
so.onchange_partner_id()
cls.order = cls.env['sale.order'].create(
so._convert_to_write(so._cache))

def test_onchange_secondary_uom(self):
self.order.order_line.write({
'secondary_uom_id': self.secondary_unit.id,
'secondary_uom_qty': 5,
})
self.order.order_line.onchange_secondary_uom()
self.assertEqual(
self.order.order_line.product_uom_qty, 3.5)

def test_onchange_secondary_unit_product_uom_qty(self):
self.order.order_line.update({
'secondary_uom_id': self.secondary_unit.id,
'product_uom_qty': 3.5,
})
self.order.order_line.onchange_secondary_unit_product_uom_qty()
self.assertEqual(
self.order.order_line.secondary_uom_qty, 5.0)

def test_default_secondary_unit(self):
self.order.order_line.onchange_secondary_unit_product_id()
self.assertEqual(
self.order.order_line.secondary_uom_id, self.secondary_unit)

def test_onchange_order_product_uom(self):
self.order.order_line.update({
'secondary_uom_id': self.secondary_unit.id,
'product_uom': self.product_uom_gram.id,
'product_uom_qty': 3500.00,
})
self.order.order_line.onchange_product_uom_for_secondary()
self.assertEqual(
self.order.order_line.secondary_uom_qty, 5.0)
29 changes: 29 additions & 0 deletions sale_order_secondary_unit/views/sale_order_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Tecnativa - Carlos Dauden
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>

<record id="view_order_form" model="ir.ui.view">
<field name="name">Sale Order Secondary Unit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="groups_id" eval="[(4, ref('product.group_uom'))]"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='order_line']/form//field[@name='price_subtotal']" position="after">
<field name="secondary_uom_qty" class="oe_inline oe_no_button"
attrs="{'readonly': [('state', 'in', ('done', 'cancel'))]}"/>
<field name="secondary_uom_id" class="oe_inline"
attrs="{'readonly': [('state', 'in', ('done', 'cancel'))]}"/>
</xpath>
<xpath expr="//field[@name='order_line']/tree//field[@name='product_uom_qty']" position="before">
<field name="secondary_uom_qty"
attrs="{'readonly': [('parent.state', 'in', ('done', 'cancel'))]}"/>
<field name="secondary_uom_id"
domain="[('product_tmpl_id.product_variant_ids', 'in', [product_id])]"
options="{'no_create': True}"
attrs="{'readonly': [('parent.state', 'in', ('done', 'cancel'))]}"/>
</xpath>
</field>
</record>

</odoo>

2 comments on commit d7ac444

@moturi12
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dependency module "product_secondary_unit" is missing

@pedrobaeza
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's in another repository.

Please sign in to comment.