Skip to content

Commit

Permalink
Merge PR #151 into 12.0
Browse files Browse the repository at this point in the history
Signed-off-by aheficent
  • Loading branch information
OCA-git-bot committed Nov 26, 2019
2 parents 214398e + 5fa3099 commit 4ec7578
Show file tree
Hide file tree
Showing 21 changed files with 1,070 additions and 0 deletions.
89 changes: 89 additions & 0 deletions sale_operating_unit/README.rst
@@ -0,0 +1,89 @@
=======================
Operating Unit in Sales
=======================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! 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-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Foperating--unit-lightgray.png?logo=github
:target: https://github.com/OCA/operating-unit/tree/12.0/sale_operating_unit
:alt: OCA/operating-unit
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/operating-unit-12-0/operating-unit-12-0-sale_operating_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/213/12.0
:alt: Try me on Runbot

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

This module extends the Sales capabilities of Odoo and introduces the operating
unit to the Sales Order. Security rules are defined to ensure that users can
only display the Sales Orders in which they are allowed access to.

**Table of contents**

.. contents::
:local:

Usage
=====

Follow these steps:

#. Create a Sale Order.
#. The Operating Unit of the Sale Team is assigned to the Sale Order.

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

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

* Eficent
* Serpent Consulting Services Pvt. Ltd.

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

* Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Aaron Henriquez <aheficent@eficent.com>
* Lois Rilo <lois.rilo@eficent.com>
* Miquel Raich <miquel.raich@eficent.com>
* Sudhir Arya <sudhir.arya@serpentcs.com>
* Darshan Patel <darshan.patel.serpencs@gmail.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/operating-unit <https://github.com/OCA/operating-unit/tree/12.0/sale_operating_unit>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
5 changes: 5 additions & 0 deletions sale_operating_unit/__init__.py
@@ -0,0 +1,5 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from . import models
from . import report
from . import wizard
23 changes: 23 additions & 0 deletions sale_operating_unit/__manifest__.py
@@ -0,0 +1,23 @@
# © 2019 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2019 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
{
"name": "Operating Unit in Sales",
"version": "12.0.1.0.0",
"summary": "An operating unit (OU) is an organizational entity part of a "
"company",
"author": "Eficent, "
"Serpent Consulting Services Pvt. Ltd.,"
"Odoo Community Association (OCA)",
"license": "LGPL-3",
"website": "https://github.com/OCA/operating-unit",
"category": "Sales Management",
"depends": ["sale", "account_operating_unit", "sales_team_operating_unit"],
"data": [
"security/sale_security.xml",
"views/sale_view.xml",
"views/sale_report_view.xml",
],
'installable': True
}
4 changes: 4 additions & 0 deletions sale_operating_unit/models/__init__.py
@@ -0,0 +1,4 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from . import sale_order
from . import crm_team
24 changes: 24 additions & 0 deletions sale_operating_unit/models/crm_team.py
@@ -0,0 +1,24 @@
# © 2019 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2019 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo import _, api, models
from odoo.exceptions import ValidationError


class CrmTeam(models.Model):
_inherit = 'crm.team'

@api.multi
@api.constrains('operating_unit_id')
def _check_sales_order_operating_unit(self):
for rec in self:
orders = self.sudo().env['sale.order'].search(
[('team_id', '=', rec.id), ('operating_unit_id', '!=',
rec.operating_unit_id.id)])
if orders:
raise ValidationError(_('Configuration error. It is not '
'possible to change this '
'team. There are sale orders '
'referencing it in other operating '
'units'))
72 changes: 72 additions & 0 deletions sale_operating_unit/models/sale.py
@@ -0,0 +1,72 @@
# © 2019 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2019 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


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

@api.model
def _default_operating_unit(self):
team = self.env['crm.team']._get_default_team_id()
if team.operating_unit_id:
return team.operating_unit_id
return self.env.user.default_operating_unit_id

operating_unit_id = fields.Many2one(
comodel_name='operating.unit',
string='Operating Unit',
default=_default_operating_unit,
readonly=True,
states={'draft': [('readonly', False)],
'sent': [('readonly', False)]}
)

@api.onchange('team_id')
def onchange_team_id(self):
if self.team_id:
self.operating_unit_id = self.team_id.operating_unit_id

@api.onchange('operating_unit_id')
def onchange_operating_unit_id(self):
if self.team_id and self.team_id.operating_unit_id != \
self.operating_unit_id:
self.team_id = False

@api.multi
@api.constrains('team_id', 'operating_unit_id')
def _check_team_operating_unit(self):
for rec in self:
if (rec.team_id and
rec.team_id.operating_unit_id != rec.operating_unit_id):
raise ValidationError(_('Configuration error. The Operating '
'Unit of the sales team must match '
'with that of the quote/sales order'))

@api.multi
@api.constrains('operating_unit_id', 'company_id')
def _check_company_operating_unit(self):
for rec in self:
if (rec.company_id and rec.operating_unit_id and
rec.company_id != rec.operating_unit_id.company_id):
raise ValidationError(_('Configuration error. The Company in'
' the Sales Order and in the Operating'
' Unit must be the same.'))

@api.multi
def _prepare_invoice(self):
self.ensure_one()
invoice_vals = super(SaleOrder, self)._prepare_invoice()
invoice_vals['operating_unit_id'] = self.operating_unit_id.id
return invoice_vals


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

operating_unit_id = fields.Many2one(related='order_id.operating_unit_id',
string='Operating Unit',
readonly=True)
72 changes: 72 additions & 0 deletions sale_operating_unit/models/sale_order.py
@@ -0,0 +1,72 @@
# © 2019 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2019 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError


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

