Browse Source

[ADD] new module pos_picking_delayed

- creating pos.order doesn't create picking, when it is created via create_from_ui;
- add a cron to generate picking of pos.order
- log when cron is called
- configuration in pos.config (picking_creation_delayed)
- handle correctly pos order that doesn't generate pickings. (based on services)
pull/293/head
Sylvain LE GAL 6 years ago
parent
commit
ad594d2530
  1. 21
      pos_picking_delayed/README.rst
  2. 2
      pos_picking_delayed/__init__.py
  3. 26
      pos_picking_delayed/__manifest__.py
  4. 20
      pos_picking_delayed/data/ir_cron.xml
  5. 47
      pos_picking_delayed/i18n/fr.po
  6. 4
      pos_picking_delayed/models/__init__.py
  7. 16
      pos_picking_delayed/models/pos_config.py
  8. 57
      pos_picking_delayed/models/pos_order.py
  9. 5
      pos_picking_delayed/readme/CONFIGURE.rst
  10. 1
      pos_picking_delayed/readme/CONTRIBUTORS.rst
  11. 4
      pos_picking_delayed/readme/CREDITS.rst
  12. 23
      pos_picking_delayed/readme/DESCRIPTION.rst
  13. 5
      pos_picking_delayed/readme/ROADMAP.rst
  14. 4
      pos_picking_delayed/readme/USAGE.rst
  15. BIN
      pos_picking_delayed/static/description/pos_config_form.png
  16. BIN
      pos_picking_delayed/static/description/pos_order_tree.png
  17. 3
      pos_picking_delayed/tests/__init__.py
  18. 106
      pos_picking_delayed/tests/test_module.py
  19. 17
      pos_picking_delayed/views/view_pos_config.xml
  20. 30
      pos_picking_delayed/views/view_pos_order.xml

21
pos_picking_delayed/README.rst

@ -0,0 +1,21 @@
**This file is going to be generated by oca-gen-addon-readme.**
*Manual changes will be overwritten.*
Please provide content in the ``readme`` directory:
* **DESCRIPTION.rst** (required)
* INSTALL.rst (optional)
* CONFIGURE.rst (optional)
* **USAGE.rst** (optional, highly recommended)
* DEVELOP.rst (optional)
* ROADMAP.rst (optional)
* HISTORY.rst (optional, recommended)
* **CONTRIBUTORS.rst** (optional, highly recommended)
* CREDITS.rst (optional)
Content of this README will also be drawn from the addon manifest,
from keys such as name, authors, maintainers, development_status,
and license.
A good, one sentence summary in the manifest is also highly recommended.

2
pos_picking_delayed/__init__.py

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

26
pos_picking_delayed/__manifest__.py

@ -0,0 +1,26 @@
# coding: utf-8
# Copyright 2018 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Point of Sale - Picking Creation Delayed',
'summary': 'Delay the creation of the picking when PoS order is created',
'version': '10.0.1.0.0',
'category': 'Point Of Sale',
'author': 'GRAP, '
'Odoo Community Association (OCA)',
'license': 'AGPL-3',
'website': 'https://www.github.com/OCA/pos',
'depends': [
'point_of_sale',
],
'data': [
'data/ir_cron.xml',
'views/view_pos_config.xml',
'views/view_pos_order.xml',
],
'images': [
'static/description/pos_order_tree.png',
],
'installable': True,
}

20
pos_picking_delayed/data/ir_cron.xml

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!-- Copyright 2018 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-->
<odoo>
<data noupdate="1">
<record forcecreate="True" id="cron_create_delayed_pos_picking" model="ir.cron">
<field name="name">Create Delayed PoS Picking</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model">pos.order</field>
<field name="function">create_delayed_picking</field>
<field name="args">()</field>
</record>
</data>
</odoo>

47
pos_picking_delayed/i18n/fr.po

@ -0,0 +1,47 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_picking_delayed
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 10.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-10-17 11:06+0000\n"
"PO-Revision-Date: 2018-10-17 11:06+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_picking_delayed
#: model:ir.model.fields,help:pos_picking_delayed.field_pos_config_picking_creation_delayed
msgid "Check this box if you want to delay the creation of the picking created by the PoS orders. If checked, the pickings will be created later, by a cron task."
msgstr "Cochez cette case si vous souhaitez retarder la création des transferts de stock liés au commandes de point de vente. Si la case est cochée, ceux-ci seront créés ultérieurement, par une tâche de fond."
#. module: pos_picking_delayed
#: model:ir.model.fields,field_description:pos_picking_delayed.field_pos_order_has_picking_delayed
msgid "Has picking delayed"
msgstr "A un transfert de stock retardé"
#. module: pos_picking_delayed
#: model:ir.model.fields,field_description:pos_picking_delayed.field_pos_config_picking_creation_delayed
msgid "Picking Creation Delayed"
msgstr "Retarder la création des transferts de stock"
#. module: pos_picking_delayed
#: model:ir.model,name:pos_picking_delayed.model_pos_order
msgid "Point of Sale Orders"
msgstr "Commandes du point de vente"
#. module: pos_picking_delayed
#: model:ir.model.fields,help:pos_picking_delayed.field_pos_order_has_picking_delayed
msgid "This checkbox is checked if the generation of the picking has been delayed. The picking will be created by cron."
msgstr "Cette case est cochée si la génération du transfert de stock a été retardée. Celui ci sera créé par une tâche de fond."
#. module: pos_picking_delayed
#: model:ir.model,name:pos_picking_delayed.model_pos_config
msgid "pos.config"
msgstr "pos.config"

