[FIX] wizard fiscal year close: speedup
authorQuentin <>
Fri, 19 Aug 2011 13:37:01 +0000 (15:37 +0200)
committerolt@tinyerp.com <>
Fri, 19 Aug 2011 13:37:01 +0000 (15:37 +0200)
bzr revid: olt@tinyerp.com-20110819133701-416spe0k1rvpmwaj

addons/account/wizard/wizard_fiscalyear_close.py

index 1e5ce56..e0f3039 100644 (file)
@@ -50,157 +50,200 @@ def _data_load(self, cr, uid, data, context):
     data['form']['report_name'] = _('End of Fiscal Year Entry')
     return data['form']
 
-def _data_save(self, cr, uid, data, context):
-    if not data['form']['sure']:
-        raise wizard.except_wizard(_('UserError'), _('Closing of fiscal year cancelled, please check the box !'))
+def _data_save(self, cr, uid, data, context=None):
+    """
+    This function close account fiscalyear and create entries in new fiscalyear
+    @param cr: the current row, from the database cursor,
+    @param uid: the current user’s ID for security checks,
+    @param ids: List of Account fiscalyear close state’s IDs
+
+    """
     pool = pooler.get_pool(cr.dbname)
+    obj_acc_period = pool.get('account.period')
+    obj_acc_fiscalyear = pool.get('account.fiscalyear')
+    obj_acc_journal = pool.get('account.journal')
+    obj_acc_move = pool.get('account.move')
+    obj_acc_move_line = pool.get('account.move.line')
+    obj_acc_account = pool.get('account.account')
+    obj_acc_journal_period = pool.get('account.journal.period')
+    currency_obj = pool.get('res.currency')
 
+    if context is None:
+        context = {}
     fy_id = data['form']['fy_id']
-    period_ids = pool.get('account.period').search(cr, uid, [('fiscalyear_id', '=', fy_id)])
-    cr.execute("SELECT id FROM account_period WHERE date_stop < (SELECT date_start FROM account_fiscalyear WHERE id = %s)" , (str(data['form']['fy2_id']),))
+
+    cr.execute("SELECT id FROM account_period WHERE date_stop < (SELECT date_start FROM account_fiscalyear WHERE id = %s)", (str(data['form']['fy2_id']),))
     fy_period_set = ','.join(map(lambda id: str(id[0]), cr.fetchall()))
-    cr.execute("SELECT id FROM account_period WHERE date_start > (SELECT date_stop FROM account_fiscalyear WHERE id = %s)" , (str(fy_id),))
+    cr.execute("SELECT id FROM account_period WHERE date_start > (SELECT date_stop FROM account_fiscalyear WHERE id = %s)", (str(fy_id),))
     fy2_period_set = ','.join(map(lambda id: str(id[0]), cr.fetchall()))
-    period = pool.get('account.period').browse(cr, uid, data['form']['period_id'], context=context)
-    new_fyear = pool.get('account.fiscalyear').browse(cr, uid, data['form']['fy2_id'], context=context)
-    old_fyear = pool.get('account.fiscalyear').browse(cr, uid, data['form']['fy_id'], context=context)
-    
+
+    period = obj_acc_period.browse(cr, uid, data['form']['period_id'], context=context)
+    new_fyear = obj_acc_fiscalyear.browse(cr, uid, data['form']['fy2_id'], context=context)
+    old_fyear = obj_acc_fiscalyear.browse(cr, uid, data['form']['fy_id'], context=context)
+
     new_journal = data['form']['journal_id']
-    new_journal = pool.get('account.journal').browse(cr, uid, new_journal, context=context)
+    new_journal = obj_acc_journal.browse(cr, uid, new_journal, context=context)
 
     if not new_journal.default_credit_account_id or not new_journal.default_debit_account_id:
