Browse Source

[ADD][8.0] pos_change_payment. (from github.com/grap/grap-odoo-incubator)

pull/480/head
Sylvain LE GAL 4 years ago
parent
commit
6e6e2aab73
  1. 91
      pos_change_payment/README.rst
  2. 6
      pos_change_payment/__init__.py
  3. 23
      pos_change_payment/__openerp__.py
  4. 168
      pos_change_payment/i18n/fr.po
  5. 9
      pos_change_payment/models/__init__.py
  6. 66
      pos_change_payment/models/account_bank_statement_line.py
  7. 72
      pos_change_payment/models/pos_change_payments_wizard.py
  8. 25
      pos_change_payment/models/pos_change_payments_wizard_line.py
  9. 25
      pos_change_payment/models/pos_make_payment.py
  10. 57
      pos_change_payment/models/pos_order.py
  11. 78
      pos_change_payment/models/pos_switch_journal_wizard.py
  12. 2
      pos_change_payment/readme/CONTRIBUTORS.rst
  13. 34
      pos_change_payment/readme/DESCRIPTION.rst
  14. BIN
      pos_change_payment/static/description/icon.png
  15. BIN
      pos_change_payment/static/description/pos_order_change_payments.png
  16. BIN
      pos_change_payment/static/description/pos_order_switch_payment.png
  17. 2
      pos_change_payment/tests/__init__.py
  18. 157
      pos_change_payment/tests/test_module.py
  19. 26
      pos_change_payment/views/action.xml
  20. 21
      pos_change_payment/views/view_account_bank_statement.xml
  21. 36
      pos_change_payment/views/view_pos_change_payments_wizard.xml
  22. 30
      pos_change_payment/views/view_pos_order.xml
  23. 29
      pos_change_payment/views/view_pos_switch_journal_wizard.xml

91
pos_change_payment/README.rst

@ -0,0 +1,91 @@
===============================
Point Of Sale - Payments Change
===============================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-grap%2Fgrap--odoo--incubator-lightgray.png?logo=github
:target: https://github.com/grap/grap-odoo-incubator/tree/8.0/pos_change_payment
:alt: grap/grap-odoo-incubator
|badge1| |badge2| |badge3|
Improve payment changes when user did a mistake and disable some actions on
Point of Sale Bank Statement Line
* Add the possibility to switch a payment (account.bank.statement.line)
of an order from a journal to another. This feature is usefull when
the user realized that he did a mistake, during the close of the session,
or just after he marked the order as paid
(Only if entries has not been generated)
.. figure:: https://raw.githubusercontent.com/grap/grap-odoo-incubator/8.0/pos_change_payment/static/description/pos_order_switch_payment.png
* Add the possibility to change all payments (method and amount) of a POS
(Only if entries has not been generated)
.. figure:: https://raw.githubusercontent.com/grap/grap-odoo-incubator/8.0/pos_change_payment/static/description/pos_order_change_payments.png
Bug Fixes / Improvement
~~~~~~~~~~~~~~~~~~~~~~~
* In the pos.payment wizard, display only the payment methods defined in
the current POS session
* Disable the possibility to edit / delete a bank statement line on a POS
Order that has generated his entries, except using the wizard of this
module. This will prevent the generation of bad account move during
the close of the session; (mainly unbalanced moves)
* All the cash payment are merged into a single one statement line. This
feature is usefull if the user use OpenERP as a calculator, writing
for a payment:
1. Payment 1/ Cash 50 €;
2. Payment 2/ Cash -3,56 €;
3. With this module, the final statement line is a single line Payment 1/ Cash 46,44 €
**Table of contents**
.. contents::
:local:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/grap/grap-odoo-incubator/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/grap/grap-odoo-incubator/issues/new?body=module:%20pos_change_payment%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
~~~~~~~
* GRAP
Contributors
~~~~~~~~~~~~
* Sylvain LE GAL <https://twitter.com/legalsylvain>
* Julien WESTE
Maintainers
~~~~~~~~~~~
This module is part of the `grap/grap-odoo-incubator <https://github.com/grap/grap-odoo-incubator/tree/8.0/pos_change_payment>`_ project on GitHub.
You are welcome to contribute.

6
pos_change_payment/__init__.py

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models

23
pos_change_payment/__openerp__.py

