From 341c6b0843a0aa059b6ba6d7e08c70bb0f95d2df Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Sun, 13 May 2012 00:37:43 +0200 Subject: [PATCH] [IMP] PoS Backend Improved layout of "PoS orders", "PoS Sessions" and "PoS Config" for useability Apply new design layouts for web client v7.0 Rename PoS by Point of Sale everywhere Some typos, improved views Reviewed menu structure "Default Point of Sale" field accessible through users preferences PoS Config: Sequence is readonly Removed the "Draft" state --> easier, you do not need to active a PoS Config Default values on Shop and Journals PoS Orders: Changed shop_id & journal_id on PoS Orders --> from normal fields to related field, depending on the session Open Session: Fixed the wizard Several bugfixes and useability improvements Accounting Transactions posted at the close (not at the control) Cash Registers: Lots of cleanups and bugfixes Pos Sessions: Fixes and improved layout Better computation of all fields removed unused object "pos.config.journal" PoS Orders: Default session_id bzr revid: fp@openerp.com-20120512223743-b1vvbbybo8xq7e54 --- addons/account/account_bank_statement.py | 37 +-- addons/account/account_cash_statement.py | 244 +++-------------- addons/account/account_view.xml | 120 ++++---- .../account/test/account_cash_statement.yml | 1 - addons/account/wizard/pos_box.py | 2 +- .../account_voucher/account_voucher_view.xml | 8 +- .../point_of_sale/account_bank_statement.py | 49 ---- .../point_of_sale/account_statement_view.xml | 9 +- addons/point_of_sale/point_of_sale.py | 257 ++++++------------ addons/point_of_sale/point_of_sale_view.xml | 254 ++++++++--------- .../report/pos_details_summary.py | 9 +- addons/point_of_sale/res_users.py | 6 +- addons/point_of_sale/res_users_view.xml | 31 ++- .../security/ir.model.access.csv | 4 +- .../point_of_sale/wizard/pos_box_entries.py | 1 - .../wizard/pos_session_opening.py | 43 ++- .../wizard/pos_session_opening.xml | 20 +- addons/procurement/procurement_view.xml | 2 +- 18 files changed, 364 insertions(+), 733 deletions(-) diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 889721d4fa5..03523348c6b 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -53,36 +53,11 @@ class account_bank_statement(osv.osv): return False 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: + for statement in self.browse(cursor, user, ids, context=context): 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) + for line in statement.line_ids: + res[statement.id] += line.amount return res def _get_period(self, cr, uid, context=None): @@ -122,7 +97,7 @@ class account_bank_statement(osv.osv): _description = "Bank Statement" _columns = { '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'), # readonly for account_cash_statement - 'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}, select=True), + 'date': fields.date('Creation Date', required=True, states={'confirm': [('readonly', True)]}, select=True), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}), 'period_id': fields.many2one('account.period', 'Period', required=True, @@ -133,7 +108,7 @@ class account_bank_statement(osv.osv): states={'confirm': [('readonly', True)]}), 'balance_end': fields.function(_end_balance, store = { - 'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10), + 'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids','balance_start'], 10), 'account.bank.statement.line': (_get_statement, ['amount'], 10), }, string="Computed Balance", help='Balance as calculated based on Starting Balance and transaction lines'), @@ -303,7 +278,7 @@ class account_bank_statement(osv.osv): def balance_check(self, cr, uid, st_id, journal_type='bank', context=None): st = self.browse(cr, uid, st_id, context=context) - if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_cash) < 0.0001)): + if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001)): raise osv.except_osv(_('Error !'), _('The statement balance is incorrect !\nThe expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end)) return True diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index 8011cdac45b..d46f14b1607 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -61,8 +61,8 @@ class account_cashbox_line(osv.osv): 'pieces': fields.float('Unit of Currency', digits_compute=dp.get_precision('Account')), 'number_opening' : fields.integer('Number of Units', help='Opening Unit Numbers'), 'number_closing' : fields.integer('Number of Units', help='Closing Unit Numbers'), - 'subtotal_opening': fields.function(_sub_total, string='Subtotal Opening', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'), - 'subtotal_closing': fields.function(_sub_total, string='Subtotal Closing', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'), + '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'), 'bank_statement_id' : fields.many2one('account.bank.statement', ondelete='cascade'), } @@ -72,36 +72,26 @@ class account_cash_statement(osv.osv): _inherit = 'account.bank.statement' - def _get_starting_balance(self, cr, uid, ids, context=None): - - """ Find starting balance - @param name: Names of fields. - @param arg: User defined arguments - @return: Dictionary of values. + def _update_balances(self, cr, uid, ids, context=None): + """ + Set starting and ending balances according to pieces count """ res = {} + print 'Updating' for statement in self.browse(cr, uid, ids, context=context): - if statement.journal_id.type not in('cash'): + if statement.journal_id.type not in ('cash',): continue - res[statement.id] = { - 'balance_start': sum((line.pieces * line.number_opening - for line in statement.details_ids), 0.0) + 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, } - - print "_get_starting_balance: %r" % (res,) - return res - - 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. - """ - res = {} - for statement in self.browse(cr, uid, ids, context=context): - res[statement.id] = sum((line.pieces * line.number_closing - for line in statement.details_ids), 0.0) - print "_balance_end_cash: %r" % (res,) + res[statement.id] = data + print statement.id, data + super(account_cash_statement, self).write(cr, uid, [statement.id], data, context=context) return res def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None): @@ -114,7 +104,6 @@ class account_cash_statement(osv.osv): res = {} for statement in self.browse(cr, uid, ids, context=context): res[statement.id] = sum((line.amount for line in statement.line_ids), 0.0) - print "_get_sum_entry_encoding: %r" % (res,) return res def _get_company(self, cr, uid, context=None): @@ -126,63 +115,7 @@ class account_cash_statement(osv.osv): company_id = company_pool.search(cr, uid, []) return company_id and company_id[0] or False - def _get_cash_open_box_lines(self, cr, uid, context=None): - res = [] - curr = [1, 2, 5, 10, 20, 50, 100, 500] - for rs in curr: - dct = { - 'pieces': rs, - 'number': 0 - } - res.append(dct) - 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=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 - return res - - def _get_default_cash_close_box_lines(self, cr, uid, context=None): - res = [] - curr = [1, 2, 5, 10, 20, 50, 100, 500] - for rs in curr: - dct = { - 'pieces': rs, - 'number': 0 - } - res.append(dct) - return res - - def _get_cash_close_box_lines(self, cr, uid, context=None): - res = [] - curr = [1, 2, 5, 10, 20, 50, 100, 500] - for rs in curr: - dct = { - 'pieces': rs, - 'number': 0 - } - res.append((0, 0, dct)) - return res - - def _get_cash_open_close_box_lines(self, cr, uid, context=None): - res = {} - start_l = [] - end_l = [] - starting_details = self._get_cash_open_box_lines(cr, uid, context=context) - ending_details = self._get_default_cash_close_box_lines(cr, uid, context) - for start in starting_details: - start_l.append((0, 0, start)) - for end in ending_details: - end_l.append((0, 0, end)) - res['start'] = start_l - res['end'] = end_l - return res - - def _get_statement(self, cr, uid, ids, context=None): + def _get_statement_from_line(self, cr, uid, ids, context=None): result = {} for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context): result[line.statement_id.id] = True @@ -192,83 +125,46 @@ class account_cash_statement(osv.osv): result = dict.fromkeys(ids, 0.0) for obj in self.browse(cr, uid, ids, context=context): - result[obj.id] = obj.balance_end - obj.balance_end_cash + result[obj.id] = obj.balance_end_real - obj.balance_end return result _columns = { - 'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Cash Transaction", help="Total cash transactions", + 'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Total Cash Transactions", store = { 'account.bank.statement': (lambda self, cr, uid, ids, context=None: ids, ['line_ids','move_line_ids'], 10), - 'account.bank.statement.line': (_get_statement, ['amount'], 10), + 'account.bank.statement.line': (_get_statement_from_line, ['amount'], 10), }), 'closing_date': fields.datetime("Closed On"), - 'balance_end_cash': fields.function(_balance_end_cash, store=False, string='Closing Balance', help="Closing balance based on cashBox"), 'details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='CashBox Lines'), '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'), 'user_id': fields.many2one('res.users', 'Responsible', required=False), 'difference' : fields.function(_compute_difference, method=True, string="Difference", type="float"), } - _defaults = { 'state': 'draft', 'date': lambda self, cr, uid, context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")), 'user_id': lambda self, cr, uid, context=None: uid, } - def check_opening_journal(self, cr, uid, ids, context=None): - """ - This constraint will check than the journal is not used twice in the system, - to avoid a concurrency opening of this journal. - """ - for cash in self.browse(cr, uid, ids, context=None): - domain = [ - ('id', '!=', cash.id), - ('journal_id', '=', cash.journal_id.id), - ('journal_id.type', '=', 'cash'), - ('state', 'in', ('open',)), - ] - count = self.search_count(cr, uid, domain, context=context) - - if count: - return False - return True - - _constraints = [ - #(check_opening_journal, "The selected journal has been opened !", ['journal_id']), - ] - def create(self, cr, uid, vals, context=None): - if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash': - amount_total = 0.0 - for line in vals.get('details_ids',[]): - print "line: %r" % (line,) - if line and len(line)==3 and line[2]: - # FIXME: If there is no piece # does not work with GTK - amount_total+= line[2].get('pieces', 0) * line[2]['number_opening'] + journal = False + if vals.get('journal_id'): + journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context) + if journal and (journal.type == 'cash') and not vals.get('details_ids'): + vals['details_ids'] = [] + for value in journal.cashbox_line_ids: + nested_values = { + 'number_closing' : 0, + 'number_opening' : 0, + 'pieces' : value.pieces + } + vals['details_ids'].append([0, False, nested_values]) - vals.update(balance_start= amount_total) - vals.update(balance_end_real=self._compute_balance_end_real(cr, uid, vals['journal_id'], context=context)) - - details = vals.get('details_ids') - if not details: - result = self.onchange_journal_id(cr, uid, None, vals['journal_id'], context=context) - vals['details_ids'] = [] - - for value in (result['value']['details_ids'] or []): - print "value: %r" % (value,) - nested_values = { - 'number_closing' : False, - 'number_opening' : False, - 'pieces' : value['pieces'], - 'subtotal_closing' : False, - 'subtotal_opening' : False, - } - - vals['details_ids'].append([0, False, nested_values]) - - return super(account_cash_statement, self).create(cr, uid, vals, context=context) + res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context) + self._update_balances(cr, uid, [res_id], context) + return res_id def write(self, cr, uid, ids, vals, context=None): """ @@ -284,54 +180,9 @@ class account_cash_statement(osv.osv): @return: True on success, False otherwise """ - super(account_cash_statement, self).write(cr, uid, ids, vals, context=context) - res = self._get_starting_balance(cr, uid, ids) - for rs in res: - super(account_cash_statement, self).write(cr, uid, [rs], res.get(rs)) - return True - - def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None): - """ Changes balance start and starting details if journal_id changes" - @param statement_id: Changed statement_id - @param journal_id: Changed journal_id - @return: Dictionary of changed values - """ - balance_start = 0.0 - if journal_id: - count = self.search_count(cr, uid, [('journal_id', '=', journal_id),('state', '=', 'open')], context=None) - if 0: # count: - journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context) - raise osv.except_osv(_('Error !'), (_('The Account Journal %s is opened by an other Cash Register !') % (journal.name,))) - else: - values = super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context) - proxy_line = self.pool.get('account.cashbox.line') - - values.setdefault('value', {}) - values['value']['details_ids'] = [] - values['value']['balance_end_real'] = self._compute_balance_end_real(cr, uid, journal_id, context=context) - values['value']['balance_start'] = 0.0 - - journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context) - - for line in journal.cashbox_line_ids: - values['value']['details_ids'].append({'pieces' : line.pieces}) - - return values - else: - return { - 'value' : { - 'balance_start': balance_start, - 'details_ids' : [], - } - } - return super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context) - - 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}) - if statement.balance_end != statement.balance_end_cash: - return False - return True + res = super(account_cash_statement, self).write(cr, uid, ids, vals, context=context) + self._update_balances(cr, uid, ids, context) + return res def _user_allow(self, cr, uid, statement_id, context=None): return True @@ -347,7 +198,7 @@ class account_cash_statement(osv.osv): for statement in statement_pool.browse(cr, uid, ids, context=context): vals = {} if not self._user_allow(cr, uid, statement.id, context=context): - raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name))) + raise osv.except_osv(_('Error !'), (_('You do not have rights to open this %s journal !') % (statement.journal_id.name, ))) if statement.name and statement.name == '/': c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id} @@ -365,13 +216,6 @@ class account_cash_statement(osv.osv): self.write(cr, uid, [statement.id], vals, context=context) return True - 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 !'), _('The closing balance should be the same than the computed balance!')) - return True - 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) @@ -417,14 +261,6 @@ class account_cash_statement(osv.osv): return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context) - def button_cancel(self, cr, uid, ids, context=None): - cash_box_line_pool = self.pool.get('account.cashbox.line') - super(account_cash_statement, self).button_cancel(cr, uid, ids, context=context) - for st in self.browse(cr, uid, ids, context): - for end in st.details_ids: - cash_box_line_pool.write(cr, uid, [end.id], {'number_closing': 0}) - return True - account_cash_statement() class account_journal(osv.osv): diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 83d2e6264c3..0dd95c29fc1 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -32,7 +32,7 @@ - +