stock/wizard/stock_quant_relocate.py

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'))