@ -0,0 +1,23 @@
# coding: utf-8
# Copyright (C) 2013 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Point Of Sale - Payments Change',
'version': '8.0.1.0.0',
'category': 'Point Of Sale',
'author': 'GRAP',
'website': 'http://www.grap.coop',
'license': 'AGPL-3',
'depends': [
'point_of_sale',
],
'data': [
'views/action.xml',
'views/view_account_bank_statement.xml',
'views/view_pos_change_payments_wizard.xml',
'views/view_pos_order.xml',
'views/view_pos_switch_journal_wizard.xml',
],
'installable': True,
}

168
pos_change_payment/i18n/fr.po

@ -0,0 +1,168 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * pos_change_payment
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-04-01 14:25+0000\n"
"PO-Revision-Date: 2015-04-01 14:25+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: pos_change_payment
#: field:pos.change.payments.wizard.line,amount:0
#: field:pos.switch.journal.wizard,amount:0
msgid "Amount"
msgstr "Montant"
#. module: pos_change_payment
#: code:_description:0
#: model:ir.model,name:pos_change_payment.model_account_bank_statement_line
#, python-format
msgid "Bank Statement Line"
msgstr "Ligne de relevé de banque"
#. module: pos_change_payment
#: view:pos.change.payments.wizard:0
#: view:pos.switch.journal.wizard:0
msgid "Cancel"
msgstr "Annuler"
#. module: pos_change_payment
#: model:ir.actions.act_window,name:pos_change_payment.action_pos_change_payments_wizard
#: view:pos.change.payments.wizard:0
#: view:pos.order:0
msgid "Change Payments"
msgstr "Changer les paiements"
#. module: pos_change_payment
#: code:addons/pos_change_payment/model/pos_change_payments_wizard.py:77
#, python-format
msgid "Differences between the two values for the POS Order '%s':\n"
"\n"
" * Total of all the new payments %s;\n"
" * Total of the POS Order %s;\n"
"\n"
"Please change the payments."
msgstr "Différences entre les deux valeurs pour la vente '%s':\n"
"\n"
" * Total des nouveaux paiements %s;\n"
" * Total de la vente %s;\n"
"\n"
"Veuillez changer les paiements."
#. module: pos_change_payment
#: code:addons/pos_change_payment/model/account_bank_statement_line.py:78
#: code:addons/pos_change_payment/model/pos_change_payments_wizard.py:36
#: code:addons/pos_change_payment/model/pos_change_payments_wizard.py:72
#: code:addons/pos_change_payment/model/pos_order.py:76
#: code:addons/pos_change_payment/model/pos_switch_journal_wizard.py:64
#, python-format
msgid "Error!"
msgstr "Erreur !"
#. module: pos_change_payment
#: code:addons/pos_change_payment/model/pos_change_payments_wizard.py:36
#: code:addons/pos_change_payment/model/pos_switch_journal_wizard.py:64
#, python-format
msgid "Incorrect Call!"
msgstr "Appel incorrect !"
#. module: pos_change_payment
#: code:_description:0
#: model:ir.model,name:pos_change_payment.model_account_journal
#: field:pos.change.payments.wizard.line,journal_id:0
#, python-format
msgid "Journal"
msgstr "Journal"
#. module: pos_change_payment
#: field:pos.switch.journal.wizard,new_statement_id:0
msgid "New Journal"
msgstr "Nouveau journal"
#. module: pos_change_payment
#: field:pos.switch.journal.wizard,old_journal_id:0
msgid "Old Journal"
msgstr "Ancien journal"
#. module: pos_change_payment
#: field:pos.change.payments.wizard,order_id:0
msgid "POS Order"
msgstr "Vente"
#. module: pos_change_payment
#: view:pos.order:0
msgid "Payment"
msgstr "Paiement"
#. module: pos_change_payment
#: view:pos.change.payments.wizard:0
msgid "Payment Lines"
msgstr "Lignes de paiement"
#. module: pos_change_payment
#: code:_description:0
#: model:ir.model,name:pos_change_payment.model_pos_order
#, python-format
msgid "Point of Sale"
msgstr "Point de Vente"
#. module: pos_change_payment
#: code:_description:0
#: model:ir.model,name:pos_change_payment.model_pos_make_payment
#, python-format
msgid "Point of Sale Payment"
msgstr "Paiement du ticket"
#. module: pos_change_payment
#: field:pos.switch.journal.wizard,statement_line_id:0
msgid "Statement"
msgstr "Relevé bancaire"
#. module: pos_change_payment
#: view:account.bank.statement:0
#: model:ir.actions.act_window,name:pos_change_payment.action_pos_switch_journal_wizard
#: view:pos.order:0
#: view:pos.switch.journal.wizard:0
msgid "Switch Journal"
msgstr "Changer de Journal"
#. module: pos_change_payment
#: field:pos.change.payments.wizard,amount_total:0
msgid "Total"
msgstr "Total"
#. module: pos_change_payment
#: field:pos.change.payments.wizard,line_ids:0
msgid "Wizard Lines"
msgstr "Lignes"
#. module: pos_change_payment
#: field:pos.change.payments.wizard.line,wizard_id:0
msgid "Wizard Ref"
msgstr "Référence"
#. module: pos_change_payment
#: code:addons/pos_change_payment/model/account_bank_statement_line.py:79
#, python-format
msgid "You can not change payments of POS by this way. Please use the regular wizard in POS view!"
msgstr "Vous ne pouvez pas changer les paiements de cette vente de cette façon. Veuillez utiliser l'interface prévue à cet effet dans la vue de la vente !"
#. module: pos_change_payment
#: code:addons/pos_change_payment/model/pos_order.py:78
#, python-format
msgid "You can not change payments of the POS '%s' because the associated session '%s' has been closed!"
msgstr "Vous ne pouvez pas changer les paiements de la Vente '%s' car la session associée '%s' a été clôturé !"
#. module: pos_change_payment
#: view:pos.change.payments.wizard:0
#: view:pos.switch.journal.wizard:0
msgid "or"
msgstr "ou"

