summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorTiffany Chang (tic) <tic@odoo.com>2020-05-29 14:30:44 +0000
committersvs-odoo <svs@odoo.com>2020-08-20 15:06:08 +0000
commit71e7f56719622c7fc3b2f6b750121971875e2750 (patch)
tree5885f453b82263bf82628293d7a1baf8f8498ec7 /addons
parent1bd2594b8390baddcc65cac310a75322f436b15f (diff)
[IMP] stock_picking_batch: add "Scheduled Date" field
This commit adds a "Scheduled Date" field to the batch pickings. Logic behind this date is a bit tricky: 1. If "Scheduled Date" is edited directly in batch then this date will also be applied to all of its picking's "Schedule Date"s. 2. If "Scheduled Date" is not edited directly in the batch, then this date will be the earliest date of its assigned pickings and pickings will maintain their original scheduled date' including if picking scheduled date is changed. 3. If "Scheduled Date" is not edited directly and all pickings are removed or there are none then date will default to no date. First cut of test for scheduled_date logic has also been added. Update will be needed for testing onchange logic since it is currently not supported by the tests.Form due to M2M widget used with O2M picking_ids (M2M widget is used for when doing a "Add a Line" transfer to a batch in backend). Additionally this commit adds the 'scheduled_date' and 'operation_type' to the kanban view. Part of "1. Improve Batch Pickings" specification of overall barcode app improvements task. Task: 1884520 Enterprise PR: odoo/enterprise#12086 Upgrade PR: odoo/upgrade#1569 Closes: odoo/odoo#55096
Diffstat (limited to 'addons')
-rw-r--r--addons/stock_picking_batch/models/stock_picking_batch.py27
-rw-r--r--addons/stock_picking_batch/tests/test_batch_picking.py78
-rw-r--r--addons/stock_picking_batch/views/stock_picking_batch_views.xml9
3 files changed, 113 insertions, 1 deletions
diff --git a/addons/stock_picking_batch/models/stock_picking_batch.py b/addons/stock_picking_batch/models/stock_picking_batch.py
index 7d6cb969d75..696c67eabc5 100644
--- a/addons/stock_picking_batch/models/stock_picking_batch.py
+++ b/addons/stock_picking_batch/models/stock_picking_batch.py
@@ -47,6 +47,13 @@ class StockPickingBatch(models.Model):
picking_type_id = fields.Many2one(
'stock.picking.type', 'Operation Type', check_company=True, copy=False,
readonly=True, states={'draft': [('readonly', False)]})
+ scheduled_date = fields.Datetime(
+ 'Scheduled Date', copy=False, store=True, readonly=False, compute="_compute_scheduled_date",
+ states={'done': [('readonly', True)], 'cancel': [('readonly', True)]},
+ help="""Scheduled date for the transfers to be processed.
+ - If manually set then scheduled date for all transfers in batch will automatically update to this date.
+ - If not manually changed and transfers are added/removed/updated then this will be their earliest scheduled date
+ but this scheduled date will not be set for all transfers in batch.""")
@api.depends('company_id', 'picking_type_id', 'state')
def _compute_allowed_picking_ids(self):
@@ -95,6 +102,15 @@ class StockPickingBatch(models.Model):
elif all(picking.state in ['cancel', 'done'] for picking in batch.picking_ids):
batch.state = 'done'
+ @api.depends('picking_ids', 'picking_ids.scheduled_date')
+ def _compute_scheduled_date(self):
+ self.scheduled_date = min(self.picking_ids.filtered('scheduled_date').mapped('scheduled_date'), default=False)
+
+ @api.onchange('scheduled_date')
+ def onchange_scheduled_date(self):
+ if self.scheduled_date:
+ self.picking_ids.scheduled_date = self.scheduled_date
+
def _set_move_line_ids(self):
new_move_lines = self[0].move_line_ids
for picking in self.picking_ids:
@@ -129,6 +145,17 @@ class StockPickingBatch(models.Model):
raise UserError(_("You can only delete draft batch transfers."))
return super().unlink()
+ def onchange(self, values, field_name, field_onchange):
+ """Override onchange to NOT to update all scheduled_date on pickings when
+ scheduled_date on batch is updated by the change of scheduled_date on pickings.
+ """
+ result = super().onchange(values, field_name, field_onchange)
+ if field_name == 'picking_ids' and 'value' in result:
+ for line in result['value'].get('picking_ids', []):
+ if line[0] < 2 and 'scheduled_date' in line[2]:
+ del line[2]['scheduled_date']
+ return result
+
# -------------------------------------------------------------------------
# Action methods
# -------------------------------------------------------------------------
diff --git a/addons/stock_picking_batch/tests/test_batch_picking.py b/addons/stock_picking_batch/tests/test_batch_picking.py
index f23270e003c..c7352699439 100644
--- a/addons/stock_picking_batch/tests/test_batch_picking.py
+++ b/addons/stock_picking_batch/tests/test_batch_picking.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from datetime import datetime, timedelta
+
from odoo.tests import Form
from odoo.tests.common import TransactionCase
@@ -58,12 +60,88 @@ class TestBatchPicking(TransactionCase):
'location_dest_id': self.customer_location.id,
})
+ self.picking_client_3 = self.env['stock.picking'].create({
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.customer_location.id,
+ 'picking_type_id': self.picking_type_out,
+ 'company_id': self.env.company.id,
+ })
+
+ self.env['stock.move'].create({
+ 'name': self.productB.name,
+ 'product_id': self.productB.id,
+ 'product_uom_qty': 10,
+ 'product_uom': self.productA.uom_id.id,
+ 'picking_id': self.picking_client_3.id,
+ 'location_id': self.stock_location.id,
+ 'location_dest_id': self.customer_location.id,
+ })
+
self.batch = self.env['stock.picking.batch'].create({
'name': 'Batch 1',
'company_id': self.env.company.id,
'picking_ids': [(4, self.picking_client_1.id), (4, self.picking_client_2.id)]
})
+ def test_batch_scheduled_date(self):
+ """ Test to make sure the correct scheduled date is set for both a batch and its pickings.
+ Setting a batch's scheduled date manually has different behavior from when it is automatically
+ set/updated via compute.
+ """
+
+ now = datetime.now().replace(microsecond=0)
+ self.batch.scheduled_date = now
+
+ # TODO: this test cannot currently handle the onchange scheduled_date logic because of test form
+ # view not handling the M2M widget assigned to picking_ids (O2M). Hopefully if this changes then
+ # commented parts of this test can be used later.
+
+
+ # manually set batch scheduled date => picking's scheduled dates auto update to match (onchange logic test)
+ # with Form(self.batch) as batch_form:
+ # batch_form.scheduled_date = now - timedelta(days=1)
+ # batch_form.save()
+ # self.assertEqual(self.batch.scheduled_date, self.picking_client_1.scheduled_date)
+ # self.assertEqual(self.batch.scheduled_date, self.picking_client_2.scheduled_date)
+
+ picking1_scheduled_date = now - timedelta(days=2)
+ picking2_scheduled_date = now - timedelta(days=3)
+ picking3_scheduled_date = now - timedelta(days=4)
+
+ # manually update picking scheduled dates => batch's scheduled date auto update to match lowest value
+ self.picking_client_1.scheduled_date = picking1_scheduled_date
+ self.picking_client_2.scheduled_date = picking2_scheduled_date
+ self.assertEqual(self.batch.scheduled_date, self.picking_client_2.scheduled_date)
+ # but individual pickings keep original scheduled dates
+ self.assertEqual(self.picking_client_1.scheduled_date, picking1_scheduled_date)
+ self.assertEqual(self.picking_client_2.scheduled_date, picking2_scheduled_date)
+
+ # add a new picking with an earlier scheduled date => batch's scheduled date should auto-update
+ self.picking_client_3.scheduled_date = picking3_scheduled_date
+ self.batch.write({'picking_ids': [(4, self.picking_client_3.id)]})
+ self.assertEqual(self.batch.scheduled_date, self.picking_client_3.scheduled_date)
+
+ # remove that picking and batch scheduled date should auto-update to next min date
+ self.batch.write({'picking_ids': [(3, self.picking_client_3.id)]})
+ self.assertEqual(self.batch.scheduled_date, self.picking_client_2.scheduled_date)
+
+ # directly add new picking with an earlier scheduled date => batch's scheduled date auto updates to match,
+ # but existing pickings do not (onchange logic test)
+ # with Form(self.batch) as batch_form:
+ # batch_form.picking_ids.add(self.picking_client_3)
+ # batch_form.save()
+ # # individual pickings keep original scheduled dates
+ self.assertEqual(self.picking_client_1.scheduled_date, picking1_scheduled_date)
+ self.assertEqual(self.picking_client_2.scheduled_date, picking2_scheduled_date)
+ # self.assertEqual(self.batch.scheduled_date, self.picking_client_3.scheduled_date)
+ # self.batch.write({'picking_ids': [(3, self.picking_client_3.id)]})
+
+
+ # remove all pickings and batch scheduled date should default to none
+ self.batch.write({'picking_ids': [(3, self.picking_client_1.id)]})
+ self.batch.write({'picking_ids': [(3, self.picking_client_2.id)]})
+ self.assertEqual(self.batch.scheduled_date, False)
+
def test_simple_batch_with_manual_qty_done(self):
""" Test a simple batch picking with all quantity for picking available.
The user set all the quantity_done on picking manually and no wizard are used.
diff --git a/addons/stock_picking_batch/views/stock_picking_batch_views.xml b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
index a83bf4f5258..016d53cfb87 100644
--- a/addons/stock_picking_batch/views/stock_picking_batch_views.xml
+++ b/addons/stock_picking_batch/views/stock_picking_batch_views.xml
@@ -102,6 +102,9 @@
<field name="picking_type_id"/>
<field name="company_id" groups="base.group_multi_company" attrs="{'readonly': [('picking_ids', '!=', [])]}" force_save="1"/>
</group>
+ <group>
+ <field name="scheduled_date"/>
+ </group>
</group>
<notebook>
<page string="Detailed Operations" attrs="{'invisible': [('state', '=', 'draft')]}">
@@ -140,6 +143,7 @@
<field name="arch" type="xml">
<tree string="Stock Batch Transfer" multi_edit="1" sample="1">
<field name="name" decoration-bf="1"/>
+ <field name="scheduled_date"/>
<field name="user_id" widget="many2one_avatar_user"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="state" widget="badge" decoration-success="state == 'done'" decoration-info="state in ('draft', 'in_progress')"/>
@@ -165,8 +169,11 @@
<field name="state" widget="label_selection"/>
</div>
<div class="o_kanban_record_bottom">
- <div class="oe_kanban_bottom_left"/>
+ <div class="oe_kanban_bottom_left">
+ <field name="picking_type_id"/>
+ </div>
<div class="oe_kanban_bottom_right">
+ <field name="scheduled_date" widget="date"/>
<field name="user_id" widget="many2one_avatar_user"/>
</div>
</div>