Browse Source

[ADD] Add pos_cash_move_reason module

pull/384/head
Adrien Peiffer (ACSONE) 9 years ago
committed by Sylvain LE GAL
parent
commit
528533f289
  1. 62
      pos_cash_move_reason/README.rst
  2. 5
      pos_cash_move_reason/__init__.py
  3. 19
      pos_cash_move_reason/__openerp__.py
  4. 45
      pos_cash_move_reason/i18n/fr.po
  5. 43
      pos_cash_move_reason/i18n/pos_cash_move_reason.pot
  6. BIN
      pos_cash_move_reason/static/description/icon.png
  7. BIN
      pos_cash_move_reason/static/description/pos_cash_move_reason_02.png
  8. 5
      pos_cash_move_reason/tests/__init__.py
  9. 106
      pos_cash_move_reason/tests/test_pos_cash_move_reason.py
  10. 5
      pos_cash_move_reason/wizard/__init__.py
  11. 86
      pos_cash_move_reason/wizard/pos_box.py
  12. 26
      pos_cash_move_reason/wizard/pos_box.xml

62
pos_cash_move_reason/README.rst

@ -0,0 +1,62 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
======================
POS cash in-out reason
======================
This module allow to define some products as reason for the functionality of
"Put Money In" and "Take Money Out" available in point of sale session.
So, with this module it's possible to impact directly an expense or income
account which is defined on the related product or in its category.
Configuration
=============
You need to configure some products that can be used on "Put Money In" and
"Take Money Out". You have to set Point of Sale Cash In or Out and income and
expense account.
Usage
=====
You can use configured products on "Put Money In" and "Take Money Out" wizard available in point of sale session:
.. figure:: static/description/pos_cash_move_reason_02.png
:alt: Take money out wizard
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/184/8.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/pos/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
`here <https://github.com/OCA/pos/issues/new?body=module:%20pos_cash_move_reason%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======
Contributors
------------
* Adrien Peiffer <adrien.peiffer@acsone.eu>
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

5
pos_cash_move_reason/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import wizard

19
pos_cash_move_reason/__openerp__.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': "POS cash in-out reason",
'summary': """""",
'author': 'ACSONE SA/NV,'
'Odoo Community Association (OCA)',
'website': "http://acsone.eu",
'category': 'POS',
'version': '8.0.1.0.0',
'license': 'AGPL-3',
'depends': [
'point_of_sale',
],
'data': [
'wizard/pos_box.xml',
],
}

45
pos_cash_move_reason/i18n/fr.po

@ -0,0 +1,45 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_cash_move_reason
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-04-12 11:10+0000\n"
"PO-Revision-Date: 2016-04-12 11:10+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_cash_move_reason
#: code:addons/pos_cash_move_reason/wizard/pos_box.py:36
#, python-format
msgid "Description"
msgstr "Description"
#. module: pos_cash_move_reason
#: field:cash.box.in,product_id:0
#: field:cash.box.out,product_id:0
msgid "Reason"
msgstr "Motif"
#. module: pos_cash_move_reason
#: code:addons/pos_cash_move_reason/wizard/pos_box.py:84
#, python-format
msgid "You have to define an\n"
" expense account on the related product"
msgstr "Vous devez définir un\n"
" compte de charge sur le produit lié"
#. module: pos_cash_move_reason
#: code:addons/pos_cash_move_reason/wizard/pos_box.py:60
#, python-format
msgid "You have to define an\n"
" income account on the related product"
msgstr "Vous devez définir un\n"
" compte de produit sur le produit lié"

43
pos_cash_move_reason/i18n/pos_cash_move_reason.pot

@ -0,0 +1,43 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_cash_move_reason
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-04-12 11:09+0000\n"
"PO-Revision-Date: 2016-04-12 11:09+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_cash_move_reason
#: code:addons/pos_cash_move_reason/wizard/pos_box.py:36
#, python-format
msgid "Description"
msgstr ""
#. module: pos_cash_move_reason
#: field:cash.box.in,product_id:0
#: field:cash.box.out,product_id:0
msgid "Reason"
msgstr ""
#. module: pos_cash_move_reason
#: code:addons/pos_cash_move_reason/wizard/pos_box.py:84
#, python-format
msgid "You have to define an\n"
" expense account on the related product"
msgstr ""
#. module: pos_cash_move_reason
#: code:addons/pos_cash_move_reason/wizard/pos_box.py:60
#, python-format
msgid "You have to define an\n"
" income account on the related product"
msgstr ""

BIN
pos_cash_move_reason/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

BIN
pos_cash_move_reason/static/description/pos_cash_move_reason_02.png

After

Width: 903  |  Height: 275  |  Size: 24 KiB

5
pos_cash_move_reason/tests/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2015 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import test_pos_cash_move_reason

106
pos_cash_move_reason/tests/test_pos_cash_move_reason.py

@ -0,0 +1,106 @@
# -*- coding: utf-8 -*-
# © 2015 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp.tests import common
class TestPosCashMoveReason(common.TransactionCase):
def setUp(self):
super(TestPosCashMoveReason, self).setUp()
self.pos_session_obj = self.env['pos.session']
self.aml_obj = self.env['account.move.line']
self.cash_in_obj = self.env['cash.box.in']
self.cash_out_obj = self.env['cash.box.out']
self.cash_move_reason_obj = self.env['product.template']
self.main_config = self.env.ref('point_of_sale.pos_config_main')
self.cash_journal = self.env.ref('account.cash_journal')
self.income_account = self.env.ref('account.o_income')
self.expense_account = self.env.ref('account.a_expense')
def test01(self):
# I create one move reason
vals = {'name': 'Miscellaneous income',
'property_account_income': self.income_account.id,
'income_pdt': True}
move_reason = self.cash_move_reason_obj.create(vals)
# I set cash control on cash journal
self.cash_journal.cash_control = True
# I create and open a new session
self.session_01 = self.pos_session_obj.create(
{'config_id': self.main_config.id})
ctx = self.env.context.copy()
# context is updated in open_cb
# -> Need to call with old api to give unfrozen context
self.registry['pos.session'].open_cb(
self.cr, self.uid, [self.session_01.id], context=ctx)
ctx['active_ids'] = self.session_01.id
ctx['active_model'] = self.session_01._name
# I put the session in validation control
self.session_01.signal_workflow('cashbox_control')
ctx['active_ids'] = self.session_01.id
ctx['active_model'] = self.session_01._name
# I create a cash in
cash_in = self.cash_in_obj.with_context(ctx).create(
{'name': 'Initialization',
'product_id': move_reason.id,
'amount': 500.0})
cash_in.with_context(ctx).run()
# I close the session
self.session_01.signal_workflow('close')
# I get the statement from the session
statement = self.env['account.bank.statement'].search(
[('pos_session_id', '=', self.session_01.id),
('journal_id', '=', self.cash_journal.id)])
# I get all move lines of this statement
move_line_ids = statement.move_line_ids.ids
move_line = self.env['account.move.line'].search(
[('account_id', '=', self.income_account.id),
('credit', '=', 500.0),
('id', 'in', move_line_ids)])
# I check the created move line from the cash in
self.assertEquals(len(move_line.ids), 1)
def test02(self):
# I create one move reason
vals = {'name': 'Miscellaneous expense',
'property_account_expense': self.expense_account.id,
'expense_pdt': True}
move_reason = self.cash_move_reason_obj.create(vals)
# I set cash control on cash journal
self.cash_journal.cash_control = True
# I create and open a new session
self.session_01 = self.pos_session_obj.create(
{'config_id': self.main_config.id})
ctx = self.env.context.copy()
# context is updated in open_cb
# -> Need to call with old api to give unfrozen context
self.registry['pos.session'].open_cb(
self.cr, self.uid, [self.session_01.id], context=ctx)
ctx['active_ids'] = self.session_01.id
ctx['active_model'] = self.session_01._name
# I put the session in validation control
self.session_01.signal_workflow('cashbox_control')
ctx['active_ids'] = self.session_01.id
ctx['active_model'] = self.session_01._name
# I create a cash out
cash_out = self.cash_out_obj.with_context(ctx).create(
{'name': 'Miscellaneous expense',
'product_id': move_reason.id,
'amount': 500.0})
cash_out.with_context(ctx).run()
# I close the session
self.session_01.signal_workflow('close')
# I get the statement from the session
statement = self.env['account.bank.statement'].search(
[('pos_session_id', '=', self.session_01.id),
('journal_id', '=', self.cash_journal.id)])
# I get all move lines of this statement
move_line_ids = statement.move_line_ids.ids
move_line = self.env['account.move.line'].search(
[('account_id', '=', self.expense_account.id),
('debit', '=', 500.0),
('id', 'in', move_line_ids)])
# I check the created move line from the cash in
self.assertEquals(len(move_line.ids), 1)

5
pos_cash_move_reason/wizard/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2015 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import pos_box

86
pos_cash_move_reason/wizard/pos_box.py

@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
# © 2015 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, exceptions, fields, _
from openerp.addons.point_of_sale.wizard.pos_box import PosBox
from lxml import etree
import simplejson
class PosBoxCashMoveReason(PosBox):
_register = False
@api.onchange('product_id')
def onchange_reason(self):
for record in self:
if record.product_id.id:
record.name = record.product_id.name
@api.model
def fields_view_get(self, view_id=None, view_type='form',
toolbar=False, submenu=False):
res = super(PosBoxCashMoveReason, self).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
doc = etree.XML(res['arch'])
if self.env.context.get('active_model', '') != 'pos.session':
for node in doc.xpath("//field[@name='product_id']"):
modifiers = {'invisible': True, 'required': False}
node.set('invisible', '1')
node.set('required', '0')
node.set('modifiers', simplejson.dumps(modifiers))
else:
for node in doc.xpath("//field[@name='name']"):
node.set('string', _('Description'))
res['arch'] = etree.tostring(doc)
return res
class PosBoxIn(PosBoxCashMoveReason):
_inherit = 'cash.box.in'
product_id = fields.Many2one(
comodel_name='product.template', string='Reason',
domain="[('income_pdt', '=', True)]")
@api.model
def _compute_values_for_statement_line(self, box, record):
values = super(PosBoxIn, self)._compute_values_for_statement_line(
box, record)
if self.env.context.get('active_model', '') == 'pos.session':
if box.product_id.id:
product = box.product_id
account_id = product.property_account_income.id or\
product.categ_id.property_account_income_categ.id
if account_id:
values['account_id'] = account_id
else:
raise exceptions.Warning(_("""You have to define an
income account on the related product"""))
return values
class PosBoxOut(PosBoxCashMoveReason):
_inherit = 'cash.box.out'
product_id = fields.Many2one(
comodel_name='product.template', string='Reason',
domain="[('expense_pdt', '=', True)]")
@api.model
def _compute_values_for_statement_line(self, box, record):
values = super(PosBoxOut, self)._compute_values_for_statement_line(
box, record)
if self.env.context.get('active_model', '') == 'pos.session':
if box.product_id.id:
product = box.product_id
account_id = product.property_account_expense.id or\
product.categ_id.property_account_expense_categ.id
if account_id:
values['account_id'] = account_id
else:
raise exceptions.Warning(_("""You have to define an
expense account on the related product"""))
return values

26
pos_cash_move_reason/wizard/pos_box.xml

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="cash_box_in_form">
<field name="name">cash.box.in.form</field>
<field name="model">cash.box.in</field>
<field name="inherit_id" ref="account.cash_box_in_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="before">
<field name="product_id" required="1" class="oe_inline" />
</xpath>
</field>
</record>
<record model="ir.ui.view" id="cash_box_out_form">
<field name="name">cash.box.out.form</field>
<field name="model">cash.box.out</field>
<field name="inherit_id" ref="account.cash_box_out_form" />
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="before">
<field name="product_id" required="1" class="oe_inline"/>
</xpath>
</field>
</record>
</data>
</openerp>
Loading…
Cancel
Save