9
pos_change_payment/models/__init__.py

@ -0,0 +1,9 @@
# coding: utf-8
from . import pos_order
from . import account_bank_statement_line
from . import pos_make_payment
from . import pos_switch_journal_wizard
from . import pos_change_payments_wizard
from . import pos_change_payments_wizard_line

66
pos_change_payment/models/account_bank_statement_line.py

@ -0,0 +1,66 @@
# coding: utf-8
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import _, api, models
from openerp.exceptions import ValidationError
class AccountBankStatementLine(models.Model):
_inherit = 'account.bank.statement.line'
_POS_PAYMENT_ALLOW_WRITE = [
'sequence', 'journal_entry_id',
]
# Private Function Section
@api.multi
def _check_allow_change_pos_payment(self, vals):
"""Allow or block change of account bank statement line, linked to
a non draft POS Order.
* if 'change_pos_payment' is in the context, changes are allowed;
* otherwise:
* allow write of some fields only;
* forbid deletion;"""
values = vals.copy() if vals else {}
check_pos_order = False
if values:
# Allow some write
for key in self._POS_PAYMENT_ALLOW_WRITE:
if key in values:
del values[key]
if not values:
return
# Allow changes, if user use the wizard
if self._context.get('change_pos_payment', False):
check_pos_order = True
for statement_line in self:
order = statement_line.pos_statement_id
if order:
if order.state != 'draft':
if check_pos_order:
order._allow_change_payments()
else:
if values.keys() == ['partner_id']:
order._allow_change_payments()
else:
raise ValidationError(_(
"You can not change payments of POS by this"
" way. Please use the regular wizard in POS"
" view!"))
# Overload Section
@api.multi
def write(self, vals):
self._check_allow_change_pos_payment(vals)
return super(AccountBankStatementLine, self).write(vals)
@api.multi
def unlink(self):
self._check_allow_change_pos_payment(None)
return super(AccountBankStatementLine, self).unlink()

72
pos_change_payment/models/pos_change_payments_wizard.py

