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

# -*- 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