Skip to content

Commit

Permalink
Merge 342c78b into ae21fc8
Browse files Browse the repository at this point in the history
  • Loading branch information
JordiBForgeFlow committed Sep 5, 2016
2 parents ae21fc8 + 342c78b commit 5b71fdc
Show file tree
Hide file tree
Showing 27 changed files with 1,017 additions and 0 deletions.
105 changes: 105 additions & 0 deletions account_operating_unit/README.rst
@@ -0,0 +1,105 @@
.. image:: https://img.shields.io/badge/license-LGPLv3-blue.svg
:target: https://www.gnu.org/licenses/lgpl.html
:alt: License: LGPL-3

===============================
Accounting with Operating Units
===============================

This module introduces the following features:

* Adds the Operating Unit (OU) to the account move line.

* Defines if the Operating Units are self-balanced and Inter-Operating Unit
clearing account at company level.

* Journal entry with lines in different Operating Units are checked based on
the "self-balanced" set up in OU.

At the time of posting the journal entry, the corresponding lines in the
Inter-Operating Unit clearing account are automatically created, making
each OU self-balanced.

* The account financial reports include the option to filter by OU.

* Adds the Operating Unit (OU) to the invoice.

* Implements security rules in the invoice based on OU.

Installation
============

No specific installation requirements.

Configuration
=============

If your company is required to generate a balanced balance sheet by
Operating Unit you can specify at company level that Operating Units should
be self-balanced, and then indicate a self-balancing clearing account.

1. Create an account for "Inter-OU Clearing" of type Current assets.

2. Go to *Settings / Companies / Configuration* and Set the "Operating Units
are self-balanced" checkbox.

Then set the "Inter-OU Clearing" account in "Inter-Operating Unit
clearing account" field.

3. Assign Operating Unit in Accounts.


Usage
=====

* Add the Operating Unit to invoices.

* Add the Default Operating Unit to account move. Then all move lines will
by default adopt this Operating Unit.

* Add Operating Units to the move lines.

If they differ across lines of the same move, and the OU's are
self-balanced, then additional move lines will be created so as to make
the move self-balanced from OU perspective.

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

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.

Credits
=======

Images
------

* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.

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

* Eficent Business and IT Consulting Services S.L. <contact@eficent.com>
* Serpent Consulting Services Pvt. Ltd. <support@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.
9 changes: 9 additions & 0 deletions account_operating_unit/__init__.py
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# © 2016 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2016 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from . import models
from . import wizard
from . import report
30 changes: 30 additions & 0 deletions account_operating_unit/__openerp__.py
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# © 2016 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2016 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

{
"name": 'Accounting with Operating Units',
"summary": "Introduces Operating Unit fields in invoices and "
"Accounting Entries with clearing account",
"version": "9.0.1.0.0",
"author": "Eficent Business and IT Consulting Services S.L., "
"Serpent Consulting Services Pvt. Ltd.,"
"Odoo Community Association (OCA)",
"website": "http://www.eficent.com",
"category": "Accounting & Finance",
"depends": ['account', 'operating_unit'],
"license": "LGPL-3",
"data": [
"security/account_security.xml",
"views/account_move_view.xml",
"views/account_account_view.xml",
"views/company_view.xml",
"views/invoice_view.xml",
"views/account_invoice_report_view.xml",
"wizard/account_report_common_view.xml",
"wizard/account_financial_report_view.xml",
],
"installable": True,
}
9 changes: 9 additions & 0 deletions account_operating_unit/models/__init__.py
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# © 2016 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2016 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from . import company
from . import account_account
from . import account_move
from . import invoice
15 changes: 15 additions & 0 deletions account_operating_unit/models/account_account.py
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
# © 2016 Eficent Business and IT Consulting Services S.L. (www.eficent.com)
# - Jordi Ballester Alomar
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from openerp import fields, models


class AccountAccount(models.Model):
_inherit = "account.account"

operating_unit_id = fields.Many2one('operating.unit',
'Default Operating Unit',
default=lambda self:
self.env['res.users'].
operating_unit_default_get(self._uid))
149 changes: 149 additions & 0 deletions account_operating_unit/models/account_move.py
@@ -0,0 +1,149 @@
# -*- coding: utf-8 -*-
# © 2016 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2016 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from openerp.tools.translate import _
from openerp import api, fields, models
from openerp.exceptions import UserError


class AccountMoveLine(models.Model):
_inherit = "account.move.line"

operating_unit_id = fields.Many2one('operating.unit', 'Operating Unit',
default=lambda self:
self.env['res.users'].
operating_unit_default_get(self._uid))

@api.model
def create(self, vals):
if vals.get('move_id', False):
move = self.env['account.move'].browse(vals['move_id'])
if move.operating_unit_id:
vals['operating_unit_id'] = move.operating_unit_id.id
return super(AccountMoveLine, self).create(vals)

