77 lines
3.9 KiB
Python
77 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from ast import literal_eval
|
|
|
|
from odoo import fields, models, api
|
|
|
|
|
|
class RelocateStockQuant(models.TransientModel):
|
|
_name = 'stock.quant.relocate'
|
|
_description = 'Stock Quantity Relocation'
|
|
|
|
quant_ids = fields.Many2many('stock.quant')
|
|
company_id = fields.Many2one(related="quant_ids.company_id")
|
|
dest_location_id = fields.Many2one('stock.location', domain="[('usage', '=', 'internal'), ('company_id', '=', company_id)]")
|
|
dest_package_id_domain = fields.Char(compute="_compute_dest_package_id_domain")
|
|
dest_package_id = fields.Many2one('stock.quant.package', domain="dest_package_id_domain", compute="_compute_dest_package_id", store=True)
|
|
message = fields.Text('Reason for relocation')
|
|
is_partial_package = fields.Boolean(compute='_compute_is_partial_package')
|
|
partial_package_names = fields.Char(compute="_compute_is_partial_package")
|
|
is_multi_location = fields.Boolean(compute='_compute_is_multi_location')
|
|
|
|
@api.depends('quant_ids')
|
|
def _compute_is_partial_package(self):
|
|
self.is_partial_package = False
|
|
self.partial_package_names = ''
|
|
for wizard in self:
|
|
packages = wizard.quant_ids.package_id
|
|
incomplete_packages = packages.filtered(lambda p: any(q not in wizard.quant_ids.ids for q in p.quant_ids.ids))
|
|
if packages and incomplete_packages:
|
|
wizard.is_partial_package = True
|
|
wizard.partial_package_names = ', '.join(incomplete_packages.mapped('display_name'))
|
|
|
|
@api.depends('dest_location_id', 'quant_ids')
|
|
def _compute_is_multi_location(self):
|
|
self.is_multi_location = False
|
|
for wizard in self:
|
|
if len(wizard.quant_ids.location_id) > 1 and not wizard.dest_location_id:
|
|
wizard.is_multi_location = True
|
|
|
|
@api.depends('dest_location_id', 'quant_ids')
|
|
def _compute_dest_package_id_domain(self):
|
|
for wizard in self:
|
|
domain = ['|', ('company_id', '=', wizard.company_id.id), ('company_id', '=', False)]
|
|
if wizard.dest_location_id:
|
|
domain += ['|', ('location_id', '=', False), ('location_id', '=', wizard.dest_location_id.id)]
|
|
elif len(wizard.quant_ids.location_id) == 1:
|
|
domain += ['|', ('location_id', '=', False), ('location_id', '=', wizard.quant_ids.location_id.id)]
|
|
wizard.dest_package_id_domain = domain
|
|
|
|
@api.depends('dest_package_id_domain')
|
|
def _compute_dest_package_id(self):
|
|
for wizard in self:
|
|
if wizard.dest_package_id and wizard.dest_package_id not in wizard.dest_package_id.search(literal_eval(wizard.dest_package_id_domain)):
|
|
wizard.dest_package_id = False
|
|
|
|
def action_relocate_quants(self):
|
|
self.ensure_one()
|
|
lot_ids = self.quant_ids.lot_id
|
|
product_ids = self.quant_ids.product_id
|
|
|
|
if not self.dest_location_id and not self.dest_package_id:
|
|
return
|
|
self.quant_ids.action_clear_inventory_quantity()
|
|
|
|
if self.is_partial_package and not self.dest_package_id:
|
|
quants_to_unpack = self.quant_ids.filtered(lambda q: not all(sub_q in self.quant_ids.ids for sub_q in q.package_id.quant_ids.ids))
|
|
quants_to_unpack.move_quants(location_dest_id=self.dest_location_id, message=self.message, unpack=True)
|
|
self.quant_ids -= quants_to_unpack
|
|
self.quant_ids.move_quants(location_dest_id=self.dest_location_id, package_dest_id=self.dest_package_id, message=self.message)
|
|
|
|
if self.env.context.get('default_lot_id', False) and len(lot_ids) == 1:
|
|
return lot_ids.action_lot_open_quants()
|
|
elif self.env.context.get('single_product', False) and len(product_ids) == 1:
|
|
return product_ids.action_update_quantity_on_hand()
|
|
return self.env['ir.actions.server']._for_xml_id(self.env.context.get('action_ref', 'stock.action_view_quants'))
|