Merge PR #1062 into 13.0

Signed-off-by simahawk
This commit is contained in:
OCA-git-bot
2021-01-26 07:28:57 +00:00
9 changed files with 176 additions and 15 deletions

View File

@@ -91,6 +91,18 @@ so when they arrive in WH/Stock, they are stored in WH/Stock/Vertical Lift. On
the put-away screen, when scanning the tray type to store, the destination will
be updated with an available cell of the same tray type in the current shuttle.
Barcodes
~~~~~~~~
The operations allowed in the screen for the vertical lift (save, release, skip)
can be triggered using a barcode. For this, print the barcodes contained in the
folder 'images'.
Development
===========
The barcodes used are of the type Code 128 (with the code set B).
Known issues / Roadmap
======================

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink" width="290" height="81.587" viewBox="0 0 290 81.587">
<desc></desc>
<rect x="0" y="0" width="290" height="81.587" style="fill:#ffffff;" />
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="2" y1="0" x2="2" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="7" y1="0" x2="7" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="13" y1="0" x2="13" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="23" y1="0" x2="23" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:6;" x1="33" y1="0" x2="33" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="40" y1="0" x2="40" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="45" y1="0" x2="45" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="52" y1="0" x2="52" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:6;" x1="59" y1="0" x2="59" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="67" y1="0" x2="67" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="75" y1="0" x2="75" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="80" y1="0" x2="80" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="90" y1="0" x2="90" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:6;" x1="97" y1="0" x2="97" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="107" y1="0" x2="107" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="111" y1="0" x2="111" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:6;" x1="117" y1="0" x2="117" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="128" y1="0" x2="128" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="133" y1="0" x2="133" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="140" y1="0" x2="140" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:6;" x1="149" y1="0" x2="149" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="155" y1="0" x2="155" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:8;" x1="162" y1="0" x2="162" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="171" y1="0" x2="171" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="178" y1="0" x2="178" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="189" y1="0" x2="189" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="195" y1="0" x2="195" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="199" y1="0" x2="199" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="210" y1="0" x2="210" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="215" y1="0" x2="215" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="221" y1="0" x2="221" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="225" y1="0" x2="225" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:8;" x1="234" y1="0" x2="234" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="244" y1="0" x2="244" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="253" y1="0" x2="253" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="257" y1="0" x2="257" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="266" y1="0" x2="266" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:6;" x1="277" y1="0" x2="277" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:2;" x1="283" y1="0" x2="283" y2="60"/>
<line fill="none" style="stroke:#000000; stroke-width:4;" x1="288" y1="0" x2="288" y2="60"/>
<text x="145" y="77.271" text-anchor="middle" style="font-family: Tahoma; font-size: 20px; stroke: none; fill:#000000;">O-BTN.skip</text></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,12 +1,20 @@
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
from odoo import fields, models
class StockMoveLine(models.Model):
_inherit = "stock.move.line"
vertical_lift_skipped = fields.Boolean(
"Skipped in Vertical Lift?",
default=False,
help="If this flag is set, it means that when the move "
"was being processed in the Vertical Lift, the operator decided to "
"skip its processing.",
)
def fetch_vertical_lift_tray_source(self):
self.ensure_one()
self.location_id.fetch_vertical_lift_tray()

View File

