Skip to content

Commit

Permalink
Merge 2fff6ef into 19e153a
Browse files Browse the repository at this point in the history
  • Loading branch information
JordiBForgeFlow committed Dec 5, 2019
2 parents 19e153a + 2fff6ef commit 7925fab
Show file tree
Hide file tree
Showing 14 changed files with 286 additions and 0 deletions.
3 changes: 3 additions & 0 deletions oca_dependencies.txt
@@ -0,0 +1,3 @@
# list the OCA project dependencies, one per line
# add a github url if you need a forked version
stock-logistics-warehouse
1 change: 1 addition & 0 deletions stock_barcodes_move_location/__init__.py
@@ -0,0 +1 @@
from . import wizard
23 changes: 23 additions & 0 deletions stock_barcodes_move_location/__manifest__.py
@@ -0,0 +1,23 @@
# Copyright Eficent Business and IT Consulting Services, S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Stock Barcodes Move Location",
"summary": "This module allows to move stock between locations using"
"a barcode scanner.",
"version": "11.0.1.0.0",
"author": "Eficent, "
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/stock-logistics-barcode",
"license": "AGPL-3",
"category": "Extra Tools",
"depends": [
'stock_barcodes',
'stock_move_location',
],
"data": [
'views/assets.xml',
'wizard/stock_move_location_views.xml',
'wizard/stock_barcodes_read_move_location_views.xml',
],
'installable': True,
}
1 change: 1 addition & 0 deletions stock_barcodes_move_location/readme/CONTRIBUTORS.rst
@@ -0,0 +1 @@
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
5 changes: 5 additions & 0 deletions stock_barcodes_move_location/readme/DESCRIPTION.rst
@@ -0,0 +1,5 @@
This module allows user to move stock between two locations using
barcode scanners.

The module builds on the OCA module 'Stock Move Location' and introduces
barcode scanning capabilities.
9 changes: 9 additions & 0 deletions stock_barcodes_move_location/readme/USAGE.rst
@@ -0,0 +1,9 @@
Go to one of the various menu entries to move stock between locations,
as described in the module 'Stock Move Location'. The user will see a
button 'Scan barcodes'.

The user can start to scan the barcodes of the products to be moved.

If the user wants to enter manually the quantity she should set the toggle
button 'Manual Entry'. Upon scanning she will then be directed to enter
the quantity to move using the keyboard and press 'Manual Entry +'.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions stock_barcodes_move_location/static/src/js/stock_barcodes.js
@@ -0,0 +1,20 @@
/* Copyright 2018-2019 Sergio Teruel <sergio.teruel@tecnativa.com>.
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */

odoo.define('stock_barcodes_move_location.FormController', function(require) {
'use strict';

var FormController = require('web.FormController');

FormController.include({
canBeDiscarded: function(recordID) {
/*
This prevents the dialog box telling the user that changes have been made whenever we exit the form view
*/
if (!this.modelName.includes("wiz.stock.barcodes.read.move.location")) {
return this._super(recordID);
}
return $.when(false);
},
});
});
11 changes: 11 additions & 0 deletions stock_barcodes_move_location/views/assets.xml
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<odoo>

<template id="assets_backend" name="stock_barcodes Assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="application/javascript"
src="/stock_barcodes_move_location/static/src/js/stock_barcodes.js"/>
</xpath>
</template>

</odoo>
2 changes: 2 additions & 0 deletions stock_barcodes_move_location/wizard/__init__.py
@@ -0,0 +1,2 @@
from . import stock_barcodes_read_move_location
from . import stock_move_location
@@ -0,0 +1,123 @@
# Copyright Eficent Business and IT Consulting Services, S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, fields, models
from odoo.fields import first
from odoo.addons import decimal_precision as dp


class WizStockBarcodesReadMoveLocation(models.TransientModel):
_name = 'wiz.stock.barcodes.read.move.location'
_inherit = 'wiz.stock.barcodes.read'
_description = 'Wizard to read barcode on move location'

move_location_id = fields.Many2one(
comodel_name='wiz.stock.move.location',
string='Move Location',
readonly=True,
)
move_location_qty = fields.Float(
string='To Move quantities',
digits=dp.get_precision('Product Unit of Measure'),
readonly=True,
)

def name_get(self):
return [
(rec.id, '{} - {}'.format(
_('Barcode reader'),
self.env.user.name)) for rec in self]

def _prepare_move_location_line(self):

search_args = [
('location_id', '=', self.move_location_id.origin_location_id.id),
('product_id', '=', self.product_id.id),
]
if self.lot_id:
search_args.append(('lot_id', '=', self.lot_id.id))
else:
search_args.append(('lot_id', '=', False))
res = self.env['stock.quant'].read_group(search_args, ['quantity'], [])
max_quantity = res[0]['quantity']
# Apply the putaway strategy
move_location_dest_id = self.move_location_id.destination_location_id
location_dest_id = \
self.move_location_id.destination_location_id.get_putaway_strategy(
self.product_id).id or move_location_dest_id.id
return {
'move_location_wizard_id': self.move_location_id.id,
'product_id': self.product_id.id,
'origin_location_id': self.move_location_id.origin_location_id.id,
'destination_location_id': location_dest_id,
'product_uom_id': self.product_id.uom_id.id,
'move_quantity': self.product_qty,
'lot_id': self.lot_id.id,
'max_quantity': max_quantity,
}

def _prepare_move_location_line_domain(self, log_scan=False):
"""
Use the same domain for create or update a stock move location line.
Source data is scanning log record if undo or wizard model if create or
update one
"""
record = log_scan or self
return [
('move_location_wizard_id', '=', self.move_location_id.id),
('product_id', '=', record.product_id.id),
('lot_id', '=', record.lot_id.id),
]

def _add_move_location_line(self):
MoveLocationLine = self.env['wiz.stock.move.location.line']
line = MoveLocationLine.search(
self._prepare_move_location_line_domain(), limit=1)
if line:
line.write({
'move_quantity': line.move_quantity + self.product_qty,
})
else:
line = MoveLocationLine.create(self._prepare_move_location_line())
self.move_location_qty = line.move_quantity

def check_done_conditions(self):
if self.product_id.tracking != 'none' and not self.lot_id:
self._set_messagge_info('info', _('Waiting for input lot'))
return False
force_add_log = self.env.context.get('force_add_log', False)
if self.manual_entry and not force_add_log:
return False
return super().check_done_conditions()

def action_done(self):
result = super().action_done()
if result:
self._add_move_location_line()
return result

def action_manual_entry(self):
result = super().action_manual_entry()
if result:
self.with_context(force_add_log=True).action_done()
return result

def reset_qty(self):
super().reset_qty()
self.move_location_qty = 0.0

def action_undo_last_scan(self):
res = super().action_undo_last_scan()
log_scan = first(self.scan_log_ids.filtered(
lambda x: x.create_uid == self.env.user))
if log_scan:
move_location_line = self.env['wiz.stock.move.location.line'].search(
self._prepare_move_location_line_domain(log_scan=log_scan))
if move_location_line:
qty = move_location_line.move_quantity - log_scan.product_qty
move_location_line.move_quantity = max(qty, 0.0)
self.move_location_qty = move_location_line.move_quantity
log_scan.unlink()
return res

def action_confirm(self):
return {'type': 'ir.actions.act_window_close'}
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="view_stock_barcodes_read_move_location_form" model="ir.ui.view">
<field name="name">stock.barcodes.read.move.location.form</field>
<field name="model">wiz.stock.barcodes.read.move.location</field>
<field name="inherit_id" ref="stock_barcodes.view_stock_barcodes_read_form"/>
<field name="arch" type="xml">
<field name="location_id" position="before">
<field name="move_location_id" invisible="not context.get('default_default_move_location_id', False)"/>
</field>
<field name="product_qty" position="after">
<field name="move_location_qty"/>
</field>
<button name="action_manual_entry" position="before">
<button name='action_confirm' type="object" string="Confirm" class="btn-default barcode-automatic-entry" invisible="1"/>
</button>
</field>
</record>

<!--
Open wizard in current target option to avoid that the wizard is
closed after any button click,
-->
<record model="ir.actions.act_window" id="action_stock_barcodes_read_stock_move_location">
<field name="name">Barcodes Read</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="src_model">wiz.stock.move.location</field>
<field name="res_model">wiz.stock.barcodes.read.move.location</field>
<field name="context">{}</field>
<field name="view_id" ref="view_stock_barcodes_read_move_location_form"/>
<field name="target">current</field>
</record>

</odoo>
27 changes: 27 additions & 0 deletions stock_barcodes_move_location/wizard/stock_move_location.py
@@ -0,0 +1,27 @@
# Copyright Eficent Business and IT Consulting Services, S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, _


class StockMoveLocationWizard(models.TransientModel):
_inherit = "wiz.stock.move.location"

def name_get(self):
return [
(rec.id, '{} - {}'.format(
_('Move Between Locations'),
self.env.user.name)) for rec in self]

def action_barcode_scan(self):
action = self.env.ref(
'stock_barcodes_move_location.'
'action_stock_barcodes_read_stock_move_location').read()[0]
action['context'] = {
'default_location_id': self.destination_location_id.id,
'default_move_location_id': self.id,
'default_res_model_id':
self.env.ref(
'stock_move_location.model_wiz_stock_move_location').id,
'default_res_id': self.id,
}
return action
25 changes: 25 additions & 0 deletions stock_barcodes_move_location/wizard/stock_move_location_views.xml
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="view_wiz_stock_move_location_form_stock_move_location" model="ir.ui.view">
<field name="model">wiz.stock.move.location</field>
<field name="inherit_id" ref="stock_move_location.view_wiz_stock_move_location_form_stock_move_location"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button name="action_barcode_scan"
class="oe_stat_button"
icon="fa-barcode"
type="object"
help="List view of lines">
<div class="o_form_field o_stat_info">
<span class="o_stat_text">Scan barcodes</span>
</div>
</button>
</div>
</field>
</record>

<record id="stock_move_location.wiz_stock_move_location_action" model="ir.actions.act_window">
<field name="target">current</field>
</record>
</odoo>

0 comments on commit 7925fab

Please sign in to comment.