@ -0,0 +1,72 @@
# coding: utf-8
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import _, api, fields, models
from openerp.exceptions import Warning as UserError
class PosChangePaymentsWizard(models.TransientModel):
_name = 'pos.change.payments.wizard'
# Column Section
order_id = fields.Many2one(
comodel_name='pos.order', string='Order', readonly=True)
session_id = fields.Many2one(
comodel_name='pos.session', string='Session', readonly=True)
line_ids = fields.One2many(
comodel_name='pos.change.payments.wizard.line',
inverse_name='wizard_id', string='Payment Lines')
amount_total = fields.Float(string='Total', readonly=True)
# View Section
@api.model
def default_get(self, fields):
order_obj = self.env['pos.order']
res = super(PosChangePaymentsWizard, self).default_get(fields)
order = order_obj.browse(self._context.get('active_id'))
res.update({'order_id': order.id})
res.update({'session_id': order.session_id.id})
res.update({'amount_total': order.amount_total})
return res
# View section
@api.multi
def button_change_payments(self):
self.ensure_one()
order = self.order_id
# Check if the total is correct
total = 0
for line in self.line_ids:
total += line.amount
if total != self.amount_total:
raise UserError(_(
"Differences between the two values for the POS"
" Order '%s':\n\n"
" * Total of all the new payments %s;\n"
" * Total of the POS Order %s;\n\n"
"Please change the payments." % (
order.name, total, order.amount_total)))
# Check if change payments is allowed
order._allow_change_payments()
# Remove old statements
order.statement_ids.with_context(change_pos_payment=True).unlink()
# Create new payment
for line in self.line_ids:
order.add_payment_v8({
'journal': line.new_journal_id.id,
'amount': line.amount,
})
return {
'type': 'ir.actions.client',
'tag': 'reload',
}

25
pos_change_payment/models/pos_change_payments_wizard_line.py

@ -0,0 +1,25 @@
# coding: utf-8
# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, fields, models
class PosChangePaymentsWizardLine(models.TransientModel):
_name = 'pos.change.payments.wizard.line'
wizard_id = fields.Many2one(
comodel_name='pos.change.payments.wizard', ondelete='cascade')
new_journal_id = fields.Many2one(
comodel_name='account.journal', string='Journal', required=True,
domain=lambda s: s._domain_new_journal_id())
amount = fields.Float(string='Amount', required=True)
@api.model
def _domain_new_journal_id(self):
PosOrder = self.env['pos.order']
order = PosOrder.browse(self.env.context.get('active_id'))
return [('id', 'in', order.session_id.journal_ids.ids)]

25
pos_change_payment/models/pos_make_payment.py

@ -0,0 +1,25 @@
# coding: utf-8
# Copyright (C) 2015-Today GRAP (http://www.grap.coop)
# @author Julien WESTE
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, models, fields
class PosMakePayment(models.TransientModel):
_inherit = 'pos.make.payment'
# # Column Section (Overload)
journal_id = fields.Many2one(
default=False,
domain=lambda s: s._domain_journal_id())
@api.model
def _domain_journal_id(self):
session_obj = self.env['pos.session']
if self.env.context.get('pos_session_id', False):
session = session_obj.browse(
int(self._context.get('pos_session_id')))
return [('id', 'in', session.journal_ids.ids)]
return []

57
pos_change_payment/models/pos_order.py

@ -0,0 +1,57 @@
# coding: utf-8
# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop)
# @author: Julien WESTE
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import _, api, models
from openerp.exceptions import Warning as UserError
class PosOrder(models.Model):
_inherit = 'pos.order'
# Overload Section
@api.multi
def action_paid(self):
""" Merge all cash statement line of the Order"""
self._merge_cash_payment()
return super(PosOrder, self).action_paid()
@api.multi
def add_payment_v8(self, data):
"""Hack to call old api. TODO-V10 : remove me."""
for order in self:
self.pool['pos.order'].add_payment(
self._cr, self._uid, order.id, data, context=self._context)
return True
# Private Function Section
@api.multi
def _merge_cash_payment(self):
for order in self:
cash_statements = order.statement_ids.filtered(
lambda x: x.journal_id.type == 'cash')
if len(cash_statements) < 2:
continue
main_statement = cash_statements[0]
cash_total = sum(cash_statements.mapped('amount'))
# Unlink all statements except one
cash_statements.filtered(
lambda x: x.id != main_statement.id).unlink()
main_statement.write({'amount': cash_total})
@api.multi
def _allow_change_payments(self):
"""Return True if the user can change the payment of a POS, depending
of the state of the current session."""
closed_orders = self.filtered(
lambda x: x.session_id.state == 'closed')
if len(closed_orders):
raise UserError(_(
"You can not change payments of the POS '%s' because"
" the associated session '%s' has been closed!" % (
', '.join(closed_orders.mapped('name')),
', '.join(closed_orders.mapped('session_id.name')))))

