2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2008 PC Solutions (<http://pcsol.be>). All Rights Reserved
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
25 from osv import osv, fields
26 from tools.translate import _
27 import decimal_precision as dp
29 class account_cashbox_line(osv.osv):
31 """ Cash Box Details """
33 _name = 'account.cashbox.line'
34 _description = 'CashBox Line'
37 def _sub_total(self, cr, uid, ids, name, arg, context=None):
39 """ Calculates Sub total
40 @param name: Names of fields.
41 @param arg: User defined arguments
42 @return: Dictionary of values.
45 for obj in self.browse(cr, uid, ids, context=context):
46 res[obj.id] = obj.pieces * obj.number
49 def on_change_sub(self, cr, uid, ids, pieces, number, *a):
51 """ Calculates Sub total on change of number
52 @param pieces: Names of fields.
56 return {'value': {'subtotal': sub or 0.0}}
59 'pieces': fields.float('Values', digits_compute=dp.get_precision('Account')),
60 'number': fields.integer('Number'),
61 'subtotal': fields.function(_sub_total, string='Sub Total', type='float', digits_compute=dp.get_precision('Account')),
62 'starting_id': fields.many2one('account.bank.statement', ondelete='cascade'),
63 'ending_id': fields.many2one('account.bank.statement', ondelete='cascade'),
66 account_cashbox_line()
68 class account_cash_statement(osv.osv):
70 _inherit = 'account.bank.statement'
72 def _get_starting_balance(self, cr, uid, ids, context=None):
74 """ Find starting balance
75 @param name: Names of fields.
76 @param arg: User defined arguments
77 @return: Dictionary of values.
80 for statement in self.browse(cr, uid, ids, context=context):
83 if statement.journal_id.type not in('cash'):
86 for line in statement.starting_details_ids:
87 amount_total+= line.pieces * line.number
89 'balance_start': amount_total
93 def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
94 """ Find ending balance "
95 @param name: Names of fields.
96 @param arg: User defined arguments
97 @return: Dictionary of values.
100 for statement in self.browse(cr, uid, ids, context=context):
102 for line in statement.ending_details_ids:
103 amount_total += line.pieces * line.number
104 res[statement.id] = amount_total
107 def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
109 """ Find encoding total of statements "
110 @param name: Names of fields.
111 @param arg: User defined arguments
112 @return: Dictionary of values.
115 for statement in self.browse(cr, uid, ids, context=context):
117 for line in statement.line_ids:
118 encoding_total += line.amount
119 res2[statement.id] = encoding_total
122 def _get_company(self, cr, uid, context=None):
123 user_pool = self.pool.get('res.users')
124 company_pool = self.pool.get('res.company')
125 user = user_pool.browse(cr, uid, uid, context=context)
126 company_id = user.company_id
128 company_id = company_pool.search(cr, uid, [])
129 return company_id and company_id[0] or False
131 def _get_cash_open_box_lines(self, cr, uid, context=None):
133 curr = [1, 2, 5, 10, 20, 50, 100, 500]
140 journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')], context=context)
142 results = self.search(cr, uid, [('journal_id', 'in', journal_ids),('state', '=', 'confirm')], context=context)
144 cash_st = self.browse(cr, uid, results, context=context)[0]
145 for cash_line in cash_st.ending_details_ids:
147 if cash_line.pieces == r['pieces']:
148 r['number'] = cash_line.number
151 def _get_default_cash_close_box_lines(self, cr, uid, context=None):
153 curr = [1, 2, 5, 10, 20, 50, 100, 500]
162 def _get_cash_close_box_lines(self, cr, uid, context=None):
164 curr = [1, 2, 5, 10, 20, 50, 100, 500]
170 res.append((0, 0, dct))
173 def _get_cash_open_close_box_lines(self, cr, uid, context=None):
177 starting_details = self._get_cash_open_box_lines(cr, uid, context=context)
178 ending_details = self._get_default_cash_close_box_lines(cr, uid, context)
179 for start in starting_details:
180 start_l.append((0, 0, start))
181 for end in ending_details:
182 end_l.append((0, 0, end))
183 res['start'] = start_l
187 def _get_statement(self, cr, uid, ids, context=None):
189 for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
190 result[line.statement_id.id] = True
194 'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Cash Transaction", help="Total cash transactions",
196 'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
197 'account.bank.statement.line': (_get_statement, ['amount'], 10),
199 'closing_date': fields.datetime("Closed On"),
200 'balance_end_cash': fields.function(_balance_end_cash, store=True, string='Closing Balance', help="Closing balance based on cashBox"),
201 'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'),
202 'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'),
203 'user_id': fields.many2one('res.users', 'Responsible', required=False),
207 'date': lambda self,cr,uid,context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")),
208 'user_id': lambda self, cr, uid, context=None: uid,
209 'starting_details_ids': _get_cash_open_box_lines,
210 'ending_details_ids': _get_default_cash_close_box_lines
213 def create(self, cr, uid, vals, context=None):
214 if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash':
215 open_close = self._get_cash_open_close_box_lines(cr, uid, context)
216 if vals.get('starting_details_ids', False):
217 for start in vals.get('starting_details_ids'):
219 for end in open_close['end']:
220 if end[2]['pieces'] == dict_val['pieces']:
221 end[2]['number'] += dict_val['number']
223 # 'ending_details_ids': open_close['start'],
224 'starting_details_ids': open_close['end']
228 'ending_details_ids': False,
229 'starting_details_ids': False
231 res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
232 self.write(cr, uid, [res_id], {})
235 def write(self, cr, uid, ids, vals, context=None):
237 Update redord(s) comes in {ids}, with new value comes as {vals}
238 return True on success, False otherwise
240 @param cr: cursor to database
241 @param user: id of current user
242 @param ids: list of record ids to be update
243 @param vals: dict of new values to be set
244 @param context: context arguments, like lang, time zone
246 @return: True on success, False otherwise
249 super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
250 res = self._get_starting_balance(cr, uid, ids)
252 super(account_cash_statement, self).write(cr, uid, [rs], res.get(rs))
255 def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
256 """ Changes balance start and starting details if journal_id changes"
257 @param statement_id: Changed statement_id
258 @param journal_id: Changed journal_id
259 @return: Dictionary of changed values
265 'balance_start': balance_start
268 return super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
270 def _equal_balance(self, cr, uid, cash_id, context=None):
271 statement = self.browse(cr, uid, cash_id, context=context)
272 self.write(cr, uid, [cash_id], {'balance_end_real': statement.balance_end})
273 statement.balance_end_real = statement.balance_end
274 if statement.balance_end != statement.balance_end_cash:
278 def _user_allow(self, cr, uid, statement_id, context=None):
281 def button_open(self, cr, uid, ids, context=None):
282 """ Changes statement state to Running.
285 obj_seq = self.pool.get('ir.sequence')
288 statement_pool = self.pool.get('account.bank.statement')
289 for statement in statement_pool.browse(cr, uid, ids, context=context):
291 if not self._user_allow(cr, uid, statement.id, context=context):
292 raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name)))
294 if statement.name and statement.name == '/':
295 if statement.journal_id.sequence_id:
296 c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
297 st_number = obj_seq.get_id(cr, uid, statement.journal_id.sequence_id.id, context=c)
299 st_number = obj_seq.get(cr, uid, 'account.cash.statement')
307 self.write(cr, uid, [statement.id], vals, context=context)
310 def balance_check(self, cr, uid, cash_id, journal_type='bank', context=None):
311 if journal_type == 'bank':
312 return super(account_cash_statement, self).balance_check(cr, uid, cash_id, journal_type, context)
313 if not self._equal_balance(cr, uid, cash_id, context):
314 raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance !'))
317 def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
318 if journal_type == 'bank':
319 return super(account_cash_statement, self).statement_close(cr, uid, ids, journal_type, context)
322 'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")
324 return self.write(cr, uid, ids, vals, context=context)
326 def check_status_condition(self, cr, uid, state, journal_type='bank'):
327 if journal_type == 'bank':
328 return super(account_cash_statement, self).check_status_condition(cr, uid, state, journal_type)
331 def button_confirm_cash(self, cr, uid, ids, context=None):
332 super(account_cash_statement, self).button_confirm_bank(cr, uid, ids, context=context)
333 return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context)
335 def button_cancel(self, cr, uid, ids, context=None):
336 cash_box_line_pool = self.pool.get('account.cashbox.line')
337 super(account_cash_statement, self).button_cancel(cr, uid, ids, context=context)
338 for st in self.browse(cr, uid, ids, context):
339 for end in st.ending_details_ids:
340 cash_box_line_pool.write(cr, uid, [end.id], {'number': 0})
343 account_cash_statement()
345 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: