2010-06-26 19:16:11 +00:00
# encoding: utf-8
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 PC Solutions (<http://pcsol.be>). All Rights Reserved
# $Id$
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv , fields
import time
from mx import DateTime
from decimal import Decimal
from tools . translate import _
2010-07-15 13:07:11 +00:00
import decimal_precision as dp
2010-06-26 19:16:11 +00:00
2010-06-28 11:47:10 +00:00
class account_cashbox_line ( osv . osv ) :
2010-08-14 05:48:09 +00:00
2010-06-28 11:47:10 +00:00
""" Cash Box Details """
2010-08-14 05:48:09 +00:00
2010-06-28 11:47:10 +00:00
_name = ' account.cashbox.line '
_description = ' CashBox Line '
2010-06-26 19:16:11 +00:00
def _sub_total ( self , cr , uid , ids , name , arg , context = None ) :
2010-08-14 05:48:09 +00:00
2010-06-28 11:50:18 +00:00
""" Calculates Sub total
2010-06-26 19:16:11 +00:00
@param name : Names of fields .
@param arg : User defined arguments
@return : Dictionary of values .
"""
res = { }
for obj in self . browse ( cr , uid , ids ) :
res [ obj . id ] = obj . pieces * obj . number
return res
def on_change_sub ( self , cr , uid , ids , pieces , number , * a ) :
""" Calculates Sub total on change of number
@param pieces : Names of fields .
@param number :
2010-08-14 05:48:09 +00:00
"""
2010-06-26 19:16:11 +00:00
sub = pieces * number
return { ' value ' : { ' subtotal ' : sub or 0.0 } }
_columns = {
2010-07-15 13:07:11 +00:00
' pieces ' : fields . float ( ' Values ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2010-06-26 19:16:11 +00:00
' number ' : fields . integer ( ' Number ' ) ,
2010-07-15 13:07:11 +00:00
' subtotal ' : fields . function ( _sub_total , method = True , string = ' Sub Total ' , type = ' float ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2010-06-26 19:16:11 +00:00
' starting_id ' : fields . many2one ( ' account.bank.statement ' , ondelete = ' cascade ' ) ,
' ending_id ' : fields . many2one ( ' account.bank.statement ' , ondelete = ' cascade ' ) ,
}
2010-06-28 11:47:10 +00:00
account_cashbox_line ( )
2010-06-26 19:16:11 +00:00
class account_cash_statement ( osv . osv ) :
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
_inherit = ' account.bank.statement '
2010-08-14 05:48:09 +00:00
2010-07-09 09:12:12 +00:00
def _get_starting_balance ( self , cr , uid , ids , context = None ) :
2010-06-26 19:16:11 +00:00
2010-07-09 09:12:12 +00:00
""" Find starting balance
2010-06-26 19:16:11 +00:00
@param name : Names of fields .
@param arg : User defined arguments
@return : Dictionary of values .
2010-07-09 09:12:12 +00:00
"""
2010-06-26 19:16:11 +00:00
res = { }
for statement in self . browse ( cr , uid , ids ) :
2010-08-30 10:46:42 +00:00
amount_total = 0.0
2010-08-14 05:48:09 +00:00
2010-07-09 09:12:12 +00:00
if statement . journal_id . type not in ( ' cash ' ) :
continue
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
for line in statement . starting_details_ids :
amount_total + = line . pieces * line . number
2010-07-09 09:12:12 +00:00
res [ statement . id ] = {
' balance_start ' : amount_total
}
2010-06-26 19:16:11 +00:00
return res
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
def _balance_end_cash ( self , cr , uid , ids , name , arg , context = None ) :
""" Find ending balance "
@param name : Names of fields .
@param arg : User defined arguments
@return : Dictionary of values .
2010-08-14 05:48:09 +00:00
"""
2010-06-26 19:16:11 +00:00
res = { }
for statement in self . browse ( cr , uid , ids ) :
amount_total = 0.0
for line in statement . ending_details_ids :
amount_total + = line . pieces * line . number
res [ statement . id ] = amount_total
return res
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
def _get_sum_entry_encoding ( self , cr , uid , ids , name , arg , context = None ) :
""" Find encoding total of statements "
@param name : Names of fields .
@param arg : User defined arguments
@return : Dictionary of values .
"""
res2 = { }
for statement in self . browse ( cr , uid , ids ) :
encoding_total = 0.0
for line in statement . line_ids :
encoding_total + = line . amount
res2 [ statement . id ] = encoding_total
return res2
def _end_balance ( self , cursor , user , ids , name , attr , context = None ) :
res_currency_obj = self . pool . get ( ' res.currency ' )
res_users_obj = self . pool . get ( ' res.users ' )
res = { }
company_currency_id = res_users_obj . browse ( cursor , user , user ,
context = context ) . company_id . currency_id . id
statements = self . browse ( cursor , user , ids , context = context )
for statement in statements :
res [ statement . id ] = statement . balance_start
currency_id = statement . currency . id
for line in statement . move_line_ids :
if line . debit > 0 :
if line . account_id . id == \
statement . journal_id . default_debit_account_id . id :
res [ statement . id ] + = res_currency_obj . compute ( cursor ,
user , company_currency_id , currency_id ,
line . debit , context = context )
else :
if line . account_id . id == \
statement . journal_id . default_credit_account_id . id :
res [ statement . id ] - = res_currency_obj . compute ( cursor ,
user , company_currency_id , currency_id ,
line . credit , context = context )
if statement . state in ( ' draft ' , ' open ' ) :
for line in statement . line_ids :
res [ statement . id ] + = line . amount
for r in res :
res [ r ] = round ( res [ r ] , 2 )
return res
2010-08-14 05:48:09 +00:00
2010-09-03 11:25:45 +00:00
def _get_company ( self , cr , uid , context = { } ) :
2010-06-28 11:47:10 +00:00
user_pool = self . pool . get ( ' res.users ' )
company_pool = self . pool . get ( ' res.company ' )
2010-09-03 11:25:45 +00:00
user = user_pool . browse ( cr , uid , uid , context )
2010-06-28 11:47:10 +00:00
company_id = user . company_id and user . company_id . id
if not company_id :
company_id = company_pool . search ( cr , uid , [ ] ) [ 0 ]
2010-08-14 05:48:09 +00:00
2010-06-28 11:47:10 +00:00
return company_id
2010-07-09 09:12:12 +00:00
2010-09-03 11:25:45 +00:00
def _get_cash_open_box_lines ( self , cr , uid , context = { } ) :
2010-07-26 14:41:32 +00:00
res = [ ]
curr = [ 1 , 2 , 5 , 10 , 20 , 50 , 100 , 500 ]
for rs in curr :
dct = {
' pieces ' : rs ,
' number ' : 0
}
2010-07-30 11:12:06 +00:00
res . append ( dct )
2010-09-03 11:25:45 +00:00
journal_ids = self . pool . get ( ' account.journal ' ) . search ( cr , uid , [ ( ' type ' , ' = ' , ' cash ' ) ] , context = context )
if journal_ids :
results = self . search ( cr , uid , [ ( ' journal_id ' , ' in ' , journal_ids ) , ( ' state ' , ' = ' , ' confirm ' ) ] , context = context )
if results :
cash_st = self . browse ( cr , uid , results , context ) [ 0 ]
for cash_line in cash_st . ending_details_ids :
for r in res :
if cash_line . pieces == r [ ' pieces ' ] :
r [ ' number ' ] = cash_line . number
2010-07-26 14:41:32 +00:00
return res
2010-07-30 11:57:58 +00:00
2010-09-03 11:25:45 +00:00
def _get_default_cash_close_box_lines ( self , cr , uid , context = { } ) :
2010-07-30 11:57:58 +00:00
res = [ ]
curr = [ 1 , 2 , 5 , 10 , 20 , 50 , 100 , 500 ]
for rs in curr :
dct = {
' pieces ' : rs ,
' number ' : 0
}
2010-09-03 11:25:45 +00:00
res . append ( dct )
return res
def _get_cash_close_box_lines ( self , cr , ids , uid , context = { } ) :
res = [ ]
curr = [ 1 , 2 , 5 , 10 , 20 , 50 , 100 , 500 ]
for rs in curr :
dct = {
' pieces ' : rs ,
' number ' : 0
}
res . append ( ( 0 , 0 , dct ) )
2010-07-30 11:57:58 +00:00
return res
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
_columns = {
2010-07-15 13:07:11 +00:00
' balance_end_real ' : fields . float ( ' Closing Balance ' , digits_compute = dp . get_precision ( ' Account ' ) , states = { ' confirm ' : [ ( ' readonly ' , True ) ] } , help = " closing balance entered by the cashbox verifier " ) ,
2010-06-26 19:16:11 +00:00
' state ' : fields . selection (
[ ( ' draft ' , ' Draft ' ) ,
2010-09-13 12:34:53 +00:00
( ' confirm ' , ' Closed ' ) ,
2010-06-26 19:16:11 +00:00
( ' open ' , ' Open ' ) ] , ' State ' , required = True , states = { ' confirm ' : [ ( ' readonly ' , True ) ] } , readonly = " 1 " ) ,
2010-06-28 11:47:10 +00:00
' total_entry_encoding ' : fields . function ( _get_sum_entry_encoding , method = True , store = True , string = " Cash Transaction " , help = " Total cash transactions " ) ,
2010-06-26 19:16:11 +00:00
' closing_date ' : fields . datetime ( " Closed On " ) ,
2010-07-13 09:01:30 +00:00
' balance_end ' : fields . function ( _end_balance , method = True , store = True , string = ' Balance ' , help = " Closing balance based on Starting Balance and Cash Transactions " ) ,
2010-06-28 11:47:10 +00:00
' balance_end_cash ' : fields . function ( _balance_end_cash , method = True , store = True , string = ' Balance ' , help = " Closing balance based on cashBox " ) ,
' starting_details_ids ' : fields . one2many ( ' account.cashbox.line ' , ' starting_id ' , string = ' Opening Cashbox ' ) ,
' ending_details_ids ' : fields . one2many ( ' account.cashbox.line ' , ' ending_id ' , string = ' Closing Cashbox ' ) ,
2010-09-03 12:29:47 +00:00
' name ' : fields . char ( ' Name ' , size = 64 , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True , help = ' if you give the Name other then / , its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself ' ) ,
2010-06-26 19:16:11 +00:00
' user_id ' : fields . many2one ( ' res.users ' , ' Responsible ' , required = False ) ,
}
_defaults = {
' state ' : lambda * a : ' draft ' ,
' date ' : lambda * a : time . strftime ( " % Y- % m- %d % H: % M: % S " ) ,
2010-06-28 11:47:10 +00:00
' user_id ' : lambda self , cr , uid , context = None : uid ,
2010-07-30 11:57:58 +00:00
' starting_details_ids ' : _get_cash_open_box_lines ,
2010-09-03 11:25:45 +00:00
' ending_details_ids ' : _get_default_cash_close_box_lines
2010-06-26 19:16:11 +00:00
}
def create ( self , cr , uid , vals , context = None ) :
2010-09-14 17:53:07 +00:00
sql = [
2010-08-14 05:48:09 +00:00
( ' journal_id ' , ' = ' , vals [ ' journal_id ' ] ) ,
2010-07-26 14:41:32 +00:00
( ' state ' , ' = ' , ' open ' )
2010-09-14 17:53:07 +00:00
]
open_jrnl = self . search ( cr , uid , sql )
if open_jrnl :
raise osv . except_osv ( ' Error ' , _ ( ' You can not have two open register for the same journal ' ) )
2010-07-30 11:57:58 +00:00
2010-07-30 12:16:56 +00:00
if self . pool . get ( ' account.journal ' ) . browse ( cr , uid , vals [ ' journal_id ' ] ) . type == ' cash ' :
lines = end_lines = self . _get_cash_close_box_lines ( cr , uid , [ ] , context )
vals . update ( {
' ending_details_ids ' : lines
} )
else :
vals . update ( {
' ending_details_ids ' : False ,
' starting_details_ids ' : False
} )
2010-07-09 09:12:12 +00:00
res_id = super ( account_cash_statement , self ) . create ( cr , uid , vals , context = context )
2010-08-31 11:47:27 +00:00
#self.write(cr, uid, [res_id], {})
2010-07-09 09:12:12 +00:00
return res_id
2010-08-14 05:48:09 +00:00
2010-07-09 09:12:12 +00:00
def write ( self , cr , uid , ids , vals , context = None ) :
"""
Update redord ( s ) comes in { ids } , with new value comes as { vals }
return True on success , False otherwise
2010-08-14 05:48:09 +00:00
2010-07-09 09:12:12 +00:00
@param cr : cursor to database
@param user : id of current user
@param ids : list of record ids to be update
@param vals : dict of new values to be set
@param context : context arguments , like lang , time zone
2010-08-14 05:48:09 +00:00
2010-07-09 09:12:12 +00:00
@return : True on success , False otherwise
"""
2010-08-14 05:48:09 +00:00
2010-07-09 09:12:12 +00:00
super ( account_cash_statement , self ) . write ( cr , uid , ids , vals )
res = self . _get_starting_balance ( cr , uid , ids )
for rs in res :
2010-09-16 12:48:28 +00:00
super ( account_cash_statement , self ) . write ( cr , uid , [ rs ] , res . get ( rs ) )
2010-07-09 09:12:12 +00:00
return True
2010-08-14 05:48:09 +00:00
2010-09-17 11:06:42 +00:00
def onchange_journal_id ( self , cr , uid , statement_id , journal_id , context = None ) :
2010-08-14 05:48:09 +00:00
""" Changes balance start and starting details if journal_id changes "
2010-06-26 19:16:11 +00:00
@param statement_id : Changed statement_id
@param journal_id : Changed journal_id
@return : Dictionary of changed values
"""
2010-08-14 05:48:09 +00:00
2010-06-28 11:47:10 +00:00
cash_pool = self . pool . get ( ' account.cashbox.line ' )
2010-06-26 19:16:11 +00:00
statement_pool = self . pool . get ( ' account.bank.statement ' )
res = { }
balance_start = 0.0
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
if not journal_id :
res . update ( {
' balance_start ' : balance_start
} )
return res
2010-09-17 11:06:42 +00:00
res = super ( account_cash_statement , self ) . onchange_journal_id ( cr , uid , statement_id , journal_id , context = context )
2010-06-26 19:16:11 +00:00
return res
2010-08-14 05:48:09 +00:00
2010-09-22 15:41:58 +00:00
def _equal_balance ( self , cr , uid , cash_id , context = None ) :
statement = self . browse ( cr , uid , cash_id , context = context )
self . write ( cr , uid , [ cash_id ] , { ' balance_end_real ' : statement . balance_end } )
statement . balance_end_real = statement . balance_end
2010-06-28 14:35:41 +00:00
if statement . balance_end != statement . balance_end_cash :
return False
else :
return True
2010-08-14 05:48:09 +00:00
2010-06-28 14:35:41 +00:00
def _user_allow ( self , cr , uid , ids , statement , context = { } ) :
return True
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
def button_open ( self , cr , uid , ids , context = None ) :
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
""" Changes statement state to Running.
2010-08-14 05:48:09 +00:00
@return : True
2010-06-26 19:16:11 +00:00
"""
2010-06-28 11:47:10 +00:00
cash_pool = self . pool . get ( ' account.cashbox.line ' )
2010-06-26 19:16:11 +00:00
statement_pool = self . pool . get ( ' account.bank.statement ' )
statement = statement_pool . browse ( cr , uid , ids [ 0 ] )
2010-08-02 18:57:44 +00:00
vals = { }
2010-08-14 05:48:09 +00:00
2010-06-28 14:35:41 +00:00
if not self . _user_allow ( cr , uid , ids , statement , context = { } ) :
2010-06-29 06:29:06 +00:00
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' User %s does not have rights to access %s journal ! ' % ( statement . user_id . name , statement . journal_id . name ) ) )
2010-08-14 05:48:09 +00:00
2010-08-02 18:57:44 +00:00
if statement . name and statement . name == ' / ' :
number = self . pool . get ( ' ir.sequence ' ) . get ( cr , uid , ' account.cash.statement ' )
vals . update ( {
2010-08-30 12:08:40 +00:00
' name ' : number
2010-08-02 18:57:44 +00:00
} )
2010-08-14 05:48:09 +00:00
2010-08-02 18:57:44 +00:00
vals . update ( {
2010-08-14 05:48:09 +00:00
' date ' : time . strftime ( " % Y- % m- %d % H: % M: % S " ) ,
2010-06-26 19:16:11 +00:00
' state ' : ' open ' ,
2010-08-14 05:48:09 +00:00
2010-08-02 18:57:44 +00:00
} )
2010-08-14 05:48:09 +00:00
2010-06-26 19:16:11 +00:00
self . write ( cr , uid , ids , vals )
return True
2010-09-22 15:41:58 +00:00
def balance_check ( self , cr , uid , cash_id , journal_type = ' bank ' , context = None ) :
if journal_type == ' bank ' :
return super ( account_cash_statement , self ) . balance_check ( cr , uid , cash_id , journal_type , context )
if not self . _equal_balance ( cr , uid , cash_id , context ) :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' CashBox Balance is not matching with Calculated Balance ! ' ) )
return True
2010-08-14 05:48:09 +00:00
2010-09-22 15:41:58 +00:00
def statement_close ( self , cr , uid , ids , journal_type = ' bank ' , context = None ) :
if journal_type == ' bank ' :
return super ( account_cash_statement , self ) . statement_close ( cr , uid , ids , journal_type , context )
2010-07-09 09:12:12 +00:00
vals = {
' state ' : ' confirm ' ,
' closing_date ' : time . strftime ( " % Y- % m- %d % H: % M: % S " )
}
2010-09-22 15:41:58 +00:00
return self . write ( cr , uid , ids , vals , context = context )
def check_status_condition ( self , cr , uid , state , journal_type = ' bank ' ) :
if journal_type == ' bank ' :
return super ( account_cash_statement , self ) . check_status_condition ( cr , uid , state , journal_type )
return state == ' open '
def button_confirm_cash ( self , cr , uid , ids , context = None ) :
super ( account_cash_statement , self ) . button_confirm_bank ( cr , uid , ids , context = context )
return self . write ( cr , uid , ids , { ' closing_date ' : time . strftime ( " % Y- % m- %d % H: % M: % S " ) } , context = context )
2010-06-26 19:16:11 +00:00
def button_cancel ( self , cr , uid , ids , context = { } ) :
done = [ ]
for st in self . browse ( cr , uid , ids , context ) :
ids = [ ]
for line in st . line_ids :
ids + = [ x . id for x in line . move_ids ]
self . pool . get ( ' account.move ' ) . unlink ( cr , uid , ids , context )
done . append ( st . id )
self . write ( cr , uid , done , { ' state ' : ' draft ' } , context = context )
return True
account_cash_statement ( )