78
pos_change_payment/models/pos_switch_journal_wizard.py

@ -0,0 +1,78 @@
# coding: utf-8
# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, fields, models
class PosSwitchJournalWizard(models.TransientModel):
_name = 'pos.switch.journal.wizard'
order_id = fields.Many2one(
comodel_name='pos.order', string='PoS Order',
required=True, readonly=True)
statement_line_id = fields.Many2one(
comodel_name='account.bank.statement.line', string='Statement',
required=True, readonly=True)
old_journal_id = fields.Many2one(
comodel_name='account.journal', string='Old Journal',
required=True, readonly=True)
new_journal_id = fields.Many2one(
comodel_name='account.journal', string='New Journal',
required=True, domain=lambda s: s._domain_new_journal_id())
amount = fields.Float(string='Amount', readonly=True)
@api.model
def _domain_new_journal_id(self):
AccountBankStatementLine = self.env['account.bank.statement.line']
statement_line = AccountBankStatementLine.browse(
self.env.context.get('active_id'))
return [(
'id', 'in',
statement_line.pos_statement_id.session_id.journal_ids.ids)]
@api.model
def default_get(self, fields):
AccountBankStatementLine = self.env['account.bank.statement.line']
res = super(PosSwitchJournalWizard, self).default_get(fields)
statement_line = AccountBankStatementLine.browse(
self.env.context.get('active_id'))
res.update({'statement_line_id': statement_line.id})
res.update({'order_id': statement_line.pos_statement_id.id})
res.update({'old_journal_id': statement_line.journal_id.id})
res.update({'amount': statement_line.amount})
return res
# Action section
@api.multi
def button_switch_journal(self):
self.ensure_one()
# Check if changing payment is allowed
self.order_id._allow_change_payments()
# TODO (FIXME) when upstream is fixed.
# We do 2 write, one in the old statement, one in the new, with
# 'amount' value each time to recompute all the functional fields
# of the Account Bank Statements
amount = self.amount
self.statement_line_id.with_context(change_pos_payment=True).write({
'amount': 0.0,
})
# Change statement of the statement line
new_statement = self.order_id.session_id.statement_ids.filtered(
lambda x: x.journal_id == self.new_journal_id)[0]
self.statement_line_id.with_context(change_pos_payment=True).write({
'amount': amount,
'statement_id': new_statement.id,
})
return {
'type': 'ir.actions.client',
'tag': 'reload',
}

2
pos_change_payment/readme/CONTRIBUTORS.rst

@ -0,0 +1,2 @@
* Sylvain LE GAL <https://twitter.com/legalsylvain>
* Julien WESTE

34
pos_change_payment/readme/DESCRIPTION.rst

@ -0,0 +1,34 @@
Improve payment changes when user did a mistake and disable some actions on
Point of Sale Bank Statement Line
* Add the possibility to switch a payment (account.bank.statement.line)
of an order from a journal to another. This feature is usefull when
the user realized that he did a mistake, during the close of the session,
or just after he marked the order as paid
(Only if entries has not been generated)
.. figure:: ../static/description/pos_order_switch_payment.png
* Add the possibility to change all payments (method and amount) of a POS
(Only if entries has not been generated)
.. figure:: ../static/description/pos_order_change_payments.png
Bug Fixes / Improvement
~~~~~~~~~~~~~~~~~~~~~~~
* In the pos.payment wizard, display only the payment methods defined in
the current POS session
* Disable the possibility to edit / delete a bank statement line on a POS
Order that has generated his entries, except using the wizard of this
module. This will prevent the generation of bad account move during
the close of the session; (mainly unbalanced moves)
* All the cash payment are merged into a single one statement line. This
feature is usefull if the user use OpenERP as a calculator, writing
for a payment:
1. Payment 1/ Cash 50 €;
2. Payment 2/ Cash -3,56 €;
3. With this module, the final statement line is a single line Payment 1/ Cash 46,44 €

BIN
pos_change_payment/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 8.6 KiB

BIN
pos_change_payment/static/description/pos_order_change_payments.png

After

Width: 892  |  Height: 435  |  Size: 28 KiB

