You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
7.1 KiB
158 lines
7.1 KiB
# -*- coding: utf-8 -*-
|
|
#############################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
|
# Author: Akhil Ashok @cybrosys(odoo@cybrosys.com)
|
|
#
|
|
# You can modify it under the terms of the GNU AFFERO
|
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
|
|
#
|
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
# (AGPL v3) along with this program.
|
|
# If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
#############################################################################
|
|
from odoo import fields, models
|
|
|
|
|
|
class SaleOrder(models.Model):
|
|
"""
|
|
Inherits the Sale Order model to add the ability to apply stock
|
|
reservation for products in draft state. This model also adds a state for
|
|
tracking the reservation status and a one-to-many relationship to the
|
|
Stock Reserved model for storing the details of the reserved stock.
|
|
"""
|
|
_inherit = "sale.order"
|
|
|
|
apply_stock_reservation = fields.Boolean(string="Apply stock reservation",
|
|
help="Apply stock reservation in "
|
|
"draft")
|
|
state_reservation = fields.Selection([
|
|
('reserved', 'Reserved'), ('cancel', 'Cancelled')],
|
|
help="Condition for visibility of buttons")
|
|
reserved_stock_ids = fields.One2many("stock.reserved", "sale_order_id",
|
|
string="Reserved Stock",
|
|
help="Stock reserved details")
|
|
|
|
def action_create_stock_reservation(self):
|
|
"""
|
|
This function creates a stock reservation based on the current sale
|
|
order's order lines.
|
|
If the sale order has order lines, the function creates a list of
|
|
tuples representing the order lines,which are used to set default
|
|
values for the stock reservation. Each tuple contains three elements:
|
|
(0, 0, {...}), where the dictionary contains values for the following
|
|
fields of the stock reservation:
|
|
|
|
- order_line_name: a string representing the name of the sale order
|
|
and the order line, concatenated
|
|
- product_id: the ID of the product being reserved
|
|
- quantity: the quantity being reserved, in the unit of measure
|
|
specified by the order line
|
|
- unit_of_measure_id: the ID of the unit of measure being used for the
|
|
reservation
|
|
- reserve_quantity: the quantity being reserved, in the unit of
|
|
measure specified by the product
|
|
|
|
If the sale order does not have any order lines, an empty list
|
|
created.
|
|
|
|
The function then returns a dictionary representing an action to
|
|
create a new stock reservation.
|
|
The dictionary has the following keys:
|
|
|
|
- name: a string representing the name of the action
|
|
- type: a string representing the type of the action (in this case,
|
|
'ir.actions.act_window')
|
|
- view_type: a string representing the type of view to use
|
|
(in this case, 'form')
|
|
- view_mode: a string representing the mode of the view
|
|
(in this case, 'form')
|
|
- res_model: a string representing the name of the model being used
|
|
(in this case,'sale.stock.reservation')
|
|
- context: a dictionary representing the context to use when creating
|
|
the stock reservation
|
|
- default_sale_order_id: the ID of the sale order being used as the
|
|
basis for the reservation
|
|
- default_stock_reservation_ids: the list of tuples representing the
|
|
order lines (or an empty list)
|
|
- view_id: the ID of the view to use (retrieved using self.env.ref())
|
|
- target: a string representing the target for the action
|
|
(in this case, 'new')
|
|
|
|
:return: a dictionary representing the action to create a new stock
|
|
reservation
|
|
"""
|
|
line_vals = [(0, 0, {
|
|
'order_line_name': f"{self.name}-{line.name}",
|
|
'product_id': line.product_id.id,
|
|
'quantity': line.product_uom_qty,
|
|
'unit_of_measure_id': line.product_uom.id,
|
|
'reserve_quantity': line.product_uom_qty
|
|
}) for line in self.order_line] if self.order_line else []
|
|
return {
|
|
'name': "Stock Reservation",
|
|
'type': 'ir.actions.act_window',
|
|
'view_type': 'form',
|
|
'view_mode': 'form',
|
|
'res_model': 'sale.stock.reservation',
|
|
'context': {'default_sale_order_id': self.id,
|
|
'default_stock_reservation_ids': line_vals},
|
|
'view_id': self.env.ref(
|
|
'sales_stock_reservation.sale_stock_reservation_view_form').id,
|
|
'target': 'new',
|
|
}
|
|
|
|
def action_cancel_reservation(self):
|
|
"""
|
|
This function cancels a stock reservation by setting its state to
|
|
'cancel', cancelling the moves associated with the reservation's
|
|
reserved stock,and setting the status of the reserved stock to
|
|
'cancelled'.
|
|
|
|
The function first sets the `state_reservation` field of the current
|
|
object to 'cancel'.
|
|
|
|
It then retrieves the `move_id` field of each reserved stock associated
|
|
with the reservation using `mapped()`,and calls the `_action_cancel()`
|
|
method on the resulting recordset to cancel the moves.
|
|
|
|
After cancelling the moves, the function sets the `status` field of each
|
|
reserved stock associated with the reservation to 'cancelled' using
|
|
`mapped()`.
|
|
|
|
Finally, the function returns True to indicate that the cancellation
|
|
was successful.
|
|
|
|
:return: True if the reservation was successfully cancelled, False
|
|
otherwise
|
|
"""
|
|
self.state_reservation = 'cancel'
|
|
self.reserved_stock_ids.mapped('move_id')._action_cancel()
|
|
self.mapped("reserved_stock_ids").status = 'cancelled'
|
|
return True
|
|
|
|
def action_confirm(self):
|
|
"""
|
|
This function confirms a sale order by calling the parent
|
|
`action_confirm()` method and then cancelling any associated stock
|
|
reservation.
|
|
The function first calls the `super()` method to confirm the sale order
|
|
using the parent implementation.
|
|
It then calls the `cancel_reservation()` method to cancel any existing
|
|
stock reservation associated with the sale order.
|
|
Finally, the function returns the result of the `super()` method call to
|
|
indicate whether the sale order was successfully confirmed.
|
|
|
|
:return: the result of the parent `action_confirm()` method call
|
|
"""
|
|
res = super().action_confirm()
|
|
self.action_cancel_reservation()
|
|
return res
|
|
|