@@ -17,6 +17,7 @@ class VerticalLiftOperationPick(models.Model):
("scan_destination", "Scan New Destination Location"),
("save", "Pick goods and save"),
("release", "Release"),
("skip", "Skip"), # Virtual state.
]
def _transitions(self):
@@ -24,15 +25,30 @@ class VerticalLiftOperationPick(models.Model):
self.Transition(
"noop", "scan_destination", lambda self: self.select_next_move_line()
),
self.Transition("scan_destination", "skip", lambda self: self.is_skipped()),
self.Transition("scan_destination", "save"),
self.Transition("save", "skip", lambda self: self.is_skipped()),
self.Transition("save", "release", lambda self: self.process_current()),
self.Transition("release", "skip", lambda self: self.is_skipped()),
# go to scan_destination if we have lines in queue, otherwise, go to noop
self.Transition(
"release", "scan_destination", lambda self: self.select_next_move_line()
),
self.Transition("release", "noop"),
self.Transition(
"skip",
"scan_destination",
lambda self: self.select_next_move_line(),
direct_eval=True,
),
self.Transition("skip", "noop", direct_eval=True),
)
def is_skipped(self):
"""Was the current stock.move.line marked as to be skipped?"""
self.ensure_one()
return self.current_move_line_id.vertical_lift_skipped
def on_barcode_scanned(self, barcode):
self.ensure_one()
if not self.current_move_line_id or self.current_move_line_id.state == "done":
@@ -69,11 +85,20 @@ class VerticalLiftOperationPick(models.Model):
def select_next_move_line(self):
self.ensure_one()
next_move_line_order = "vertical_lift_skipped"
if self._order:
# If there already exists an order, keep it.
next_move_line_order += "," + self._order
next_move_line = self.env["stock.move.line"].search(
self._domain_move_lines_to_do(), limit=1
self._domain_move_lines_to_do(), limit=1, order=next_move_line_order
)
self.current_move_line_id = next_move_line
if next_move_line:
if next_move_line.vertical_lift_skipped:
# If a move line that was previously skipped was selected,
# we allow to process it again (maybe this time it's not
# skipped).
next_move_line.vertical_lift_skipped = False
self.fetch_tray()
return True
return False
@@ -88,3 +113,10 @@ class VerticalLiftOperationPick(models.Model):
self.shuttle_id.release_vertical_lift_tray()
# sorry not sorry
return self._rainbow_man()
def button_skip(self):
"""Skip the operation, go to the next"""
self.ensure_one()
self.current_move_line_id.vertical_lift_skipped = True
if self.step() != "noop":
self.next_step()

View File

@@ -46,3 +46,10 @@ vertical lift view as destination. E.g. create put-away rules on the products
so when they arrive in WH/Stock, they are stored in WH/Stock/Vertical Lift. On
the put-away screen, when scanning the tray type to store, the destination will
be updated with an available cell of the same tray type in the current shuttle.
Barcodes
~~~~~~~~
The operations allowed in the screen for the vertical lift (save, release, skip)
can be triggered using a barcode. For this, print the barcodes contained in the
folder 'images'.

View File

@@ -0,0 +1 @@
The barcodes used are of the type Code 128 (with the code set B).

View File