BIN
pos_change_payment/static/description/pos_order_switch_payment.png

After

Width: 890  |  Height: 199  |  Size: 26 KiB

2
pos_change_payment/tests/__init__.py

@ -0,0 +1,2 @@
# coding: utf-8
from . import test_module

157
pos_change_payment/tests/test_module.py

@ -0,0 +1,157 @@
# coding: utf-8
# Copyright (C) 2018 - Today: GRAP (http://www.grap.coop)
# @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests.common import TransactionCase
from openerp.exceptions import Warning as UserError
class TestModule(TransactionCase):
"""Tests for 'Point of Sale - Change Payment' Module"""
def setUp(self):
super(TestModule, self).setUp()
self.PosSession = self.env['pos.session']
self.PosOrder = self.env['pos.order']
self.PosMakePayment = self.env['pos.make.payment']
self.PosSwitchJournalWizard = self.env['pos.switch.journal.wizard']
self.PosChangePaymentsWizard = self.env['pos.change.payments.wizard']
self.PosChangePaymentsWizardLine =\
self.env['pos.change.payments.wizard.line']
self.product = self.env.ref('product.product_product_3')
self.pos_config = self.env.ref('point_of_sale.pos_config_main')
self.check_journal = self.env.ref('account.check_journal')
self.cash_journal = self.env.ref('account.cash_journal')
# create new session and open it
self.session = self.PosSession.create(
{'config_id': self.pos_config.id})
self.session.open_cb()
self.check_statement = self.session.statement_ids.filtered(
lambda x: x.journal_id == self.check_journal)
self.cash_statement = self.session.statement_ids.filtered(
lambda x: x.journal_id == self.cash_journal)
def _sale(self, session, journal_1, price_1, journal_2=False, price_2=0.0):
order = self.PosOrder.create({
'session_id': session.id,
'lines': [[0, False, {
'name': 'OL/0001',
'product_id': self.product.id,
'qty': 1.0,
'price_unit': price_1 + price_2,
}]],
})
payment = self.PosMakePayment.with_context(active_id=order.id).create({
'journal_id': journal_1.id,
'amount': price_1,
})
payment.with_context(active_id=order.id).check()
if journal_2:
payment = self.PosMakePayment.with_context(
active_id=order.id).create({
'journal_id': journal_2.id,
'amount': price_2,
})
payment.with_context(active_id=order.id).check()
return order
# Test Section
def test_01_pos_switch_journal(self):
# Make a sale with 100 in cash journal
order = self._sale(self.session, self.cash_journal, 100)
statement_line = order.statement_ids[0]
# Switch to check journal
wizard = self.PosSwitchJournalWizard.with_context(
active_id=statement_line.id).create({
'new_journal_id': self.check_journal.id,
})
wizard.button_switch_journal()
# Check Order
self.assertEqual(
len(order.statement_ids.filtered(
lambda x: x.journal_id == self.cash_journal)), 0,
"Altered order should not have the original payment journal")
self.assertEqual(
len(order.statement_ids.filtered(
lambda x: x.journal_id == self.check_journal)), 1,
"Altered order should have the final payment journal")
# Check Session
self.assertEqual(
self.cash_statement.balance_end, 0,
"Bad recompute of the balance for the old statement")
self.assertEqual(
self.check_statement.balance_end, 100,
"Bad recompute of the balance for the new statement")
def test_02_pos_change_payment(self):
# Make a sale with 35 in cash journal and 65 in check
order = self._sale(
self.session, self.cash_journal, 35, self.check_journal, 65)
# Switch to check journal
wizard = self.PosChangePaymentsWizard.with_context(
active_id=order.id).create({})
self.PosChangePaymentsWizardLine.with_context(
active_id=order.id).create({
'wizard_id': wizard.id,
'new_journal_id': self.cash_journal.id,
'amount': 10,
})
self.PosChangePaymentsWizardLine.with_context(
active_id=order.id).create({
'wizard_id': wizard.id,
'new_journal_id': self.check_journal.id,
'amount': 40,
})
with self.assertRaises(UserError):
# Should not work if total is not correct
wizard.button_change_payments()
# Finish payement
self.PosChangePaymentsWizardLine.with_context(
active_id=order.id).create({
'wizard_id': wizard.id,
'new_journal_id': self.check_journal.id,
'amount': 50,
})
wizard.button_change_payments()
# check Session
self.assertEqual(
self.cash_statement.balance_end, 10,
"Bad recompute of the balance for the old statement")
self.assertEqual(
self.check_statement.balance_end, 90,
"Bad recompute of the balance for the new statement")
def test_03_merge_statement(self):
# Make a sale with multiple cash payement
order = self._sale(
self.session, self.cash_journal, 100,
journal_2=self.cash_journal, price_2=200)
# Check that statement has been merged
self.assertEqual(
len(order.statement_ids), 1,
"Adding many cash statement for an order should merge them.")
self.assertEqual(
order.statement_ids[0].amount, 300,
"Invalid total amount for merged cash statements")
# Make a sale with multiple check payement
order = self._sale(
self.session, self.check_journal, 100,
self.check_journal, 200)
# Check that statement has been merged
self.assertEqual(
len(order.statement_ids), 2,
"Adding many check statement for an order should not merge them.")

