173 lines
7.4 KiB
Python
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() |