-        raise wizard.except_wizard(_('UserError'),
+        raise osv.except_osv(_('UserError'),
                 _('The journal must have default credit and debit account'))
     if (not new_journal.centralisation) or new_journal.entry_posted:
-        raise wizard.except_wizard(_('UserError'),
+        raise osv.except_osv(_('UserError'),
                 _('The journal must have centralised counterpart without the Skipping draft state option checked!'))
 
-    move_ids = pool.get('account.move.line').search(cr, uid, [
-        ('journal_id','=',new_journal.id),('period_id.fiscalyear_id','=',new_fyear.id)])
+    move_ids = obj_acc_move_line.search(cr, uid, [
+        ('journal_id', '=', new_journal.id), ('period_id.fiscalyear_id', '=', new_fyear.id)])
+
     if move_ids:
         raise wizard.except_wizard(_('UserError'),
                 _('The opening journal must not have any entry in the new fiscal year !'))
+    #if move_ids:
+        #obj_acc_move_line._remove_move_reconcile(cr, uid, move_ids, context=context)
+    #    obj_acc_move_line.unlink(cr, uid, move_ids, context=context)
+
     cr.execute("SELECT id FROM account_fiscalyear WHERE date_stop < %s", (str(new_fyear.date_start),))
     result = cr.dictfetchall()
     fy_ids = ','.join([str(x['id']) for x in result])
-    query_line = pool.get('account.move.line')._query_get(cr, uid,
+    query_line = obj_acc_move_line._query_get(cr, uid,
             obj='account_move_line', context={'fiscalyear': fy_ids})
-    cr.execute('select id from account_account WHERE active')
-    ids = map(lambda x: x[0], cr.fetchall())
-    for account in pool.get('account.account').browse(cr, uid, ids,
-        context={'fiscalyear': fy_id}):
-        
+    #create the opening move
+    vals = {
+        'name': '/',
+        'ref': '',
+        'period_id': period.id,
+        'journal_id': new_journal.id,
+    }
+    move_id = obj_acc_move.create(cr, uid, vals, context=context)
+
+    #1. report of the accounts with defferal method == 'unreconciled'
+    cr.execute('''
+        SELECT a.id 
+        FROM account_account a
+        LEFT JOIN account_account_type t ON (a.user_type = t.id)
+        WHERE a.active 
+          AND a.type != 'view'
+          AND t.close_method = %s''', ('unreconciled', ))
+    account_ids = map(lambda x: x[0], cr.fetchall())
+
+    if account_ids:
+        cr.execute('''
+            INSERT INTO account_move_line (
+                 name, create_uid, create_date, write_uid, write_date,
+                 statement_id, journal_id, currency_id, date_maturity,
+                 partner_id, blocked, credit, state, debit,
+                 ref, account_id, period_id, date, move_id, amount_currency, 
+                 quantity, product_id) 
+              (SELECT name, create_uid, create_date, write_uid, write_date,
+                 statement_id, %s,currency_id, date_maturity, partner_id,
+                 blocked, credit, 'draft', debit, ref, account_id,
+                 %s, date, %s, amount_currency, quantity,product_id
+               FROM account_move_line
+               WHERE account_id IN %s 
+                 AND ''' + query_line + ''' 
+                 AND reconcile_id IS NULL)''', (new_journal.id, period.id, move_id, tuple(account_ids),))
+
+
+        #We have also to consider all move_lines that were reconciled
+        #on another fiscal year, and report them too
+        cr.execute('''
+            INSERT INTO account_move_line (
+                 name, create_uid, create_date, write_uid, write_date,
+                 statement_id, journal_id, currency_id, date_maturity,
+                 partner_id, blocked, credit, state, debit,
+                 ref, account_id, period_id, date, move_id, amount_currency, 
+                 quantity, product_id) 
+              (SELECT 
+                 b.name, b.create_uid, b.create_date, b.write_uid, b.write_date,
+                 b.statement_id, %s, b.currency_id, b.date_maturity,
+                 b.partner_id, b.blocked, b.credit, 'draft', b.debit,
+                 b.ref, b.account_id, %s, b.date, %s, b.amount_currency, 
+                 b.quantity, b.product_id
+                 FROM account_move_line a, account_move_line b
+                 WHERE b.account_id IN %s
+                   AND b.reconcile_id IS NOT NULL
+                   AND a.reconcile_id = b.reconcile_id
+                   AND b.period_id IN ('''+fy_period_set+''')
+                   AND a.period_id IN ('''+fy2_period_set+'''))''', (new_journal.id, period.id, move_id, tuple(account_ids),))
+
+    #2. report of the accounts with defferal method == 'detail'
+    cr.execute('''
+        SELECT a.id 
+        FROM account_account a
+        LEFT JOIN account_account_type t ON (a.user_type = t.id)
+        WHERE a.active 
+          AND a.type != 'view'
+          AND t.close_method = %s''', ('detail', ))
+    account_ids = map(lambda x: x[0], cr.fetchall())
+
+    if account_ids:
+        cr.execute('''
+            INSERT INTO account_move_line (
+                 name, create_uid, create_date, write_uid, write_date,
+                 statement_id, journal_id, currency_id, date_maturity,
+                 partner_id, blocked, credit, state, debit,
+                 ref, account_id, period_id, date, move_id, amount_currency, 
+                 quantity, product_id) 
+              (SELECT name, create_uid, create_date, write_uid, write_date,
+                 statement_id, %s,currency_id, date_maturity, partner_id,
+                 blocked, credit, 'draft', debit, ref, account_id,
+                 %s, date, %s, amount_currency, quantity,product_id
+               FROM account_move_line
+               WHERE account_id IN %s 
+                 AND ''' + query_line + ''') 
+                 ''', (new_journal.id, period.id, move_id, tuple(account_ids),))
+
+
+    #3. report of the accounts with defferal method == 'balance'
+    cr.execute('''
+        SELECT a.id 
+        FROM account_account a
+        LEFT JOIN account_account_type t ON (a.user_type = t.id)
+        WHERE a.active 
+          AND a.type != 'view'
+          AND t.close_method = %s''', ('balance', ))
+    account_ids = map(lambda x: x[0], cr.fetchall())
+
+    for account in obj_acc_account.browse(cr, uid, account_ids, context={'fiscalyear': fy_id}):
         accnt_type_data = account.user_type
-        if not accnt_type_data:
-            continue
-        if accnt_type_data.close_method=='none' or account.type == 'view':
-            continue
-        if accnt_type_data.close_method=='balance':
-            if abs(account.balance)>0.0001:
-                pool.get('account.move.line').create(cr, uid, {
-                    'debit': account.balance>0 and account.balance,
-                    'credit': account.balance<0 and -account.balance,
+        if accnt_type_data.close_method == 'balance':
+            balance_in_currency = 0.0
+            if account.currency_id:
+                cr.execute('SELECT sum(amount_currency) as balance_in_currency FROM account_move_line ' \
+                        'WHERE account_id = %s ' \
+                            'AND ' + query_line + ' ' \
+                            'AND currency_id = %s', (account.id, account.currency_id.id)) 
+                balance_in_currency = cr.dictfetchone()['balance_in_currency']
+
+            company_currency_id = pool.get('res.users').browse(cr, uid, uid).company_id.currency_id
+            if not currency_obj.is_zero(cr, uid, company_currency_id, abs(account.balance)):
+                obj_acc_move_line.create(cr, uid, {
+                    'debit': account.balance > 0 and account.balance,
+                    'credit': account.balance < 0 and -account.balance,
                     'name': data['form']['report_name'],
                     'date': period.date_start,
+                    'move_id': move_id,
                     'journal_id': new_journal.id,
                     'period_id': period.id,
-                    'account_id': account.id
+                    'account_id': account.id,
+                    'currency_id': account.currency_id and account.currency_id.id or False,
+                    'amount_currency': balance_in_currency,
                 }, {'journal_id': new_journal.id, 'period_id':period.id})
-        if accnt_type_data.close_method == 'unreconciled':
-            offset = 0
-            limit = 100
-            while True:
-                cr.execute('SELECT id, name, quantity, debit, credit, account_id, ref, ' \
-                            'amount_currency, currency_id, blocked, partner_id, ' \
-                            'date_maturity, date_created ' \
-                        'FROM account_move_line ' \
-                        'WHERE account_id = %s ' \
-                            'AND ' + query_line + ' ' \
-                            'AND reconcile_id is NULL ' \
-                        'ORDER BY id ' \
-                        'LIMIT %s OFFSET %s', (account.id, limit, offset))
-                result = cr.dictfetchall()
-                if not result:
-                    break
-                for move in result:
-                    move.pop('id')
-                    move.update({
-                        'date': period.date_start,
-                        'journal_id': new_journal.id,
-                        'period_id': period.id,
-                    })
-                    pool.get('account.move.line').create(cr, uid, move, {
-                        'journal_id': new_journal.id,
-                        'period_id': period.id,
-                        })
-                offset += limit
-
-            #We have also to consider all move_lines that were reconciled 
-            #on another fiscal year, and report them too
-            offset = 0
-            limit = 100
-            while True:
-                cr.execute('SELECT DISTINCT b.id, b.name, b.quantity, b.debit, b.credit, b.account_id, b.ref, ' \
-                            'b.amount_currency, b.currency_id, b.blocked, b.partner_id, ' \
-                            'b.date_maturity, b.date_created ' \
-                        'FROM account_move_line a, account_move_line b ' \
-                        'WHERE b.account_id = %s ' \
-                            'AND b.reconcile_id is NOT NULL ' \
-                            'AND a.reconcile_id = b.reconcile_id ' \
-                            'AND b.period_id IN ('+fy_period_set+') ' \
-                            'AND a.period_id IN ('+fy2_period_set+') ' \
-                        'ORDER BY id ' \
-                        'LIMIT %s OFFSET %s', (account.id, limit, offset))
-                result = cr.dictfetchall()
-                if not result:
-                    break
-                for move in result:
-                    move.pop('id')
-                    move.update({
-                        'date': period.date_start,
-                        'journal_id': new_journal.id,
-                        'period_id': period.id,
-                    })
-                    pool.get('account.move.line').create(cr, uid, move, {
-                        'journal_id': new_journal.id,
-                        'period_id': period.id,
-                        })
-                offset += limit
-        if accnt_type_data.close_method=='detail':
-            offset = 0
-            limit = 100
-            while True:
-                cr.execute('SELECT id, name, quantity, debit, credit, account_id, ref, ' \
-                            'amount_currency, currency_id, blocked, partner_id, ' \
-                            'date_maturity, date_created ' \
-                        'FROM account_move_line ' \
-                        'WHERE account_id = %s ' \
-                            'AND ' + query_line + ' ' \
-                        'ORDER BY id ' \
-                        'LIMIT %s OFFSET %s', (account.id, limit, offset))
-                
-                result = cr.dictfetchall()
-                if not result:
-                    break
-                for move in result:
-                    move.pop('id')
-                    move.update({
-                        'date': period.date_start,
-                        'journal_id': new_journal.id,
-                        'period_id': period.id,
-                    })
-                    pool.get('account.move.line').create(cr, uid, move)
-                offset += limit
-    ids = pool.get('account.move.line').search(cr, uid, [('journal_id','=',new_journal.id),
+
+    #validate and centralize the opening move
+    obj_acc_move.validate(cr, uid, [move_id], context=context)
+
+    #reconcile all the move.line of the opening move
+    ids = obj_acc_move_line.search(cr, uid, [('journal_id','=',new_journal.id),
         ('period_id.fiscalyear_id','=',new_fyear.id)])
     context['fy_closing'] = True
-
     if ids:
-        pool.get('account.move.line').reconcile(cr, uid, ids, context=context)
+        obj_acc_move_line.reconcile(cr, uid, ids, context=context)
+
+    #create the journal.period object and link it to the old fiscalyear
     new_period = data['form']['period_id']
-    ids = pool.get('account.journal.period').search(cr, uid, [('journal_id','=',new_journal.id),('period_id','=',new_period)])
+    ids = obj_acc_journal_period.search(cr, uid, [('journal_id','=',new_journal.id),('period_id','=',new_period)])
     if not ids:
-        ids = [pool.get('account.journal.period').create(cr, uid, {
+        ids = [obj_acc_journal_period.create(cr, uid, {
                'name': (new_journal.name or '')+':'+(period.code or ''),
                'journal_id': new_journal.id,
                'period_id': period.id
@@ -209,7 +252,8 @@ def _data_save(self, cr, uid, data, context):
                 'SET end_journal_period_id = %s ' \
                 'WHERE id = %s', (ids[0], old_fyear.id))
 
-    return {}
+    return {'type': 'ir.actions.act_window_close'}
+
 
 class wiz_journal_close(wizard.interface):
     states = {
@@ -224,6 +268,3 @@ class wiz_journal_close(wizard.interface):
     }
 wiz_journal_close('account.fiscalyear.close')
 
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-