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/>.
#
##############################################################################
2010-10-15 07:35:42 +00:00
2010-06-26 19:16:11 +00:00
import time
2010-09-27 06:58:21 +00:00
2012-12-06 14:56:32 +00:00
from openerp . osv import fields , osv
2014-10-17 08:58:06 +00:00
from openerp . tools import float_compare
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
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 '
2012-07-31 12:22:02 +00:00
_rec_name = ' pieces '
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 = { }
2010-11-19 13:48:01 +00:00
for obj in self . browse ( cr , uid , ids , context = context ) :
2012-04-26 12:30:17 +00:00
res [ obj . id ] = {
' subtotal_opening ' : obj . pieces * obj . number_opening ,
' subtotal_closing ' : obj . pieces * obj . number_closing ,
}
2010-06-26 19:16:11 +00:00
return res
2012-04-26 12:30:17 +00:00
def on_change_sub_opening ( self , cr , uid , ids , pieces , number , * a ) :
""" Compute the subtotal for the opening """
return { ' value ' : { ' subtotal_opening ' : ( pieces * number ) or 0.0 } }
2010-06-26 19:16:11 +00:00
2012-04-26 12:30:17 +00:00
def on_change_sub_closing ( self , cr , uid , ids , pieces , number , * a ) :
""" Compute the subtotal for the closing """
return { ' value ' : { ' subtotal_closing ' : ( pieces * number ) or 0.0 } }
2010-06-26 19:16:11 +00:00
_columns = {
2012-04-18 11:32:49 +00:00
' pieces ' : fields . float ( ' Unit of Currency ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2012-04-26 12:30:17 +00:00
' number_opening ' : fields . integer ( ' Number of Units ' , help = ' Opening Unit Numbers ' ) ,
' number_closing ' : fields . integer ( ' Number of Units ' , help = ' Closing Unit Numbers ' ) ,
2012-05-12 22:37:43 +00:00
' subtotal_opening ' : fields . function ( _sub_total , string = ' Opening Subtotal ' , type = ' float ' , digits_compute = dp . get_precision ( ' Account ' ) , multi = ' subtotal ' ) ,
' subtotal_closing ' : fields . function ( _sub_total , string = ' Closing Subtotal ' , type = ' float ' , digits_compute = dp . get_precision ( ' Account ' ) , multi = ' subtotal ' ) ,
2012-04-26 12:30:17 +00:00
' bank_statement_id ' : fields . many2one ( ' account.bank.statement ' , ondelete = ' cascade ' ) ,
2010-06-26 19:16:11 +00:00
}
2010-10-15 07:35:42 +00:00
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
2012-05-12 22:37:43 +00:00
def _update_balances ( self , cr , uid , ids , context = None ) :
"""
Set starting and ending balances according to pieces count
2010-07-09 09:12:12 +00:00
"""
2010-10-15 07:35:42 +00:00
res = { }
2010-11-19 13:48:01 +00:00
for statement in self . browse ( cr , uid , ids , context = context ) :
2014-08-21 08:38:21 +00:00
if ( statement . journal_id . type not in ( ' cash ' , ) ) :
continue
if not statement . journal_id . cash_control :
2014-10-17 08:58:06 +00:00
prec = self . pool [ ' decimal.precision ' ] . precision_get ( cr , uid , ' Account ' )
if float_compare ( statement . balance_end_real , statement . balance_end , precision_digits = prec ) :
2014-08-21 08:43:49 +00:00
statement . write ( { ' balance_end_real ' : statement . balance_end } )
2010-07-09 09:12:12 +00:00
continue
2012-05-12 22:37:43 +00:00
start = end = 0
for line in statement . details_ids :
start + = line . subtotal_opening
end + = line . subtotal_closing
data = {
' balance_start ' : start ,
' balance_end_real ' : end ,
2010-07-09 09:12:12 +00:00
}
2012-05-12 22:37:43 +00:00
res [ statement . id ] = data
super ( account_cash_statement , self ) . write ( cr , uid , [ statement . id ] , data , context = context )
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 _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 .
"""
2012-04-26 12:30:17 +00:00
res = { }
2010-11-19 13:48:01 +00:00
for statement in self . browse ( cr , uid , ids , context = context ) :
2012-04-26 12:30:17 +00:00
res [ statement . id ] = sum ( ( line . amount for line in statement . line_ids ) , 0.0 )
return res
2010-06-26 19:16:11 +00:00
2010-10-11 09:07:37 +00:00
def _get_company ( self , cr , uid , context = None ) :
2010-06-28 11:47:10 +00:00
user_pool = self . pool . get ( ' res.users ' )
company_pool = self . pool . get ( ' res.company ' )
2010-10-11 09:07:37 +00:00
user = user_pool . browse ( cr , uid , uid , context = context )
company_id = user . company_id
2010-06-28 11:47:10 +00:00
if not company_id :
2010-10-11 09:07:37 +00:00
company_id = company_pool . search ( cr , uid , [ ] )
return company_id and company_id [ 0 ] or False
2010-07-09 09:12:12 +00:00
2012-05-12 22:37:43 +00:00
def _get_statement_from_line ( self , cr , uid , ids , context = None ) :
2011-09-25 21:00:20 +00:00
result = { }
for line in self . pool . get ( ' account.bank.statement.line ' ) . browse ( cr , uid , ids , context = context ) :
result [ line . statement_id . id ] = True
return result . keys ( )
2012-05-04 12:51:58 +00:00
def _compute_difference ( self , cr , uid , ids , fieldnames , args , context = None ) :
result = dict . fromkeys ( ids , 0.0 )
for obj in self . browse ( cr , uid , ids , context = context ) :
2012-05-12 22:37:43 +00:00
result [ obj . id ] = obj . balance_end_real - obj . balance_end
2012-05-04 12:51:58 +00:00
return result
2012-05-24 08:04:43 +00:00
def _compute_last_closing_balance ( self , cr , uid , ids , fieldnames , args , context = None ) :
result = dict . fromkeys ( ids , 0.0 )
for obj in self . browse ( cr , uid , ids , context = context ) :
if obj . state == ' draft ' :
2012-07-18 14:12:54 +00:00
statement_ids = self . search ( cr , uid ,
[ ( ' journal_id ' , ' = ' , obj . journal_id . id ) , ( ' state ' , ' = ' , ' confirm ' ) ] ,
2012-05-24 08:04:43 +00:00
order = ' create_date desc ' ,
limit = 1 ,
context = context
)
if not statement_ids :
2012-07-18 14:12:54 +00:00
continue
else :
st = self . browse ( cr , uid , statement_ids [ 0 ] , context = context )
result [ obj . id ] = st . balance_end_real
2012-05-24 08:04:43 +00:00
return result
def onchange_journal_id ( self , cr , uid , ids , journal_id , context = None ) :
2012-05-25 12:23:28 +00:00
result = super ( account_cash_statement , self ) . onchange_journal_id ( cr , uid , ids , journal_id )
2012-05-24 08:04:43 +00:00
if not journal_id :
return result
statement_ids = self . search ( cr , uid ,
2012-05-25 12:23:28 +00:00
[ ( ' journal_id ' , ' = ' , journal_id ) , ( ' state ' , ' = ' , ' confirm ' ) ] ,
2012-05-24 08:04:43 +00:00
order = ' create_date desc ' ,
limit = 1 ,
context = context
)
2013-04-01 10:25:12 +00:00
opening_details_ids = self . _get_cash_open_box_lines ( cr , uid , journal_id , context )
2013-03-25 11:08:36 +00:00
if opening_details_ids :
result [ ' value ' ] [ ' opening_details_ids ' ] = opening_details_ids
2013-06-18 07:36:49 +00:00
2012-05-24 08:04:43 +00:00
if not statement_ids :
return result
st = self . browse ( cr , uid , statement_ids [ 0 ] , context = context )
result . setdefault ( ' value ' , { } ) . update ( { ' last_closing_balance ' : st . balance_end_real } )
return result
2010-06-26 19:16:11 +00:00
_columns = {
2012-08-09 21:23:11 +00:00
' total_entry_encoding ' : fields . function ( _get_sum_entry_encoding , string = " Total Transactions " ,
2011-09-25 21:00:20 +00:00
store = {
2012-04-26 12:30:17 +00:00
' account.bank.statement ' : ( lambda self , cr , uid , ids , context = None : ids , [ ' line_ids ' , ' move_line_ids ' ] , 10 ) ,
2012-05-12 22:37:43 +00:00
' account.bank.statement.line ' : ( _get_statement_from_line , [ ' amount ' ] , 10 ) ,
2013-04-05 09:24:19 +00:00
} ,
help = " Total of cash transaction lines. " ) ,
2010-10-21 12:08:26 +00:00
' closing_date ' : fields . datetime ( " Closed On " ) ,
2014-07-06 14:44:26 +00:00
' details_ids ' : fields . one2many ( ' account.cashbox.line ' , ' bank_statement_id ' , string = ' CashBox Lines ' , copy = True ) ,
2012-05-10 07:48:04 +00:00
' opening_details_ids ' : fields . one2many ( ' account.cashbox.line ' , ' bank_statement_id ' , string = ' Opening Cashbox Lines ' ) ,
' closing_details_ids ' : fields . one2many ( ' account.cashbox.line ' , ' bank_statement_id ' , string = ' Closing Cashbox Lines ' ) ,
2010-10-21 12:08:26 +00:00
' user_id ' : fields . many2one ( ' res.users ' , ' Responsible ' , required = False ) ,
2013-04-12 09:38:07 +00:00
' difference ' : fields . function ( _compute_difference , method = True , string = " Difference " , type = " float " , help = " Difference between the theoretical closing balance and the real closing balance. " ) ,
2012-05-25 12:23:28 +00:00
' last_closing_balance ' : fields . function ( _compute_last_closing_balance , method = True , string = ' Last Closing Balance ' , type = ' float ' ) ,
2010-06-26 19:16:11 +00:00
}
_defaults = {
2010-10-15 07:35:42 +00:00
' state ' : ' draft ' ,
2012-04-26 12:30:17 +00:00
' date ' : lambda self , cr , uid , context = { } : context . get ( ' date ' , 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 ,
2012-04-17 14:52:04 +00:00
}
2013-04-01 10:25:12 +00:00
def _get_cash_open_box_lines ( self , cr , uid , journal_id , context ) :
2013-03-22 10:52:09 +00:00
details_ids = [ ]
2013-04-01 10:25:12 +00:00
if not journal_id :
2013-04-01 07:08:55 +00:00
return details_ids
2013-04-01 10:25:12 +00:00
journal = self . pool . get ( ' account.journal ' ) . browse ( cr , uid , journal_id , context = context )
2013-03-22 10:52:09 +00:00
if journal and ( journal . type == ' cash ' ) :
2012-08-28 11:21:16 +00:00
last_pieces = None
if journal . with_last_closing_balance == True :
domain = [ ( ' journal_id ' , ' = ' , journal . id ) ,
( ' state ' , ' = ' , ' confirm ' ) ]
last_bank_statement_ids = self . search ( cr , uid , domain , limit = 1 , order = ' create_date desc ' , context = context )
if last_bank_statement_ids :
last_bank_statement = self . browse ( cr , uid , last_bank_statement_ids [ 0 ] , context = context )
last_pieces = dict (
( line . pieces , line . number_closing ) for line in last_bank_statement . details_ids
)
2012-05-12 22:37:43 +00:00
for value in journal . cashbox_line_ids :
nested_values = {
' number_closing ' : 0 ,
2012-08-28 11:21:16 +00:00
' number_opening ' : last_pieces . get ( value . pieces , 0 ) if isinstance ( last_pieces , dict ) else 0 ,
2012-05-12 22:37:43 +00:00
' pieces ' : value . pieces
}
2013-03-22 10:52:09 +00:00
details_ids . append ( [ 0 , False , nested_values ] )
return details_ids
2012-08-28 11:21:16 +00:00
2013-03-22 10:52:09 +00:00
def create ( self , cr , uid , vals , context = None ) :
2013-12-30 07:24:52 +00:00
journal_id = vals . get ( ' journal_id ' )
if journal_id and not vals . get ( ' opening_details_ids ' ) :
vals [ ' opening_details_ids ' ] = vals . get ( ' opening_details_ids ' ) or self . _get_cash_open_box_lines ( cr , uid , journal_id , context )
2012-05-12 22:37:43 +00:00
res_id = super ( account_cash_statement , self ) . create ( cr , uid , vals , context = context )
self . _update_balances ( cr , uid , [ res_id ] , context )
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
"""
2013-03-25 06:33:22 +00:00
if vals . get ( ' journal_id ' , False ) :
2014-01-02 11:30:09 +00:00
cashbox_line_obj = self . pool . get ( ' account.cashbox.line ' )
2013-12-30 07:24:52 +00:00
cashbox_ids = cashbox_line_obj . search ( cr , uid , [ ( ' bank_statement_id ' , ' in ' , ids ) ] , context = context )
cashbox_line_obj . unlink ( cr , uid , cashbox_ids , context )
2012-05-12 22:37:43 +00:00
res = super ( account_cash_statement , self ) . write ( cr , uid , ids , vals , context = context )
self . _update_balances ( cr , uid , ids , context )
return res
2010-08-14 05:48:09 +00:00
2010-10-21 07:08:55 +00:00
def _user_allow ( self , cr , uid , statement_id , context = None ) :
2010-06-28 14:35:41 +00:00
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 ) :
""" Changes statement state to Running.
2010-08-14 05:48:09 +00:00
@return : True
2010-06-26 19:16:11 +00:00
"""
2011-03-17 13:34:19 +00:00
obj_seq = self . pool . get ( ' ir.sequence ' )
2010-10-21 07:08:55 +00:00
if context is None :
context = { }
2010-06-26 19:16:11 +00:00
statement_pool = self . pool . get ( ' account.bank.statement ' )
2010-10-21 07:08:55 +00:00
for statement in statement_pool . browse ( cr , uid , ids , context = context ) :
vals = { }
2010-10-28 07:18:27 +00:00
if not self . _user_allow ( cr , uid , statement . id , context = context ) :
2013-04-29 07:15:57 +00:00
raise osv . except_osv ( _ ( ' Error! ' ) , ( _ ( ' You do not have rights to open this %s journal! ' ) % ( statement . journal_id . name , ) ) )
2010-08-14 05:48:09 +00:00
2010-10-21 07:08:55 +00:00
if statement . name and statement . name == ' / ' :
2012-03-22 11:39:59 +00:00
c = { ' fiscalyear_id ' : statement . period_id . fiscalyear_id . id }
2011-03-17 13:34:19 +00:00
if statement . journal_id . sequence_id :
2011-09-29 13:22:54 +00:00
st_number = obj_seq . next_by_id ( cr , uid , statement . journal_id . sequence_id . id , context = c )
2011-03-17 13:34:19 +00:00
else :
2012-03-14 12:53:24 +00:00
st_number = obj_seq . next_by_code ( cr , uid , ' account.cash.statement ' , context = c )
2010-10-21 07:08:55 +00:00
vals . update ( {
2011-03-17 13:34:19 +00:00
' name ' : st_number
2010-10-21 07:08:55 +00:00
} )
2010-08-14 05:48:09 +00:00
2010-10-21 07:08:55 +00:00
vals . update ( {
2010-10-21 12:08:26 +00:00
' state ' : ' open ' ,
2010-10-21 07:08:55 +00:00
} )
2010-12-13 06:43:09 +00:00
self . write ( cr , uid , [ statement . id ] , vals , context = context )
2010-10-21 07:08:55 +00:00
return True
2010-06-26 19:16:11 +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 ' ,
2010-10-15 07:35:42 +00:00
' closing_date ' : time . strftime ( " % Y- % m- %d % H: % M: % S " )
2010-07-09 09:12:12 +00:00
}
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 ) :
2012-05-04 12:51:58 +00:00
absl_proxy = self . pool . get ( ' account.bank.statement.line ' )
2012-11-03 17:16:27 +00:00
TABLES = ( ( _ ( ' Profit ' ) , ' profit_account_id ' ) , ( _ ( ' Loss ' ) , ' loss_account_id ' ) , )
2012-05-04 12:51:58 +00:00
for obj in self . browse ( cr , uid , ids , context = context ) :
if obj . difference == 0.0 :
continue
2014-08-21 09:02:18 +00:00
elif obj . difference < 0.0 :
account = obj . journal_id . loss_account_id
name = _ ( ' Loss ' )
if not obj . journal_id . loss_account_id :
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' There is no Loss Account on the journal %s . ' ) % ( obj . journal_id . name , ) )
else : # obj.difference > 0.0
account = obj . journal_id . profit_account_id
name = _ ( ' Profit ' )
if not obj . journal_id . profit_account_id :
raise osv . except_osv ( _ ( ' Error! ' ) , _ ( ' There is no Profit Account on the journal %s . ' ) % ( obj . journal_id . name , ) )
2012-05-04 12:51:58 +00:00
values = {
' statement_id ' : obj . id ,
' journal_id ' : obj . journal_id . id ,
' account_id ' : account . id ,
' amount ' : obj . difference ,
2014-08-21 09:02:18 +00:00
' name ' : name ,
2012-05-04 12:51:58 +00:00
}
absl_proxy . create ( cr , uid , values , context = context )
2014-08-21 08:54:38 +00:00
return super ( account_cash_statement , self ) . button_confirm_bank ( cr , uid , ids , context = context )
2010-09-22 15:41:58 +00:00
2010-09-29 08:49:19 +00:00
2012-04-16 09:01:22 +00:00
class account_journal ( osv . osv ) :
_inherit = ' account.journal '
2012-05-29 12:00:29 +00:00
def _default_cashbox_line_ids ( self , cr , uid , context = None ) :
# Return a list of coins in Euros.
result = [
dict ( pieces = value ) for value in [ 0.01 , 0.02 , 0.05 , 0.1 , 0.2 , 0.5 , 1 , 2 , 5 , 10 , 20 , 50 , 100 , 200 , 500 ]
]
return result
2012-04-16 09:01:22 +00:00
_columns = {
2014-07-06 14:44:26 +00:00
' cashbox_line_ids ' : fields . one2many ( ' account.journal.cashbox.line ' , ' journal_id ' , ' CashBox ' , copy = True ) ,
2012-04-16 09:01:22 +00:00
}
2012-05-29 12:00:29 +00:00
_defaults = {
' cashbox_line_ids ' : _default_cashbox_line_ids ,
}
2012-04-16 09:01:22 +00:00
class account_journal_cashbox_line ( osv . osv ) :
_name = ' account.journal.cashbox.line '
2012-07-31 12:22:02 +00:00
_rec_name = ' pieces '
2012-04-16 09:01:22 +00:00
_columns = {
2012-04-16 11:36:33 +00:00
' pieces ' : fields . float ( ' Values ' , digits_compute = dp . get_precision ( ' Account ' ) ) ,
2013-02-15 17:50:42 +00:00
' journal_id ' : fields . many2one ( ' account.journal ' , ' Journal ' , required = True , select = 1 , ondelete = " cascade " ) ,
2012-04-16 09:01:22 +00:00
}
2012-04-16 11:36:33 +00:00
_order = ' pieces asc '
2012-04-16 09:01:22 +00:00
2010-10-21 07:08:55 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: