Real-time competitive bidding with SignalR WebSocket, auto-extension, vendor ranking, and bid validation for cost optimization through dynamic price discovery.
The Reverse Auction module enables competitive real-time bidding among vendors where they compete by lowering their prices. The system provides live updates via SignalR WebSocket connections, ensuring all participants see bids in real-time.
| Status | Code | Description | Allowed Actions |
|---|---|---|---|
| DRAFT | 0 | Auction created but not yet scheduled | Edit, Delete, Schedule |
| SCHEDULED | 1 | Auction scheduled, vendors notified | Modify (before start), Cancel |
| ACTIVE | 2 | Live auction in progress | View Only, Auto-Extend |
| EXTENDED | 3 | Auction extended due to last-minute bid | View Only, Auto-Extend Again |
| COMPLETED | 4 | Auction ended, results available | View Results, Shortlist, Award |
| CANCELLED | 5 | Auction terminated before completion | View Only |
| NO_PARTICIPATION | 6 | No vendors participated | Restart, Cancel |
| RESERVE_NOT_MET | 7 | Lowest bid above reserve price | Negotiate, Cancel |
public class ChatHub : Hub { // Called when a vendor submits a new bid [HubMethodName("sendBid")] public void SendBid() { IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ChatHub>(); context.Clients.All.updatedData(); // Broadcast to all } // Called for general data updates (rank changes, time extensions) [HubMethodName("sendData")] public void SendData() { IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ChatHub>(); context.Clients.All.send(); } }
// Initialize SignalR connection var hubNotif = $.connection.chatHub; // Handle real-time bid updates hubNotif.client.updatedData = function() { $.ajax({ url: RootUrl + 'ReverseAuction/VendorLiveRA', data: { RASlno: RASlno, SignalRChat: "true" }, success: function(data) { $('#vendorRank').text(data.InitialRank); // Update rank $('#RAToMinute').val(data.ToTimeMinutes); // Update time if extended } }); }; // Start connection and submit bids $.connection.hub.start().done(function() { $("#btn_save").click(function() { $.ajax({ url: RootUrl + 'ReverseAuction/VendorLiveRA', type: 'POST', data: formData, success: function() { hubNotif.server.sendBid(); // Broadcast to all hubNotif.server.sendData(); } }); }); });
At least 2 shortlisted vendors required to create reverse auction
New quote must be lower than current lowest bid
Must meet minimum decrement requirement (percentage or fixed amount)
Quotes are locked after auction deadline (unless extended)
Terms & Conditions acceptance is mandatory before quoting
function validateDiscount(discountType, discountValue, initialBid, minDecrement) { if (discountType === 'P') { // Percentage-based if (discountValue < minDecrement || discountValue >= 100) { return { valid: false, error: `Discount must be >= ${minDecrement}% and < 100%` }; } var newBidPrice = initialBid - (initialBid * discountValue / 100); } else if (discountType === 'A') { // Amount-based if (discountValue < minDecrement || discountValue >= initialBid) { return { valid: false, error: `Discount must be >= ${minDecrement} and < ${initialBid}` }; } var newBidPrice = initialBid - discountValue; } return { valid: true, newBidPrice: newBidPrice }; }
| Table | Schema | Purpose | Key Columns |
|---|---|---|---|
reverse_auctions |
procurement | Auction header with configuration | auction_id, rfq_id, start_time, end_time, min_decrement |
auction_participants |
procurement | Vendor participation tracking | auction_id, vendor_id, terms_accepted, final_rank |
auction_bids |
procurement | Individual bid submissions | auction_id, vendor_id, bid_amount, bid_time, bid_sequence |
auction_line_items |
procurement | Items being auctioned | auction_id, product_id, quantity, starting_price |
rfqs |
procurement | Source RFQ (rfq_type = 'REVERSE_AUCTION') | rfq_id, rfq_type, is_sealed_bid, submission_deadline |
| Procedure Name | Purpose | Key Parameters |
|---|---|---|
PROC_INSERT_TReverseAuction |
Create new reverse auction | ReverseAuctionNo, RADate, TargetPrice, MinDiscount |
PROC_INSERT_TVENDORRA |
Insert vendor bid during live auction | RASlno, VendorSlno, InitialBid, DiscountPer, NewBidPrice |
PROC_UPDATE_TOTIME |
Extend auction end time | RADate, ToTimeHour, ToTimeMinute, RASlno |
PROC_SELECT_VENDORDETAILSSUMMARY |
Get all vendor bids for ranking | RASlno |
PROC_MODIFY_TRAAcceptPaymentsTerms |
Record vendor T&C acceptance | RASlno, VendorSlno |
PROC_SELECT_LiveRAList |
Get list of active/live auctions | PageNumber, PageSize, SearchText |