[IMP] stock: wave pickings
This commit introduce Wave Pickings. This new object is a group of stock move lines related to different pickings. The goal is to group stock movements having similar characteristics like same source location, same product category, ... Wave pickings are created from stock move lines. Those are removed from their picking to a copy of it. All the new picking are grouped together in a new batch picking. This batch is the wave. To differentiate the batch pickings and the wave pickings. This commit introduces a new menu and a new sequence. Task : 2411102 Part-of: odoo/odoo#63291
This commit is contained in:
@@ -23,7 +23,9 @@ class ResConfigSettings(models.TransientModel):
|
||||
help="Add and customize route operations to process product moves in your warehouse(s): e.g. unload > quality control > stock for incoming products, pick > pack > ship for outgoing products. \n You can also set putaway strategies on warehouse locations in order to send incoming products into specific child locations straight away (e.g. specific bins, racks).")
|
||||
group_warning_stock = fields.Boolean("Warnings for Stock", implied_group='stock.group_warning_stock')
|
||||
group_stock_sign_delivery = fields.Boolean("Signature", implied_group='stock.group_stock_sign_delivery')
|
||||
module_stock_picking_batch = fields.Boolean("Batch Pickings")
|
||||
module_stock_picking_batch = fields.Boolean("Batch Transfers")
|
||||
group_stock_picking_wave = fields.Boolean('Wave Transfers', implied_group='stock.group_stock_picking_wave',
|
||||
help="Group your move operations in wave transfer to process them together")
|
||||
module_stock_barcode = fields.Boolean("Barcode Scanner")
|
||||
stock_move_email_validation = fields.Boolean(related='company_id.stock_move_email_validation', readonly=False)
|
||||
stock_mail_confirmation_template_id = fields.Many2one(related='company_id.stock_mail_confirmation_template_id', readonly=False)
|
||||
|
||||
@@ -78,6 +78,10 @@
|
||||
<field name="name">Display Reception Report at Validation</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
</record>
|
||||
<record id="group_stock_picking_wave" model="res.groups">
|
||||
<field name="name">Use wave pickings</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
</record>
|
||||
</data>
|
||||
<data noupdate="1">
|
||||
<record id="base.default_user" model="res.users">
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
<div class="text-muted">
|
||||
Process transfers in batch per worker
|
||||
</div>
|
||||
<div class="row mt-2" attrs="{'invisible': [('module_stock_picking_batch','=',False)]}">
|
||||
<field name="group_stock_picking_wave" widget="upgrade_boolean" class="col-lg-1 ml16 mr0"/>
|
||||
<div class="col pl-0">
|
||||
<label for="group_stock_picking_wave"/>
|
||||
<div class="text-muted">Process operations in wave transfers</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="warning_info">
|
||||
|
||||
@@ -13,14 +13,22 @@ This module adds the batch transfer option in warehouse management
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'views/stock_picking_batch_views.xml',
|
||||
'views/stock_picking_wave_views.xml',
|
||||
'views/stock_move_line_views.xml',
|
||||
'data/stock_picking_batch_data.xml',
|
||||
'wizard/stock_picking_to_batch_views.xml',
|
||||
'wizard/stock_add_to_wave_views.xml',
|
||||
'report/stock_picking_batch_report_views.xml',
|
||||
'report/report_picking_batch.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/stock_picking_batch_demo.xml',
|
||||
],
|
||||
'assets': {
|
||||
'web.assets_backend': [
|
||||
'stock_picking_batch/static/src/js/*',
|
||||
]
|
||||
},
|
||||
'installable': True,
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
|
||||
@@ -15,4 +15,12 @@
|
||||
<field name="padding">5</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="seq_picking_wave" model="ir.sequence">
|
||||
<field name="name">Wave Transfer</field>
|
||||
<field name="code">picking.wave</field>
|
||||
<field name="prefix">WAVE/</field>
|
||||
<field name="padding">5</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
</data></odoo>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import stock_move_line
|
||||
from . import stock_picking
|
||||
from . import stock_picking_batch
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
from odoo import _, fields, models
|
||||
from odoo import Command
|
||||
|
||||
|
||||
class StockMoveLine(models.Model):
|
||||
_inherit = "stock.move.line"
|
||||
|
||||
batch_id = fields.Many2one(related='picking_id.batch_id')
|
||||
|
||||
def action_open_add_to_wave(self):
|
||||
# This action can be called from the move line list view or from the 'Add to wave' wizard
|
||||
if 'active_wave_id' in self.env.context:
|
||||
wave = self.env['stock.picking.batch'].browse(self.env.context.get('active_wave_id'))
|
||||
return self._add_to_wave(wave)
|
||||
view = self.env.ref('stock_picking_batch.stock_add_to_wave_form')
|
||||
return {
|
||||
'name': _('Add to Wave'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'stock.add.to.wave',
|
||||
'views': [(view.id, 'form')],
|
||||
'view_id': view.id,
|
||||
'target': 'new',
|
||||
}
|
||||
|
||||
def _add_to_wave(self, wave=False):
|
||||
""" Detach lines (and corresponding stock move from a picking to another). If wave is
|
||||
passed, attach new picking into it. If not attach line to their original picking.
|
||||
|
||||
:param int wave: id of the wave picking on which to put the move lines. """
|
||||
|
||||
if not wave:
|
||||
wave = self.env['stock.picking.batch'].create({
|
||||
'is_wave': True
|
||||
})
|
||||
line_by_picking = defaultdict(lambda: self.env['stock.move.line'])
|
||||
for line in self:
|
||||
# if not wave and line.orig_picking_id.is_wave:
|
||||
# continue
|
||||
line_by_picking[line.picking_id] |= line
|
||||
picking_to_wave_vals_list = []
|
||||
for picking, lines in line_by_picking.items():
|
||||
# Move the entire picking if all the line are taken
|
||||
if lines == picking.move_line_ids:
|
||||
wave.picking_ids = [Command.link(picking.id)]
|
||||
continue
|
||||
|
||||
# Split the picking in two part to extract only line that are taken on the wave
|
||||
picking_to_wave_vals = picking.copy_data({
|
||||
'move_lines': [],
|
||||
'move_line_ids': [],
|
||||
'batch_id': wave.id,
|
||||
})[0]
|
||||
line_by_move = defaultdict(lambda: self.env['stock.move.line'])
|
||||
for line in lines:
|
||||
line_by_move[line.move_id] |= line
|
||||
for move, move_lines in line_by_move.items():
|
||||
picking_to_wave_vals['move_line_ids'] += [Command.link(line.id) for line in lines]
|
||||
# if all the line of a stock move are taken we change the picking on the stock move
|
||||
if move_lines == move.move_line_ids:
|
||||
picking_to_wave_vals['move_lines'] += [Command.link(move.id)]
|
||||
continue
|
||||
# Split the move
|
||||
qty = sum(lines.mapped('product_qty'))
|
||||
new_move = move._split(qty)
|
||||
new_move[0]['move_line_ids'] = [Command.set(move_lines.ids)]
|
||||
picking_to_wave_vals['move_lines'] += [Command.create(new_move)]
|
||||
|
||||
picking_to_wave_vals_list.append(picking_to_wave_vals)
|
||||
|
||||
if picking_to_wave_vals_list:
|
||||
self.env['stock.picking'].create(picking_to_wave_vals_list)
|
||||
wave.action_confirm()
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import _, api, fields, models
|
||||
|
||||
|
||||
class StockPicking(models.Model):
|
||||
@@ -30,6 +30,27 @@ class StockPicking(models.Model):
|
||||
self.batch_id._sanity_check()
|
||||
return res
|
||||
|
||||
def action_add_operations(self):
|
||||
view = self.env.ref('stock_picking_batch.view_move_line_tree_detailed_wave')
|
||||
return {
|
||||
'name': _('Add Operations'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'list',
|
||||
'view': view,
|
||||
'views': [(view.id, 'tree')],
|
||||
'res_model': 'stock.move.line',
|
||||
'target': 'new',
|
||||
'domain': [
|
||||
('picking_id', 'in', self.ids),
|
||||
('state', '!=', 'done')
|
||||
],
|
||||
'context': dict(
|
||||
self.env.context,
|
||||
picking_to_wave=self.ids,
|
||||
active_wave_id=self.env.context.get('active_wave_id').id,
|
||||
search_default_by_location=True,
|
||||
)}
|
||||
|
||||
def _should_show_transfers(self):
|
||||
if len(self.batch_id) == 1 and self == self.batch_id.picking_ids:
|
||||
return False
|
||||
|
||||
@@ -59,6 +59,7 @@ class StockPickingBatch(models.Model):
|
||||
- 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.""")
|
||||
is_wave = fields.Boolean('This batch is a wave')
|
||||
|
||||
@api.depends('company_id', 'picking_type_id', 'state')
|
||||
def _compute_allowed_picking_ids(self):
|
||||
@@ -127,7 +128,10 @@ class StockPickingBatch(models.Model):
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if vals.get('name', '/') == '/':
|
||||
vals['name'] = self.env['ir.sequence'].next_by_code('picking.batch') or '/'
|
||||
if vals.get('is_wave'):
|
||||
vals['name'] = self.env['ir.sequence'].next_by_code('picking.wave') or '/'
|
||||
else:
|
||||
vals['name'] = self.env['ir.sequence'].next_by_code('picking.batch') or '/'
|
||||
return super().create(vals)
|
||||
|
||||
def write(self, vals):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_stock_picking_batch,stock.picking.batch stock users,model_stock_picking_batch,stock.group_stock_user,1,1,1,1
|
||||
access_stock_picking_to_batch,access.stock.picking.to.batch,model_stock_picking_to_batch,stock.group_stock_user,1,1,1,0
|
||||
access_stock_add_to_wave,access.stock.picking.to.wave,model_stock_add_to_wave,stock.group_stock_user,1,1,1,0
|
||||
|
||||
|
@@ -0,0 +1,43 @@
|
||||
odoo.define('stock_picking_wave.choose_lines_widget', function (require) {
|
||||
const relationalFields = require('web.relational_fields');
|
||||
const FieldsRegistry = require('web.field_registry');
|
||||
const core = require('web.core');
|
||||
|
||||
var ChoosePickingWidget = relationalFields.FieldOne2Many.extend({
|
||||
|
||||
init: function (parent, name, record, options) {
|
||||
this._super.apply(this, arguments);
|
||||
this.isMany2Many = true;
|
||||
this.isWave = record.data.is_wave;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
/**
|
||||
* Opens a SelectCreateDialog
|
||||
*/
|
||||
_setValue: function (value, options) {
|
||||
return this._super(value, options).then(() => {
|
||||
if (value.operation === 'ADD_M2M') {
|
||||
core.bus.trigger('add_move_lines', value.ids);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var ChooseLinesWidget = relationalFields.FieldMany2Many.extend({
|
||||
|
||||
start: function () {
|
||||
core.bus.on('add_move_lines', this, this.onAddRecordOpenDialog);
|
||||
return this._super();
|
||||
},
|
||||
});
|
||||
|
||||
FieldsRegistry.add('choose_lines_widget', ChooseLinesWidget);
|
||||
FieldsRegistry.add('choose_picking_widget', ChoosePickingWidget);
|
||||
|
||||
return ChooseLinesWidget, ChoosePickingWidget;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_move_line_tree_detailed_wave" model="ir.ui.view">
|
||||
<field name="name">stock_picking_wave.move.line.tree.wave</field>
|
||||
<field name="model">stock.move.line</field>
|
||||
<field name="inherit_id" ref="stock.view_move_line_tree_detailed"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="inside">
|
||||
<header>
|
||||
<button name="action_open_add_to_wave" type="object" string="Add to Wave" groups="stock.group_stock_picking_wave"/>
|
||||
</header>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='picking_id']" position="after">
|
||||
<field name="batch_id" optional="hide"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -14,7 +14,22 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_picking_tree_batch" model="ir.ui.view">
|
||||
<field name="name">stock_picking_batch.picking.tree.batch</field>
|
||||
<field name="model">stock.picking</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="priority" eval="1000"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="scheduled_date"/>
|
||||
<field name="location_id"/>
|
||||
<field name="backorder_id"/>
|
||||
<field name="origin"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_picking_move_tree_inherited" model="ir.ui.view">
|
||||
<field name="name">stock_picking_batch.picking.move.tree</field>
|
||||
@@ -70,6 +85,7 @@
|
||||
<field name="show_check_availability" invisible="1"/>
|
||||
<field name="show_validate" invisible="1"/>
|
||||
<field name="picking_type_code" invisible="1"/>
|
||||
<field name="is_wave" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_confirm" states="draft" string="Confirm" type="object" class="oe_highlight"/>
|
||||
<button name="action_done" string="Validate" type="object" class="oe_highlight"
|
||||
@@ -137,16 +153,7 @@
|
||||
<page string="Transfers">
|
||||
<field name="allowed_picking_ids" invisible="1"/>
|
||||
<field name="picking_ids" widget="many2many" mode="tree,kanban"
|
||||
context="{'form_view_ref': 'stock_picking_batch.view_picking_form_inherited'}">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="scheduled_date"/>
|
||||
<field name="location_id"/>
|
||||
<field name="backorder_id"/>
|
||||
<field name="origin"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
context="{'form_view_ref': 'stock_picking_batch.view_picking_form_inherited', 'tree_view_ref': 'stock_picking_batch.view_picking_tree_batch'}"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
@@ -166,6 +173,7 @@
|
||||
<field name="name" decoration-bf="1"/>
|
||||
<field name="scheduled_date"/>
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
<field name="picking_type_id"/>
|
||||
<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')"/>
|
||||
<field name="activity_exception_decoration" widget="activity_exception"/>
|
||||
@@ -210,6 +218,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Batch Transfer">
|
||||
<field name="name" string="Batch Transfer"/>
|
||||
<field name="picking_type_id" invisible="1"/>
|
||||
<field name="user_id"/>
|
||||
<filter name="draft" string="Draft" domain="[('state', '=', 'draft')]"/>
|
||||
<filter name="in_progress" string="In Progress" domain="[('state', '=', 'in_progress')]" help="Batch Transfers not finished"/>
|
||||
@@ -234,11 +243,8 @@
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">stock.picking.batch</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="context">{
|
||||
"search_default_draft" : True,
|
||||
"search_default_in_progress" : True,
|
||||
'default_company_id': allowed_company_ids[0]
|
||||
}</field>
|
||||
<field name="domain">[('is_wave', '=', False)]</field>
|
||||
<field name="context">{'search_default_draft': True, 'search_default_in_progress': True}</field>
|
||||
<field name="search_view_id" ref="stock_picking_batch_filter"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
@@ -251,7 +257,7 @@
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem action="stock_picking_batch_action" id="stock_picking_batch_menu" parent="stock.menu_stock_warehouse_mgmt" sequence="10"/>
|
||||
<menuitem action="stock_picking_batch_action" id="stock_picking_batch_menu" parent="stock.menu_stock_warehouse_mgmt" sequence="6"/>
|
||||
|
||||
<record id="vpicktree_inherit_stock_picking_batch" model="ir.ui.view">
|
||||
<field name="name">stock.picking.tree</field>
|
||||
@@ -266,6 +272,7 @@
|
||||
('picking_type_id', '=', picking_type_id),
|
||||
('picking_type_id', '=', False),
|
||||
]"
|
||||
widget="many2onebutton"
|
||||
context="{'default_picking_type_id': picking_type_id}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="stock_picking_wave_tree" model="ir.ui.view">
|
||||
<field name="name">stock.picking.wave.tree</field>
|
||||
<field name="model">stock.picking.batch</field>
|
||||
<field name="priority">25</field>
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="stock_picking_batch.stock_picking_batch_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="create">0</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_picking_tree_wave" model="ir.actions.act_window">
|
||||
<field name="name">Waves Transfers</field>
|
||||
<field name="res_model">stock.picking.batch</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="context">{'search_default_draft': True, 'search_default_in_progress': True}</field>
|
||||
<field name="view_ids" eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('stock_picking_batch.stock_picking_wave_tree')})]"/>
|
||||
<field name="domain">[('is_wave', '=', True)]</field>
|
||||
<field name="search_view_id" ref="stock_picking_batch_filter"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new wave transfer
|
||||
</p><p>
|
||||
The goal of the wave transfer is to group operations from differents transfer
|
||||
together in order to increase their efficiency.
|
||||
It may also be useful to assign jobs (one person = one batch) or
|
||||
help the timing management of operations (tasks to be done at 1pm).
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
action="action_picking_tree_wave"
|
||||
id="stock_picking_wave_menu"
|
||||
parent="stock.menu_stock_warehouse_mgmt"
|
||||
groups="stock.group_stock_picking_wave"
|
||||
sequence="8"/>
|
||||
|
||||
</odoo>
|
||||
@@ -2,4 +2,5 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import stock_picking_to_batch
|
||||
from . import stock_add_to_wave
|
||||
from . import stock_package_destination
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models, api, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class StockPickingToWave(models.TransientModel):
|
||||
_name = 'stock.add.to.wave'
|
||||
_description = 'Wave Transfer Lines'
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
res = super().default_get(fields_list)
|
||||
if self.env.context.get('active_model') == 'stock.move.line':
|
||||
lines = self.env['stock.move.line'].browse(self.env.context.get('active_ids'))
|
||||
res['line_ids'] = self.env.context.get('active_ids')
|
||||
picking_types = lines.picking_type_id
|
||||
elif self.env.context.get('active_model') == 'stock.picking':
|
||||
pickings = self.env['stock.picking'].browse(self.env.context.get('active_ids'))
|
||||
res['picking_ids'] = self.env.context.get('active_ids')
|
||||
picking_types = pickings.picking_type_id
|
||||
else:
|
||||
return res
|
||||
|
||||
if len(picking_types) > 1:
|
||||
raise UserError(_("The selected transfers should belong to the same operation type"))
|
||||
return res
|
||||
|
||||
wave_id = fields.Many2one('stock.picking.batch', string='Wave Transfer', domain="[('is_wave', '=', True), ('state', '!=', 'done')]")
|
||||
picking_ids = fields.Many2many('stock.picking')
|
||||
line_ids = fields.Many2many('stock.move.line')
|
||||
mode = fields.Selection([('existing', 'an existing wave transfer'), ('new', 'a new wave transfer')], default='existing')
|
||||
user_id = fields.Many2one('res.users', string='Responsible', help='Person responsible for this wave transfer')
|
||||
|
||||
|
||||
def attach_pickings(self):
|
||||
self.ensure_one()
|
||||
|
||||
if self.line_ids:
|
||||
company = self.line_ids.company_id
|
||||
if len(company) > 1:
|
||||
raise UserError(_("The selected operations should belong to a unique company."))
|
||||
return self.line_ids._add_to_wave(self.wave_id)
|
||||
if self.picking_ids:
|
||||
company = self.picking_ids.company_id
|
||||
if len(company) > 1:
|
||||
raise UserError(_("The selected transfers should belong to a unique company."))
|
||||
else:
|
||||
raise UserError(_('Cannot create wave transfers'))
|
||||
|
||||
view = self.env.ref('stock_picking_batch.view_move_line_tree_detailed_wave')
|
||||
return {
|
||||
'name': _('Add Operations'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'list',
|
||||
'views': [(view.id, 'tree')],
|
||||
'res_model': 'stock.move.line',
|
||||
'target': 'new',
|
||||
'domain': [
|
||||
('picking_id', 'in', self.picking_ids.ids),
|
||||
('state', '!=', 'done')
|
||||
],
|
||||
'context': dict(
|
||||
self.env.context,
|
||||
picking_to_wave=self.picking_ids.ids,
|
||||
active_wave_id=self.wave_id.id,
|
||||
)}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- add picking to wave -->
|
||||
<record id="stock_add_to_wave_form" model="ir.ui.view">
|
||||
<field name="name">stock.add.to.wave.form</field>
|
||||
<field name="model">stock.add.to.wave</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Add to Wave">
|
||||
<group>
|
||||
<group>
|
||||
<label for="mode" string="Add to"/>
|
||||
<field name="mode" widget="radio" nolabel="1"/>
|
||||
<field name="wave_id" options="{'no_create_edit': True, 'no_open': True}" attrs="{'invisible': [('mode', '=', 'new')], 'required': [('mode', '=', 'existing')]}"/>
|
||||
<field name="user_id" options="{'no_create_edit': True}" attrs="{'invisible': [('mode', '=', 'existing')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<footer>
|
||||
<button name="attach_pickings" type="object" string="Confirm" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="stock_add_to_wave_action_stock_picking" model="ir.actions.act_window">
|
||||
<field name="name">Add to wave</field>
|
||||
<field name="res_model">stock.add.to.wave</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="groups_id" eval="[(4, ref('stock.group_stock_picking_wave'))]"/>
|
||||
<field name="binding_model_id" ref="stock.model_stock_picking"/>
|
||||
<field name="binding_view_types">list</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user