26
pos_change_payment/views/action.xml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-Today GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<openerp><data>
<record id="action_pos_switch_journal_wizard" model="ir.actions.act_window">
<field name="name">Switch Journal</field>
<field name="res_model">pos.switch.journal.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record id="action_pos_change_payments_wizard" model="ir.actions.act_window">
<field name="name">Change Payments</field>
<field name="res_model">pos.change.payments.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data></openerp>

21
pos_change_payment/views/view_account_bank_statement.xml

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-Today GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<openerp><data>
<record id="view_account_bank_statement_form" model="ir.ui.view">
<field name="model">account.bank.statement</field>
<field name="inherit_id" ref="account.view_bank_statement_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='line_ids']/tree/field[@name='amount']" position="after">
<field name="pos_statement_id" invisible="1" />
<button name="%(action_pos_switch_journal_wizard)d" string="Switch Journal" type="action" icon="gtk-index" attrs="{'invisible':[('pos_statement_id', '=', False)]}"/>
</xpath>
</field>
</record>
</data></openerp>

36
pos_change_payment/views/view_pos_change_payments_wizard.xml

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-Today GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<openerp><data>
<record id="view_pos_change_payments_wizard_form" model="ir.ui.view">
<field name="model">pos.change.payments.wizard</field>
<field name="arch" type="xml">
<form>
<group col="4">
<field name="order_id" />
<field name="session_id" />
<field name="amount_total" />
<newline />
<field name="line_ids" colspan="4">
<tree string="Payment Lines" editable="bottom">
<field name="new_journal_id" widget="selection"/>
<field name="amount" />
</tree>
</field>
</group>
<footer>
<button name="button_change_payments" string="Change Payments"
type="object" class="oe_highlight"/>
<label string="or" />
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
</data></openerp>

30
pos_change_payment/views/view_pos_order.xml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-Today GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<openerp><data>
<record id="view_pos_order_form" model="ir.ui.view">
<field name="model">pos.order</field>
<field name="inherit_id" ref="point_of_sale.view_pos_pos_form" />
<field name="arch" type="xml">
<button string="Payment" position="attributes">
<attribute name="context">{'pos_session_id' : session_id}</attribute>
</button>
<button name="refund" position="before">
<button name="%(action_pos_change_payments_wizard)d"
context="{'pos_session_id' : session_id}"
string="Change Payments" type="action" states="paid,invoiced"/>
</button>
<field name="journal_id" position="after">
<button name="%(action_pos_switch_journal_wizard)d" string="Switch Journal"
type="action" icon="gtk-index"/>
</field>
</field>
</record>
</data></openerp>

29
pos_change_payment/views/view_pos_switch_journal_wizard.xml

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-Today GRAP (http://www.grap.coop)
@author: Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-->
<openerp><data>
<record id="view_pos_switch_journal_wizard_form" model="ir.ui.view">
<field name="model">pos.switch.journal.wizard</field>
<field name="arch" type="xml">
<form>
<group col="4">
<field name="order_id" />
<field name="statement_line_id" />
<field name="old_journal_id" />
<field name="new_journal_id" widget="selection"/>
<field name="amount" />
</group>
<footer>
<button name="button_switch_journal" string="Switch Journal" type="object" class="oe_highlight"/>
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
</data></openerp>
Loading…
Cancel
Save