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.
157 lines
7.7 KiB
157 lines
7.7 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
|
|
from odoo.http import request
|
|
|
|
|
|
class SaleStockReservation(models.TransientModel):
|
|
"""
|
|
This model is used to reserve products for a sale order.
|
|
|
|
Fields:
|
|
- stock_reservation_ids: A one-to-many relationship to the
|
|
`stock.reservation` model, representing the reservations to be made.
|
|
- sale_order_id: The ID of the sale order for which the products are being
|
|
reserved.
|
|
- mail_notification_ids: A many-to-many relationship to the `res.users`
|
|
model,representing the users who should receive email notifications about
|
|
the reservation.
|
|
"""
|
|
_name = "sale.stock.reservation"
|
|
_description = "Stock Reservation"
|
|
|
|
stock_reservation_ids = fields.One2many("stock.reservation",
|
|
"stock_reservation_wizard_id",
|
|
string="Order line",
|
|
help='This is a One2many field that '
|
|
'refers to the reserved stock items '
|
|
'associated with the wizard.')
|
|
sale_order_id = fields.Many2one("sale.order", string="Sale order",
|
|
readonly="True",
|
|
help="Many2one field that returns the Sale "
|
|
"Order")
|
|
mail_notification_ids = fields.Many2many("res.users",
|
|
string="Email Notification",
|
|
help='This is a Many2many field '
|
|
'that refers to the '
|
|
'users who will receive '
|
|
'email notifications.')
|
|
|
|
def action_reserve_stock(self):
|
|
"""
|
|
This function reserves stock for a sale order and creates a stock
|
|
reservation.
|
|
|
|
The function sets the state of the associated sale order to "reserved".
|
|
|
|
It then retrieves the source and destination locations for the stock
|
|
reservation from the system parameters.
|
|
|
|
For each product in the stock reservation, the function creates a
|
|
stock move to transfer the product from the source location to the
|
|
destination location, sets the reservation status for the product, and
|
|
updates the stock reservation with the ID of the newly created stock
|
|
move.
|
|
|
|
The function then creates a new record for each reserved product and
|
|
adds it to the `reserved_stock_ids` field of the associated sale order.
|
|
|
|
Finally, if there are any mail notifications associated with the stock
|
|
reservation,the function sends an email to each recipient with details
|
|
of the reserved items.
|
|
|
|
:return: None
|
|
"""
|
|
self.sale_order_id.state_reservation = "reserved"
|
|
source_location = int(
|
|
self.env['ir.config_parameter'].sudo().get_param(
|
|
'sales_stock_reservation.source_location_id'))
|
|
destination_location = int(
|
|
self.env['ir.config_parameter'].sudo().get_param(
|
|
'sales_stock_reservation.destination_location_id'))
|
|
for rec in self.stock_reservation_ids:
|
|
move_vals = {
|
|
"name": "Product Quantity Reserved",
|
|
"location_id": source_location,
|
|
"location_dest_id": destination_location,
|
|
'product_id': rec.product_id.id,
|
|
"product_uom_qty": rec.reserve_quantity,
|
|
"date": fields.Datetime.now(),
|
|
"product_uom": rec.unit_of_measure_id.id
|
|
}
|
|
move = self.env["stock.move"].create(move_vals)
|
|
rec.move_id = move.id
|
|
move._action_confirm()
|
|
move._action_assign()
|
|
line_vals = [{
|
|
"order_line_name": rec.order_line_name,
|
|
"product_id": rec.product_id.id,
|
|
"reserved_quantity": rec.reserve_quantity,
|
|
"sale_order_id": self.sale_order_id.id,
|
|
"status": 'reserved',
|
|
"move_id": rec.move_id.id
|
|
} for rec in self.stock_reservation_ids]
|
|
self.sale_order_id.write(
|
|
{'reserved_stock_ids': [(0, 0, vals) for vals in line_vals]})
|
|
if self.mail_notification_ids:
|
|
for rec in self.mail_notification_ids:
|
|
message_body = f"Dear {rec.name}," \
|
|
f"<br>We would like to inform you that, some item(s)" \
|
|
f" have been reserved for - {self.sale_order_id.name}." \
|
|
f" Please check and take necessary action if needed."
|
|
message_body += '<table border="1" cellpadding="0" bgcolor="#ededed">'
|
|
message_body += '<tr><th width="250px;">Name</th><th width="250px;">Product</th>' \
|
|
'<th width="250px;">Quantity for Reservation</th></tr>'
|
|
for reserved in self.sale_order_id.reserved_stock_ids.filtered(
|
|
lambda r: r.status == 'reserved'):
|
|
message_body += f"<tr><td>{reserved.name}</td>" \
|
|
f"<td>{reserved.product_id.name}</th>" \
|
|
f"<td>{reserved.reserved_quantity}</td></tr>"
|
|
message_body += '</table>Thank you'
|
|
template_obj = self.env['mail.mail'].create({
|
|
'subject': f"Stock Reservation: {self.sale_order_id.name}",
|
|
'body_html': message_body,
|
|
'email_from': request.env.user.company_id.email,
|
|
'email_to': rec.login
|
|
})
|
|
template_obj.send()
|
|
|
|
|
|
class StockReservation(models.TransientModel):
|
|
""" This model for storing wizard order line values."""
|
|
_name = "stock.reservation"
|
|
|
|
stock_reservation_wizard_id = fields.Many2one("sale.stock.reservation",
|
|
string="Wizard",
|
|
help="Sale stock reservation "
|
|
"wizard")
|
|
order_line_name = fields.Char(string="Order Line",
|
|
help="Name of order line")
|
|
product_id = fields.Many2one("product.product", string="Product",
|
|
help="Product to be reserved")
|
|
quantity = fields.Float(string="Quantity", help="Product quantity")
|
|
unit_of_measure_id = fields.Many2one("uom.uom", string="UOM",
|
|
help="Unit of measure")
|
|
reserve_quantity = fields.Char(string="Reserve Quantity",
|
|
help="Quantity to be reserved")
|
|
move_id = fields.Many2one("stock.move", string="Move Id",
|
|
help="Stock move")
|
|
|