Hi,
Here give the code for requirement ,
Implementation Steps
1. Add Manager Field on Locations
Extend the stock.location model to include a manager_id field:
class StockLocation(models.Model):
_inherit = 'stock.location'
manager_id = fields.Many2one('res.users', string="Location Manager")
2. Add Approval Status to Stock Picking
Extend stock.picking to include an approval field and logic:
class StockPicking(models.Model):
_inherit = 'stock.picking'
approval_state = fields.Selection([
('draft', 'Waiting Approval'),
('approved', 'Approved'),
('rejected', 'Rejected')
], default='draft', string="Approval Status")
def action_approve_transfer(self):
self.ensure_one()
self.approval_state = 'approved'
def action_reject_transfer(self):
self.ensure_one()
self.approval_state = 'rejected'
3. Block Validation Without Approval
Override the button_validate() method:
@api.multi
def button_validate(self):
for picking in self:
if picking.picking_type_id.code == 'internal':
source_mgr = picking.location_id.manager_id
dest_mgr = picking.location_dest_id.manager_id
if source_mgr or dest_mgr:
if picking.approval_state != 'approved':
raise UserError("This internal transfer must be approved by the location manager(s) before validation.")
return super(StockPicking, self).button_validate()
4. Auto-Notify Manager(s)
On internal transfer creation, send activity to manager(s) using mail.activity:
@api.model
create(vals):
picking = super().create(vals)
if picking.picking_type_id.code == 'internal':
users_to_notify = []
if picking.location_id.manager_id:
users_to_notify.append(picking.location_id.manager_id)
if picking.location_dest_id.manager_id:
users_to_notify.append(picking.location_dest_id.manager_id)
for user in set(users_to_notify):
self.env['mail.activity'].create({
'res_model_id': self.env['ir.model']._get_id('stock.picking'),
'res_id': picking.id,
'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
'user_id': user.id,
'summary': 'Approval Required for Internal Transfer',
'note': 'Please approve this internal transfer before it can be validated.',
})
return picking
5. Add Approve/Reject Buttons (Optional but Recommended)
Add two buttons in the stock.picking form view (inheriting):
<button name="action_approve_transfer" string="Approve" type="object"
attrs="{'invisible': [('approval_state', '!=', 'draft')]}" class="btn-primary"/>
<button name="action_reject_transfer" string="Reject" type="object"
attrs="{'invisible': [('approval_state', '!=', 'draft')]}" class="btn-secondary"/>
Hope it helps