From 733fb360d25f885bd5c5b4688bbbc7f306f6f648 Mon Sep 17 00:00:00 2001 From: Pierre Masereel Date: Mon, 13 May 2019 08:52:57 +0000 Subject: [PATCH] [IMP] account, point_of_sale: properly handle cashbox When you use a cash journal in the point of sale, you can enable the 'Cash Control' option on your pos config to be able to count the money in your cashbox before and after selling goods in the POS. To better manage this behavior, we've made some improvements to handle the starting and ending of a session. First, instead of having just some cashbox lines set on the pos config representing the default cash fund in the cashbox, we are using an object of type cashbox as template. This allows to use the same default config for multiple POS config without recreating it. Then, we've added a currency on the cashbox, which is just computed based on the currency referencing the cashbox. When a POS session is open, the content of the cashbox is the same as the last closed session, to represent how a real cashbox works. We also always have the possibility to set the default cashbox of the POS config at the begining of a session. TASK-ID: 1934784 --- .../account/models/account_bank_statement.py | 96 ++++++++++++++----- addons/account/views/account_view.xml | 57 ++++++----- addons/point_of_sale/models/pos_config.py | 76 ++++++++++++--- addons/point_of_sale/models/pos_session.py | 30 +----- .../security/ir.model.access.csv | 2 +- .../point_of_sale/tests/test_anglo_saxon.py | 5 +- .../views/account_statement_view.xml | 76 +++++++++------ .../point_of_sale/views/pos_config_view.xml | 5 +- .../point_of_sale/views/pos_session_view.xml | 2 +- .../pos_mercury/views/pos_mercury_views.xml | 7 +- 10 files changed, 232 insertions(+), 124 deletions(-) diff --git a/addons/account/models/account_bank_statement.py b/addons/account/models/account_bank_statement.py index 25797b50edf..0028be54c81 100644 --- a/addons/account/models/account_bank_statement.py +++ b/addons/account/models/account_bank_statement.py @@ -20,13 +20,14 @@ class AccountCashboxLine(models.Model): @api.depends('coin_value', 'number') def _sub_total(self): """ Calculates Sub total""" - for line in self: - line.subtotal = line.coin_value * line.number + for cashbox_line in self: + cashbox_line.subtotal = cashbox_line.coin_value * cashbox_line.number coin_value = fields.Float(string='Coin/Bill Value', required=True, digits=0) - number = fields.Integer(string='Number of Coins/Bills', help='Opening Unit Numbers') + number = fields.Integer(string='#Coins/Bills', help='Opening Unit Numbers') subtotal = fields.Float(compute='_sub_total', string='Subtotal', digits=0, readonly=True) cashbox_id = fields.Many2one('account.bank.statement.cashbox', string="Cashbox") + currency_id = fields.Many2one('res.currency', related='cashbox_id.currency_id') class AccountBankStmtCashWizard(models.Model): @@ -37,20 +38,59 @@ class AccountBankStmtCashWizard(models.Model): _description = 'Bank Statement Cashbox' cashbox_lines_ids = fields.One2many('account.cashbox.line', 'cashbox_id', string='Cashbox Lines') + start_bank_stmt_ids = fields.One2many('account.bank.statement', 'cashbox_start_id') + end_bank_stmt_ids = fields.One2many('account.bank.statement', 'cashbox_end_id') + total = fields.Float(compute='_compute_total') + currency_id = fields.Many2one('res.currency', compute='_compute_currency') - def validate(self): - bnk_stmt_id = self.env.context.get('bank_statement_id', False) or self.env.context.get('active_id', False) - bnk_stmt = self.env['account.bank.statement'].browse(bnk_stmt_id) - total = 0.0 - for lines in self.cashbox_lines_ids: - total += lines.subtotal - if self.env.context.get('balance', False) == 'start': - #starting balance - bnk_stmt.write({'balance_start': total, 'cashbox_start_id': self.id}) - else: - #closing balance - bnk_stmt.write({'balance_end_real': total, 'cashbox_end_id': self.id}) - return {'type': 'ir.actions.act_window_close'} + @api.depends('start_bank_stmt_ids', 'end_bank_stmt_ids') + def _compute_currency(self): + for cashbox in self: + if cashbox.end_bank_stmt_ids: + cashbox.currency_id = cashbox.end_bank_stmt_ids[0].currency_id + if cashbox.start_bank_stmt_ids: + cashbox.currency_id = cashbox.start_bank_stmt_ids[0].currency_id + + @api.depends('cashbox_lines_ids', 'cashbox_lines_ids.coin_value', 'cashbox_lines_ids.number') + def _compute_total(self): + for cashbox in self: + cashbox.total = sum([line.subtotal for line in cashbox.cashbox_lines_ids]) + + @api.model + def default_get(self, fields): + vals = super(AccountBankStmtCashWizard, self).default_get(fields) + balance = self.env.context.get('balance') + statement_id = self.env.context.get('statement_id') + if 'start_bank_stmt_ids' in fields and not vals.get('start_bank_stmt_ids') and statement_id and balance == 'start': + vals['start_bank_stmt_ids'] = [(6, 0, [statement_id])] + if 'end_bank_stmt_ids' in fields and not vals.get('end_bank_stmt_ids') and statement_id and balance == 'close': + vals['end_bank_stmt_ids'] = [(6, 0, [statement_id])] + + return vals + + def name_get(self): + result = [] + for cashbox in self: + result.append((cashbox.id, _("%s")%(cashbox.total))) + return result + + @api.model_create_multi + def create(self, vals): + cashboxes = super(AccountBankStmtCashWizard, self).create(vals) + cashboxes._validate_cashbox() + return cashboxes + + def write(self, vals): + res = super(AccountBankStmtCashWizard, self).write(vals) + self._validate_cashbox() + return res + + def _validate_cashbox(self): + for cashbox in self: + if self.start_bank_stmt_ids: + self.start_bank_stmt_ids.write({'balance_start': self.total}) + if self.end_bank_stmt_ids: + self.end_bank_stmt_ids.write({'balance_end_real': self.total}) class AccountBankStmtCloseCheck(models.TransientModel): @@ -176,7 +216,7 @@ class AccountBankStatement(models.Model): account = stmt.journal_id.profit_account_id name = _('Profit') if not account: - raise UserError(_('There is no account defined on the journal %s for %s involved in a cash difference.') % (stmt.journal_id.name, name)) + raise UserError(_('Please go on the %s journal and define a %s Account. This account will be used to record cash difference.') % (stmt.journal_id.name, name)) values = { 'statement_id': stmt.id, @@ -201,20 +241,30 @@ class AccountBankStatement(models.Model): return super(AccountBankStatement, self).unlink() def open_cashbox_id(self): + self.ensure_one() context = dict(self.env.context or {}) - if context.get('cashbox_id'): - context['active_id'] = self.id - return { + if context.get('balance'): + context['statement_id'] = self.id + if context['balance'] == 'start': + cashbox_id = self.cashbox_start_id.id + elif context['balance'] == 'close': + cashbox_id = self.cashbox_end_id.id + else: + cashbox_id = False + + action = { 'name': _('Cash Control'), 'view_mode': 'form', 'res_model': 'account.bank.statement.cashbox', - 'view_id': self.env.ref('account.view_account_bnk_stmt_cashbox').id, + 'view_id': self.env.ref('account.view_account_bnk_stmt_cashbox_footer').id, 'type': 'ir.actions.act_window', - 'res_id': self.env.context.get('cashbox_id'), + 'res_id': cashbox_id, 'context': context, 'target': 'new' } + return action + def check_confirm_bank(self): if self.journal_type == 'cash' and not self.currency_id.is_zero(self.difference): action_rec = self.env['ir.model.data'].xmlid_to_object('account.action_view_account_bnk_stmt_check') @@ -270,7 +320,7 @@ class AccountBankStatement(models.Model): st_number = SequenceObj.with_context(**context).next_by_code('account.bank.statement') statement.name = st_number statement.state = 'open' - + def action_bank_reconcile_bank_statements(self): self.ensure_one() bank_stmt_lines = self.mapped('line_ids') diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml index 68e28bc6ec7..77e10a8529f 100644 --- a/addons/account/views/account_view.xml +++ b/addons/account/views/account_view.xml @@ -417,29 +417,46 @@ action = model.setting_init_bank_account_action() account.bank.statement.cashbox
- - + + + + + - + - + + - -
-
+
+ + + +
+ +
+
+
+
- - Cash Control - account.bank.statement.cashbox - tree,form - - new + + account.bnk_stmt_cashbox.form + account.bank.statement.cashbox + 1000 + primary + + + +
+
+
+
@@ -543,18 +560,12 @@ action = model.setting_init_bank_account_action()