diff --git a/supplier_bid_price/__init__.py b/supplier_bid_price/__init__.py new file mode 100644 index 00000000000..f7209b17100 --- /dev/null +++ b/supplier_bid_price/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import controllers diff --git a/supplier_bid_price/__manifest__.py b/supplier_bid_price/__manifest__.py new file mode 100644 index 00000000000..4416ee4b60d --- /dev/null +++ b/supplier_bid_price/__manifest__.py @@ -0,0 +1,23 @@ +{ + 'name': "Supplier Bid Price Update", + 'version': '1.0', + 'depends': ['purchase', 'website'], + 'author': "djsh", + 'category': 'Purchase', + 'description': """ +Supplier Bid Price Update from portal +""", + 'data': [ + 'security/ir.model.access.csv', + 'data/email_templates.xml', + 'views/purchase_views.xml', + 'views/portal_templates.xml' + ], + 'assets': { + 'web.assets_frontend': [ + 'supplier_bid_price/static/src/js/update_bid.js', + ], + }, + 'license': 'LGPL-3', + 'application': True, +} diff --git a/supplier_bid_price/controllers/__init__.py b/supplier_bid_price/controllers/__init__.py new file mode 100644 index 00000000000..8c3feb6f562 --- /dev/null +++ b/supplier_bid_price/controllers/__init__.py @@ -0,0 +1 @@ +from . import portal diff --git a/supplier_bid_price/controllers/portal.py b/supplier_bid_price/controllers/portal.py new file mode 100644 index 00000000000..6c58fe09e30 --- /dev/null +++ b/supplier_bid_price/controllers/portal.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import http +from odoo.http import request, Response + +class BidController(http.Controller): + + @http.route('/update_bids', type='json', auth='user', methods=['POST']) + def update_bids(self, bids): + if not bids: + return {'success': False, 'message': 'No bid data received'} + + mail_values = [] + try: + for bid in bids: + order_id = int(bid.get("order_id")) + line_id = int(bid.get("line_id")) + bid_qty = float(bid.get("bid_qty", 0)) + bid_price = float(bid.get("bid_price", 0)) + + order = request.env['purchase.order'].browse(order_id) + line = request.env['purchase.order.line'].browse(line_id) + if line.exists(): + if line.bid_qty != bid_qty or line.bid_price != bid_price: + mail_values.append({ + 'product_id' : line.product_id.sudo().name, + 'bid_qty' : bid_qty, + 'bid_price' : bid_price + }) + line.write({ + 'bid_qty': bid_qty, + 'bid_price': bid_price, + }) + order._send_bid_update_email(mail_values) + return {'success': True, 'message': 'Bids updated successfully'} + + except Exception as e: + return {'success': False, 'message': str(e)} diff --git a/supplier_bid_price/data/email_templates.xml b/supplier_bid_price/data/email_templates.xml new file mode 100644 index 00000000000..3b79cd6f069 --- /dev/null +++ b/supplier_bid_price/data/email_templates.xml @@ -0,0 +1,25 @@ + + + + Supplier Bid Update Notification + + Supplier Updated Bid Price for RFQ {{ object.name or 'n/a' }} + {{ object.company_id.email or 'info@yourcompany.com' }} + {{ object.user_id.email }} + + + + + Supplier: + RFQ Number: + + New Bid Price for : $ + New Bid Quantity for : Units + + + Action Required: Review the updated bid price in the system. + + + + + diff --git a/supplier_bid_price/models/__init__.py b/supplier_bid_price/models/__init__.py new file mode 100644 index 00000000000..13158b43600 --- /dev/null +++ b/supplier_bid_price/models/__init__.py @@ -0,0 +1,2 @@ +from . import product_order_line +from . import purchase_order diff --git a/supplier_bid_price/models/product_order_line.py b/supplier_bid_price/models/product_order_line.py new file mode 100644 index 00000000000..444724e445f --- /dev/null +++ b/supplier_bid_price/models/product_order_line.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import api, fields, models + + +class PurchaseOrderLine(models.Model): + _inherit = 'purchase.order.line' + + bid_qty = fields.Float(string="Bid Quantity", readonly=False) + bid_price = fields.Float(string="Bid Price", readonly=False) diff --git a/supplier_bid_price/models/purchase_order.py b/supplier_bid_price/models/purchase_order.py new file mode 100644 index 00000000000..ca772a9dc2c --- /dev/null +++ b/supplier_bid_price/models/purchase_order.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo import api, fields, models + + +class PurchaseOrder(models.Model): + _inherit = 'purchase.order' + + def _send_bid_update_email(self,mail_values): + if not mail_values: + return + template = self.env.ref('supplier_bid_price.email_template_supplier_bid_update').sudo() + if template: + email_ctx = { + 'mail_values' : mail_values + } + template.with_context(**email_ctx).send_mail(self.id, force_send=True) diff --git a/supplier_bid_price/security/ir.model.access.csv b/supplier_bid_price/security/ir.model.access.csv new file mode 100644 index 00000000000..e193a25ed46 --- /dev/null +++ b/supplier_bid_price/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_purchase_order_line_supplier,purchase.order.line,model_purchase_order_line,base.group_portal,1,1,0,0 +access_purchase_order_line_user,purchase.order.line,model_purchase_order_line,base.group_user,1,0,0,0 diff --git a/supplier_bid_price/static/src/js/update_bid.js b/supplier_bid_price/static/src/js/update_bid.js new file mode 100644 index 00000000000..b81da5d5c34 --- /dev/null +++ b/supplier_bid_price/static/src/js/update_bid.js @@ -0,0 +1,43 @@ +/** @odoo-module **/ +import { rpc } from "@web/core/network/rpc"; + +async function update_all_bids() { + const bid_data = [...document.querySelectorAll(".bid-qty")] + .map(input => { + const line_id = input.dataset.lineId; + return { + order_id: input.dataset.orderId, + line_id: line_id, + bid_qty: parseFloat(input.value) || 0, + bid_price: parseFloat( + document.querySelector(`.bid-price[data-line-id="${line_id}"]`)?.value || "0" + ) + }; + }) + .filter(bid => bid.bid_qty > 0 || bid.bid_price > 0); + + if (bid_data.length === 0) { + alert("No valid bids to update!"); + return; + } + try { + const response = await rpc("/update_bids", { bids: bid_data }); + if (response.success) { + alert("Bids updated successfully!"); + location.reload(); + } else { + alert("Error updating bids."); + } + } catch (error) { + alert("Failed to update bids."); + } +} + +function onClick() { + const button = document.getElementById("update_all_bids"); + if (button) { + button.addEventListener("click", update_all_bids); + } +} + +onClick(); diff --git a/supplier_bid_price/views/portal_templates.xml b/supplier_bid_price/views/portal_templates.xml new file mode 100644 index 00000000000..ed0d391555b --- /dev/null +++ b/supplier_bid_price/views/portal_templates.xml @@ -0,0 +1,38 @@ + + + + + Bid Quantity + Bid Price + + + + + + + + + + + + + + + + + + + + + + + + + + + Update Bid Quantity and Price + + + + + diff --git a/supplier_bid_price/views/purchase_views.xml b/supplier_bid_price/views/purchase_views.xml new file mode 100644 index 00000000000..2aa290049c8 --- /dev/null +++ b/supplier_bid_price/views/purchase_views.xml @@ -0,0 +1,14 @@ + + + + purchase.order.form.inherit + purchase.order + + + + + + + + +
+
Action Required: Review the updated bid price in the system.