182 lines
6.5 KiB
Python
182 lines
6.5 KiB
Python
# Copyright 2012-2016 Camptocamp SA
|
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
|
import json
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class StockBatchPickingCreator(models.TransientModel):
|
|
"""Create a stock.picking.batch from stock.picking
|
|
"""
|
|
|
|
_name = 'stock.picking.batch.creator'
|
|
_description = 'Batch Picking Creator'
|
|
_group_field_param = 'stock_batch_picking.group_field'
|
|
|
|
name = fields.Char(
|
|
'Name', required=True,
|
|
default=lambda x: x.env['ir.sequence'].next_by_code(
|
|
'stock.picking.batch'
|
|
),
|
|
help='Name of the batch picking'
|
|
)
|
|
date = fields.Date(
|
|
'Date', required=True, index=True, default=fields.Date.context_today,
|
|
help='Date on which the batch picking is to be processed'
|
|
)
|
|
|
|
user_id = fields.Many2one(
|
|
'res.users', string='Picker',
|
|
oldname='picker_id',
|
|
default=lambda self: self._default_user_id(),
|
|
help='The user to which the pickings are assigned',
|
|
)
|
|
notes = fields.Text('Notes', help='Free form remarks')
|
|
batch_by_group = fields.Boolean(
|
|
string='Create batch pickings grouped by fields',
|
|
)
|
|
group_field_ids = fields.One2many(
|
|
comodel_name='stock.picking.batch.creator.group.field',
|
|
inverse_name='batch_picking_creator_id',
|
|
string='Group by field',
|
|
help='If set any, multiple batch picking will be created, one per '
|
|
'group field',
|
|
)
|
|
|
|
@api.onchange('batch_by_group')
|
|
def onchange_batch_by_group(self):
|
|
if self.batch_by_group:
|
|
self.group_field_ids = False
|
|
for index, field in enumerate(self.load_store_fields()):
|
|
self.group_field_ids += self.group_field_ids.new({
|
|
'sequence': index,
|
|
'field_id': field.id,
|
|
})
|
|
|
|
def load_store_fields(self):
|
|
group_field_ids = self.env['ir.config_parameter'].sudo().get_param(
|
|
self._group_field_param)
|
|
group_fields = self.env['ir.model.fields'].browse(
|
|
group_field_ids and json.loads(group_field_ids))
|
|
return group_fields
|
|
|
|
@api.model
|
|
def default_get(self, fields):
|
|
"""
|
|
Set last grouped fields used that are stored in config parameters
|
|
"""
|
|
res = super().default_get(fields)
|
|
group_fields = self.load_store_fields()
|
|
res['batch_by_group'] = group_fields and True or False
|
|
return res
|
|
|
|
def _default_user_id(self):
|
|
""" Return default_user_id from the main company warehouse
|
|
except if a warehouse_id is specified in context.
|
|
"""
|
|
warehouse_id = self.env.context.get('warehouse_id')
|
|
if warehouse_id:
|
|
warehouse = self.env['stock.warehouse'].browse(warehouse_id)
|
|
else:
|
|
warehouse = self.env['stock.warehouse'].search([
|
|
('company_id', '=', self.env.user.company_id.id)
|
|
], limit=1)
|
|
|
|
return warehouse.default_user_id
|
|
|
|
def _prepare_stock_batch_picking(self):
|
|
return {
|
|
'name': self.name,
|
|
'date': self.date,
|
|
'notes': self.notes,
|
|
'user_id': self.user_id.id,
|
|
}
|
|
|
|
def _raise_message_error(self):
|
|
return _(
|
|
"All selected pickings are already in a batch picking "
|
|
"or are in a wrong state."
|
|
)
|
|
|
|
def create_simple_batch(self, domain):
|
|
""" Create one batch picking with all pickings """
|
|
pickings = self.env['stock.picking'].search(domain)
|
|
if not pickings:
|
|
raise UserError(self._raise_message_error())
|
|
batch = self.env['stock.picking.batch'].create(
|
|
self._prepare_stock_batch_picking())
|
|
pickings.write({'batch_id': batch.id})
|
|
return batch
|
|
|
|
def create_multiple_batch(self, domain):
|
|
""" Create n batch pickings by grouped fields selected """
|
|
StockPicking = self.env['stock.picking']
|
|
groupby = [f.field_id.name for f in self.group_field_ids]
|
|
pickings_grouped = StockPicking.read_group(domain, groupby, groupby)
|
|
if not pickings_grouped:
|
|
raise UserError(self._raise_message_error())
|
|
batchs = self.env['stock.picking.batch'].browse()
|
|
for group in pickings_grouped:
|
|
batchs += self.env['stock.picking.batch'].create(
|
|
self._prepare_stock_batch_picking())
|
|
StockPicking.search(group['__domain']).write({
|
|
'batch_id': batchs[-1:].id,
|
|
})
|
|
return batchs
|
|
|
|
@api.multi
|
|
def action_create_batch(self):
|
|
""" Create a batch picking with selected pickings after having checked
|
|
that they are not already in another batch or done/cancel.
|
|
"""
|
|
domain = [
|
|
('id', 'in', self.env.context['active_ids']),
|
|
('batch_id', '=', False),
|
|
('state', 'not in', ('cancel', 'done')),
|
|
]
|
|
if self.batch_by_group and self.group_field_ids:
|
|
batchs = self.create_multiple_batch(domain)
|
|
else:
|
|
batchs = self.create_simple_batch(domain)
|
|
|
|
# Store as system parameter the fields used to be loaded in the next
|
|
# execution keeping the order.
|
|
if self.batch_by_group:
|
|
group_fields = [f.field_id.id for f in self.group_field_ids]
|
|
self.env["ir.config_parameter"].sudo().set_param(
|
|
self._group_field_param, group_fields)
|
|
return self.action_view_batch_picking(batchs)
|
|
|
|
@api.multi
|
|
def action_view_batch_picking(self, batch_pickings):
|
|
if len(batch_pickings) > 1:
|
|
action = self.env.ref(
|
|
'stock_picking_batch_extended.action_stock_batch_picking_tree'
|
|
).read()[0]
|
|
action['domain'] = [('id', 'in', batch_pickings.ids)]
|
|
else:
|
|
action = batch_pickings.get_formview_action()
|
|
return action
|
|
|
|
|
|
class StockBatchPickingCreatorGroupField(models.TransientModel):
|
|
""" Make mass batch pickings from grouped fields """
|
|
_name = 'stock.picking.batch.creator.group.field'
|
|
_description = 'Batch Picking Creator Group Field'
|
|
_order = 'sequence, id'
|
|
|
|
batch_picking_creator_id = fields.Many2one(
|
|
comodel_name='stock.picking.batch.creator',
|
|
ondelete="cascade",
|
|
required=True,
|
|
)
|
|
sequence = fields.Integer(help='Group by picking field', default=0)
|
|
field_id = fields.Many2one(
|
|
comodel_name='ir.model.fields',
|
|
string='Field to group',
|
|
domain=[
|
|
('model', '=', 'stock.picking'),
|
|
('store', '=', True),
|
|
],
|
|
required=True,
|
|
)
|