1
# -*- encoding: utf-8 -*-
3
###########################################################################
4
# Module Writen to OpenERP, Open Source Management Solution
5
# Copyright (C) OpenERP Venezuela (<http://openerp.com.ve>).
7
# Credits######################################################
8
# Coded by: Katherine Zaoral <katherine.zaoral@vauxoo.com>
9
# Coded by: Yanina Aular <yanina.aular@vauxoo.com>
10
# Planified by: Humberto Arocha <hbto@vauxoo.com>
11
# Audited by: Nhomar Hernandez <nhomar@vauxoo.com>
12
#############################################################################
13
# This program is free software: you can redistribute it and/or modify
14
# it under the terms of the GNU Affero General Public License as published by
15
# the Free Software Foundation, either version 3 of the License, or
16
# (at your option) any later version.
18
# This program is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
# GNU Affero General Public License for more details.
23
# You should have received a copy of the GNU Affero General Public License
24
# along with this program. If not, see <http://www.gnu.org/licenses/>.
25
##########################################################################
28
from osv import fields
29
from tools.translate import _
33
class ifrs_ifrs(osv.osv):
38
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
39
context = context or {}
40
context['company_id'] = company_id
46
cur_id = self.pool.get('res.company').browse(
47
cr, uid, company_id, context=context).currency_id.id
48
fy_id = self.pool.get('account.fiscalyear').find(
49
cr, uid, context=context)
51
res['value'].update({'fiscalyear_id': fy_id})
52
res['value'].update({'currency_id': cur_id})
56
'name': fields.char('Name', 128, required=True, help='Report name'),
57
'company_id': fields.many2one('res.company', string='Company', ondelete='cascade', help='Company name'),
58
'currency_id': fields.related('company_id', 'currency_id', type='many2one', relation='res.currency', string='Company Currency', help="Currency at which this report will be expressed. If not selected will be used the one set in the company"),
59
'title': fields.char('Title', 128, required=True, translate=True, help='Report title that will be printed'),
60
'code': fields.char('Code', 128, required=True, help='Report code'),
61
'description': fields.text('Description'),
62
'ifrs_lines_ids': fields.one2many('ifrs.lines', 'ifrs_id', 'IFRS lines'),
63
'state': fields.selection([
67
('cancel', 'Cancel')],
68
'State', required=True),
69
'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', help='Fiscal Year'),
70
'help': fields.boolean('Show Help', help='Allows you to show the help in the form'),
71
'ifrs_ids': fields.many2many('ifrs.ifrs', 'ifrs_m2m_rel', 'parent_id', 'child_id', string='Other Reportes',)
77
'company_id': lambda s, c, u, cx: s.pool.get('res.users').browse(
78
c, u, u, context=cx).company_id.id,
79
'fiscalyear_id': lambda s, c, u, cx: \
80
s.pool.get('account.fiscalyear').find(c, u,exception=False),
83
def _get_level(self, cr, uid, l, level, tree, context=None):
84
""" Calcula los niveles de los ifrs.lines, tomando en cuenta que sera
85
un mismo arbol para los campos total_ids y operand_ids.
86
@param l: objeto a un ifrs.lines
87
@param level: Nivel actual de la recursion
88
@param tree: Arbol de dependencias entre lineas construyendose
90
context = context or {}
91
if not tree.get(level):
93
# The search through level should be backwards from the deepest level to
100
xlevel = isinstance(tree[n].get(l.id), (set)) and n or xlevel
102
tree[level][l.id] = set()
104
tree[level][l.id] = tree[xlevel][l.id]
105
del tree[xlevel][l.id]
106
else: # xlevel >= level
108
for j in set(l.total_ids + l.operand_ids):
109
tree[level][l.id].add(j.id)
110
self._get_level(cr, uid, j, level+1, tree, context=context)
113
def _get_ordered_lines(self, cr, uid, ids, context=None):
114
""" Return list of browse ifrs_lines per level in order ASC, for can
115
calculate in order of depending.
117
Retorna la lista de ifrs.lines del ifrs_id organizados desde el nivel
118
mas bajo hasta el mas alto. Lo niveles mas bajos se deben calcular
119
primero, por eso se posicionan en primer lugar de la lista.
121
context = context or {}
122
ids = isinstance(ids, (int, long)) and [ids] or ids
123
ifrs_brw = self.browse(cr, uid, ids[0], context=context)
126
for l in ifrs_brw.ifrs_lines_ids:
127
self._get_level(cr, uid, l, level, tree, context=context)
131
ids_o = [i.id for i in ifrs_brw.ifrs_lines_ids]
132
ids_x = [] # List of ids per level in order ASC
134
ids_x += tree[i].keys()
135
ifrs_lines = self.pool.get('ifrs.lines')
137
res = ifrs_lines.browse(
138
cr, uid, ids_x, context=context) # List of browse per level in order ASC
141
def compute(self, cr, uid, ids, context=None):
142
""" Se encarga de calcular los montos para visualizarlos desde
143
el formulario del ifrs, hace una llamada al get_report_data, el
144
cual se encarga de realizar los calculos.
146
context = context or {}
147
ids = isinstance(ids, (int, long)) and [ids] or ids
148
fy = self.browse(cr, uid, ids, context=context)[0]
149
context.update({'whole_fy': True, 'fiscalyear': fy.fiscalyear_id.id})
150
ifrs_lines = self.pool.get('ifrs.lines')
151
self.get_report_data(cr, uid, ids, is_compute=True, context=context)
154
def _get_periods_name_list(self, cr, uid, ids, fiscalyear_id, context=None):
155
""" Devuelve una lista con la info de los periodos fiscales
156
(numero mes, id periodo, nombre periodo)
157
@param fiscalyear_id: Año fiscal escogido desde el wizard encargada
158
de preparar el reporte para imprimir
164
period_list.append(('0', None, ' '))
166
fiscalyear_bwr = self.pool.get('account.fiscalyear').browse(
167
cr, uid, fiscalyear_id, context=context)
169
periods_ids = fiscalyear_bwr._get_fy_period_ids()
171
periods = self.pool.get('account.period')
173
for ii, period_id in enumerate(periods_ids, start=1):
174
period_list.append((str(ii), period_id, periods.browse(
175
cr, uid, period_id, context=context).name))
179
def _get_period_print_info(self, cr, uid, ids, period_id, report_type, context=None):
180
""" Return all the printable information about period
181
@param period_id: Dependiendo del report_type, en el caso que sea 'per',
182
este campo indica el periodo a tomar en cuenta, en caso de que el
183
report_type sea 'all', es Falso.
184
@param report_type: Su valor se establece desde el wizard que se encarga
185
de preparar al reporte para imprimir, el report_type puede ser 'all' (incluir
186
todo el año fiscal en el reporte) o 'per' (tomar en cuenta solo un periodo
187
determinado en el reporte)
191
if report_type == 'all':
192
res = _('ALL PERIODS OF THE FISCALYEAR')
194
period = self.pool.get('account.period').browse(
195
cr, uid, period_id, context=context)
196
res = str(period.name) + ' [' + str(period.code) + ']'
199
def step_sibling(self, cr, uid, old_id, new_id, context=None):
201
Sometimes total_ids and operand_ids include lines from their own
202
ifrs_id report, They are siblings. In this case m2m copy_data just make
203
a link from the old report.
204
In the new report we have to substitute the cousins that are pretending
205
to be siblings with the siblings
206
This can be achieved due to the fact that each line has unique sequence
207
within each report, using the analogy about relatives then each
208
pretending cousin is of same age than that of the actual sibling
209
cousins with common parent are siblings among them
211
context = context or {}
213
old_brw = self.browse(cr, uid, old_id, context=context)
214
new_brw = self.browse(cr, uid, new_id, context=context)
215
il_obj = self.pool.get('ifrs.lines')
220
for l in old_brw.ifrs_lines_ids:
221
for t in l.total_ids:
222
if t.ifrs_id.id == l.ifrs_id.id:
223
sibling_ids[t.sequence]= t.id
224
markt.append(l.sequence)
225
for o in l.operand_ids:
226
if o.ifrs_id.id == l.ifrs_id.id:
227
sibling_ids[o.sequence]= o.id
228
marko.append(l.sequence)
230
if not sibling_ids: return True
232
markt = markt and set(markt) or []
233
marko = marko and set(marko) or []
236
for seq in sibling_ids:
237
ns_id = il_obj.search(cr,uid,[ ('sequence','=',seq),
238
('ifrs_id','=',new_id) ],context=context)
239
o2n[sibling_ids[seq]] = ns_id[0]
241
for nl in new_brw.ifrs_lines_ids:
242
if nl.sequence in markt:
243
tt = [o2n.get(nt.id,nt.id) for nt in nl.total_ids]
244
nl.write({'total_ids':[(6,0,tt)]})
245
if nl.sequence in marko:
246
oo = [o2n.get(no.id,no.id) for no in nl.operand_ids]
247
nl.write({'operand_ids':[(6,0,oo)]})
251
def copy_data(self, cr, uid, id, default=None, context=None):
252
res = super(ifrs_ifrs, self).copy_data(cr, uid, id, default, context)
253
if res['ifrs_lines_ids'] and context.get('clear_cons_ids', False):
254
for l in res['ifrs_lines_ids']:
255
l[2]['cons_ids'] = l[2]['type']=='detail' and l[2]['cons_ids']\
259
def copy(self, cr, uid, id, default=None, context=None):
260
context = context or {}
261
default = default or {}
262
ru_brw = self.pool.get('res.users').browse(cr, uid, uid, context=context)
263
ii_brw = self.pool.get('ifrs.ifrs').browse(cr, uid, id, context=context)
264
if ru_brw.company_id.id != ii_brw.company_id.id:
265
context['clear_cons_ids']=True
266
default['company_id'] = ru_brw.company_id.id
267
default['fiscalyear_id'] = self.pool.get('account.fiscalyear').find(
268
cr, uid, exception=False, context=context)
269
res = super(ifrs_ifrs, self).copy(cr, uid, id, default, context)
270
self.step_sibling(cr, uid, id, res, context=context)
273
def _get_children_and_consol(self, cr, uid, ids, level, context={}):
274
""" Retorna todas las cuentas relacionadas con las cuentas ids
275
recursivamente, incluyendolos
277
aa_obj = self.pool.get('account.account')
279
for aa_brw in aa_obj.browse(cr, uid, ids, context):
280
if not aa_brw.child_id and aa_brw.level < level and aa_brw.type not in ('consolidation','view'):
281
ids2.append(aa_brw.id)
283
ids2.append(aa_brw.id)
284
ids2 += self._get_children_and_consol(cr, uid, [x.id for x in aa_brw.child_id], level, context=context)
285
return list(set(ids2))
287
def get_num_month(self, cr, uid, id, fiscalyear, period, context=None):
288
accountfy_obj = self.pool.get('account.fiscalyear')
289
return accountfy_obj._get_fy_month(cr, uid, fiscalyear, period, special=False, context=context)
293
self, cr, uid, ids, fiscalyear=None, exchange_date=None,
294
currency_wizard=None, target_move=None, period=None, two=None, is_compute=None, context=None):
295
""" Metodo que se encarga de retornar un diccionario con los montos
296
totales por periodo de cada linea, o la sumatoria de todos montos
297
por periodo de cada linea. La información del diccionario se utilizara
298
para llenar el reporte, ya sea de dos columnas o de 12 columnas.
299
@param fiscalyear: Año fiscal que se reflejara en el reporte
300
@param exchange_date:
301
@param currency_wizard: Moneda que se reflejara en el reporte
302
@param target_move: Asientos contables a tomar en cuenta en los calculos
303
@param period: Periodo a reflejar en caso de que no se tome en cuenta todo el año fiscal
304
@param two: Nos dice si el reporte es de 2 o 12 columnas
311
ifrs_line = self.pool.get('ifrs.lines')
313
if is_compute is None:
314
period_name = self._get_periods_name_list(
315
cr, uid, ids, fiscalyear, context=context)
317
ordered_lines = self._get_ordered_lines(cr, uid, ids, context=context)
319
if is_compute: # Si es llamado desde el metodo compute, solo se actualizaran los montos y no se creara el diccionario
320
for ifrs_l in ordered_lines:
321
ifrs_line._get_amount_with_operands(cr, uid,
322
ids, ifrs_l, is_compute=True, context=context)
325
for ifrs_l in ordered_lines:
326
amount_value = ifrs_line._get_amount_with_operands(cr, uid,
327
ids, ifrs_l, period_name, fiscalyear, exchange_date,
328
currency_wizard, period, target_move, two=two,
331
line = {'sequence': int(ifrs_l.sequence), 'id': ifrs_l.id, 'name': ifrs_l.name, 'invisible': ifrs_l.invisible, 'type': str(
332
ifrs_l.type), 'amount': amount_value,'comparison':ifrs_l.comparison,'operator':ifrs_l.operator}
334
if ifrs_l.ifrs_id.id == ids[0]: # Se toman las lineas del ifrs actual, ya que en los calculos se incluyen lineas de otros ifrs
336
data.sort(key=lambda x: int(x['sequence']))
339
for ifrs_l in ordered_lines:
341
'sequence': int(ifrs_l.sequence), 'id': ifrs_l.id, 'name': ifrs_l.name,
342
'invisible': ifrs_l.invisible, 'type': ifrs_l.type,
343
'period': {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0},
344
'comparison':ifrs_l.comparison,'operator':ifrs_l.operator}
345
for lins in range(1, 13):
346
amount_value = ifrs_line._get_amount_with_operands(
348
ids, ifrs_l, period_name, fiscalyear, exchange_date,
349
currency_wizard, lins, target_move,
351
line['period'][lins] = amount_value
353
if ifrs_l.ifrs_id.id == ids[0]:
354
# Se toman las lineas del ifrs actual, ya que en los
355
# calculos se incluyen lineas de otros ifrs
357
data.sort(key=lambda x: int(x['sequence']))
359
for i in xrange(1, 13):
360
cr.execute("update ifrs_lines set period_" + str(i) +"= 0.0;" )
364
class ifrs_lines(osv.osv):
368
_order = 'ifrs_id, sequence'
370
def _get_sum_operator(self, cr, uid, brw, number_month=None, is_compute=None, context=None):
371
""" Calculates the sum of the line operand_ids the current ifrs.line
372
@param number_month: periodo a calcular
373
@param is_compute: si el metodo actualizara el campo amount para la vista
379
# If the report is two or twelve columns, will choose the field needed
382
field_name = 'amount'
384
if context.get('whole_fy', False):
387
field_name = 'period_%s' % str(number_month)
389
# It takes the sum of the operands
390
for t in brw.operand_ids:
391
res += getattr(t, field_name)
394
def _get_sum_total(self, cr, uid, brw, number_month=None, is_compute=None, context=None):
395
""" Calculates the sum of the line total_ids the current ifrs.line
396
@param number_month: periodo a calcular
397
@param is_compute: si el metodo actualizara el campo amount para la vista
403
# If the report is two or twelve columns, will choose the field needed
406
field_name = 'amount'
408
if context.get('whole_fy', False):
411
field_name = 'period_%s' % str(number_month)
413
# It takes the sum of the total_ids
414
for t in brw.total_ids:
415
res += getattr(t, field_name)
418
def _get_sum_detail(self, cr, uid, id=None, number_month=None, is_compute=None, context=None):
419
""" Calculates the amount sum of the line type == 'detail'
420
@param number_month: periodo a calcular
421
@param is_compute: si el metodo actualizara el campo amount para la vista
423
fy_obj = self.pool.get('account.fiscalyear')
424
period_obj = self.pool.get('account.period')
425
context = context or {}
429
if not cx.get('fiscalyear'):
430
cx['fiscalyear'] = fy_obj.find(cr, uid)
432
fy_id = cx['fiscalyear']
434
brw = self.browse(cr, uid, id)
436
if brw.acc_val == 'init':
437
if cx.get('whole_fy',False):
438
cx['periods'] = period_obj.search(cr, uid, [
439
('fiscalyear_id','=',fy_id),('special','=',True)])
441
period_from = period_obj.search(cr, uid, [
442
('fiscalyear_id','=',fy_id),('special','=',True)])
443
# Case when the period_from is the first non-special period
445
if period_obj.browse(cr, uid, cx['period_from']).date_start ==\
446
fy_obj.browse(cr, uid, fy_id).date_start:
447
cx['period_to'] = period_from[0]
449
cx['period_to'] = period_obj.previous(
450
cr, uid, cx['period_from'])
451
cx['period_from'] = period_from[0]
452
elif brw.acc_val == 'var':
453
#it is going to be the one sent by the previous cx
454
if cx.get('whole_fy',False):
455
cx['periods'] = period_obj.search(cr, uid, [
456
('fiscalyear_id','=',fy_id),('special','=',False)])
458
#it is going to be from the fiscalyear's beginning
459
if cx.get('whole_fy',False):
460
cx['periods'] = period_obj.search(cr, uid, [
461
('fiscalyear_id','=',fy_id)])
463
period_from = period_obj.search(cr, uid, [
464
('fiscalyear_id','=',fy_id),('special','=',True)])
465
cx['period_from'] = period_from[0]
466
cx['periods'] = period_obj.build_ctx_periods(cr, uid,
467
cx['period_from'], cx['period_to'])
469
brw = self.browse(cr, uid, id, context=cx)
471
if brw.type == 'detail':
472
# Si es de tipo detail
473
analytic = [an.id for an in brw.analytic_ids]
474
# Tomo los ids de las cuentas analiticas de las lineas
476
# Si habian cuentas analiticas en la linea, se guardan en el
477
# context y se usan en algun metodo dentro del modulo de
479
cx['analytic'] = analytic
480
cx['partner_detail'] = cx.get('partner_detail')
482
for aa in brw.cons_ids:
483
# Se hace la sumatoria de la columna balance, credito o debito.
484
# Dependiendo de lo que se escoja en el wizard
485
if brw.value == 'debit':
487
elif brw.value == 'credit':
493
def _get_grand_total(self, cr, uid, id=None, number_month=None, is_compute=None, context=None):
494
""" Calculates the amount sum of the line type == 'total'
495
@param number_month: periodo a calcular
496
@param is_compute: si el metodo actualizara el campo amount para la vista
498
fy_obj = self.pool.get('account.fiscalyear')
499
context = context or {}
503
if not cx.get('fiscalyear'):
504
cx['fiscalyear'] = fy_obj.find(cr, uid)
506
fy_id = cx['fiscalyear']
508
brw = self.browse(cr, uid, id)
509
res = self._get_sum_total( cr, uid, brw, number_month, is_compute,
512
if brw.operator in ('subtract','percent','ratio','product'):
513
so = self._get_sum_operator( cr, uid, brw, number_month,
514
is_compute, context=cx)
515
if brw.operator == 'subtract':
517
elif brw.operator == 'percent':
518
res = so != 0 and (100 * res / so) or 0.0
519
elif brw.operator == 'ratio':
520
res = so != 0 and (res / so) or 0.0
521
elif brw.operator == 'product':
525
def _get_constant(self, cr, uid, id=None, number_month=None, is_compute=None, context=None):
526
""" Calculates the amount sum of the line of constant
527
@param number_month: periodo a calcular
528
@param is_compute: si el metodo actualizara el campo amount para la vista
531
brw = self.browse(cr, uid, id, context=cx)
532
fy_obj = self.pool.get('account.fiscalyear')
533
period_obj = self.pool.get('account.period')
535
if not cx.get('fiscalyear'):
536
cx['fiscalyear'] = fy_obj.find(cr, uid, dt=None, context=cx)
538
if not cx.get('period_from', False) and not cx.get('period_to', False):
539
if context.get('whole_fy', False):
540
cx['period_from'] = period_obj.search(cr, uid, [(
541
'fiscalyear_id', '=', cx['fiscalyear']), ('special', '=', True)])
542
if not cx['period_from']:
543
raise osv.except_osv(_('Error !'), _('There are no special period in %s') % (
544
fy_obj.browse(cr, uid, cx['fiscalyear'], context=cx).name))
545
cx['period_from'] = cx['period_from'][0]
546
cx['period_to'] = period_obj.search(cr, uid, [
547
('fiscalyear_id', '=', cx['fiscalyear'])])[-1]
549
if brw.constant_type == 'period_days':
550
res = period_obj._get_period_days(
551
cr, uid, cx['period_from'], cx['period_to'])
552
elif brw.constant_type == 'fy_periods':
553
res = fy_obj._get_fy_periods(cr, uid, cx['fiscalyear'])
554
elif brw.constant_type == 'fy_month':
555
res = fy_obj._get_fy_month(cr, uid, cx[
556
'fiscalyear'], cx['period_to'])
557
elif brw.constant_type == 'number_customer':
558
res = self._get_number_customer_portfolio(cr, uid, id, cx[
559
'fiscalyear'], cx['period_to'], cx)
562
def _get_level(self, cr, uid, ids, field_name, arg, context=None):
564
for ifrs_line in self.browse(cr, uid, ids, context=context):
566
parent = ifrs_line.parent_id
569
parent = parent.parent_id
570
res[ifrs_line.id] = level
573
def _get_children_and_total(self, cr, uid, ids, context=None):
574
"""this function search for all the children and all consolidated children (recursively) of the given total ids
578
sql = 'select * from ifrs_lines_rel where parent_id in (' + ','.join(
581
childs = cr.fetchall()
584
self.write(cr, uid, rec[1], {'parent_id': rec[0]})
585
rec = self.browse(cr, uid, rec[1], context=context)
586
for child in rec.total_ids:
587
ids3.append(child.id)
589
ids3 = self._get_children_and_total(cr, uid, ids3, context=context)
593
def exchange(self, cr, uid, ids, from_amount, to_currency_id, from_currency_id, exchange_date, context=None):
596
if from_currency_id == to_currency_id:
598
curr_obj = self.pool.get('res.currency')
599
context['date'] = exchange_date
600
return curr_obj.compute(cr, uid, from_currency_id, to_currency_id, from_amount, context=context)
602
def _get_amount_value(self, cr, uid, ids, ifrs_line=None, period_info=None, fiscalyear=None, exchange_date=None, currency_wizard=None, number_month=None, target_move=None, pd=None, undefined=None, two=None, is_compute=None, context=None):
605
""" Returns the amount corresponding to the period of fiscal year
606
@param ifrs_line: linea a calcular monto
607
@param period_info: informacion de los periodos del fiscal year
608
@param fiscalyear: selected fiscal year
609
@param exchange_date: date of change currency
610
@param currency_wizard: currency in the report
611
@param number_month: period number
612
@param target_move: target move to consider
613
@param is_compute: si el metodo actualizara el campo amount para la vista
616
from_currency_id = ifrs_line.ifrs_id.company_id.currency_id.id
617
to_currency_id = currency_wizard
619
ifrs_line = self.browse(cr, uid, ifrs_line.id)
624
'period_from': number_month, 'period_to': number_month}
626
period_id = period_info[number_month][1]
627
context = {'period_from': period_id, 'period_to': period_id}
629
context = {'whole_fy': 'True'}
631
context['partner_detail'] = pd
632
context['fiscalyear'] = fiscalyear
633
context['state'] = target_move
635
if ifrs_line.type == 'detail':
636
res = self._get_sum_detail( cr, uid, ifrs_line.id, number_month,
637
is_compute, context=context)
638
elif ifrs_line.type == 'total':
639
res = self._get_grand_total( cr, uid, ifrs_line.id, number_month,
640
is_compute, context=context)
641
elif ifrs_line.type == 'constant':
642
res = self._get_constant( cr, uid, ifrs_line.id, number_month,
643
is_compute, context=context)
647
if ifrs_line.type == 'detail':
649
cr, uid, ids, res, to_currency_id, from_currency_id, exchange_date, context=context)
650
# Total amounts come from details so if the details are already
651
# converted into the regarding currency then it is not useful to do at
653
#elif ifrs_line.type == 'total':
654
# if ifrs_line.operator not in ('percent', 'ratio'):
655
# if ifrs_line.comparison not in ('percent', 'ratio', 'product'):
656
# res = self.exchange(
657
# cr, uid, ids, res, to_currency_id, from_currency_id, exchange_date, context=context)
660
def _get_amount_with_operands(self, cr, uid, ids, ifrs_line, period_info=None, fiscalyear=None, exchange_date=None, currency_wizard=None, number_month=None, target_move=None, pd=None, undefined=None, two=None, is_compute=None, context=None):
663
""" Integrate operand_ids field in the calculation of the amounts for each line
664
@param ifrs_line: linea a calcular monto
665
@param period_info: informacion de los periodos del fiscal year
666
@param fiscalyear: selected fiscal year
667
@param exchange_date: date of change currency
668
@param currency_wizard: currency in the report
669
@param number_month: period number
670
@param target_move: target move to consider
671
@param is_compute: si el metodo actualizara el campo amount para la vista
674
ifrs_line = self.browse(cr, uid, ifrs_line.id)
676
context = {'whole_fy': 'True'}
679
field_name = 'amount'
681
if context.get('whole_fy', False):
684
field_name = 'period_%s' % str(number_month)
686
res = self._get_amount_value(
687
cr, uid, ids, ifrs_line, period_info, fiscalyear, exchange_date,
688
currency_wizard, number_month, target_move, pd, undefined, two, is_compute, context=context)
690
res = ifrs_line.inv_sign and (-1.0 * res) or res
691
self.write(cr, uid, ifrs_line.id, {field_name: res})
695
def _get_partner_detail(self, cr, uid, ids, ifrs_l, context=None):
696
ifrs = self.pool.get('ifrs.lines')
697
aml_obj = self.pool.get('account.move.line')
698
account_obj = self.pool.get('account.account')
699
partner_obj = self.pool.get('res.partner')
701
if ifrs_l.type == 'detail':
702
ids2 = [lin.id for lin in ifrs_l.cons_ids]
703
ids3 = ids2 and account_obj._get_children_and_consol(
704
cr, uid, ids2, context=context) or []
706
cr.execute(""" SELECT rp.id
707
FROM account_move_line l JOIN res_partner rp ON rp.id = l.partner_id
708
WHERE l.account_id IN %s
710
ORDER BY rp.name ASC""", ( tuple(ids3), )
712
dat = cr.dictfetchall()
713
res = [lins for lins in partner_obj.browse(cr, uid, [
714
li['id'] for li in dat], context=context)]
716
def _get_number_customer_portfolio(self, cr, uid, ids, fy, period,
718
ifrs_brw = self.browse(cr, uid, ids, context=context)
719
company_id = ifrs_brw.ifrs_id.company_id.id
720
if context.get('whole_fy', False):
721
period_fy = [('period_id.fiscalyear_id', '=', fy),
722
('period_id.special', '=', False)]
724
period_fy = [('period_id', '=', period)]
725
invoice_obj = self.pool.get('account.invoice')
726
invoice_ids = invoice_obj.search(cr, uid, [
727
('type', '=', 'out_invoice'),
728
('state', 'in', ('open', 'paid',)),
729
('company_id', '=', company_id)] + period_fy)
730
partner_number = set([inv.partner_id.id for inv\
731
in invoice_obj.browse(cr, uid, invoice_ids, context=context)])
732
return len(list(partner_number))
734
def onchange_sequence(self, cr, uid, ids, sequence, context=None):
735
context = context or {}
736
return {'value' : {'priority' : sequence}}
738
def _get_default_sequence(self, cr, uid, context=None):
741
if ctx.get('ifrs_id'):
742
ifrs_lines_ids = self.search(cr, uid ,
743
[('ifrs_id','=',ctx['ifrs_id'])])
745
res = max([line['sequence'] for line in self.read(cr,
746
uid, ifrs_lines_ids, ['sequence'])])
750
'help': fields.related('ifrs_id','help', string='Show Help',type='boolean',help='Allows you to show the help in the form'),
751
# Really!!! A repeated field with same functionality! This was done due
752
# to the fact that web view everytime that sees sequence tries to allow
753
# you to change the values and this feature here is undesirable.
754
'priority': fields.related('sequence', string='Sequence', type='integer', store=True, help='Indicates the order of the line in the report. The sequence must be unique and unrepeatable'),
755
'sequence': fields.integer('Sequence', required=True, help='Indicates the order of the line in the report. The sequence must be unique and unrepeatable'),
756
'name': fields.char('Name', 128, required=True, translate=True, help='Line name in the report. This name can be translatable, if there are multiple languages loaded it can be translated'),
757
'type': fields.selection(
759
('abstract', 'Abstract'),
760
('detail', 'Detail'),
761
('constant', 'Constant'),
765
help='Line type of report:'
766
" -Abstract(A),-Detail(D),-Constant(C),-Total(T)"),
767
'constant_type': fields.selection(
769
('period_days', 'Days of Period'),
770
('fy_periods', "FY's Periods"),
771
('fy_month', "FY's Month"),
772
('number_customer', "Number of customers* in portfolio")
774
string='Constant Type',
776
help='Constant Type'),
777
'ifrs_id': fields.many2one('ifrs.ifrs', 'IFRS', required=True),
778
'company_id': fields.related('ifrs_id', 'company_id', type='many2one',
779
relation='res.company', string='Company', store=True),
780
'amount': fields.float(string='Amount', help=("This field will update "
781
"when you click the compute button in the IFRS doc form"),
783
'cons_ids': fields.many2many('account.account', 'ifrs_account_rel', 'ifrs_lines_id', 'account_id', string='Consolidated Accounts'),
784
'analytic_ids': fields.many2many('account.analytic.account', 'ifrs_analytic_rel', 'ifrs_lines_id', 'analytic_id', string='Consolidated Analytic Accounts'),
785
'parent_id': fields.many2one('ifrs.lines', 'Parent', select=True, ondelete='set null', domain="[('ifrs_id','=',parent.id), ('type','=','total'),('id','!=',id)]"),
786
'parent_abstract_id': fields.many2one('ifrs.lines', 'Parent Abstract', select=True, ondelete='set null', domain="[('ifrs_id','=',parent.id),('type','=','abstract'),('id','!=',id)]"),
787
'parent_right': fields.integer('Parent Right', select=1),
788
'parent_left': fields.integer('Parent Left', select=1),
789
'level': fields.function(_get_level, string='Level', method=True, type='integer',
791
'ifrs.lines': (_get_children_and_total, ['parent_id'], 10),
793
'operand_ids': fields.many2many('ifrs.lines', 'ifrs_operand_rel',
794
'ifrs_parent_id', 'ifrs_child_id', string='Second Operand'),
795
'operator': fields.selection([
796
('subtract', 'Subtraction'),
797
('percent', 'Percentage'),
799
('product', 'Product'),
800
('without', 'First Operand Only')
802
'Operator', required=False,
803
help='Leaving blank will not take into account Operands'),
804
'comparison': fields.selection([
805
('subtract', 'Subtraction'),
806
('percent', 'Percentage'),
808
('without', 'No Comparison')],
809
'Make Comparison', required=False,
810
help='Make a Comparison against the previous period.\nThat is, period X(n) minus period X(n-1)\nLeaving blank will not make any effects'),
811
'acc_val': fields.selection([
812
('init', 'Initial Values'),
813
('var', 'Variation in Periods'),
814
('fy', ('Ending Values'))],
815
'Accounting Span', required=False,
816
help='Leaving blank means YTD'),
817
'value': fields.selection([
819
('credit', 'Credit'),
820
('balance', 'Balance')],
821
'Accounting Value', required=False,
822
help='Leaving blank means Balance'),
823
'total_ids': fields.many2many('ifrs.lines', 'ifrs_lines_rel', 'parent_id', 'child_id', string='First Operand'),
824
'inv_sign': fields.boolean('Change Sign to Amount', help='Allows a change of sign'),
825
'invisible': fields.boolean('Invisible', help='Allows whether the line of the report is printed or not'),
826
'comment': fields.text('Comments/Question', help='Comments or questions about this ifrs line'),
827
'ytd': fields.float('YTD', help='amount control field, functions to prevent repeated computes'),
828
'period_1': fields.float('Periodo 1', help='1st period amount control field, functions to prevent repeated computes'),
829
'period_2': fields.float('Periodo 2', help='2nd period amount control field, functions to prevent repeated computes'),
830
'period_3': fields.float('Periodo 3', help='3rd period amount control field, functions to prevent repeated computes'),
831
'period_4': fields.float('Periodo 4', help='4th period amount control field, functions to prevent repeated computes'),
832
'period_5': fields.float('Periodo 5', help='5th period amount control field, functions to prevent repeated computes'),
833
'period_6': fields.float('Periodo 6', help='6th period amount control field, functions to prevent repeated computes'),
834
'period_7': fields.float('Periodo 7', help='7th period amount control field, functions to prevent repeated computes'),
835
'period_8': fields.float('Periodo 8', help='8th period amount control field, functions to prevent repeated computes'),
836
'period_9': fields.float('Periodo 9', help='9th period amount control field, functions to prevent repeated computes'),
837
'period_10': fields.float('Periodo 10', help='10th period amount control field, functions to prevent repeated computes'),
838
'period_11': fields.float('Periodo 11', help='11th period amount control field, functions to prevent repeated computes'),
839
'period_12': fields.float('Periodo 12', help='12th period amount control field, functions to prevent repeated computes'),
847
'help': lambda s, c, u, cx: cx.get('ifrs_help',True),
848
'operator': 'without',
849
'comparison': 'without',
850
'sequence': _get_default_sequence,
851
'priority': _get_default_sequence,
854
def _check_description(self, cr, user, ids,context=None):
855
context = context or {}
856
for s in self.browse(cr, user, ids):
857
# if s.type=='total' and s.parent_id.type!='abstract':
863
(_check_description, (
864
'Error: Los padres de las lineas ifrs de tipo total solo pueden tener padres de tipo abstract'), ['parent_id']),
867
_sql_constraints = [('sequence_ifrs_id_unique', 'unique(sequence,id)',
868
'The sequence already have been set in another IFRS line')]
875
#~ pregunta. comprobacion de la linea... lo hace cuando le da a guardar--- no lo hace a la hora de ingresarlo, puede taer confuciones a la hora que el usuario agregue a mucha gente y luego no sepa a cual se refiere.
877
#~ buscar, como hacer para que ordene por secuencia, lo que ingreso!