@api.model
def _default_operating_unit(self):
team = self.env['crm.team']._get_default_team_id()
if team.operating_unit_id:
return team.operating_unit_id
else:
return self.env.user.default_operating_unit_id

operating_unit_id = fields.Many2one(
comodel_name='operating.unit',
string='Operating Unit',
default=_default_operating_unit,
readonly=True,
states={'draft': [('readonly', False)],
'sent': [('readonly', False)]}
)

@api.onchange('team_id')
def onchange_team_id(self):
if self.team_id:
self.operating_unit_id = self.team_id.operating_unit_id

@api.onchange('operating_unit_id')
def onchange_operating_unit_id(self):
if self.team_id and self.team_id.operating_unit_id != \
self.operating_unit_id:
self.team_id = False

@api.multi
@api.constrains('team_id', 'operating_unit_id')
def _check_team_operating_unit(self):
for rec in self:
if (rec.team_id and
rec.team_id.operating_unit_id != rec.operating_unit_id):
raise ValidationError(_('Configuration error. The Operating '
'Unit of the sales team must match '
'with that of the quote/sales order.'))

@api.multi
@api.constrains('operating_unit_id', 'company_id')
def _check_company_operating_unit(self):
for rec in self:
if (rec.company_id and rec.operating_unit_id and
rec.company_id != rec.operating_unit_id.company_id):
raise ValidationError(_('Configuration error. The Company in '
'the Sales Order and in the Operating '
'Unit must be the same.'))

@api.multi
def _prepare_invoice(self):
self.ensure_one()
invoice_vals = super(SaleOrder, self)._prepare_invoice()
invoice_vals['operating_unit_id'] = self.operating_unit_id.id
return invoice_vals


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

operating_unit_id = fields.Many2one(related='order_id.operating_unit_id',
string='Operating Unit')
6 changes: 6 additions & 0 deletions sale_operating_unit/readme/CONTRIBUTORS.rst
@@ -0,0 +1,6 @@
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
* Aaron Henriquez <aheficent@eficent.com>
* Lois Rilo <lois.rilo@eficent.com>
* Miquel Raich <miquel.raich@eficent.com>
* Sudhir Arya <sudhir.arya@serpentcs.com>
* Darshan Patel <darshan.patel.serpencs@gmail.com>
3 changes: 3 additions & 0 deletions sale_operating_unit/readme/DESCRIPTION.rst
@@ -0,0 +1,3 @@
This module extends the Sales capabilities of Odoo and introduces the operating
unit to the Sales Order. Security rules are defined to ensure that users can
only display the Sales Orders in which they are allowed access to.
4 changes: 4 additions & 0 deletions sale_operating_unit/readme/USAGE.rst
@@ -0,0 +1,4 @@
Follow these steps:

#. Create a Sale Order.
#. The Operating Unit of the Sale Team is assigned to the Sale Order.
3 changes: 3 additions & 0 deletions sale_operating_unit/report/__init__.py
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from . import sale_report
20 changes: 20 additions & 0 deletions sale_operating_unit/report/sale_report.py
@@ -0,0 +1,20 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0).

from odoo import fields, models


class SaleReport(models.Model):

_inherit = "sale.report"

operating_unit_id = fields.Many2one('operating.unit', 'Operating Unit')

def _query(self, with_clause='', fields=False, # noqa
groupby='', from_clause=''):
if not fields:
fields = {}
fields['operating_unit_id'] = \
", s.operating_unit_id as operating_unit_id"
groupby += ', s.operating_unit_id'
return super(SaleReport, self)._query(with_clause, fields,
groupby, from_clause)
43 changes: 43 additions & 0 deletions sale_operating_unit/security/sale_security.xml
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 Eficent Business and IT Consulting Services S.L.
Serpent Consulting Services Pvt. Ltd.
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl-3.0) -->
<odoo>

<record id="ir_rule_sale_order_allowed_operating_units"
model="ir.rule">
<field name="model_id" ref="sale.model_sale_order"/>
<field name="domain_force">['|',('operating_unit_id','=',False),('operating_unit_id','in', user.operating_unit_ids.ids)]</field>
<field name="name">Sales Orders from allowed operating units</field>
<field name="global" eval="True"/>
<field eval="0" name="perm_unlink"/>
<field eval="0" name="perm_write"/>
<field eval="1" name="perm_read"/>
<field eval="0" name="perm_create"/>
</record>

<record id="ir_rule_sale_order_line_allowed_operating_units"
model="ir.rule">
<field name="model_id" ref="sale.model_sale_order_line"/>
<field name="domain_force">['|',('operating_unit_id','=',False),('operating_unit_id','in', user.operating_unit_ids.ids)]</field>
<field name="name">Sales Order lines from allowed operating units</field>
<field name="global" eval="True"/>
<field eval="0" name="perm_unlink"/>
<field eval="0" name="perm_write"/>
<field eval="1" name="perm_read"/>
<field eval="0" name="perm_create"/>
</record>

<record id="ir_rule_sale_report_allowed_operating_units"
model="ir.rule">
<field name="model_id" ref="sale.model_sale_report"/>
<field name="domain_force">['|',('operating_unit_id','=',False),('operating_unit_id','in', user.operating_unit_ids.ids)]</field>
<field name="name">Sales Report from allowed operating units</field>
<field name="global" eval="True"/>
<field eval="0" name="perm_unlink"/>
<field eval="0" name="perm_write"/>
<field eval="1" name="perm_read"/>
<field eval="0" name="perm_create"/>
</record>

</odoo>
Binary file added sale_operating_unit/static/description/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4ec7578

Please sign in to comment.