/
account_move.py
149 lines (128 loc) · 5.91 KB
/
account_move.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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.'))