4
pos_picking_delayed/models/__init__.py

@ -0,0 +1,4 @@
# coding: utf-8
from . import pos_config
from . import pos_order

16
pos_picking_delayed/models/pos_config.py

@ -0,0 +1,16 @@
# coding: utf-8
# Copyright 2018 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class PosConfig(models.Model):
_inherit = 'pos.config'
picking_creation_delayed = fields.Boolean(
string='Picking Creation Delayed', default=True,
help="Check this box if you want to delay the creation of the picking"
" created by the PoS orders. If checked, the pickings will"
" be created later, by a cron task.")

57
pos_picking_delayed/models/pos_order.py

@ -0,0 +1,57 @@
# coding: utf-8
# Copyright 2018 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import api, fields, models
_logger = logging.getLogger(__name__)
class PosOrder(models.Model):
_inherit = 'pos.order'
has_picking_delayed = fields.Boolean(
default=False, help="This checkbox is checked if the generation of"
" the picking has been delayed. The picking will be created by cron.")
# Overload Section
@api.model
def create_from_ui(self, orders):
PosSession = self.env['pos.session']
for order_data in orders:
session_id = order_data.get('data').get('pos_session_id')
session = PosSession.browse(session_id)
order_data['data']['has_picking_delayed'] =\
session.config_id.picking_creation_delayed
return super(PosOrder, self.with_context(
create_from_ui=True)).create_from_ui(orders)
def create_picking(self):
if self.env.context.get('create_from_ui', False):
orders = self.filtered(lambda x: not x.has_picking_delayed)
else:
orders = self
res = super(PosOrder, orders).create_picking()
orders.write({'has_picking_delayed': False})
return res
@api.model
def _order_fields(self, ui_order):
res = super(PosOrder, self)._order_fields(ui_order)
res['has_picking_delayed'] = ui_order['has_picking_delayed']
return res
# Custom Section
@api.model
def create_delayed_picking(self):
orders = self.search([
('state', '!=', 'draft'),
('has_picking_delayed', '=', True),
], order='date_order')
for order in orders:
order.sudo(order.user_id.id).with_context(
force_company=order.company_id.id).create_picking()
if orders:
_logger.info("Pickings handled for %d PoS Orders" % (len(orders)))

5
pos_picking_delayed/readme/CONFIGURE.rst

@ -0,0 +1,5 @@
* Go to 'Point of Sale' / 'Configuration' / 'Point of Sale'
* Select your Point of Sale
* Set the value in the field 'Picking Creation Delayed'. (Checked by default)
.. image:: /pos_picking_delayed/static/description/pos_config_form.png

1
pos_picking_delayed/readme/CONTRIBUTORS.rst

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

4
pos_picking_delayed/readme/CREDITS.rst

