subcontracting_inventory_mo.../models/purchase_order.py

173 lines
7.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, api
class PurchaseOrder(models.Model):
_inherit = 'purchase.order'
# Field to link purchase order to inventory moves
subcontracting_move_ids = fields.Many2many(
'stock.move',
string='Subcontracting Inventory Moves',
relation='purchase_order_stock_move_subcontract_rel',
column1='purchase_order_id',
column2='stock_move_id',
help='Inventory moves linked to this purchase order for subcontracting'
)
# Computed field to show count of linked inventory moves for smart button
subcontracting_move_count = fields.Integer(
string='Subcontracting Moves Count',
compute='_compute_subcontracting_move_count'
)
@api.depends('subcontracting_move_ids')
def _compute_subcontracting_move_count(self):
for order in self:
order.subcontracting_move_count = len(order.subcontracting_move_ids)
def action_link_subcontracting_moves(self):
"""Action to link existing inventory moves to this purchase order"""
self.ensure_one()
return {
'name': 'Link Subcontracting Inventory Moves',
'type': 'ir.actions.act_window',
'view_mode': 'list',
'res_model': 'stock.move',
'domain': [
('location_dest_id.name', '=', 'Subcontracting Location'),
('purchase_order_id', '=', False),
('state', 'in', ['done']),
],
'target': 'new',
'context': {
'default_purchase_order_id': self.id,
},
'views': [
(self.env.ref('subcontracting_inventory_move_first.view_stock_move_link_subcontracting_tree').id, 'list')
],
'limit': 1,
}
def action_view_subcontracting_moves(self):
"""Action to view linked subcontracting inventory moves"""
self.ensure_one()
action = {
'name': 'Subcontracting Inventory Moves',
'type': 'ir.actions.act_window',
'view_mode': 'list,form',
'res_model': 'stock.move',
'domain': [('id', 'in', self.subcontracting_move_ids.ids)],
'context': {'create': False}
}
if len(self.subcontracting_move_ids) == 1:
action['views'] = [(False, 'form')]
action['res_id'] = self.subcontracting_move_ids.id
return action
def link_selected_subcontracting_move(self, move_id):
"""Method to link a selected subcontracting move to this purchase order"""
self.ensure_one()
move = self.env['stock.move'].browse(move_id)
if move and move.exists() and not move.purchase_order_id:
# Link the move to this purchase order
move.write({
'purchase_order_id': self.id,
'origin': self.name # Update source document to purchase order number
})
# Also update the related stock.picking if it exists
if move.picking_id:
move.picking_id.write({
'origin': self.name,
# Note: stock.picking doesn't have a purchase_order_id field, so we can't link it directly
})
# Also add to the Many2many field
current_moves = self.subcontracting_move_ids.ids
current_moves.append(move.id)
self.write({'subcontracting_move_ids': [(6, 0, current_moves)]})
return True
return False
@api.model_create_multi
def create(self, vals_list):
"""Override create to handle linking with inventory moves if provided"""
# Create the purchase orders first using the parent method
orders = super().create(vals_list)
# Process subcontracting moves linking for each created order
for order, vals in zip(orders, vals_list):
subcontracting_move_ids = vals.get('subcontracting_move_ids')
# If subcontracting moves were provided, link them
if subcontracting_move_ids:
# Process the commands in the Many2many field
for command in subcontracting_move_ids:
if command[0] == 6: # Replace all
move_ids = command[2]
moves = self.env['stock.move'].browse(move_ids)
moves.write({'purchase_order_id': order.id})
elif command[0] == 4: # Add one
move_id = command[1]
move = self.env['stock.move'].browse(move_id)
move.write({'purchase_order_id': order.id})
return orders
def write(self, vals):
"""Override write to handle linking/unlinking of inventory moves"""
# Handle subcontracting moves linking/unlinking
if 'subcontracting_move_ids' in vals:
# Get current linked moves before the update
old_moves = self.subcontracting_move_ids
# Call super to update the record
result = super().write(vals)
# Update the purchase_order_id on the linked moves
for order in self:
# Unlink old moves that are no longer linked
moves_to_unlink = old_moves - order.subcontracting_move_ids
moves_to_unlink.write({'purchase_order_id': False})
# Link new moves
moves_to_link = order.subcontracting_move_ids - old_moves
moves_to_link.write({'purchase_order_id': order.id})
else:
result = super().write(vals)
return result
def button_confirm(self):
"""Override to handle subcontracting moves when confirming purchase order"""
# First call the original confirm method
result = super().button_confirm()
# For each linked subcontracting move, potentially trigger additional actions
for order in self:
for move in order.subcontracting_move_ids:
# When the purchase order is confirmed, we may want to update the move's state
# or trigger the standard subcontracting flow for these moves
if move.state in ['draft', 'waiting']:
# Confirm the linked moves if they're not already confirmed
if move.state == 'draft':
move._action_confirm()
# Assign them if needed
if move.state in ['confirmed', 'waiting']:
move._action_assign()
return result
def button_cancel(self):
"""Override to handle subcontracting moves when cancelling purchase order"""
# For each linked subcontracting move, we may need to unlink or update them
for order in self:
# Unlink moves if needed based on business requirements
# Here we'll keep the moves but remove the purchase order link
order.subcontracting_move_ids.write({'purchase_order_id': False})
# Then call the original cancel method
return super().button_cancel()