diff options
| author | Azka Nathan <darizkyfaz@gmail.com> | 2024-09-12 13:58:27 +0700 |
|---|---|---|
| committer | Azka Nathan <darizkyfaz@gmail.com> | 2024-09-12 13:58:27 +0700 |
| commit | 5c6098158ab0f82437aa24e947a66b78b21b6bd7 (patch) | |
| tree | d664336b488ad4321a886e4f37e28ffbbf9271a6 | |
| parent | 16acaa437f203ccfa52aba132225b2bb82ac1c79 (diff) | |
push
| -rw-r--r-- | indoteknik_custom/models/approval_unreserve.py | 19 | ||||
| -rw-r--r-- | indoteknik_custom/models/stock_move.py | 44 | ||||
| -rw-r--r-- | indoteknik_custom/views/approval_unreserve.xml | 8 |
3 files changed, 66 insertions, 5 deletions
diff --git a/indoteknik_custom/models/approval_unreserve.py b/indoteknik_custom/models/approval_unreserve.py index 4feb51fa..a8f9fd3b 100644 --- a/indoteknik_custom/models/approval_unreserve.py +++ b/indoteknik_custom/models/approval_unreserve.py @@ -21,8 +21,25 @@ class ApprovalUnreserve(models.Model): ], 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) 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)]) + + 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 + }) + @api.model def create(self, vals): if vals.get('number', 'New') == 'New': @@ -66,4 +83,4 @@ class ApprovalUnreserveLine(models.Model): 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", required=True) + unreserve_qty = fields.Float(string="Quantity to Unreserve") diff --git a/indoteknik_custom/models/stock_move.py b/indoteknik_custom/models/stock_move.py index fe46bf65..6c44f8a6 100644 --- a/indoteknik_custom/models/stock_move.py +++ b/indoteknik_custom/models/stock_move.py @@ -1,5 +1,6 @@ from odoo import fields, models, api - +from odoo.tools.misc import format_date, OrderedSet +from odoo.exceptions import UserError class StockMove(models.Model): _inherit = 'stock.move' @@ -7,6 +8,47 @@ class StockMove(models.Model): line_no = fields.Integer('No', default=0) sale_id = fields.Many2one('sale.order', string='SO') + def _do_unreserve(self, product=None, quantity=None): + moves_to_unreserve = OrderedSet() + for move in self: + if move.state == 'cancel' or (move.state == 'done' and move.scrapped): + continue + elif move.state == 'done': + raise UserError(_("You cannot unreserve a stock move that has been set to 'Done'.")) + + if product and move.product_id != product: + continue # Skip moves that don't match the specified product + moves_to_unreserve.add(move.id) + + moves_to_unreserve = self.env['stock.move'].browse(moves_to_unreserve) + + ml_to_update, ml_to_unlink = OrderedSet(), OrderedSet() + moves_not_to_recompute = OrderedSet() + + for ml in moves_to_unreserve.move_line_ids: + if product and ml.product_id != product: + continue # Only affect the specified product + + if quantity > 0: + # Only reduce by the specified quantity if it is greater than zero + ml_to_update.add(ml.id) + remaining_qty = ml.product_uom_qty - quantity + ml.write({'product_uom_qty': remaining_qty if remaining_qty > 0 else 0}) + quantity = 0 # Set to zero to prevent further unreserving in the same loop + elif ml.qty_done: + ml_to_update.add(ml.id) + else: + ml_to_unlink.add(ml.id) + moves_not_to_recompute.add(ml.move_id.id) + + ml_to_update, ml_to_unlink = self.env['stock.move.line'].browse(ml_to_update), self.env['stock.move.line'].browse(ml_to_unlink) + moves_not_to_recompute = self.env['stock.move'].browse(moves_not_to_recompute) + + ml_to_unlink.unlink() + (moves_to_unreserve - moves_not_to_recompute)._recompute_state() + return True + + def _prepare_account_move_line_from_mr(self, po_line, qty, move=False): po_line.ensure_one() aml_currency = move and move.currency_id or po_line.currency_id diff --git a/indoteknik_custom/views/approval_unreserve.xml b/indoteknik_custom/views/approval_unreserve.xml index cd238125..08a5b49e 100644 --- a/indoteknik_custom/views/approval_unreserve.xml +++ b/indoteknik_custom/views/approval_unreserve.xml @@ -7,24 +7,25 @@ <tree string="Approval Unreserve"> <field name="number"/> <field name="request_date"/> + <field name="picking_id"/> <field name="state"/> <field name="approved_by"/> </tree> </field> </record> - + <record id="approval_unreserve_line_tree" model="ir.ui.view"> <field name="name">approval.unreserve.line.tree</field> <field name="model">approval.unreserve.line</field> <field name="arch" type="xml"> - <tree> + <tree editable="bottom"> <field name="move_id"/> <field name="product_id"/> <field name="unreserve_qty"/> </tree> </field> </record> - + <record id="approval_unreserve_form" model="ir.ui.view"> <field name="name">approval.unreserve.form</field> <field name="model">approval.unreserve</field> @@ -40,6 +41,7 @@ <group> <field name="number"/> <field name="request_date"/> + <field name="picking_id"/> <field name="state"/> <field name="approved_by"/> </group> |