@ -0,0 +1,4 @@
The development of this module has been financially supported by:
* GRAP, Groupement Régional Alimentaire de Proximité (www.grap.coop)
* Mind & Go, (https://mind-and-go.com/)

23
pos_picking_delayed/readme/DESCRIPTION.rst

@ -0,0 +1,23 @@
This module extends the functionality of odoo Point Of Sale to reduce creation
time of the PoS orders, via the front UI.
For that purpose, it delays the creation of the picking associated, that will
be created later, by cron. (set by default to run each minute).
Technical information
---------------------
A log will be generated to mention the creation of the pickings by cron.
``2018-09-28 07:47:18,300 163 INFO db odoo.addons.base.ir.ir_cron: Starting job `Create Delayed PoS Picking.``
``2018-09-28 07:47:19,168 163 INFO db odoo.addons.pos_picking_delayed.models.pos_order: Pickings created for 3 PoS Orders``
This module is interesting specially in a context of Synchroneous Point Of
Sale that is introduced by certification modules like 'l10n_fr_pos_cert' because
in such cases, the bill will be printed only when the pos order is created (
after the call of the function create_from_ui) and the creation of the picking
is the process that takes the most time.
See https://github.com/odoo/odoo/pull/26314#issuecomment-422949266
for more information.

5
pos_picking_delayed/readme/ROADMAP.rst

@ -0,0 +1,5 @@
* Make this module depend on the module OCA `queue_job` job module.
* In the cron job (or the future queue job), improvment can be done, limiting
the quantity of environments, grouping orders by company, and changing
context once.

4
pos_picking_delayed/readme/USAGE.rst

@ -0,0 +1,4 @@
* Use your Point of Sale as usual. when validating an order, the order will
be in a different color until the cron is executed
.. image:: /pos_picking_delayed/static/description/pos_order_tree.png

BIN
pos_picking_delayed/static/description/pos_config_form.png

After

Width: 1019  |  Height: 353  |  Size: 42 KiB

BIN
pos_picking_delayed/static/description/pos_order_tree.png

After

Width: 971  |  Height: 153  |  Size: 25 KiB

3
pos_picking_delayed/tests/__init__.py

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

106
pos_picking_delayed/tests/test_module.py

@ -0,0 +1,106 @@
# -*- coding: utf-8 -*-
# Copyright 2018 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields
from odoo.tests.common import TransactionCase
class TestModule(TransactionCase):
def setUp(self):
super(TestModule, self).setUp()
self.pos_order_obj = self.env['pos.order']
self.pos_picking_cron = self.env.ref(
'pos_picking_delayed.cron_create_delayed_pos_picking')
self.pos_config = self.env.ref('point_of_sale.pos_config_main')
self.carotte_product = self.env.ref('point_of_sale.carotte')
def test_01_picking_delayed_enabled(self):
# Disable Cron
self.pos_picking_cron.active = False
# Enable feature
self.pos_config.picking_creation_delayed = True
order = self._open_session_create_order()
self.assertEqual(
order.picking_id.id, False,
"Creating order via UI should not generate a picking if"
" feature is enabled")
# run cron and test if picking is now created
self.pos_picking_cron.method_direct_trigger()
self.assertNotEqual(
order.picking_id.id, False,
"Run PoS picking Cron should generate picking for PoS Orders"
" without picking")
def test_02_picking_delayed_disabled(self):
# Disable Cron
self.pos_picking_cron.active = False
# Disable feature
self.pos_config.picking_creation_delayed = False
order = self._open_session_create_order()
picking_id = order.picking_id.id
self.assertNotEqual(
picking_id, False,
"Creating order via UI should generate a picking if"
" feature is disabled")
# run cron and test if picking is now created
self.pos_picking_cron.method_direct_trigger()
self.assertEqual(
order.picking_id.id, picking_id,
"Run PoS picking Cron should not regenerate picking for"
" PoS Orders that have already a picking created.")
def _open_session_create_order(self):
# Create order
self.pos_config.open_session_cb()
order_data = {
'id': u'0006-001-0010',
'to_invoice': False,
'data': {
'user_id': 1,
'name': 'Order 0006-001-0010',
'partner_id': False,
'amount_paid': 0.9,
'pos_session_id': self.pos_config.current_session_id.id,
'lines': [[0, 0, {
'id': 1,
'product_id': self.carotte_product.id,
'tax_ids': [[6, False, []]],
'price_unit': 0.9,
'qty': 1,
'pack_lot_ids': [],
'discount': 0,
}]],
'statement_ids': [[0, 0, {
'journal_id': self.pos_config.journal_ids[0].id,
'amount': 0.9,
'name': fields.Datetime.now(),
'account_id':
self.env.user.partner_id.property_account_receivable_id.id,
'statement_id':
self.pos_config.current_session_id.statement_ids[0].id,
}]],
'creation_date': u'2018-09-27 15:51:03',
'amount_tax': 0,
'fiscal_position_id': False,
'uid': u'00001-001-0001',
'amount_return': 0,
'sequence_number': 1,
'amount_total': 0.9,
}}
# Test if picking is not created
result = self.pos_order_obj.create_from_ui([order_data])
order = self.pos_order_obj.browse(result[0])
return order

17
pos_picking_delayed/views/view_pos_config.xml

@ -0,0 +1,17 @@
<?xml version="1.0"?>
<!-- Copyright 2018 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-->
<odoo>
<record id="view_pos_config_form" model="ir.ui.view">
<field name="model">pos.config</field>
<field name="inherit_id" ref="point_of_sale.view_pos_config_form"/>
<field name="arch" type="xml">
<field name="default_fiscal_position_id" position="after">
<field name="picking_creation_delayed"/>
</field>
</field>
</record>
</odoo>

30
pos_picking_delayed/views/view_pos_order.xml

@ -0,0 +1,30 @@
<?xml version="1.0"?>
<!-- Copyright 2018 - Today Sylvain LE GAL (https://twitter.com/legalsylvain)
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-->
<odoo>
<record id="view_pos_order_tree" model="ir.ui.view">
<field name="model">pos.order</field>
<field name="inherit_id" ref="point_of_sale.view_pos_order_tree"/>
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="decoration-danger">has_picking_delayed == True</attribute>
</tree>
<field name="state" position="after">
<field name="has_picking_delayed" invisible="1"/>
</field>
</field>
</record>
<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">
<field name="picking_id" position="after">
<field name="has_picking_delayed"/>
</field>
</field>
</record>
</odoo>
Loading…
Cancel
Save