2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2007-01-04 09:45:50 +00:00
##############################################################################
2009-11-25 09:31:44 +00:00
#
2008-11-06 07:29:50 +00:00
# OpenERP, Open Source Management Solution
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2007-01-04 09:45:50 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is free software: you can redistribute it and/or modify
2009-10-14 11:15:34 +00:00
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
2007-01-04 09:45:50 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2009-10-14 11:15:34 +00:00
# GNU Affero General Public License for more details.
2007-01-04 09:45:50 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2009-11-25 09:31:44 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2007-01-04 09:45:50 +00:00
#
##############################################################################
2010-10-15 06:56:48 +00:00
2007-01-04 09:45:50 +00:00
import time
2010-06-18 07:23:59 +00:00
from datetime import datetime
2013-11-21 12:06:11 +00:00
from openerp import workflow
2014-07-06 14:44:26 +00:00
from openerp . osv import fields , osv
2012-12-06 14:56:32 +00:00
from openerp . tools . translate import _
2012-12-17 15:23:03 +00:00
import openerp . addons . decimal_precision as dp
2012-12-06 14:56:32 +00:00
from openerp import tools
2014-09-04 09:32:16 +00:00
from openerp . report import report_sxw
2014-06-25 06:09:36 +00:00
import openerp
2009-09-18 10:33:21 +00:00
2007-01-04 09:45:50 +00:00
class account_move_line ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " account.move.line "
2010-08-20 18:57:46 +00:00
_description = " Journal Items "
2008-07-22 15:11:28 +00:00
2010-10-15 06:15:15 +00:00
def _query_get ( self , cr , uid , obj = ' l ' , context = None ) :
2008-07-22 15:11:28 +00:00
fiscalyear_obj = self . pool . get ( ' account.fiscalyear ' )
2010-03-05 10:36:09 +00:00
fiscalperiod_obj = self . pool . get ( ' account.period ' )
2010-10-15 09:23:25 +00:00
account_obj = self . pool . get ( ' account.account ' )
2010-03-05 10:36:09 +00:00
fiscalyear_ids = [ ]
2014-07-06 14:44:26 +00:00
context = dict ( context or { } )
2010-10-01 11:32:41 +00:00
initial_bal = context . get ( ' initial_bal ' , False )
2010-10-15 09:23:25 +00:00
company_clause = " "
2010-10-01 11:32:41 +00:00
if context . get ( ' company_id ' , False ) :
company_clause = " AND " + obj + " .company_id = %s " % context . get ( ' company_id ' , False )
if not context . get ( ' fiscalyear ' , False ) :
2011-01-10 11:15:33 +00:00
if context . get ( ' all_fiscalyear ' , False ) :
#this option is needed by the aged balance report because otherwise, if we search only the draft ones, an open invoice of a closed fiscalyear won't be displayed
fiscalyear_ids = fiscalyear_obj . search ( cr , uid , [ ] )
else :
fiscalyear_ids = fiscalyear_obj . search ( cr , uid , [ ( ' state ' , ' = ' , ' draft ' ) ] )
2008-07-22 15:11:28 +00:00
else :
2010-11-16 08:34:20 +00:00
#for initial balance as well as for normal query, we check only the selected FY because the best practice is to generate the FY opening entries
fiscalyear_ids = [ context [ ' fiscalyear ' ] ]
2010-03-05 10:36:09 +00:00
fiscalyear_clause = ( ' , ' . join ( [ str ( x ) for x in fiscalyear_ids ] ) ) or ' 0 '
2010-10-15 09:23:25 +00:00
state = context . get ( ' state ' , False )
2009-03-16 11:41:01 +00:00
where_move_state = ' '
where_move_lines_by_date = ' '
if context . get ( ' date_from ' , False ) and context . get ( ' date_to ' , False ) :
2010-10-01 15:24:03 +00:00
if initial_bal :
2011-01-07 11:38:11 +00:00
where_move_lines_by_date = " AND " + obj + " .move_id IN (SELECT id FROM account_move WHERE date < ' " + context [ ' date_from ' ] + " ' ) "
2010-10-01 11:32:41 +00:00
else :
2010-10-15 09:23:25 +00:00
where_move_lines_by_date = " AND " + obj + " .move_id IN (SELECT id FROM account_move WHERE date >= ' " + context [ ' date_from ' ] + " ' AND date <= ' " + context [ ' date_to ' ] + " ' ) "
2009-11-25 09:31:44 +00:00
2008-07-30 06:29:44 +00:00
if state :
if state . lower ( ) not in [ ' all ' ] :
2010-10-15 09:23:25 +00:00
where_move_state = " AND " + obj + " .move_id IN (SELECT id FROM account_move WHERE account_move.state = ' " + state + " ' ) "
2010-10-04 11:46:01 +00:00
if context . get ( ' period_from ' , False ) and context . get ( ' period_to ' , False ) and not context . get ( ' periods ' , False ) :
2010-10-01 11:32:41 +00:00
if initial_bal :
2010-10-04 11:46:01 +00:00
period_company_id = fiscalperiod_obj . browse ( cr , uid , context [ ' period_from ' ] , context = context ) . company_id . id
first_period = fiscalperiod_obj . search ( cr , uid , [ ( ' company_id ' , ' = ' , period_company_id ) ] , order = ' date_start ' , limit = 1 ) [ 0 ]
context [ ' periods ' ] = fiscalperiod_obj . build_ctx_periods ( cr , uid , first_period , context [ ' period_from ' ] )
2010-10-01 11:32:41 +00:00
else :
2010-10-04 11:46:01 +00:00
context [ ' periods ' ] = fiscalperiod_obj . build_ctx_periods ( cr , uid , context [ ' period_from ' ] , context [ ' period_to ' ] )
2008-07-22 15:11:28 +00:00
if context . get ( ' periods ' , False ) :
2010-10-05 05:51:22 +00:00
if initial_bal :
2011-01-10 11:44:00 +00:00
query = obj + " .state <> ' draft ' AND " + obj + " .period_id IN (SELECT id FROM account_period WHERE fiscalyear_id IN ( %s )) %s %s " % ( fiscalyear_clause , where_move_state , where_move_lines_by_date )
2010-10-05 05:51:22 +00:00
period_ids = fiscalperiod_obj . search ( cr , uid , [ ( ' id ' , ' in ' , context [ ' periods ' ] ) ] , order = ' date_start ' , limit = 1 )
if period_ids and period_ids [ 0 ] :
first_period = fiscalperiod_obj . browse ( cr , uid , period_ids [ 0 ] , context = context )
2011-05-06 06:27:58 +00:00
ids = ' , ' . join ( [ str ( x ) for x in context [ ' periods ' ] ] )
query = obj + " .state <> ' draft ' AND " + obj + " .period_id IN (SELECT id FROM account_period WHERE fiscalyear_id IN ( %s ) AND date_start <= ' %s ' AND id NOT IN ( %s )) %s %s " % ( fiscalyear_clause , first_period . date_start , ids , where_move_state , where_move_lines_by_date )
2010-10-05 05:51:22 +00:00
else :
ids = ' , ' . join ( [ str ( x ) for x in context [ ' periods ' ] ] )
2010-10-15 09:23:25 +00:00
query = obj + " .state <> ' draft ' AND " + obj + " .period_id IN (SELECT id FROM account_period WHERE fiscalyear_id IN ( %s ) AND id IN ( %s )) %s %s " % ( fiscalyear_clause , ids , where_move_state , where_move_lines_by_date )
2008-07-22 15:11:28 +00:00
else :
2011-01-07 11:04:25 +00:00
query = obj + " .state <> ' draft ' AND " + obj + " .period_id IN (SELECT id FROM account_period WHERE fiscalyear_id IN ( %s )) %s %s " % ( fiscalyear_clause , where_move_state , where_move_lines_by_date )
2010-03-05 10:36:09 +00:00
2011-04-19 15:34:59 +00:00
if initial_bal and not context . get ( ' periods ' , False ) and not where_move_lines_by_date :
#we didn't pass any filter in the context, and the initial balance can't be computed using only the fiscalyear otherwise entries will be summed twice
#so we have to invalidate this query
2012-08-07 11:34:14 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( " You have not supplied enough arguments to compute the initial balance, please select a period and a journal in the context. " ) )
2011-04-28 07:20:58 +00:00
2011-05-06 06:27:58 +00:00
2010-07-06 12:13:44 +00:00
if context . get ( ' journal_ids ' , False ) :
2010-10-15 09:23:25 +00:00
query + = ' AND ' + obj + ' .journal_id IN ( %s ) ' % ' , ' . join ( map ( str , context [ ' journal_ids ' ] ) )
2010-07-06 12:13:44 +00:00
2010-07-12 13:26:30 +00:00
if context . get ( ' chart_account_id ' , False ) :
2010-10-15 09:23:25 +00:00
child_ids = account_obj . _get_children_and_consol ( cr , uid , [ context [ ' chart_account_id ' ] ] , context = context )
query + = ' AND ' + obj + ' .account_id IN ( %s ) ' % ' , ' . join ( map ( str , child_ids ) )
2010-07-12 13:26:30 +00:00
2010-10-01 11:32:41 +00:00
query + = company_clause
2010-03-05 10:36:09 +00:00
return query
2008-07-22 15:11:28 +00:00
2011-01-05 13:46:54 +00:00
def _amount_residual ( self , cr , uid , ids , field_names , args , context = None ) :
"""
2011-01-07 10:38:51 +00:00
This function returns the residual amount on a receivable or payable account . move . line .
By default , it returns an amount in the currency of this journal entry ( maybe different
of the company currency ) , but if you pass ' residual_in_company_currency ' = True in the
2011-01-05 13:46:54 +00:00
context then the returned amount will be in company currency .
"""
res = { }
if context is None :
context = { }
cur_obj = self . pool . get ( ' res.currency ' )
for move_line in self . browse ( cr , uid , ids , context = context ) :
res [ move_line . id ] = {
' amount_residual ' : 0.0 ,
' amount_residual_currency ' : 0.0 ,
}
2011-01-07 10:38:51 +00:00
2011-01-05 13:46:54 +00:00
if move_line . reconcile_id :
continue
2014-06-17 14:17:05 +00:00
if not move_line . account_id . reconcile :
#this function does not suport to be used on move lines not related to a reconcilable account
2011-01-05 13:46:54 +00:00
continue
2011-01-07 10:38:51 +00:00
2011-01-05 13:46:54 +00:00
if move_line . currency_id :
move_line_total = move_line . amount_currency
sign = move_line . amount_currency < 0 and - 1 or 1
else :
move_line_total = move_line . debit - move_line . credit
sign = ( move_line . debit - move_line . credit ) < 0 and - 1 or 1
line_total_in_company_currency = move_line . debit - move_line . credit
context_unreconciled = context . copy ( )
if move_line . reconcile_partial_id :
for payment_line in move_line . reconcile_partial_id . line_partial_ids :
if payment_line . id == move_line . id :
continue
if payment_line . currency_id and move_line . currency_id and payment_line . currency_id . id == move_line . currency_id . id :
move_line_total + = payment_line . amount_currency
else :
if move_line . currency_id :
context_unreconciled . update ( { ' date ' : payment_line . date } )
amount_in_foreign_currency = cur_obj . compute ( cr , uid , move_line . company_id . currency_id . id , move_line . currency_id . id , ( payment_line . debit - payment_line . credit ) , round = False , context = context_unreconciled )
move_line_total + = amount_in_foreign_currency
else :
move_line_total + = ( payment_line . debit - payment_line . credit )
line_total_in_company_currency + = ( payment_line . debit - payment_line . credit )
result = move_line_total
res [ move_line . id ] [ ' amount_residual_currency ' ] = sign * ( move_line . currency_id and self . pool . get ( ' res.currency ' ) . round ( cr , uid , move_line . currency_id , result ) or result )
res [ move_line . id ] [ ' amount_residual ' ] = sign * line_total_in_company_currency
return res
2010-10-15 06:56:48 +00:00
def default_get ( self , cr , uid , fields , context = None ) :
data = self . _default_get ( cr , uid , fields , context = context )
2008-07-22 15:11:28 +00:00
for f in data . keys ( ) :
if f not in fields :
del data [ f ]
return data
2012-11-26 14:11:37 +00:00
def _prepare_analytic_line ( self , cr , uid , obj_line , context = None ) :
"""
Prepare the values given at the create ( ) of account . analytic . line upon the validation of a journal item having
an analytic account . This method is intended to be extended in other modules .
: param obj_line : browse record of the account . move . line that triggered the analytic line creation
"""
return { ' name ' : obj_line . name ,
' date ' : obj_line . date ,
' account_id ' : obj_line . analytic_account_id . id ,
' unit_amount ' : obj_line . quantity ,
' product_id ' : obj_line . product_id and obj_line . product_id . id or False ,
' product_uom_id ' : obj_line . product_uom_id and obj_line . product_uom_id . id or False ,
' amount ' : ( obj_line . credit or 0.0 ) - ( obj_line . debit or 0.0 ) ,
' general_account_id ' : obj_line . account_id . id ,
' journal_id ' : obj_line . journal_id . analytic_journal_id . id ,
' ref ' : obj_line . ref ,
' move_id ' : obj_line . id ,
' user_id ' : uid ,
}
2010-11-19 13:48:01 +00:00
def create_analytic_lines ( self , cr , uid , ids , context = None ) :
2010-10-15 09:23:25 +00:00
acc_ana_line_obj = self . pool . get ( ' account.analytic.line ' )
2010-11-19 13:48:01 +00:00
for obj_line in self . browse ( cr , uid , ids , context = context ) :
2014-07-17 16:44:58 +00:00
if obj_line . analytic_lines :
acc_ana_line_obj . unlink ( cr , uid , [ obj . id for obj in obj_line . analytic_lines ] )
2008-11-24 16:51:26 +00:00
if obj_line . analytic_account_id :
2008-12-26 18:11:02 +00:00
if not obj_line . journal_id . analytic_journal_id :
2013-06-07 11:38:29 +00:00
raise osv . except_osv ( _ ( ' No Analytic Journal! ' ) , _ ( " You have to define an analytic journal on the ' %s ' journal! " ) % ( obj_line . journal_id . name , ) )
2012-11-26 14:11:37 +00:00
vals_line = self . _prepare_analytic_line ( cr , uid , obj_line , context = context )
acc_ana_line_obj . create ( cr , uid , vals_line )
2008-11-24 16:51:26 +00:00
return True
2008-11-26 13:48:24 +00:00
def _default_get_move_form_hook ( self , cursor , user , data ) :
''' Called in the end of default_get method for manual entry in account_move form '''
if data . has_key ( ' analytic_account_id ' ) :
del ( data [ ' analytic_account_id ' ] )
if data . has_key ( ' account_tax_id ' ) :
del ( data [ ' account_tax_id ' ] )
return data
2010-11-19 13:48:01 +00:00
def convert_to_period ( self , cr , uid , context = None ) :
2010-11-23 11:31:52 +00:00
if context is None :
context = { }
2010-08-13 10:08:43 +00:00
period_obj = self . pool . get ( ' account.period ' )
#check if the period_id changed in the context from client side
if context . get ( ' period_id ' , False ) :
period_id = context . get ( ' period_id ' )
if type ( period_id ) == str :
2010-10-15 09:23:25 +00:00
ids = period_obj . search ( cr , uid , [ ( ' name ' , ' ilike ' , period_id ) ] )
2014-07-06 14:44:26 +00:00
context = dict ( context , period_id = ids and ids [ 0 ] or False )
2010-08-13 11:07:27 +00:00
return context
2010-08-16 07:06:33 +00:00
2010-11-19 13:48:01 +00:00
def _default_get ( self , cr , uid , fields , context = None ) :
2012-11-23 16:27:58 +00:00
#default_get should only do the following:
# -propose the next amount in debit/credit in order to balance the move
# -propose the next account from the journal (default debit/credit account) accordingly
2014-07-06 14:44:26 +00:00
context = dict ( context or { } )
2010-10-15 09:23:25 +00:00
account_obj = self . pool . get ( ' account.account ' )
2010-08-13 11:07:27 +00:00
period_obj = self . pool . get ( ' account.period ' )
2010-10-15 09:23:25 +00:00
journal_obj = self . pool . get ( ' account.journal ' )
move_obj = self . pool . get ( ' account.move ' )
tax_obj = self . pool . get ( ' account.tax ' )
fiscal_pos_obj = self . pool . get ( ' account.fiscal.position ' )
partner_obj = self . pool . get ( ' res.partner ' )
currency_obj = self . pool . get ( ' res.currency ' )
2012-11-23 16:27:58 +00:00
if not context . get ( ' journal_id ' , False ) :
context [ ' journal_id ' ] = context . get ( ' search_default_journal_id ' , False )
if not context . get ( ' period_id ' , False ) :
context [ ' period_id ' ] = context . get ( ' search_default_period_id ' , False )
2010-08-13 11:07:27 +00:00
context = self . convert_to_period ( cr , uid , context )
2012-11-23 16:27:58 +00:00
2008-07-22 15:11:28 +00:00
# Compute simple values
2010-11-19 13:48:01 +00:00
data = super ( account_move_line , self ) . default_get ( cr , uid , fields , context = context )
2012-11-23 16:27:58 +00:00
if context . get ( ' journal_id ' ) :
total = 0.0
#in account.move form view, it is not possible to compute total debit and credit using
#a browse record. So we must use the context to pass the whole one2many field and compute the total
if context . get ( ' line_id ' ) :
for move_line_dict in move_obj . resolve_2many_commands ( cr , uid , ' line_id ' , context . get ( ' line_id ' ) , context = context ) :
data [ ' name ' ] = data . get ( ' name ' ) or move_line_dict . get ( ' name ' )
data [ ' partner_id ' ] = data . get ( ' partner_id ' ) or move_line_dict . get ( ' partner_id ' )
total + = move_line_dict . get ( ' debit ' , 0.0 ) - move_line_dict . get ( ' credit ' , 0.0 )
elif context . get ( ' period_id ' ) :
#find the date and the ID of the last unbalanced account.move encoded by the current user in that journal and period
move_id = False
cr . execute ( ''' SELECT move_id, date FROM account_move_line
WHERE journal_id = % s AND period_id = % s AND create_uid = % s AND state = % s
ORDER BY id DESC limit 1 ''' , (context[ ' journal_id ' ], context[ ' period_id ' ], uid, ' draft ' ))
2008-07-22 15:11:28 +00:00
res = cr . fetchone ( )
2012-11-23 16:27:58 +00:00
move_id = res and res [ 0 ] or False
data [ ' date ' ] = res and res [ 1 ] or period_obj . browse ( cr , uid , context [ ' period_id ' ] , context = context ) . date_start
data [ ' move_id ' ] = move_id
if move_id :
#if there exist some unbalanced accounting entries that match the journal and the period,
#we propose to continue the same move by copying the ref, the name, the partner...
move = move_obj . browse ( cr , uid , move_id , context = context )
data . setdefault ( ' name ' , move . line_id [ - 1 ] . name )
for l in move . line_id :
data [ ' partner_id ' ] = data . get ( ' partner_id ' ) or l . partner_id . id
data [ ' ref ' ] = data . get ( ' ref ' ) or l . ref
total + = ( l . debit or 0.0 ) - ( l . credit or 0.0 )
#compute the total of current move
data [ ' debit ' ] = total < 0 and - total or 0.0
data [ ' credit ' ] = total > 0 and total or 0.0
#pick the good account on the journal accordingly if the next proposed line will be a debit or a credit
journal_data = journal_obj . browse ( cr , uid , context [ ' journal_id ' ] , context = context )
account = total > 0 and journal_data . default_credit_account_id or journal_data . default_debit_account_id
#map the account using the fiscal position of the partner, if needed
2014-10-31 07:38:34 +00:00
if isinstance ( data . get ( ' partner_id ' ) , ( int , long ) ) :
part = partner_obj . browse ( cr , uid , data [ ' partner_id ' ] , context = context )
elif isinstance ( data . get ( ' partner_id ' ) , ( tuple , list ) ) :
part = partner_obj . browse ( cr , uid , data [ ' partner_id ' ] [ 0 ] , context = context )
else :
part = False
if account and part :
2012-11-23 16:27:58 +00:00
account = fiscal_pos_obj . map_account ( cr , uid , part and part . property_account_position or False , account . id )
account = account_obj . browse ( cr , uid , account , context = context )
data [ ' account_id ' ] = account and account . id or False
#compute the amount in secondary currency of the account, if needed
if account and account . currency_id :
data [ ' currency_id ' ] = account . currency_id . id
#set the context for the multi currency change
compute_ctx = context . copy ( )
compute_ctx . update ( {
#the following 2 parameters are used to choose the currency rate, in case where the account
#doesn't work with an outgoing currency rate method 'at date' but 'average'
' res.currency.compute.account ' : account ,
' res.currency.compute.account_invert ' : True ,
} )
if data . get ( ' date ' ) :
compute_ctx . update ( { ' date ' : data [ ' date ' ] } )
data [ ' amount_currency ' ] = currency_obj . compute ( cr , uid , account . company_id . currency_id . id , data [ ' currency_id ' ] , - total , context = compute_ctx )
data = self . _default_get_move_form_hook ( cr , uid , data )
2008-07-22 15:11:28 +00:00
return data
2010-11-19 13:48:01 +00:00
def on_create_write ( self , cr , uid , id , context = None ) :
2010-10-18 11:03:56 +00:00
if not id :
return [ ]
2010-11-23 11:31:52 +00:00
ml = self . browse ( cr , uid , id , context = context )
2008-07-22 15:11:28 +00:00
return map ( lambda x : x . id , ml . move_id . line_id )
2010-10-01 12:50:26 +00:00
def _balance ( self , cr , uid , ids , name , arg , context = None ) :
if context is None :
context = { }
c = context . copy ( )
c [ ' initital_bal ' ] = True
2013-11-20 14:21:31 +00:00
sql = """ SELECT l1.id, COALESCE(SUM(l2.debit-l2.credit), 0)
FROM account_move_line l1 LEFT JOIN account_move_line l2
ON ( l1 . account_id = l2 . account_id
AND l2 . id < = l1 . id
AND """ + \
self . _query_get ( cr , uid , obj = ' l2 ' , context = c ) + \
" ) WHERE l1.id IN %s GROUP BY l1.id "
2010-10-01 12:50:26 +00:00
2010-11-27 20:14:29 +00:00
cr . execute ( sql , [ tuple ( ids ) ] )
2010-12-28 10:55:55 +00:00
return dict ( cr . fetchall ( ) )
2008-07-22 15:11:28 +00:00
def _invoice ( self , cursor , user , ids , name , arg , context = None ) :
invoice_obj = self . pool . get ( ' account.invoice ' )
res = { }
for line_id in ids :
res [ line_id ] = False
cursor . execute ( ' SELECT l.id, i.id ' \
2010-06-10 13:34:19 +00:00
' FROM account_move_line l, account_invoice i ' \
' WHERE l.move_id = i.move_id ' \
2010-06-16 11:51:39 +00:00
' AND l.id IN %s ' ,
2010-06-10 13:34:19 +00:00
( tuple ( ids ) , ) )
2008-07-22 15:11:28 +00:00
invoice_ids = [ ]
for line_id , invoice_id in cursor . fetchall ( ) :
res [ line_id ] = invoice_id
invoice_ids . append ( invoice_id )
2014-09-19 09:38:46 +00:00
invoice_names = { }
2010-10-15 09:23:25 +00:00
for invoice_id , name in invoice_obj . name_get ( cursor , user , invoice_ids , context = context ) :
2008-07-22 15:11:28 +00:00
invoice_names [ invoice_id ] = name
for line_id in res . keys ( ) :
invoice_id = res [ line_id ]
2014-09-19 09:38:46 +00:00
res [ line_id ] = invoice_id and ( invoice_id , invoice_names [ invoice_id ] ) or False
2008-07-22 15:11:28 +00:00
return res
2010-08-16 07:06:33 +00:00
2010-11-19 13:48:01 +00:00
def name_get ( self , cr , uid , ids , context = None ) :
2010-10-11 05:51:53 +00:00
if not ids :
2008-07-22 15:11:28 +00:00
return [ ]
result = [ ]
2010-11-23 11:31:52 +00:00
for line in self . browse ( cr , uid , ids , context = context ) :
2008-07-22 15:11:28 +00:00
if line . ref :
2010-08-26 00:14:59 +00:00
result . append ( ( line . id , ( line . move_id . name or ' ' ) + ' ( ' + line . ref + ' ) ' ) )
2008-07-22 15:11:28 +00:00
else :
2010-08-26 00:14:59 +00:00
result . append ( ( line . id , line . move_id . name ) )
2008-07-22 15:11:28 +00:00
return result
2010-02-22 15:07:24 +00:00
def _balance_search ( self , cursor , user , obj , name , args , domain = None , context = None ) :
if context is None :
context = { }
2010-10-11 05:51:53 +00:00
if not args :
2009-10-28 10:13:32 +00:00
return [ ]
2010-10-15 09:23:25 +00:00
where = ' AND ' . join ( map ( lambda x : ' (abs(sum(debit-credit)) ' + x [ 1 ] + str ( x [ 2 ] ) + ' ) ' , args ) )
cursor . execute ( ' SELECT id, SUM(debit-credit) FROM account_move_line \
GROUP BY id , debit , credit having ' +where)
2009-10-28 10:13:32 +00:00
res = cursor . fetchall ( )
2010-10-11 05:51:53 +00:00
if not res :
2009-10-28 10:13:32 +00:00
return [ ( ' id ' , ' = ' , ' 0 ' ) ]
return [ ( ' id ' , ' in ' , [ x [ 0 ] for x in res ] ) ]
2009-11-25 09:31:44 +00:00
2010-10-25 04:53:36 +00:00
def _invoice_search ( self , cursor , user , obj , name , args , context = None ) :
2010-10-11 05:51:53 +00:00
if not args :
2008-07-22 15:11:28 +00:00
return [ ]
invoice_obj = self . pool . get ( ' account.invoice ' )
i = 0
while i < len ( args ) :
fargs = args [ i ] [ 0 ] . split ( ' . ' , 1 )
if len ( fargs ) > 1 :
2008-12-15 11:46:57 +00:00
args [ i ] = ( fargs [ 0 ] , ' in ' , invoice_obj . search ( cursor , user ,
2008-07-22 15:11:28 +00:00
[ ( fargs [ 1 ] , args [ i ] [ 1 ] , args [ i ] [ 2 ] ) ] ) )
i + = 1
continue
if isinstance ( args [ i ] [ 2 ] , basestring ) :
res_ids = invoice_obj . name_search ( cursor , user , args [ i ] [ 2 ] , [ ] ,
args [ i ] [ 1 ] )
args [ i ] = ( args [ i ] [ 0 ] , ' in ' , [ x [ 0 ] for x in res_ids ] )
i + = 1
qu1 , qu2 = [ ] , [ ]
for x in args :
if x [ 1 ] != ' in ' :
if ( x [ 2 ] is False ) and ( x [ 1 ] == ' = ' ) :
qu1 . append ( ' (i.id IS NULL) ' )
elif ( x [ 2 ] is False ) and ( x [ 1 ] == ' <> ' or x [ 1 ] == ' != ' ) :
qu1 . append ( ' (i.id IS NOT NULL) ' )
else :
2008-12-10 14:29:55 +00:00
qu1 . append ( ' (i.id %s %s ) ' % ( x [ 1 ] , ' %s ' ) )
2008-07-22 15:11:28 +00:00
qu2 . append ( x [ 2 ] )
elif x [ 1 ] == ' in ' :
if len ( x [ 2 ] ) > 0 :
2010-10-15 09:23:25 +00:00
qu1 . append ( ' (i.id IN ( %s )) ' % ( ' , ' . join ( [ ' %s ' ] * len ( x [ 2 ] ) ) ) )
2008-07-22 15:11:28 +00:00
qu2 + = x [ 2 ]
else :
qu1 . append ( ' (False) ' )
2010-10-11 05:51:53 +00:00
if qu1 :
2008-07-22 15:11:28 +00:00
qu1 = ' AND ' + ' AND ' . join ( qu1 )
else :
qu1 = ' '
cursor . execute ( ' SELECT l.id ' \
' FROM account_move_line l, account_invoice i ' \
' WHERE l.move_id = i.move_id ' + qu1 , qu2 )
res = cursor . fetchall ( )
2010-10-11 05:51:53 +00:00
if not res :
2008-07-22 15:11:28 +00:00
return [ ( ' id ' , ' = ' , ' 0 ' ) ]
return [ ( ' id ' , ' in ' , [ x [ 0 ] for x in res ] ) ]
2010-10-25 04:53:36 +00:00
def _get_move_lines ( self , cr , uid , ids , context = None ) :
2008-12-14 19:37:38 +00:00
result = [ ]
for move in self . pool . get ( ' account.move ' ) . browse ( cr , uid , ids , context = context ) :
for line in move . line_id :
result . append ( line . id )
return result
2012-11-22 09:23:02 +00:00
def _get_reconcile ( self , cr , uid , ids , name , unknow_none , context = None ) :
res = dict . fromkeys ( ids , False )
for line in self . browse ( cr , uid , ids , context = context ) :
if line . reconcile_id :
res [ line . id ] = str ( line . reconcile_id . name )
elif line . reconcile_partial_id :
res [ line . id ] = str ( line . reconcile_partial_id . name )
return res
2014-05-30 16:47:50 +00:00
2014-04-24 06:53:06 +00:00
def _get_move_from_reconcile ( self , cr , uid , ids , context = None ) :
move = { }
for r in self . pool . get ( ' account.move.reconcile ' ) . browse ( cr , uid , ids , context = context ) :
for line in r . line_partial_ids :
move [ line . move_id . id ] = True
for line in r . line_id :
move [ line . move_id . id ] = True
move_line_ids = [ ]
if move :
2014-10-13 12:24:25 +00:00
move_line_ids = self . pool . get ( ' account.move.line ' ) . search ( cr , uid , [ ( ' move_id ' , ' in ' , move . keys ( ) ) ] , context = context )
2014-04-24 06:53:06 +00:00
return move_line_ids
2012-11-22 09:23:02 +00:00
2008-07-22 15:11:28 +00:00
_columns = {
2014-05-21 09:52:05 +00:00
' name ' : fields . char ( ' Name ' , required = True ) ,
2009-12-21 09:50:54 +00:00
' quantity ' : fields . float ( ' Quantity ' , digits = ( 16 , 2 ) , help = " The optional quantity expressed by this line, eg: number of product sold. The quantity is not a legal requirement but is very useful for some reports. " ) ,
2012-04-25 07:08:25 +00:00
' product_uom_id ' : fields . many2one ( ' product.uom ' , ' Unit of Measure ' ) ,
2008-11-26 17:02:29 +00:00
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' ) ,
2010-03-06 20:52:19 +00:00
' debit ' : fields . float ( ' Debit ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
' credit ' : fields . float ( ' Credit ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2008-07-22 15:11:28 +00:00
' account_id ' : fields . many2one ( ' account.account ' , ' Account ' , required = True , ondelete = " cascade " , domain = [ ( ' type ' , ' <> ' , ' view ' ) , ( ' type ' , ' <> ' , ' closed ' ) ] , select = 2 ) ,
2012-09-21 08:26:14 +00:00
' move_id ' : fields . many2one ( ' account.move ' , ' Journal Entry ' , ondelete = " cascade " , help = " The move of this entry line. " , select = 2 , required = True ) ,
2011-07-05 06:20:08 +00:00
' narration ' : fields . related ( ' move_id ' , ' narration ' , type = ' text ' , relation = ' account.move ' , string = ' Internal Note ' ) ,
2014-05-21 09:52:05 +00:00
' ref ' : fields . related ( ' move_id ' , ' ref ' , string = ' Reference ' , type = ' char ' , store = True ) ,
2014-07-06 14:44:26 +00:00
' statement_id ' : fields . many2one ( ' account.bank.statement ' , ' Statement ' , help = " The bank statement used for bank reconciliation " , select = 1 , copy = False ) ,
' reconcile_id ' : fields . many2one ( ' account.move.reconcile ' , ' Reconcile ' , readonly = True , ondelete = ' set null ' , select = 2 , copy = False ) ,
' reconcile_partial_id ' : fields . many2one ( ' account.move.reconcile ' , ' Partial Reconcile ' , readonly = True , ondelete = ' set null ' , select = 2 , copy = False ) ,
' reconcile_ref ' : fields . function ( _get_reconcile , type = ' char ' , string = ' Reconcile Ref ' , oldname = ' reconcile ' , store = {
2014-04-24 06:53:06 +00:00
' account.move.line ' : ( lambda self , cr , uid , ids , c = { } : ids , [ ' reconcile_id ' , ' reconcile_partial_id ' ] , 50 ) , ' account.move.reconcile ' : ( _get_move_from_reconcile , None , 50 ) } ) ,
2010-03-06 20:52:19 +00:00
' amount_currency ' : fields . float ( ' Amount Currency ' , help = " The amount expressed in an optional other currency if it is a multi-currency entry. " , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2012-12-08 10:45:58 +00:00
' amount_residual_currency ' : fields . function ( _amount_residual , string = ' Residual Amount in Currency ' , multi = " residual " , help = " The residual amount on a receivable or payable of a journal entry expressed in its currency (maybe different of the company currency). " ) ,
2011-07-01 23:41:24 +00:00
' amount_residual ' : fields . function ( _amount_residual , string = ' Residual Amount ' , multi = " residual " , help = " The residual amount on a receivable or payable of a journal entry expressed in the company currency. " ) ,
2009-03-25 06:53:10 +00:00
' currency_id ' : fields . many2one ( ' res.currency ' , ' Currency ' , help = " The optional other currency if it is a multi-currency entry. " ) ,
2012-11-22 15:06:45 +00:00
' journal_id ' : fields . related ( ' move_id ' , ' journal_id ' , string = ' Journal ' , type = ' many2one ' , relation = ' account.journal ' , required = True , select = True ,
2011-10-13 09:43:47 +00:00
store = {
' account.move ' : ( _get_move_lines , [ ' journal_id ' ] , 20 )
} ) ,
2012-11-22 15:06:45 +00:00
' period_id ' : fields . related ( ' move_id ' , ' period_id ' , string = ' Period ' , type = ' many2one ' , relation = ' account.period ' , required = True , select = True ,
2011-10-13 09:43:47 +00:00
store = {
' account.move ' : ( _get_move_lines , [ ' period_id ' ] , 20 )
} ) ,
2012-12-06 11:03:15 +00:00
' blocked ' : fields . boolean ( ' No Follow-up ' , help = " You can check this box to mark this journal item as a litigation with the associated partner " ) ,
2010-12-09 07:29:35 +00:00
' partner_id ' : fields . many2one ( ' res.partner ' , ' Partner ' , select = 1 , ondelete = ' restrict ' ) ,
2011-01-17 11:20:56 +00:00
' date_maturity ' : fields . date ( ' Due date ' , select = True , help = " This field is used for payable and receivable journal entries. You can put the limit date for the payment of this line. " ) ,
' date ' : fields . related ( ' move_id ' , ' date ' , string = ' Effective date ' , type = ' date ' , required = True , select = True ,
2010-10-15 09:23:25 +00:00
store = {
' account.move ' : ( _get_move_lines , [ ' date ' ] , 20 )
} ) ,
2011-01-17 11:20:56 +00:00
' date_created ' : fields . date ( ' Creation date ' , select = True ) ,
2008-07-22 15:11:28 +00:00
' analytic_lines ' : fields . one2many ( ' account.analytic.line ' , ' move_id ' , ' Analytic lines ' ) ,
2011-06-21 12:52:48 +00:00
' centralisation ' : fields . selection ( [ ( ' normal ' , ' Normal ' ) , ( ' credit ' , ' Credit Centralisation ' ) , ( ' debit ' , ' Debit Centralisation ' ) , ( ' currency ' , ' Currency Adjustment ' ) ] , ' Centralisation ' , size = 8 ) ,
2011-07-01 23:41:24 +00:00
' balance ' : fields . function ( _balance , fnct_search = _balance_search , string = ' Balance ' ) ,
2014-07-06 14:44:26 +00:00
' state ' : fields . selection ( [ ( ' draft ' , ' Unbalanced ' ) , ( ' valid ' , ' Balanced ' ) ] , ' Status ' , readonly = True , copy = False ) ,
2009-12-30 11:14:38 +00:00
' tax_code_id ' : fields . many2one ( ' account.tax.code ' , ' Tax Account ' , help = " The Account can either be a base tax code or a tax code account. " ) ,
2010-03-06 20:52:19 +00:00
' tax_amount ' : fields . float ( ' Tax/Base Amount ' , digits_compute = dp . get_precision ( ' Account ' ) , select = True , help = " If the Tax account is a tax code account, this field will contain the taxed amount.If the tax account is base tax code, " \
2009-12-30 11:14:38 +00:00
" this field will contain the basic amount(without tax). " ) ,
2011-07-01 23:41:24 +00:00
' invoice ' : fields . function ( _invoice , string = ' Invoice ' ,
2008-07-22 15:11:28 +00:00
type = ' many2one ' , relation = ' account.invoice ' , fnct_search = _invoice_search ) ,
2014-07-06 14:44:26 +00:00
' account_tax_id ' : fields . many2one ( ' account.tax ' , ' Tax ' , copy = False ) ,
2010-08-17 11:13:35 +00:00
' analytic_account_id ' : fields . many2one ( ' account.analytic.account ' , ' Analytic Account ' ) ,
2014-05-30 16:47:50 +00:00
' company_id ' : fields . related ( ' account_id ' , ' company_id ' , type = ' many2one ' , relation = ' res.company ' ,
2012-11-22 15:30:49 +00:00
string = ' Company ' , store = True , readonly = True )
2008-07-22 15:11:28 +00:00
}
2010-10-25 04:53:36 +00:00
def _get_date ( self , cr , uid , context = None ) :
2010-11-23 11:31:52 +00:00
if context is None :
context or { }
2008-07-22 15:11:28 +00:00
period_obj = self . pool . get ( ' account.period ' )
dt = time . strftime ( ' % Y- % m- %d ' )
2012-11-27 10:04:18 +00:00
if context . get ( ' journal_id ' ) and context . get ( ' period_id ' ) :
2010-10-15 09:23:25 +00:00
cr . execute ( ' SELECT date FROM account_move_line ' \
' WHERE journal_id = %s AND period_id = %s ' \
' ORDER BY id DESC limit 1 ' ,
2008-07-22 15:11:28 +00:00
( context [ ' journal_id ' ] , context [ ' period_id ' ] ) )
res = cr . fetchone ( )
if res :
dt = res [ 0 ]
else :
2010-10-15 09:23:25 +00:00
period = period_obj . browse ( cr , uid , context [ ' period_id ' ] , context = context )
2008-07-22 15:11:28 +00:00
dt = period . date_start
return dt
2010-07-26 06:30:15 +00:00
2010-10-25 04:53:36 +00:00
def _get_currency ( self , cr , uid , context = None ) :
if context is None :
context = { }
2008-10-23 21:06:50 +00:00
if not context . get ( ' journal_id ' , False ) :
return False
cur = self . pool . get ( ' account.journal ' ) . browse ( cr , uid , context [ ' journal_id ' ] ) . currency
return cur and cur . id or False
2012-11-12 14:10:00 +00:00
def _get_period ( self , cr , uid , context = None ) :
"""
Return default account period value
"""
2012-11-22 15:06:45 +00:00
context = context or { }
if context . get ( ' period_id ' , False ) :
return context [ ' period_id ' ]
2012-11-12 14:10:00 +00:00
account_period_obj = self . pool . get ( ' account.period ' )
ids = account_period_obj . find ( cr , uid , context = context )
period_id = False
if ids :
period_id = ids [ 0 ]
return period_id
def _get_journal ( self , cr , uid , context = None ) :
"""
Return journal based on the journal type
"""
2012-11-22 15:06:45 +00:00
context = context or { }
if context . get ( ' journal_id ' , False ) :
return context [ ' journal_id ' ]
2012-11-12 14:10:00 +00:00
journal_id = False
journal_pool = self . pool . get ( ' account.journal ' )
if context . get ( ' journal_type ' , False ) :
jids = journal_pool . search ( cr , uid , [ ( ' type ' , ' = ' , context . get ( ' journal_type ' ) ) ] )
if not jids :
2014-06-25 06:09:36 +00:00
model , action_id = self . pool [ ' ir.model.data ' ] . get_object_reference ( cr , uid , ' account ' , ' action_account_journal_form ' )
msg = _ ( """ Cannot find any account journal of " %s " type for this company, You should create one. \n Please go to Journal Configuration """ ) % context . get ( ' journal_type ' ) . replace ( ' _ ' , ' ' ) . title ( )
raise openerp . exceptions . RedirectWarning ( msg , action_id , _ ( ' Go to the configuration panel ' ) )
2012-11-12 14:10:00 +00:00
journal_id = jids [ 0 ]
return journal_id
2008-07-22 15:11:28 +00:00
_defaults = {
2010-10-15 06:56:48 +00:00
' blocked ' : False ,
' centralisation ' : ' normal ' ,
2008-07-22 15:11:28 +00:00
' date ' : _get_date ,
2012-02-13 18:07:41 +00:00
' date_created ' : fields . date . context_today ,
2010-10-15 06:56:48 +00:00
' state ' : ' draft ' ,
2008-10-23 21:06:50 +00:00
' currency_id ' : _get_currency ,
2012-11-12 14:10:00 +00:00
' journal_id ' : _get_journal ,
2011-11-03 14:52:42 +00:00
' credit ' : 0.0 ,
' debit ' : 0.0 ,
2012-05-10 12:51:23 +00:00
' amount_currency ' : 0.0 ,
2010-11-15 06:18:41 +00:00
' account_id ' : lambda self , cr , uid , c : c . get ( ' account_id ' , False ) ,
2012-11-12 14:10:00 +00:00
' period_id ' : _get_period ,
2010-06-16 11:51:39 +00:00
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' account.move.line ' , context = c )
2008-07-22 15:11:28 +00:00
}
2010-10-15 06:56:48 +00:00
_order = " date desc, id desc "
2008-07-22 15:11:28 +00:00
_sql_constraints = [
( ' credit_debit1 ' , ' CHECK (credit*debit=0) ' , ' Wrong credit or debit value in accounting entry ! ' ) ,
( ' credit_debit2 ' , ' CHECK (credit+debit>=0) ' , ' Wrong credit or debit value in accounting entry ! ' ) ,
]
2010-11-19 13:48:01 +00:00
def _auto_init ( self , cr , context = None ) :
2013-04-17 07:55:46 +00:00
res = super ( account_move_line , self ) . _auto_init ( cr , context = context )
2008-07-22 15:11:28 +00:00
cr . execute ( ' SELECT indexname FROM pg_indexes WHERE indexname = \' account_move_line_journal_id_period_id_index \' ' )
if not cr . fetchone ( ) :
cr . execute ( ' CREATE INDEX account_move_line_journal_id_period_id_index ON account_move_line (journal_id, period_id) ' )
2014-06-06 12:47:33 +00:00
cr . execute ( ' SELECT indexname FROM pg_indexes WHERE indexname = %s ' , ( ' account_move_line_date_id_index ' , ) )
if not cr . fetchone ( ) :
cr . execute ( ' CREATE INDEX account_move_line_date_id_index ON account_move_line (date DESC, id desc) ' )
2013-04-17 07:55:46 +00:00
return res
2008-07-22 15:11:28 +00:00
2010-11-19 13:48:01 +00:00
def _check_no_view ( self , cr , uid , ids , context = None ) :
lines = self . browse ( cr , uid , ids , context = context )
2008-07-22 15:11:28 +00:00
for l in lines :
2014-07-29 09:42:10 +00:00
if l . account_id . type in ( ' view ' , ' consolidation ' ) :
2012-11-01 13:15:42 +00:00
return False
2008-07-22 15:11:28 +00:00
return True
2010-11-19 13:48:01 +00:00
def _check_no_closed ( self , cr , uid , ids , context = None ) :
lines = self . browse ( cr , uid , ids , context = context )
2008-07-22 15:11:28 +00:00
for l in lines :
if l . account_id . type == ' closed ' :
2012-08-07 11:31:37 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' You cannot create journal items on a closed account %s %s . ' ) % ( l . account_id . code , l . account_id . name ) )
2008-07-22 15:11:28 +00:00
return True
2010-11-19 13:48:01 +00:00
def _check_company_id ( self , cr , uid , ids , context = None ) :
lines = self . browse ( cr , uid , ids , context = context )
2010-06-08 06:45:31 +00:00
for l in lines :
2010-06-09 13:22:53 +00:00
if l . company_id != l . account_id . company_id or l . company_id != l . period_id . company_id :
return False
return True
2011-07-06 10:07:01 +00:00
def _check_date ( self , cr , uid , ids , context = None ) :
2011-07-13 08:52:39 +00:00
for l in self . browse ( cr , uid , ids , context = context ) :
2011-07-06 10:07:01 +00:00
if l . journal_id . allow_date :
if not time . strptime ( l . date [ : 10 ] , ' % Y- % m- %d ' ) > = time . strptime ( l . period_id . date_start , ' % Y- % m- %d ' ) or not time . strptime ( l . date [ : 10 ] , ' % Y- % m- %d ' ) < = time . strptime ( l . period_id . date_stop , ' % Y- % m- %d ' ) :
return False
return True
2011-10-17 15:21:47 +00:00
def _check_currency ( self , cr , uid , ids , context = None ) :
for l in self . browse ( cr , uid , ids , context = context ) :
if l . account_id . currency_id :
if not l . currency_id or not l . currency_id . id == l . account_id . currency_id . id :
return False
return True
2012-10-26 10:51:32 +00:00
def _check_currency_and_amount ( self , cr , uid , ids , context = None ) :
for l in self . browse ( cr , uid , ids , context = context ) :
2012-11-22 14:28:19 +00:00
if ( l . amount_currency and not l . currency_id ) :
2012-10-26 10:51:32 +00:00
return False
return True
def _check_currency_amount ( self , cr , uid , ids , context = None ) :
for l in self . browse ( cr , uid , ids , context = context ) :
if l . amount_currency :
if ( l . amount_currency > 0.0 and l . credit > 0.0 ) or ( l . amount_currency < 0.0 and l . debit > 0.0 ) :
return False
return True
2012-10-26 11:06:31 +00:00
def _check_currency_company ( self , cr , uid , ids , context = None ) :
for l in self . browse ( cr , uid , ids , context = context ) :
if l . currency_id . id == l . company_id . currency_id . id :
return False
return True
2008-07-22 15:11:28 +00:00
_constraints = [
2014-07-29 09:42:10 +00:00
( _check_no_view , ' You cannot create journal items on an account of type view or consolidation. ' , [ ' account_id ' ] ) ,
2012-07-25 07:33:57 +00:00
( _check_no_closed , ' You cannot create journal items on closed account. ' , [ ' account_id ' ] ) ,
2012-07-11 08:48:21 +00:00
( _check_company_id , ' Account and Period must belong to the same company. ' , [ ' company_id ' ] ) ,
2011-12-31 07:57:20 +00:00
( _check_date , ' The date of your Journal Entry is not in the defined period! You should change the date or remove this constraint from the journal. ' , [ ' date ' ] ) ,
( _check_currency , ' The selected account of your Journal Entry forces to provide a secondary currency. You should remove the secondary currency on the account or select a multi-currency view on the journal. ' , [ ' currency_id ' ] ) ,
2012-10-26 10:51:32 +00:00
( _check_currency_and_amount , " You cannot create journal items with a secondary currency without recording both ' currency ' and ' amount currency ' field. " , [ ' currency_id ' , ' amount_currency ' ] ) ,
2014-04-23 12:11:17 +00:00
( _check_currency_amount , ' The amount expressed in the secondary currency must be positive when account is debited and negative when account is credited. ' , [ ' amount_currency ' ] ) ,
2012-11-22 14:28:19 +00:00
( _check_currency_company , " You cannot provide a secondary currency if it is the same than the company one. " , [ ' currency_id ' ] ) ,
2008-07-22 15:11:28 +00:00
]
2008-08-22 14:53:43 +00:00
#TODO: ONCHANGE_ACCOUNT_ID: set account_tax_id
2010-11-25 11:58:38 +00:00
def onchange_currency ( self , cr , uid , ids , account_id , amount , currency_id , date = False , journal = False , context = None ) :
if context is None :
context = { }
2010-10-15 09:23:25 +00:00
account_obj = self . pool . get ( ' account.account ' )
journal_obj = self . pool . get ( ' account.journal ' )
currency_obj = self . pool . get ( ' res.currency ' )
2008-10-23 21:06:50 +00:00
if ( not currency_id ) or ( not account_id ) :
return { }
result = { }
2010-12-13 06:43:09 +00:00
acc = account_obj . browse ( cr , uid , account_id , context = context )
2008-10-23 21:06:50 +00:00
if ( amount > 0 ) and journal :
2010-10-15 09:23:25 +00:00
x = journal_obj . browse ( cr , uid , journal ) . default_credit_account_id
2008-10-23 21:06:50 +00:00
if x : acc = x
2014-07-06 14:44:26 +00:00
context = dict ( context )
2010-12-22 16:09:26 +00:00
context . update ( {
' date ' : date ,
' res.currency.compute.account ' : acc ,
} )
v = currency_obj . compute ( cr , uid , currency_id , acc . company_id . currency_id . id , amount , context = context )
2008-10-23 21:06:50 +00:00
result [ ' value ' ] = {
2010-10-15 09:23:25 +00:00
' debit ' : v > 0 and v or 0.0 ,
' credit ' : v < 0 and - v or 0.0
2008-10-23 21:06:50 +00:00
}
return result
2013-04-18 13:40:32 +00:00
def onchange_partner_id ( self , cr , uid , ids , move_id , partner_id , account_id = None , debit = 0 , credit = 0 , date = False , journal = False , context = None ) :
2010-10-15 09:23:25 +00:00
partner_obj = self . pool . get ( ' res.partner ' )
payment_term_obj = self . pool . get ( ' account.payment.term ' )
journal_obj = self . pool . get ( ' account.journal ' )
fiscal_pos_obj = self . pool . get ( ' account.fiscal.position ' )
2008-07-22 15:11:28 +00:00
val = { }
2008-09-08 06:35:06 +00:00
val [ ' date_maturity ' ] = False
2008-09-09 07:28:14 +00:00
2008-09-08 06:35:06 +00:00
if not partner_id :
return { ' value ' : val }
if not date :
2010-03-01 05:16:51 +00:00
date = datetime . now ( ) . strftime ( ' % Y- % m- %d ' )
2012-07-11 11:14:34 +00:00
jt = False
if journal :
2013-04-18 13:40:32 +00:00
jt = journal_obj . browse ( cr , uid , journal , context = context ) . type
part = partner_obj . browse ( cr , uid , partner_id , context = context )
2008-09-09 07:28:14 +00:00
2012-07-11 11:14:34 +00:00
payment_term_id = False
if jt and jt in ( ' purchase ' , ' purchase_refund ' ) and part . property_supplier_payment_term :
payment_term_id = part . property_supplier_payment_term . id
elif jt and part . property_payment_term :
payment_term_id = part . property_payment_term . id
if payment_term_id :
res = payment_term_obj . compute ( cr , uid , payment_term_id , 100 , date )
2008-12-10 14:32:01 +00:00
if res :
val [ ' date_maturity ' ] = res [ 0 ] [ 0 ]
2008-09-08 06:35:06 +00:00
if not account_id :
id1 = part . property_account_payable . id
id2 = part . property_account_receivable . id
2012-07-11 11:14:34 +00:00
if jt :
2010-08-02 14:18:02 +00:00
if jt in ( ' sale ' , ' purchase_refund ' ) :
2010-10-15 09:23:25 +00:00
val [ ' account_id ' ] = fiscal_pos_obj . map_account ( cr , uid , part and part . property_account_position or False , id2 )
2011-06-06 05:30:15 +00:00
elif jt in ( ' purchase ' , ' sale_refund ' ) :
2010-10-15 09:23:25 +00:00
val [ ' account_id ' ] = fiscal_pos_obj . map_account ( cr , uid , part and part . property_account_position or False , id1 )
2011-06-06 05:30:15 +00:00
elif jt in ( ' general ' , ' bank ' , ' cash ' ) :
2011-09-17 17:30:01 +00:00
if part . customer :
2011-06-06 05:30:15 +00:00
val [ ' account_id ' ] = fiscal_pos_obj . map_account ( cr , uid , part and part . property_account_position or False , id2 )
2011-09-17 17:30:01 +00:00
elif part . supplier :
2011-06-06 05:30:15 +00:00
val [ ' account_id ' ] = fiscal_pos_obj . map_account ( cr , uid , part and part . property_account_position or False , id1 )
2008-12-18 14:39:05 +00:00
if val . get ( ' account_id ' , False ) :
2013-04-18 13:40:32 +00:00
d = self . onchange_account_id ( cr , uid , ids , account_id = val [ ' account_id ' ] , partner_id = part . id , context = context )
2008-12-10 14:32:01 +00:00
val . update ( d [ ' value ' ] )
return { ' value ' : val }
2013-04-18 13:40:32 +00:00
def onchange_account_id ( self , cr , uid , ids , account_id = False , partner_id = False , context = None ) :
2010-10-15 09:23:25 +00:00
account_obj = self . pool . get ( ' account.account ' )
partner_obj = self . pool . get ( ' res.partner ' )
fiscal_pos_obj = self . pool . get ( ' account.fiscal.position ' )
2008-12-10 14:32:01 +00:00
val = { }
if account_id :
2013-04-18 13:40:32 +00:00
res = account_obj . browse ( cr , uid , account_id , context = context )
2009-01-15 17:17:46 +00:00
tax_ids = res . tax_ids
if tax_ids and partner_id :
2013-04-18 13:40:32 +00:00
part = partner_obj . browse ( cr , uid , partner_id , context = context )
2010-10-15 09:23:25 +00:00
tax_id = fiscal_pos_obj . map_tax ( cr , uid , part and part . property_account_position or False , tax_ids ) [ 0 ]
2009-01-15 17:17:46 +00:00
else :
tax_id = tax_ids and tax_ids [ 0 ] . id or False
val [ ' account_tax_id ' ] = tax_id
2010-10-15 09:23:25 +00:00
return { ' value ' : val }
2008-07-22 15:11:28 +00:00
#
# type: the type if reconciliation (no logic behind this field, for info)
#
# writeoff; entry generated for the difference between the lines
#
2010-06-18 11:15:59 +00:00
def search ( self , cr , uid , args , offset = 0 , limit = None , order = None , context = None , count = False ) :
if context is None :
context = { }
2014-06-19 08:57:32 +00:00
if context . get ( ' fiscalyear ' ) :
args . append ( ( ' period_id.fiscalyear_id ' , ' = ' , context . get ( ' fiscalyear ' , False ) ) )
2010-06-18 11:15:59 +00:00
if context and context . get ( ' next_partner_only ' , False ) :
if not context . get ( ' partner_id ' , False ) :
2012-09-18 12:46:40 +00:00
partner = self . list_partners_to_reconcile ( cr , uid , context = context )
if partner :
partner = partner [ 0 ]
2010-06-18 11:15:59 +00:00
else :
partner = context . get ( ' partner_id ' , False )
if not partner :
return [ ]
args . append ( ( ' partner_id ' , ' = ' , partner [ 0 ] ) )
return super ( account_move_line , self ) . search ( cr , uid , args , offset , limit , order , context , count )
2014-09-04 09:32:16 +00:00
def prepare_move_lines_for_reconciliation_widget ( self , cr , uid , lines , target_currency = False , target_date = False , context = None ) :
""" Returns move lines formatted for the manual/bank reconciliation widget
: param target_currency : curreny you want the move line debit / credit converted into
: param target_date : date to use for the monetary conversion
"""
if not lines :
return [ ]
if context is None :
context = { }
ctx = context . copy ( )
currency_obj = self . pool . get ( ' res.currency ' )
company_currency = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context ) . company_id . currency_id
rml_parser = report_sxw . rml_parse ( cr , uid , ' reconciliation_widget_aml ' , context = context )
ret = [ ]
for line in lines :
2014-09-10 14:58:31 +00:00
partial_reconciliation_siblings_ids = [ ]
2014-09-04 09:32:16 +00:00
if line . reconcile_partial_id :
2014-09-10 14:58:31 +00:00
partial_reconciliation_siblings_ids = self . search ( cr , uid , [ ( ' reconcile_partial_id ' , ' = ' , line . reconcile_partial_id . id ) ] , context = context )
2014-09-12 13:28:50 +00:00
partial_reconciliation_siblings_ids . remove ( line . id )
2014-09-04 09:32:16 +00:00
ret_line = {
' id ' : line . id ,
2014-09-17 14:13:45 +00:00
' name ' : line . name != ' / ' and line . move_id . name + ' : ' + line . name or line . move_id . name ,
2014-09-04 09:32:16 +00:00
' ref ' : line . move_id . ref ,
' account_code ' : line . account_id . code ,
' account_name ' : line . account_id . name ,
' account_type ' : line . account_id . type ,
' date_maturity ' : line . date_maturity ,
' date ' : line . date ,
' period_name ' : line . period_id . name ,
' journal_name ' : line . journal_id . name ,
' partner_id ' : line . partner_id . id ,
' partner_name ' : line . partner_id . name ,
2014-09-16 10:23:13 +00:00
' is_partially_reconciled ' : bool ( line . reconcile_partial_id ) ,
2014-09-10 14:58:31 +00:00
' partial_reconciliation_siblings_ids ' : partial_reconciliation_siblings_ids ,
2014-09-04 09:32:16 +00:00
}
2014-09-12 10:01:25 +00:00
# Amount residual can be negative
debit = line . debit
credit = line . credit
2014-11-26 10:27:35 +00:00
amount = line . amount_residual
amount_currency = line . amount_residual_currency
2014-09-12 10:01:25 +00:00
if line . amount_residual < 0 :
debit , credit = credit , debit
2014-11-26 10:27:35 +00:00
amount = - amount
amount_currency = - amount_currency
2014-09-12 10:01:25 +00:00
2014-09-04 09:32:16 +00:00
# Get right debit / credit:
2014-11-26 10:27:35 +00:00
target_currency = target_currency or company_currency
2014-09-04 09:32:16 +00:00
line_currency = line . currency_id or company_currency
amount_currency_str = " "
2014-09-16 10:23:13 +00:00
total_amount_currency_str = " "
2014-11-26 10:27:35 +00:00
if line_currency != company_currency :
total_amount = line . amount_currency
actual_debit = debit > 0 and amount_currency or 0.0
actual_credit = credit > 0 and amount_currency or 0.0
2014-09-04 09:32:16 +00:00
else :
2014-11-26 10:27:35 +00:00
total_amount = abs ( debit - credit )
actual_debit = debit > 0 and amount or 0.0
actual_credit = credit > 0 and amount or 0.0
if line_currency != target_currency :
amount_currency_str = rml_parser . formatLang ( actual_debit or actual_credit , currency_obj = line_currency )
total_amount_currency_str = rml_parser . formatLang ( total_amount , currency_obj = line_currency )
ret_line [ ' credit_currency ' ] = actual_credit
ret_line [ ' debit_currency ' ] = actual_debit
ctx = context . copy ( )
if target_date :
ctx . update ( { ' date ' : target_date } )
total_amount = currency_obj . compute ( cr , uid , line_currency . id , target_currency . id , total_amount , context = ctx )
actual_debit = currency_obj . compute ( cr , uid , line_currency . id , target_currency . id , actual_debit , context = ctx )
actual_credit = currency_obj . compute ( cr , uid , line_currency . id , target_currency . id , actual_credit , context = ctx )
amount_str = rml_parser . formatLang ( actual_debit or actual_credit , currency_obj = target_currency )
total_amount_str = rml_parser . formatLang ( total_amount , currency_obj = target_currency )
ret_line [ ' debit ' ] = actual_debit
ret_line [ ' credit ' ] = actual_credit
2014-09-04 09:32:16 +00:00
ret_line [ ' amount_str ' ] = amount_str
2014-11-26 10:27:35 +00:00
ret_line [ ' total_amount_str ' ] = total_amount_str
2014-09-04 09:32:16 +00:00
ret_line [ ' amount_currency_str ' ] = amount_currency_str
2014-09-16 10:23:13 +00:00
ret_line [ ' total_amount_currency_str ' ] = total_amount_currency_str
2014-09-04 09:32:16 +00:00
ret . append ( ret_line )
return ret
2012-09-18 12:46:40 +00:00
def list_partners_to_reconcile ( self , cr , uid , context = None ) :
2010-06-18 11:15:59 +00:00
cr . execute (
2013-03-18 11:30:43 +00:00
""" SELECT partner_id FROM (
2013-03-22 14:34:58 +00:00
SELECT l . partner_id , p . last_reconciliation_date , SUM ( l . debit ) AS debit , SUM ( l . credit ) AS credit , MAX ( l . create_date ) AS max_date
2010-06-18 11:15:59 +00:00
FROM account_move_line l
2012-09-18 12:46:40 +00:00
RIGHT JOIN account_account a ON ( a . id = l . account_id )
RIGHT JOIN res_partner p ON ( l . partner_id = p . id )
2010-06-18 11:15:59 +00:00
WHERE a . reconcile IS TRUE
AND l . reconcile_id IS NULL
AND l . state < > ' draft '
2012-09-18 12:46:40 +00:00
GROUP BY l . partner_id , p . last_reconciliation_date
) AS s
2013-03-18 14:43:42 +00:00
WHERE debit > 0 AND credit > 0 AND ( last_reconciliation_date IS NULL OR max_date > last_reconciliation_date )
2012-09-18 12:46:40 +00:00
ORDER BY last_reconciliation_date """ )
2013-03-26 09:34:13 +00:00
ids = [ x [ 0 ] for x in cr . fetchall ( ) ]
2014-05-30 16:47:50 +00:00
if not ids :
2013-03-26 09:34:13 +00:00
return [ ]
# To apply the ir_rules
partner_obj = self . pool . get ( ' res.partner ' )
ids = partner_obj . search ( cr , uid , [ ( ' id ' , ' in ' , ids ) ] , context = context )
return partner_obj . name_get ( cr , uid , ids , context = context )
2010-06-18 11:15:59 +00:00
2011-09-27 13:07:30 +00:00
def reconcile_partial ( self , cr , uid , ids , type = ' auto ' , context = None , writeoff_acc_id = False , writeoff_period_id = False , writeoff_journal_id = False ) :
2010-10-15 09:23:25 +00:00
move_rec_obj = self . pool . get ( ' account.move.reconcile ' )
2008-07-22 15:11:28 +00:00
merges = [ ]
unmerge = [ ]
total = 0.0
merges_rec = [ ]
2010-06-09 13:22:53 +00:00
company_list = [ ]
2010-06-11 13:03:42 +00:00
if context is None :
context = { }
2010-06-09 13:22:53 +00:00
for line in self . browse ( cr , uid , ids , context = context ) :
2010-06-10 04:11:30 +00:00
if company_list and not line . company_id . id in company_list :
2012-08-07 11:34:14 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( ' To reconcile the entries company should be the same for all entries. ' ) )
2010-06-10 04:11:30 +00:00
company_list . append ( line . company_id . id )
2010-06-09 13:22:53 +00:00
2010-12-13 06:43:09 +00:00
for line in self . browse ( cr , uid , ids , context = context ) :
2011-10-13 22:39:58 +00:00
if line . account_id . currency_id :
currency_id = line . account_id . currency_id
else :
currency_id = line . company_id . currency_id
2008-07-22 15:11:28 +00:00
if line . reconcile_id :
2014-05-30 16:47:50 +00:00
raise osv . except_osv ( _ ( ' Warning ' ) , _ ( " Journal Item ' %s ' (id: %s ), Move ' %s ' is already reconciled! " ) % ( line . name , line . id , line . move_id . name ) )
2008-07-22 15:11:28 +00:00
if line . reconcile_partial_id :
for line2 in line . reconcile_partial_id . line_partial_ids :
2014-05-30 16:47:50 +00:00
if line2 . state != ' valid ' :
raise osv . except_osv ( _ ( ' Warning ' ) , _ ( " Journal Item ' %s ' (id: %s ) cannot be used in a reconciliation as it is not balanced! " ) % ( line2 . name , line2 . id ) )
2008-07-22 15:11:28 +00:00
if not line2 . reconcile_id :
2010-05-12 10:41:58 +00:00
if line2 . id not in merges :
merges . append ( line2 . id )
2011-10-13 14:58:04 +00:00
if line2 . account_id . currency_id :
total + = line2 . amount_currency
else :
total + = ( line2 . debit or 0.0 ) - ( line2 . credit or 0.0 )
2008-07-22 15:11:28 +00:00
merges_rec . append ( line . reconcile_partial_id . id )
else :
unmerge . append ( line . id )
2011-10-13 14:58:04 +00:00
if line . account_id . currency_id :
total + = line . amount_currency
else :
total + = ( line . debit or 0.0 ) - ( line . credit or 0.0 )
2011-10-13 22:39:58 +00:00
if self . pool . get ( ' res.currency ' ) . is_zero ( cr , uid , currency_id , total ) :
2011-09-27 13:07:30 +00:00
res = self . reconcile ( cr , uid , merges + unmerge , context = context , writeoff_acc_id = writeoff_acc_id , writeoff_period_id = writeoff_period_id , writeoff_journal_id = writeoff_journal_id )
2008-08-29 11:28:32 +00:00
return res
2014-08-14 13:46:37 +00:00
# marking the lines as reconciled does not change their validity, so there is no need
# to revalidate their moves completely.
reconcile_context = dict ( context , novalidate = True )
2010-10-15 09:23:25 +00:00
r_id = move_rec_obj . create ( cr , uid , {
2008-07-22 15:11:28 +00:00
' type ' : type ,
' line_partial_ids ' : map ( lambda x : ( 4 , x , False ) , merges + unmerge )
2014-08-14 13:46:37 +00:00
} , context = reconcile_context )
move_rec_obj . reconcile_partial_check ( cr , uid , [ r_id ] + merges_rec , context = reconcile_context )
2014-06-18 15:56:49 +00:00
return r_id
2008-07-22 15:11:28 +00:00
2010-06-11 13:03:42 +00:00
def reconcile ( self , cr , uid , ids , type = ' auto ' , writeoff_acc_id = False , writeoff_period_id = False , writeoff_journal_id = False , context = None ) :
2010-10-15 09:23:25 +00:00
account_obj = self . pool . get ( ' account.account ' )
move_obj = self . pool . get ( ' account.move ' )
move_rec_obj = self . pool . get ( ' account.move.reconcile ' )
partner_obj = self . pool . get ( ' res.partner ' )
currency_obj = self . pool . get ( ' res.currency ' )
2008-07-22 15:11:28 +00:00
lines = self . browse ( cr , uid , ids , context = context )
unrec_lines = filter ( lambda x : not x [ ' reconcile_id ' ] , lines )
credit = debit = 0.0
currency = 0.0
account_id = False
partner_id = False
2010-06-11 13:03:42 +00:00
if context is None :
context = { }
2010-06-09 13:22:53 +00:00
company_list = [ ]
for line in self . browse ( cr , uid , ids , context = context ) :
2010-06-10 04:11:30 +00:00
if company_list and not line . company_id . id in company_list :
2012-08-07 11:34:14 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( ' To reconcile the entries company should be the same for all entries. ' ) )
2010-06-10 04:11:30 +00:00
company_list . append ( line . company_id . id )
2008-07-22 15:11:28 +00:00
for line in unrec_lines :
if line . state < > ' valid ' :
2012-08-07 11:31:37 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) ,
2008-07-22 15:11:28 +00:00
_ ( ' Entry " %s " is not valid ! ' ) % line . name )
credit + = line [ ' credit ' ]
debit + = line [ ' debit ' ]
currency + = line [ ' amount_currency ' ] or 0.0
account_id = line [ ' account_id ' ] [ ' id ' ]
partner_id = ( line [ ' partner_id ' ] and line [ ' partner_id ' ] [ ' id ' ] ) or False
writeoff = debit - credit
2010-07-22 04:43:18 +00:00
2008-08-25 15:41:01 +00:00
# Ifdate_p in context => take this date
if context . has_key ( ' date_p ' ) and context [ ' date_p ' ] :
date = context [ ' date_p ' ]
else :
date = time . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
2010-06-10 13:34:19 +00:00
cr . execute ( ' SELECT account_id, reconcile_id ' \
' FROM account_move_line ' \
' WHERE id IN %s ' \
' GROUP BY account_id,reconcile_id ' ,
2010-10-15 09:23:25 +00:00
( tuple ( ids ) , ) )
2008-07-22 15:11:28 +00:00
r = cr . fetchall ( )
2009-11-30 10:24:22 +00:00
#TODO: move this check to a constraint in the account_move_reconcile object
2014-01-10 16:15:19 +00:00
if len ( r ) != 1 :
raise osv . except_osv ( _ ( ' Error ' ) , _ ( ' Entries are not of the same account or already reconciled ! ' ) )
2008-11-13 05:34:32 +00:00
if not unrec_lines :
2012-08-07 11:31:37 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' Entry is already reconciled. ' ) )
2010-10-15 09:23:25 +00:00
account = account_obj . browse ( cr , uid , account_id , context = context )
2014-01-10 16:15:19 +00:00
if not account . reconcile :
raise osv . except_osv ( _ ( ' Error ' ) , _ ( ' The account is not defined to be reconciled ! ' ) )
2008-07-22 15:11:28 +00:00
if r [ 0 ] [ 1 ] != None :
2012-08-07 11:31:37 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' Some entries are already reconciled. ' ) )
2008-07-22 15:11:28 +00:00
2014-01-10 16:15:19 +00:00
if ( not currency_obj . is_zero ( cr , uid , account . company_id . currency_id , writeoff ) ) or \
2010-10-15 09:23:25 +00:00
( account . currency_id and ( not currency_obj . is_zero ( cr , uid , account . currency_id , currency ) ) ) :
2008-07-22 15:11:28 +00:00
if not writeoff_acc_id :
2012-08-07 11:34:14 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( ' You have to provide an account for the write off/exchange difference entry. ' ) )
2008-07-22 15:11:28 +00:00
if writeoff > 0 :
debit = writeoff
credit = 0.0
self_credit = writeoff
self_debit = 0.0
else :
debit = 0.0
credit = - writeoff
self_credit = 0.0
self_debit = - writeoff
2008-08-25 15:41:01 +00:00
# If comment exist in context, take it
2008-09-25 04:39:44 +00:00
if ' comment ' in context and context [ ' comment ' ] :
2010-10-15 09:23:25 +00:00
libelle = context [ ' comment ' ]
2008-08-25 15:41:01 +00:00
else :
2010-12-13 13:56:37 +00:00
libelle = _ ( ' Write-Off ' )
2011-01-05 13:34:15 +00:00
cur_obj = self . pool . get ( ' res.currency ' )
cur_id = False
amount_currency_writeoff = 0.0
if context . get ( ' company_currency_id ' , False ) != context . get ( ' currency_id ' , False ) :
cur_id = context . get ( ' currency_id ' , False )
for line in unrec_lines :
if line . currency_id and line . currency_id . id == context . get ( ' currency_id ' , False ) :
amount_currency_writeoff + = line . amount_currency
else :
tmp_amount = cur_obj . compute ( cr , uid , line . account_id . company_id . currency_id . id , context . get ( ' currency_id ' , False ) , abs ( line . debit - line . credit ) , context = { ' date ' : line . date } )
amount_currency_writeoff + = ( line . debit > 0 ) and tmp_amount or - tmp_amount
2008-07-22 15:11:28 +00:00
writeoff_lines = [
( 0 , 0 , {
2010-10-15 09:23:25 +00:00
' name ' : libelle ,
' debit ' : self_debit ,
' credit ' : self_credit ,
' account_id ' : account_id ,
' date ' : date ,
' partner_id ' : partner_id ,
2011-01-05 13:34:15 +00:00
' currency_id ' : cur_id or ( account . currency_id . id or False ) ,
' amount_currency ' : amount_currency_writeoff and - 1 * amount_currency_writeoff or ( account . currency_id . id and - 1 * currency or 0.0 )
2008-07-22 15:11:28 +00:00
} ) ,
( 0 , 0 , {
2010-10-15 09:23:25 +00:00
' name ' : libelle ,
' debit ' : debit ,
' credit ' : credit ,
' account_id ' : writeoff_acc_id ,
2009-11-02 08:40:00 +00:00
' analytic_account_id ' : context . get ( ' analytic_id ' , False ) ,
2010-10-15 09:23:25 +00:00
' date ' : date ,
2011-01-05 13:34:15 +00:00
' partner_id ' : partner_id ,
' currency_id ' : cur_id or ( account . currency_id . id or False ) ,
' amount_currency ' : amount_currency_writeoff and amount_currency_writeoff or ( account . currency_id . id and currency or 0.0 )
2008-07-22 15:11:28 +00:00
} )
]
2010-10-15 09:23:25 +00:00
writeoff_move_id = move_obj . create ( cr , uid , {
2008-07-22 15:11:28 +00:00
' period_id ' : writeoff_period_id ,
' journal_id ' : writeoff_journal_id ,
2009-11-02 08:40:00 +00:00
' date ' : date ,
2008-07-22 15:11:28 +00:00
' state ' : ' draft ' ,
' line_id ' : writeoff_lines
} )
writeoff_line_ids = self . search ( cr , uid , [ ( ' move_id ' , ' = ' , writeoff_move_id ) , ( ' account_id ' , ' = ' , account_id ) ] )
2011-01-05 13:34:15 +00:00
if account_id == writeoff_acc_id :
writeoff_line_ids = [ writeoff_line_ids [ 1 ] ]
2008-07-22 15:11:28 +00:00
ids + = writeoff_line_ids
2014-08-14 13:46:37 +00:00
# marking the lines as reconciled does not change their validity, so there is no need
# to revalidate their moves completely.
reconcile_context = dict ( context , novalidate = True )
2010-10-15 09:23:25 +00:00
r_id = move_rec_obj . create ( cr , uid , {
2008-07-22 15:11:28 +00:00
' type ' : type ,
2010-10-15 09:23:25 +00:00
' line_id ' : map ( lambda x : ( 4 , x , False ) , ids ) ,
' line_partial_ids ' : map ( lambda x : ( 3 , x , False ) , ids )
2014-08-14 13:46:37 +00:00
} , context = reconcile_context )
2008-07-22 15:11:28 +00:00
# the id of the move.reconcile is written in the move.line (self) by the create method above
# because of the way the line_id are defined: (4, x, False)
for id in ids :
2013-11-21 12:06:11 +00:00
workflow . trg_trigger ( uid , ' account.move.line ' , id , cr )
2010-06-18 11:15:59 +00:00
if lines and lines [ 0 ] :
2010-09-22 06:57:27 +00:00
partner_id = lines [ 0 ] . partner_id and lines [ 0 ] . partner_id . id or False
2012-11-10 13:29:45 +00:00
if partner_id and not partner_obj . has_something_to_reconcile ( cr , uid , partner_id , context = context ) :
2012-09-18 12:46:40 +00:00
partner_obj . mark_as_reconciled ( cr , uid , [ partner_id ] , context = context )
2008-07-22 15:11:28 +00:00
return r_id
2010-12-13 06:43:09 +00:00
def view_header_get ( self , cr , user , view_id , view_type , context = None ) :
if context is None :
context = { }
context = self . convert_to_period ( cr , user , context = context )
2008-08-25 22:20:48 +00:00
if context . get ( ' account_id ' , False ) :
2010-10-15 09:23:25 +00:00
cr . execute ( ' SELECT code FROM account_account WHERE id = %s ' , ( context [ ' account_id ' ] , ) )
2008-08-25 22:20:48 +00:00
res = cr . fetchone ( )
2011-01-17 05:15:25 +00:00
if res :
res = _ ( ' Entries: ' ) + ( res [ 0 ] or ' ' )
2008-08-25 22:20:48 +00:00
return res
2008-07-22 15:11:28 +00:00
if ( not context . get ( ' journal_id ' , False ) ) or ( not context . get ( ' period_id ' , False ) ) :
return False
2012-09-13 12:41:36 +00:00
if context . get ( ' search_default_journal_id ' , False ) :
context [ ' journal_id ' ] = context . get ( ' search_default_journal_id ' )
2010-10-15 09:23:25 +00:00
cr . execute ( ' SELECT code FROM account_journal WHERE id = %s ' , ( context [ ' journal_id ' ] , ) )
2008-07-22 15:11:28 +00:00
j = cr . fetchone ( ) [ 0 ] or ' '
2010-10-15 09:23:25 +00:00
cr . execute ( ' SELECT code FROM account_period WHERE id = %s ' , ( context [ ' period_id ' ] , ) )
2008-07-22 15:11:28 +00:00
p = cr . fetchone ( ) [ 0 ] or ' '
if j or p :
2011-01-12 12:15:11 +00:00
return j + ( p and ( ' : ' + p ) or ' ' )
2008-08-25 22:20:48 +00:00
return False
2008-07-22 15:11:28 +00:00
2010-11-19 13:48:01 +00:00
def onchange_date ( self , cr , user , ids , date , context = None ) :
2010-08-12 20:17:33 +00:00
"""
Returns a dict that contains new values and context
@param cr : A database cursor
@param user : ID of the user currently logged in
@param date : latest value from user input for field date
@param args : other arguments
@param context : context arguments , like lang , time zone
@return : Returns a dict which contains new values , and context
"""
res = { }
2010-11-23 11:31:52 +00:00
if context is None :
context = { }
2010-08-12 20:17:33 +00:00
period_pool = self . pool . get ( ' account.period ' )
2013-04-18 10:39:07 +00:00
pids = period_pool . find ( cr , user , date , context = context )
2010-08-12 20:17:33 +00:00
if pids :
2014-07-06 14:44:26 +00:00
res . update ( { ' period_id ' : pids [ 0 ] } )
context = dict ( context , period_id = pids [ 0 ] )
2010-08-12 20:17:33 +00:00
return {
' value ' : res ,
' context ' : context ,
}
2010-07-23 14:07:26 +00:00
2010-11-19 13:48:01 +00:00
def _check_moves ( self , cr , uid , context = None ) :
2010-05-10 10:05:50 +00:00
# use the first move ever created for this journal and period
2010-11-23 11:31:52 +00:00
if context is None :
context = { }
2010-10-15 09:23:25 +00:00
cr . execute ( ' SELECT id, state, name FROM account_move WHERE journal_id = %s AND period_id = %s ORDER BY id limit 1 ' , ( context [ ' journal_id ' ] , context [ ' period_id ' ] ) )
2010-05-10 10:05:50 +00:00
res = cr . fetchone ( )
if res :
if res [ 1 ] != ' draft ' :
2012-08-07 11:06:16 +00:00
raise osv . except_osv ( _ ( ' User Error! ' ) ,
2010-05-10 10:05:50 +00:00
_ ( ' The account move ( %s ) for centralisation ' \
2012-08-06 15:44:10 +00:00
' has been confirmed. ' ) % res [ 2 ] )
2010-05-10 10:05:50 +00:00
return res
2012-11-22 14:28:19 +00:00
def _remove_move_reconcile ( self , cr , uid , move_ids = None , opening_reconciliation = False , context = None ) :
2010-09-07 05:03:52 +00:00
# Function remove move rencocile ids related with moves
obj_move_line = self . pool . get ( ' account.move.line ' )
obj_move_rec = self . pool . get ( ' account.move.reconcile ' )
unlink_ids = [ ]
if not move_ids :
return True
2010-10-15 09:23:25 +00:00
recs = obj_move_line . read ( cr , uid , move_ids , [ ' reconcile_id ' , ' reconcile_partial_id ' ] )
2010-09-07 05:03:52 +00:00
full_recs = filter ( lambda x : x [ ' reconcile_id ' ] , recs )
rec_ids = [ rec [ ' reconcile_id ' ] [ 0 ] for rec in full_recs ]
part_recs = filter ( lambda x : x [ ' reconcile_partial_id ' ] , recs )
part_rec_ids = [ rec [ ' reconcile_partial_id ' ] [ 0 ] for rec in part_recs ]
unlink_ids + = rec_ids
unlink_ids + = part_rec_ids
2014-04-10 09:51:32 +00:00
all_moves = obj_move_line . search ( cr , uid , [ ' | ' , ( ' reconcile_id ' , ' in ' , unlink_ids ) , ( ' reconcile_partial_id ' , ' in ' , unlink_ids ) ] )
2014-04-22 10:11:28 +00:00
all_moves = list ( set ( all_moves ) - set ( move_ids ) )
2010-10-11 05:51:53 +00:00
if unlink_ids :
2012-11-22 14:28:19 +00:00
if opening_reconciliation :
2014-06-04 14:33:58 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) ,
_ ( ' Opening Entries have already been generated. Please run " Cancel Closing Entries " wizard to cancel those entries and then run this wizard. ' ) )
2012-11-22 14:28:19 +00:00
obj_move_rec . write ( cr , uid , unlink_ids , { ' opening_reconciliation ' : False } )
2010-09-07 05:03:52 +00:00
obj_move_rec . unlink ( cr , uid , unlink_ids )
2014-05-07 13:35:52 +00:00
if len ( all_moves ) > = 2 :
2014-04-10 09:51:32 +00:00
obj_move_line . reconcile_partial ( cr , uid , all_moves , ' auto ' , context = context )
2010-09-07 05:03:52 +00:00
return True
2010-11-19 13:48:01 +00:00
def unlink ( self , cr , uid , ids , context = None , check = True ) :
2010-11-23 11:31:52 +00:00
if context is None :
context = { }
2010-10-15 09:23:25 +00:00
move_obj = self . pool . get ( ' account.move ' )
2008-07-22 15:11:28 +00:00
self . _update_check ( cr , uid , ids , context )
result = False
2011-03-25 15:38:54 +00:00
move_ids = set ( )
2010-11-23 11:31:52 +00:00
for line in self . browse ( cr , uid , ids , context = context ) :
2011-03-25 15:38:54 +00:00
move_ids . add ( line . move_id . id )
2010-10-15 09:23:25 +00:00
context [ ' journal_id ' ] = line . journal_id . id
context [ ' period_id ' ] = line . period_id . id
2008-07-22 15:11:28 +00:00
result = super ( account_move_line , self ) . unlink ( cr , uid , [ line . id ] , context = context )
2011-03-25 15:38:54 +00:00
move_ids = list ( move_ids )
if check and move_ids :
2011-03-24 09:56:31 +00:00
move_obj . validate ( cr , uid , move_ids , context = context )
2008-07-22 15:11:28 +00:00
return result
def write ( self , cr , uid , ids , vals , context = None , check = True , update_check = True ) :
2010-05-10 10:05:50 +00:00
if context is None :
2008-07-22 15:11:28 +00:00
context = { }
2010-10-15 06:56:48 +00:00
move_obj = self . pool . get ( ' account.move ' )
account_obj = self . pool . get ( ' account.account ' )
2010-10-15 09:23:25 +00:00
journal_obj = self . pool . get ( ' account.journal ' )
2011-02-07 10:36:45 +00:00
if isinstance ( ids , ( int , long ) ) :
ids = [ ids ]
2009-01-26 22:22:32 +00:00
if vals . get ( ' account_tax_id ' , False ) :
2012-08-06 15:44:10 +00:00
raise osv . except_osv ( _ ( ' Unable to change tax! ' ) , _ ( ' You cannot change the tax, you should remove and recreate lines. ' ) )
2008-07-22 15:11:28 +00:00
if ( ' account_id ' in vals ) and not account_obj . read ( cr , uid , vals [ ' account_id ' ] , [ ' active ' ] ) [ ' active ' ] :
2012-08-07 11:06:16 +00:00
raise osv . except_osv ( _ ( ' Bad Account! ' ) , _ ( ' You cannot use an inactive account. ' ) )
2008-07-22 15:11:28 +00:00
if update_check :
if ( ' account_id ' in vals ) or ( ' journal_id ' in vals ) or ( ' period_id ' in vals ) or ( ' move_id ' in vals ) or ( ' debit ' in vals ) or ( ' credit ' in vals ) or ( ' date ' in vals ) :
self . _update_check ( cr , uid , ids , context )
2008-11-18 10:51:51 +00:00
2008-12-14 19:37:38 +00:00
todo_date = None
if vals . get ( ' date ' , False ) :
todo_date = vals [ ' date ' ]
del vals [ ' date ' ]
2010-06-09 13:22:53 +00:00
2010-10-15 09:23:25 +00:00
for line in self . browse ( cr , uid , ids , context = context ) :
2010-05-10 10:05:50 +00:00
ctx = context . copy ( )
2013-06-13 11:33:05 +00:00
if not ctx . get ( ' journal_id ' ) :
2010-05-10 10:05:50 +00:00
if line . move_id :
ctx [ ' journal_id ' ] = line . move_id . journal_id . id
else :
ctx [ ' journal_id ' ] = line . journal_id . id
2013-06-13 11:33:05 +00:00
if not ctx . get ( ' period_id ' ) :
2010-05-10 10:05:50 +00:00
if line . move_id :
ctx [ ' period_id ' ] = line . move_id . period_id . id
else :
2010-06-09 13:22:53 +00:00
ctx [ ' period_id ' ] = line . period_id . id
#Check for centralisation
2010-10-15 09:23:25 +00:00
journal = journal_obj . browse ( cr , uid , ctx [ ' journal_id ' ] , context = ctx )
2010-05-10 10:05:50 +00:00
if journal . centralisation :
self . _check_moves ( cr , uid , context = ctx )
2008-11-21 15:17:45 +00:00
result = super ( account_move_line , self ) . write ( cr , uid , ids , vals , context )
2014-11-20 23:38:39 +00:00
if check and not context . get ( ' novalidate ' ) :
2008-07-22 15:11:28 +00:00
done = [ ]
for line in self . browse ( cr , uid , ids ) :
if line . move_id . id not in done :
done . append ( line . move_id . id )
2010-10-15 06:56:48 +00:00
move_obj . validate ( cr , uid , [ line . move_id . id ] , context )
2008-12-14 19:37:38 +00:00
if todo_date :
2010-10-15 06:56:48 +00:00
move_obj . write ( cr , uid , [ line . move_id . id ] , { ' date ' : todo_date } , context = context )
2008-07-22 15:11:28 +00:00
return result
2010-11-19 13:48:01 +00:00
def _update_journal_check ( self , cr , uid , journal_id , period_id , context = None ) :
2010-10-15 09:23:25 +00:00
journal_obj = self . pool . get ( ' account.journal ' )
period_obj = self . pool . get ( ' account.period ' )
jour_period_obj = self . pool . get ( ' account.journal.period ' )
cr . execute ( ' SELECT state FROM account_journal_period WHERE journal_id = %s AND period_id = %s ' , ( journal_id , period_id ) )
2008-07-22 15:11:28 +00:00
result = cr . fetchall ( )
2012-08-23 13:30:31 +00:00
journal = journal_obj . browse ( cr , uid , journal_id , context = context )
period = period_obj . browse ( cr , uid , period_id , context = context )
2008-07-22 15:11:28 +00:00
for ( state , ) in result :
2010-10-15 09:23:25 +00:00
if state == ' done ' :
2014-05-30 16:47:50 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' You can not add/modify entries in a closed period %s of journal %s . ' % ( period . name , journal . name ) ) )
2008-07-22 15:11:28 +00:00
if not result :
2010-10-15 09:23:25 +00:00
jour_period_obj . create ( cr , uid , {
2008-07-22 15:11:28 +00:00
' name ' : ( journal . code or journal . name ) + ' : ' + ( period . name or ' ' ) ,
' journal_id ' : journal . id ,
' period_id ' : period . id
} )
return True
2010-11-19 13:48:01 +00:00
def _update_check ( self , cr , uid , ids , context = None ) :
2008-07-22 15:11:28 +00:00
done = { }
2010-11-19 13:48:01 +00:00
for line in self . browse ( cr , uid , ids , context = context ) :
2011-05-30 14:14:51 +00:00
err_msg = _ ( ' Move name (id): %s ( %s ) ' ) % ( line . move_id . name , str ( line . move_id . id ) )
2010-11-11 10:13:53 +00:00
if line . move_id . state < > ' draft ' and ( not line . journal_id . entry_posted ) :
2012-08-07 11:31:37 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' You cannot do this modification on a confirmed entry. You can just change some non legal fields or you must unconfirm the journal entry first. \n %s . ' ) % err_msg )
2008-07-22 15:11:28 +00:00
if line . reconcile_id :
2012-08-07 11:31:37 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' You cannot do this modification on a reconciled entry. You can just change some non legal fields or you must unreconcile first. \n %s . ' ) % err_msg )
2008-07-22 15:11:28 +00:00
t = ( line . journal_id . id , line . period_id . id )
if t not in done :
self . _update_journal_check ( cr , uid , line . journal_id . id , line . period_id . id , context )
done [ t ] = True
return True
def create ( self , cr , uid , vals , context = None , check = True ) :
account_obj = self . pool . get ( ' account.account ' )
2010-10-15 06:56:48 +00:00
tax_obj = self . pool . get ( ' account.tax ' )
move_obj = self . pool . get ( ' account.move ' )
cur_obj = self . pool . get ( ' res.currency ' )
2010-10-15 09:23:25 +00:00
journal_obj = self . pool . get ( ' account.journal ' )
2014-07-06 14:44:26 +00:00
context = dict ( context or { } )
2010-11-02 10:55:42 +00:00
if vals . get ( ' move_id ' , False ) :
2013-01-11 13:54:26 +00:00
move = self . pool . get ( ' account.move ' ) . browse ( cr , uid , vals [ ' move_id ' ] , context = context )
if move . company_id :
vals [ ' company_id ' ] = move . company_id . id
if move . date and not vals . get ( ' date ' ) :
vals [ ' date ' ] = move . date
2014-07-06 14:44:26 +00:00
if ( ' account_id ' in vals ) and not account_obj . read ( cr , uid , [ vals [ ' account_id ' ] ] , [ ' active ' ] ) [ 0 ] [ ' active ' ] :
2012-08-07 11:06:16 +00:00
raise osv . except_osv ( _ ( ' Bad Account! ' ) , _ ( ' You cannot use an inactive account. ' ) )
2012-10-19 13:30:50 +00:00
if ' journal_id ' in vals and vals [ ' journal_id ' ] :
2008-07-22 15:11:28 +00:00
context [ ' journal_id ' ] = vals [ ' journal_id ' ]
2012-10-19 13:30:50 +00:00
if ' period_id ' in vals and vals [ ' period_id ' ] :
2008-07-22 15:11:28 +00:00
context [ ' period_id ' ] = vals [ ' period_id ' ]
2009-01-02 09:54:21 +00:00
if ( ' journal_id ' not in context ) and ( ' move_id ' in vals ) and vals [ ' move_id ' ] :
2010-10-15 06:56:48 +00:00
m = move_obj . browse ( cr , uid , vals [ ' move_id ' ] )
2008-07-22 15:11:28 +00:00
context [ ' journal_id ' ] = m . journal_id . id
context [ ' period_id ' ] = m . period_id . id
2011-11-14 11:34:05 +00:00
#we need to treat the case where a value is given in the context for period_id as a string
2012-10-19 13:30:50 +00:00
if ' period_id ' in context and not isinstance ( context . get ( ' period_id ' , ' ' ) , ( int , long ) ) :
2011-11-14 11:34:05 +00:00
period_candidate_ids = self . pool . get ( ' account.period ' ) . name_search ( cr , uid , name = context . get ( ' period_id ' , ' ' ) )
if len ( period_candidate_ids ) != 1 :
2012-08-07 11:06:16 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' No period found or more than one period found for the given date. ' ) )
2011-11-14 11:34:05 +00:00
context [ ' period_id ' ] = period_candidate_ids [ 0 ] [ 0 ]
2011-12-15 05:53:06 +00:00
if not context . get ( ' journal_id ' , False ) and context . get ( ' search_default_journal_id ' , False ) :
2012-08-06 15:44:10 +00:00
context [ ' journal_id ' ] = context . get ( ' search_default_journal_id ' )
2008-07-22 15:11:28 +00:00
self . _update_journal_check ( cr , uid , context [ ' journal_id ' ] , context [ ' period_id ' ] , context )
move_id = vals . get ( ' move_id ' , False )
2010-11-19 13:48:01 +00:00
journal = journal_obj . browse ( cr , uid , context [ ' journal_id ' ] , context = context )
2012-10-19 13:30:50 +00:00
vals [ ' journal_id ' ] = vals . get ( ' journal_id ' ) or context . get ( ' journal_id ' )
vals [ ' period_id ' ] = vals . get ( ' period_id ' ) or context . get ( ' period_id ' )
vals [ ' date ' ] = vals . get ( ' date ' ) or context . get ( ' date ' )
2008-07-22 15:11:28 +00:00
if not move_id :
if journal . centralisation :
2010-05-10 10:05:50 +00:00
#Check for centralisation
res = self . _check_moves ( cr , uid , context )
2008-07-22 15:11:28 +00:00
if res :
vals [ ' move_id ' ] = res [ 0 ]
if not vals . get ( ' move_id ' , False ) :
if journal . sequence_id :
2011-09-29 13:22:54 +00:00
#name = self.pool.get('ir.sequence').next_by_id(cr, uid, journal.sequence_id.id)
2008-07-22 15:11:28 +00:00
v = {
2008-12-14 19:37:38 +00:00
' date ' : vals . get ( ' date ' , time . strftime ( ' % Y- % m- %d ' ) ) ,
2008-07-22 15:11:28 +00:00
' period_id ' : context [ ' period_id ' ] ,
' journal_id ' : context [ ' journal_id ' ]
}
2010-10-21 06:02:07 +00:00
if vals . get ( ' ref ' , ' ' ) :
v . update ( { ' ref ' : vals [ ' ref ' ] } )
2010-10-15 06:56:48 +00:00
move_id = move_obj . create ( cr , uid , v , context )
2008-07-22 15:11:28 +00:00
vals [ ' move_id ' ] = move_id
else :
2013-06-07 11:38:29 +00:00
raise osv . except_osv ( _ ( ' No Piece Number! ' ) , _ ( ' Cannot create an automatic sequence for this piece. \n Put a sequence in the journal definition for automatic numbering or create a sequence manually for this piece. ' ) )
2008-07-22 15:11:28 +00:00
ok = not ( journal . type_control_ids or journal . account_control_ids )
if ( ' account_id ' in vals ) :
2010-11-19 13:48:01 +00:00
account = account_obj . browse ( cr , uid , vals [ ' account_id ' ] , context = context )
2008-07-22 15:11:28 +00:00
if journal . type_control_ids :
2008-09-05 15:04:38 +00:00
type = account . user_type
2008-07-22 15:11:28 +00:00
for t in journal . type_control_ids :
2009-07-07 11:03:51 +00:00
if type . code == t . code :
2008-07-22 15:11:28 +00:00
ok = True
break
if journal . account_control_ids and not ok :
for a in journal . account_control_ids :
2010-05-19 12:49:23 +00:00
if a . id == vals [ ' account_id ' ] :
2008-07-22 15:11:28 +00:00
ok = True
break
2010-09-14 13:16:57 +00:00
# Automatically convert in the account's secondary currency if there is one and
# the provided values were not already multi-currency
2014-01-08 16:04:44 +00:00
if account . currency_id and ' amount_currency ' not in vals and account . currency_id . id != account . company_id . currency_id . id :
2008-07-22 15:11:28 +00:00
vals [ ' currency_id ' ] = account . currency_id . id
ctx = { }
if ' date ' in vals :
ctx [ ' date ' ] = vals [ ' date ' ]
2008-10-23 21:06:50 +00:00
vals [ ' amount_currency ' ] = cur_obj . compute ( cr , uid , account . company_id . currency_id . id ,
2010-10-15 09:23:25 +00:00
account . currency_id . id , vals . get ( ' debit ' , 0.0 ) - vals . get ( ' credit ' , 0.0 ) , context = ctx )
2008-07-22 15:11:28 +00:00
if not ok :
2012-08-07 11:06:16 +00:00
raise osv . except_osv ( _ ( ' Bad Account! ' ) , _ ( ' You cannot use this general account in this journal, check the tab \' Entry Controls \' on the related journal. ' ) )
2008-08-14 13:37:58 +00:00
2011-08-16 10:32:48 +00:00
result = super ( account_move_line , self ) . create ( cr , uid , vals , context = context )
2008-08-22 14:53:43 +00:00
# CREATE Taxes
2010-07-24 18:18:02 +00:00
if vals . get ( ' account_tax_id ' , False ) :
2010-05-19 12:49:23 +00:00
tax_id = tax_obj . browse ( cr , uid , vals [ ' account_tax_id ' ] )
2008-11-20 17:24:48 +00:00
total = vals [ ' debit ' ] - vals [ ' credit ' ]
2014-07-11 15:15:34 +00:00
base_code = ' base_code_id '
tax_code = ' tax_code_id '
account_id = ' account_collected_id '
base_sign = ' base_sign '
tax_sign = ' tax_sign '
if journal . type in ( ' purchase_refund ' , ' sale_refund ' ) or ( journal . type in ( ' cash ' , ' bank ' ) and total < 0 ) :
2008-11-20 17:24:48 +00:00
base_code = ' ref_base_code_id '
tax_code = ' ref_tax_code_id '
account_id = ' account_paid_id '
base_sign = ' ref_base_sign '
tax_sign = ' ref_tax_sign '
2015-01-05 14:40:21 +00:00
base_adjusted = False
2014-07-11 15:15:34 +00:00
for tax in tax_obj . compute_all ( cr , uid , [ tax_id ] , total , 1.00 , force_excluded = False ) . get ( ' taxes ' ) :
2008-11-20 17:24:48 +00:00
#create the base movement
2015-01-05 14:40:21 +00:00
if base_adjusted == False :
base_adjusted = True
if tax_id . price_include :
total = tax [ ' price_unit ' ]
newvals = {
' tax_code_id ' : tax [ base_code ] ,
' tax_amount ' : tax [ base_sign ] * abs ( total ) ,
}
if tax_id . price_include :
if tax [ ' price_unit ' ] < 0 :
newvals [ ' credit ' ] = abs ( tax [ ' price_unit ' ] )
else :
newvals [ ' debit ' ] = tax [ ' price_unit ' ]
self . write ( cr , uid , [ result ] , newvals , context = context )
2008-11-20 17:24:48 +00:00
else :
data = {
' move_id ' : vals [ ' move_id ' ] ,
2009-09-18 10:33:21 +00:00
' name ' : tools . ustr ( vals [ ' name ' ] or ' ' ) + ' ' + tools . ustr ( tax [ ' name ' ] or ' ' ) ,
2008-11-20 17:24:48 +00:00
' date ' : vals [ ' date ' ] ,
2014-07-11 15:15:34 +00:00
' partner_id ' : vals . get ( ' partner_id ' , False ) ,
' ref ' : vals . get ( ' ref ' , False ) ,
' statement_id ' : vals . get ( ' statement_id ' , False ) ,
2008-11-20 17:24:48 +00:00
' account_tax_id ' : False ,
' tax_code_id ' : tax [ base_code ] ,
' tax_amount ' : tax [ base_sign ] * abs ( total ) ,
' account_id ' : vals [ ' account_id ' ] ,
' credit ' : 0.0 ,
' debit ' : 0.0 ,
}
2015-01-05 14:40:21 +00:00
self . create ( cr , uid , data , context )
2012-07-19 05:38:03 +00:00
#create the Tax movement
2008-08-22 14:53:43 +00:00
data = {
' move_id ' : vals [ ' move_id ' ] ,
2009-09-18 10:33:21 +00:00
' name ' : tools . ustr ( vals [ ' name ' ] or ' ' ) + ' ' + tools . ustr ( tax [ ' name ' ] or ' ' ) ,
2008-08-22 14:53:43 +00:00
' date ' : vals [ ' date ' ] ,
' partner_id ' : vals . get ( ' partner_id ' , False ) ,
' ref ' : vals . get ( ' ref ' , False ) ,
2014-07-11 15:15:34 +00:00
' statement_id ' : vals . get ( ' statement_id ' , False ) ,
2008-08-22 14:53:43 +00:00
' account_tax_id ' : False ,
2008-11-20 17:24:48 +00:00
' tax_code_id ' : tax [ tax_code ] ,
' tax_amount ' : tax [ tax_sign ] * abs ( tax [ ' amount ' ] ) ,
2008-11-26 13:48:24 +00:00
' account_id ' : tax [ account_id ] or vals [ ' account_id ' ] ,
2008-11-20 17:24:48 +00:00
' credit ' : tax [ ' amount ' ] < 0 and - tax [ ' amount ' ] or 0.0 ,
' debit ' : tax [ ' amount ' ] > 0 and tax [ ' amount ' ] or 0.0 ,
2008-08-22 14:53:43 +00:00
}
2015-01-05 14:40:21 +00:00
self . create ( cr , uid , data , context )
2009-01-26 22:22:32 +00:00
del vals [ ' account_tax_id ' ]
2008-11-20 17:24:48 +00:00
2014-08-18 09:53:13 +00:00
if check and not context . get ( ' novalidate ' ) and ( context . get ( ' recompute ' , True ) or journal . entry_posted ) :
2010-10-15 09:23:25 +00:00
tmp = move_obj . validate ( cr , uid , [ vals [ ' move_id ' ] ] , context )
2008-08-25 12:36:34 +00:00
if journal . entry_posted and tmp :
2010-10-15 09:23:25 +00:00
move_obj . button_validate ( cr , uid , [ vals [ ' move_id ' ] ] , context )
2008-07-22 15:11:28 +00:00
return result
2007-04-19 19:58:31 +00:00
2012-11-05 08:41:52 +00:00
def list_periods ( self , cr , uid , context = None ) :
ids = self . pool . get ( ' account.period ' ) . search ( cr , uid , [ ] )
return self . pool . get ( ' account.period ' ) . name_get ( cr , uid , ids , context = context )
def list_journals ( self , cr , uid , context = None ) :
2012-11-21 17:29:54 +00:00
ng = dict ( self . pool . get ( ' account.journal ' ) . name_search ( cr , uid , ' ' , [ ] ) )
ids = ng . keys ( )
result = [ ]
for journal in self . pool . get ( ' account.journal ' ) . browse ( cr , uid , ids , context = context ) :
result . append ( ( journal . id , ng [ journal . id ] , journal . type ,
bool ( journal . currency ) , bool ( journal . analytic_journal_id ) ) )
return result
2012-11-05 08:41:52 +00:00
2008-07-23 14:41:47 +00:00
2011-01-05 13:34:15 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: