summaryrefslogtreecommitdiff
path: root/indoteknik_custom/models/approval_unreserve.py
blob: d847ea37b3bfded1e8586734e9977fa10e4e34fc (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
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)
    reason = fields.Text(string="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', 'in', ['assigned', 'partially_available'])])

        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._check_product_and_qty()
        self.write({'state': 'waiting_approval'})


    def _check_product_and_qty(self):
        stock_move = self.env['stock.move']
        for line in self.approval_line:
            if line.dest_picking_id:   
                move = stock_move.search([
                    ('picking_id', '=', line.dest_picking_id.id),
                    ('product_id', '=', line.product_id.id),
                    ('state', 'not in', ['done', 'cancel'])
                ])

                if not move:
                    raise UserError("Product tidak ada di destination picking")
                
                qty_unreserve = line.unreserve_qty + move.reserved_availability

                if move.product_uom_qty < qty_unreserve:
                    raise UserError("Quantity yang di unreserve melebihi quantity yang ada")

    def action_approve(self):
        if self.env.user.id != self.user_id.id and not self.env.user.has_group('indoteknik_custom.group_role_it'):
            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()
        # self.picking_id.check_state_reserve()

    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:
            move = stock_move_obj.browse(line.move_id.id)
            move._do_unreserve(product=line.product_id, quantity=line.unreserve_qty)

            original_sale_id = move.picking_id.sale_id

            product_name = line.product_id.display_name
            unreserved_qty = line.unreserve_qty

            if line.dest_picking_id:
                dest_sale_id = line.dest_picking_id.sale_id
                line.dest_picking_id.action_assign()

                if original_sale_id:
                    message = (
                        f"Barang {product_name} sebanyak {unreserved_qty} dipindahkan ke SO {dest_sale_id.name}"
                        if dest_sale_id else
                        f"Barang {product_name} sebanyak {unreserved_qty} dipindahkan ke picking tujuan."
                    )
                    original_sale_id.message_post(body=message)
            else:
                if original_sale_id:
                    message = f"Barang {product_name} sebanyak {unreserved_qty} ter unreserve."
                    original_sale_id.message_post(body=message)

           
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)
    sales_id = fields.Many2one('res.users', string="Sales", readonly=True, tracking=True)
    unreserve_qty = fields.Float(string="Quantity to Unreserve")
    dest_picking_id = fields.Many2one('stock.picking', string="Destination Picking", tracking=True)


    @api.onchange('dest_picking_id')
    def onchange_dest_picking_id(self):
        if self.dest_picking_id:
            self.sales_id = self.dest_picking_id.sale_id.user_id.id