@api.model
def _query_get(self, domain=None):
if domain is None:
domain = []
if self._context.get('operating_unit_ids', False):
domain.append(('operating_unit_id', 'in',
self._context.get('operating_unit_ids')))
return super(AccountMoveLine, self)._query_get(domain)

@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 UserError(_('Configuration error!\nThe Company in the'
' Move Line and in the Operating Unit must '
'be the same.'))

@api.multi
@api.constrains('operating_unit_id', 'move_id')
def _check_move_operating_unit(self):
for rec in self:
if (rec.move_id and rec.move_id.operating_unit_id and
rec.operating_unit_id and rec.move_id.operating_unit_id !=
self.operating_unit_id):
raise UserError(_('Configuration error!\nThe Operating Unit in'
' the Move Line and in the Move must be the'
' same.'))


class AccountMove(models.Model):
_inherit = "account.move"

operating_unit_id = fields.Many2one('operating.unit',
'Default operating unit',
help="This operating unit will "
"be defaulted in the move lines.")

@api.multi
def _prepare_inter_ou_balancing_move_line(self, move, ou_id,
ou_balances):
if not move.company_id.inter_ou_clearing_account_id:
raise UserError(_('Error!\nYou need to define an inter-operating\
unit clearing account in the company settings'))

res = {
'name': 'OU-Balancing',
'move_id': move.id,
'journal_id': move.journal_id.id,
'date': move.date,
'operating_unit_id': ou_id,
'account_id': move.company_id.inter_ou_clearing_account_id.id
}

if ou_balances[ou_id] < 0.0:
res['debit'] = abs(ou_balances[ou_id])

else:
res['credit'] = ou_balances[ou_id]
return res

@api.multi
def _check_ou_balance(self, move):
# Look for the balance of each OU
ou_balance = {}
for line in move.line_ids:
if line.operating_unit_id.id not in ou_balance:
ou_balance[line.operating_unit_id.id] = 0.0
ou_balance[line.operating_unit_id.id] += (line.debit - line.credit)
return ou_balance

@api.multi
def post(self):
ml_obj = self.env['account.move.line']
for move in self:
if not move.company_id.ou_is_self_balanced:
continue

# If all move lines point to the same operating unit, there's no
# need to create a balancing move line
ou_list_ids = [line.operating_unit_id and
line.operating_unit_id.id for line in
move.line_ids if line.operating_unit_id]
if len(ou_list_ids) <= 1:
continue

# Create balancing entries for un-balanced OU's.
ou_balances = self._check_ou_balance(move)
amls = []
for ou_id in ou_balances.keys():
# If the OU is already balanced, then do not continue
if move.company_id.currency_id.is_zero(ou_balances[ou_id]):
continue
# Create a balancing move line in the operating unit
# clearing account
line_data = self._prepare_inter_ou_balancing_move_line(
move, ou_id, ou_balances)
if line_data:
amls.append(ml_obj.with_context(wip=True).
create(line_data))
if amls:
move.with_context(wip=False).\
write({'line_ids': [(4, aml.id) for aml in amls]})

return super(AccountMove, self).post()

def assert_balanced(self):
if self.env.context.get('wip'):
return True
return super(AccountMove, self).assert_balanced()

@api.multi
@api.constrains('line_ids')
def _check_ou(self):
for move in self:
if not move.company_id.ou_is_self_balanced:
continue
for line in move.line_ids:
if not line.operating_unit_id:
raise UserError(_('Configuration error!\nThe operating\
unit must be completed for each line if the operating\
unit has been defined as self-balanced at company level.'))
32 changes: 32 additions & 0 deletions account_operating_unit/models/company.py
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# © 2016 Eficent Business and IT Consulting Services S.L.
# - Jordi Ballester Alomar
# © 2016 Serpent Consulting Services Pvt. Ltd. - Sudhir Arya
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
from openerp import api, fields, models
from openerp.tools.translate import _
from openerp.exceptions import UserError


class ResCompany(models.Model):
_inherit = 'res.company'

inter_ou_clearing_account_id = fields.Many2one('account.account',
'Inter-operating unit\
clearing account')

ou_is_self_balanced = fields.Boolean('Operating Units are self-balanced',
help="Activate if your company is "
"required to generate a balanced"
" balance sheet for each "
"operating unit.",
default=False)

@api.multi
@api.constrains('ou_is_self_balanced')
def _inter_ou_clearing_acc_required(self):
for rec in self:
if rec.ou_is_self_balanced and not \
rec.inter_ou_clearing_account_id:
raise UserError(_('Configuration error!\nPlease indicate an\
Inter-operating unit clearing account.'))

0 comments on commit 5b71fdc

Please sign in to comment.