summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/approval_unreserve.py
blob: 00fd155544aa9987a4e332056c6a9d60658a095e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from odoo import models, api, fields
from odoo.exceptions import AccessError, UserError, ValidationError
from datetime import timedelta, date
import logging

_logger = logging.getLogger(__name__)

class ApprovalUnreserve(models.Model):
    _name = "approval.unreserve"
    _description = "Approval Unreserve"
    _inherit = ['mail.thread']
    _rec_name = 'number'

    number = fields.Char(string='Document No', index=True, copy=False, readonly=True, tracking=True, default='New')
    approval_line = fields.One2many('approval.unreserve.line', 'approval_id', string='Approval Unreserve Lines', auto_join=True)
    state = fields.Selection([
        ('draft', 'Draft'),
        ('waiting_approval', 'Waiting for Approval'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected')
    ], string="Status", default='draft', tracking=True)
    request_date = fields.Date(string="Request Date", default=fields.Date.today, tracking=True)
    approved_by = fields.Many2one('res.users', string="Approved By", readonly=True, tracking=True)
    picking_id = fields.Many2one('stock.picking', string="Picking", tracking=True)
    user_id = fields.Many2one('res.users', string="User", readonly=True, tracking=True)
    rejection_reason = fields.Text(string="Rejection Reason", tracking=True)

    @api.constrains('picking_id')
    def create_move_id_line(self):
        if not self.picking_id:
            raise ValidationError("Picking is required")
        
        stock_move = self.env['stock.move'].search([('picking_id', '=', self.picking_id.id), ('state', '=', 'assigned')])

        if not stock_move:
            raise ValidationError("Picking is not found")
        
        for move in stock_move:
            self.approval_line.create({
                'approval_id': self.id,
                'move_id': move.id
            })

        self.user_id = self.picking_id.sale_id.user_id.id

    @api.model
    def create(self, vals):
        if vals.get('number', 'New') == 'New':
            vals['number'] = self.env['ir.sequence'].next_by_code('approval.unreserve') or 'New'
        return super(ApprovalUnreserve, self).create(vals)

    def action_submit_for_approval(self):
        self.write({'state': 'waiting_approval'})

    def action_approve(self):
        if self.env.user.id != self.user_id.id:
            raise UserError("Hanya Sales nya yang bisa approve.")

        if self.state != 'waiting_approval':
            raise UserError("Approval can only be done in 'Waiting for Approval' state")
        

        self.write({
            'state': 'approved',
            'approved_by': self.env.user.id
        })
        # Trigger the unreserve function
        self._trigger_unreserve()

    def action_reject(self, reason):
        if self.env.user.id != self.user_id.id:
            raise UserError("Hanya Sales nya yang bisa reject.")
        
        if self.state != 'waiting_approval':
            raise UserError("Rejection can only be done in 'Waiting for Approval' state")
        self.write({
            'state': 'rejected',
            'rejection_reason': reason
        })

    def _trigger_unreserve(self):
        stock_move_obj = self.env['stock.move']
        
        for line in self.approval_line:
            # Step 1: Unreserve the product from the current picking
            move = stock_move_obj.browse(line.move_id.id)
            move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty)

            line.dest_picking_id.action_assign()

            # Step 2: Update existing stock move in dest_picking_id
            # if line.dest_picking_id:
            #     dest_move = stock_move_obj.search([
            #         ('picking_id', '=', line.dest_picking_id.id),
            #         ('product_id', '=', line.product_id.id),
            #         ('state', 'not in', ['cancel', 'done'])  # Only draft or assigned moves can be updated
            #     ], limit=1)

            #     if dest_move:
            #         # Add the unreserved quantity to the existing stock move
            #         dest_move.write({
            #             'product_uom_qty': dest_move.product_uom_qty + line.unreserve_qty
            #         })
                    
            #         # If the move is in draft state, confirm it and reserve the product
            #         if dest_move.state == 'draft':
            #             dest_move._action_confirm()
            #         dest_move._action_assign()  # Reserve the product

            #     else:
            #         # If no move is found, raise an error or handle accordingly
            #         raise UserError(f"No stock move found for product {line.product_id.display_name} in the destination picking.")

class ApprovalUnreserveLine(models.Model):
    _name = 'approval.unreserve.line'
    _description = 'Approval Unreserve Line'
    _order = 'approval_id, id'

    approval_id = fields.Many2one('approval.unreserve', string='Approval Reference', required=True, ondelete='cascade', index=True, copy=False)
    move_id = fields.Many2one('stock.move', string="Stock Move", required=True)
    product_id = fields.Many2one('product.product', string="Product", related='move_id.product_id', readonly=True)
    unreserve_qty = fields.Float(string="Quantity to Unreserve")
    dest_picking_id = fields.Many2one('stock.picking', string="Destination Picking", tracking=True)