@@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils: http://docutils.sourceforge.net/" />
<title>Vertical Lift</title>
<style type="text/css">
@@ -386,14 +386,16 @@ Only for development or testing purpose, do not use in production.
<li><a class="reference internal" href="#tray-types" id="id4">Tray types</a></li>
<li><a class="reference internal" href="#vertical-lift-shuttles" id="id5">Vertical Lift Shuttles</a></li>
<li><a class="reference internal" href="#put-away-configuration" id="id6">Put-away configuration</a></li>
<li><a class="reference internal" href="#barcodes" id="id7">Barcodes</a></li>
</ul>
</li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id7">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id8">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id9">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id10">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id11">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id12">Maintainers</a></li>
<li><a class="reference internal" href="#development" id="id8">Development</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id9">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id10">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id11">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id12">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id13">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id14">Maintainers</a></li>
</ul>
</li>
</ul>
@@ -448,9 +450,19 @@ so when they arrive in WH/Stock, they are stored in WH/Stock/Vertical Lift. On
the put-away screen, when scanning the tray type to store, the destination will
be updated with an available cell of the same tray type in the current shuttle.</p>
</div>
<div class="section" id="barcodes">
<h2><a class="toc-backref" href="#id7">Barcodes</a></h2>
<p>The operations allowed in the screen for the vertical lift (save, release, skip)
can be triggered using a barcode. For this, print the barcodes contained in the
folder images.</p>
</div>
</div>
<div class="section" id="development">
<h1><a class="toc-backref" href="#id8">Development</a></h1>
<p>The barcodes used are of the type Code 128 (with the code set B).</p>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id7">Known issues / Roadmap</a></h1>
<h1><a class="toc-backref" href="#id9">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Complete screen workflows (currently enough for a demo, not for production)</li>
<li>Inventory: find a way to have a nice autofocus for quantity, still compatible
@@ -463,7 +475,7 @@ makes sense)</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id8">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#id10">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/stock-logistics-warehouse/issues">GitHub Issues</a>.
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
@@ -471,21 +483,21 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id9">Credits</a></h1>
<h1><a class="toc-backref" href="#id11">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id10">Authors</a></h2>
<h2><a class="toc-backref" href="#id12">Authors</a></h2>
<ul class="simple">
<li>Camptocamp</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id11">Contributors</a></h2>
<h2><a class="toc-backref" href="#id13">Contributors</a></h2>
<ul class="simple">
<li>Guewen Baconnier &lt;<a class="reference external" href="mailto:guewen.baconnier&#64;camptocamp.com">guewen.baconnier&#64;camptocamp.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id12">Maintainers</a></h2>
<h2><a class="toc-backref" href="#id14">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose

View File

@@ -37,6 +37,15 @@ class TestPick(VerticalLiftCase):
self.assertEqual(operation.current_move_line_id, self.out_move_line)
self.assertEqual(operation.state, "scan_destination")
def test_pick_select_next_move_line_was_skipped(self):
"""Previously skipped moves can be reprocessed"""
self.picking_out.move_line_ids.write({"vertical_lift_skipped": True})
operation = self._open_screen("pick")
operation.select_next_move_line()
self.assertEqual(operation.current_move_line_id, self.out_move_line)
self.assertEqual(operation.state, "scan_destination")
self.assertFalse(operation.current_move_line_id.vertical_lift_skipped)
def test_pick_save(self):
operation = self._open_screen("pick")
# assume we already scanned the destination, current state is save
@@ -46,6 +55,31 @@ class TestPick(VerticalLiftCase):
self.assertEqual(operation.current_move_line_id.state, "done")
self.assertEqual(operation.state, "release")
def test_pick_skip_from_scan_destination(self):
"""Being in state Scan Destination, skip it"""
self._test_pick_skip_from_state("scan_destination")
def test_pick_skip_from_save(self):
"""Being in state Save, skip it"""
self._test_pick_skip_from_state("save")
def test_pick_skip_from_release(self):
"""Being in state Release, skip it"""
self._test_pick_skip_from_state("release")
def _test_pick_skip_from_state(self, state):
operation = self._open_screen("pick")
operation.state = state
operation.current_move_line_id = self.out_move_line
first_move_line = operation.current_move_line_id
self.assertFalse(operation.current_move_line_id.vertical_lift_skipped)
operation.button_skip()
second_move_line = operation.current_move_line_id
self.assertNotEqual(first_move_line, second_move_line)
self.assertFalse(operation.current_move_line_id.vertical_lift_skipped)
self.assertEqual(operation.current_move_line_id.state, "assigned")
self.assertEqual(operation.state, "scan_destination")
def test_pick_related_fields(self):
operation = self._open_screen("pick")
ml = operation.current_move_line_id = self.out_move_line

View File

@@ -65,6 +65,15 @@
</div>
<div class="o_shuttle_content o_shuttle_content_right">
<div>
<button
name="button_skip"
type="object"
string="Skip"
icon="fa-forward"
class="btn-danger"
barcode_trigger="skip"
attrs="{'invisible': [('state', '=', 'noop')]}"
/>
<!-- will react on barcode 'O-BTN.save' -->
<button
name="button_save"