Skip to content

Module — Procurement

The end-to-end purchasing chain: raise a Purchase Request against a project budget line, solicit quotations through an RFQ with cost/benefit (CBA) supplier analysis, issue a Purchase Order, record a Goods Received Note, and generate a Payment Order — plus the supplier (Provider) registry.

Source: NKO.Main/NKO.Main/Controllers/{PurchaseRequest,PurchaseOrder,RFQ,GRN,Providers,PaymentOrder}Controller.cs, NKO.Main/NKO.Main/BAL/{BPurchaseRequest,BPurchaseOrder,BRFQ,BGRN,BProvider,BPaymentOrder,ProcBudgetLineHandler}.cs, NKO.Lib/NKO.Shared/ViewModels/RFQ/BestPriceVM.cs.

Purpose & scope

  • In scope: PR / RFQ / PO / GRN / Payment Order documents and their material lines, CBA scoring and auto-award, provider justification, the Provider registry, and the procurement lifecycle tracker.
  • Out of scope: the step-by-step approval chains (Procurement Cycle), the budget lines the documents charge against (Grant), and putting received goods into stock (Logistics — via GRN → Transfer to Warehouse).
  • Database: NKO_DB (core), context NKO_DBEntities1.

Key features

  • Purchase Request — a multi-material request tied to a Project; each line references a procurement budget line (Materials.ProcBudgetLineId); an auto-generated FullId = branch / projectCode / seq; Excel import / export of the material template; attachments and comments; segregation-of-duty (SOD) approval tiers driven by the USD value; a PR "period" (SLA days) derived from the value.
  • RFQ — Procurement / Technical / Opening committees with managers; the quotation type (single / simple / formal / tender) is chosen automatically from the value; provider quotations with per-material pricing, sales tax, delivery & other charges and lead time; a technical assessment (Yes/No or calculation marking); the comparative analysis (CBA) with automatic winner selection; a verification passcode; threshold and committee changes; a provider justification for a non-lowest award.
  • Purchase Order — created from a winning RFQ provider (or a provider justification); PO material lines copy price and budget line from the RFQ; sequence-numbered per RFQ; a "Justification" sub-document for alternative suppliers; ProcTracker & Tracker dashboards.
  • GRN — created from an Accepted PO; copies PO material lines with a received quantity; a "Transfer to Warehouse" hand-off that writes stock / asset rows into NKO_DB_Warehouse.
  • Payment Order — created from an Accepted GRN, or entered manually (CreateManual) for a direct vendor payment (name / IBAN / method / currency).
  • Providers — a supplier registry with Excel import and a quotations history.

Screens

Route = /{Controller}/{Action}; primary screens only. Each document also has material-line add / edit / delete partials, an AddComment, attachment endpoints, and a ContextActions POST (the workflow transition — see Procurement Cycle).

PurchaseRequestController — /PurchaseRequest/*

Feature Route View Permission key
PR list /PurchaseRequest/Index PurchaseRequest/Index.cshtml PurchaseRequest
Create /PurchaseRequest/Create Create.cshtml PurchaseRequestCreate
Detail /PurchaseRequest/Details/{id} Details.cshtml PurchaseRequestDetails
Material template import / export /PurchaseRequest/ImportTemplate/{id}, /PurchaseRequest/ExportTemplate/{id} ExportTemplates/* PurchaseRequestDetails

RFQController — /RFQ/*

Feature Route View Permission key
RFQ list /RFQ/Index RFQ/Index.cshtml RFQIndex
Create / edit /RFQ/Create/{prId}, /RFQ/Edit/{id} _Create.cshtml, Edit.cshtml RFQCreate, RFQEdit
Providers & quotations /RFQ/Providers/{id}, /RFQ/ProvidersAnalyse/{id}, /RFQ/ProvidersDetails/{id} Providers*.cshtml RFQProviders, RFQProvidersAnalyse, RFQProvidersDetails
Comparative analysis (CBA) /RFQ/Compare/{id} Compare.cshtml / CompareYN.cshtml RFQProvidersAnalyse
Technical assessment / report /RFQ/TechnicalAssesment/{id}, /RFQ/TechnicalReport/{id} Technical*.cshtml RFQProvidersAnalyse
Provider justification /RFQ/SetJustification/{id} _SetJustification.cshtml RFQProvidersAnalyse
Verify (passcode) /RFQ/Verify/{id} _Verify.cshtml RFQVerify
Detail /RFQ/Details/{id} Details.cshtml RFQDetails

PurchaseOrderController — /PurchaseOrder/*

Feature Route View Permission key
PO list /PurchaseOrder/Index PurchaseOrder/Index.cshtml PurchaseOrderIndex
Create from RFQ / from justification /PurchaseOrder/Create/{id}, /PurchaseOrder/CreateJustification/{id} (redirect) PurchaseOrderCreate
Detail / sheet edit /PurchaseOrder/Details/{id}, /PurchaseOrder/SheetEdit/{id} Details.cshtml PurchaseOrderDetails
Justification queue / detail /PurchaseOrder/Justifications, /PurchaseOrder/Justification/{id} Justification*.cshtml RFQProvidersAnalyse
Procurement lifecycle tracker /PurchaseOrder/ProcTracker, /PurchaseOrder/Tracker/{id} ProcTracker.cshtml, Tracker.cshtml PurchaseOrderProcTracker, PurchaseOrderIndex

GRNController — /GRN/* · PaymentOrderController — /PaymentOrder/* · ProvidersController — /Providers/*

Feature Route View Permission key
GRN list / create from PO / detail /GRN/Index, /GRN/Create/{id}, /GRN/Details/{id} GRN/*.cshtml PurchaseOrderIndex, PurchaseOrderCreate, PurchaseOrderDetails
Transfer received goods to warehouse /GRN/TransfareToWarehouse/{id} (redirect) PurchaseOrderDetails
Payment Order list / create from GRN /PaymentOrder/Index, /PaymentOrder/Create/{id} PaymentOrder/*.cshtml PurchaseOrderIndex, PurchaseOrderCreate
Manual (direct vendor) payment /PaymentOrder/CreateManual, /PaymentOrder/EditManual/{id} CreateManual.cshtml, EditManual.cshtml PurchaseRequestCreate, PurchaseOrderEditMat
Payment Order detail /PaymentOrder/Details/{id} Details.cshtml PurchaseOrderDetails
Provider registry / quotations / import /Providers/Index, /Providers/Quotations/{id}, /Providers/ImportProviders Providers/*.cshtml RFQIndex

Business logic

Class File Responsibility & notable logic
BPurchaseRequest NKO.Main/NKO.Main/BAL/BPurchaseRequest.cs (~2290 ln) Create — status Draft; FullId from Bsettings.GetNextIncrement(Areas.PR, year, projectCode, branch); per material EstTotalPrice = EstPrice × Quantity × Duration, AreaId = Areas.PR, ProcBudgetLineId stored (no availability gate). Value thresholds (USD): SOD1 > 1 000, SOD2 > 5 000, SOD3 > 10 000, SOD4 > 100 000. Quotation type by value: ≤ 500 single, ≤ 3 000 simple, ≤ 20 000 formal, > 20 000 tender; NeedsRFQ when < 1 000; IsPONeedsGMApprove when > 250 000. CalculatePRPeriod (SLA days) — < 1 000 → 3, < 2 500 → 5, < 10 000 → 15, ≥ 10 000 → 25. UsdAmount converts non-USD via TRYRate / EURRate of the enabled ExchangeRates row. Workflow: SetSent, SetReset, SetBudgetHolder/SOD1..4/Finance/Proc Accepted/Refused, SetProcAssigned, SetCancelled, GetStatus (PRTrackerStatus).
BRFQ NKO.Main/NKO.Main/BAL/BRFQ.cs (~3840 ln — the largest) AnalysePrice — per provider builds a ProviderModel (DueAmount = Σ mat.TotalPrice), ordered cheapest-first; GetBestPrice = the lowest. CBA scoring (BestPriceVM): TechnicalMark = (100 − PricePercent) × avg(RFQProviderMats.MatMark) / 100; FinanceMark = PricePercent × (MinAmount / Amount); FinalMark = TechnicalMark + FinanceMark. SetAutoFinanceAcceptance — the scored auto-award: AutoProvider winner = max FinalMark (tie-break LeadDate), all its mats IsFinanceAccepted; AutoMat winning provider-mat = max (PriceMatMark + MatMark) where PriceMatMark = PricePercent × minMatTotal / matTotal. SetAutoFinanceAcceptanceByYesNo — Yes/No pattern picks the lowest Amount / Total. JustifyMaterials — write-back of the technical assessment; MatMark < rfq.TechSuccessPercent ⇒ IsAccepted = false. Verification: SetVerificationToken / Verify(id, passCode). Many Set*Committee1/2/3 and SetTech* workflow methods.
BPurchaseOrder NKO.Main/NKO.Main/BAL/BPurchaseOrder.cs (~1450 ln) Create(rfqProviderGuid, …) — guard: provider WinType ∈ {PartialWin, FullWin} or an Accepted RFQProviderJustification, and the RFQ Accepted (or single-quotation). Copies SaleTax / DeliveryCharge / OtherCharge from the RFQ provider; PoSeqId from GetSeqId(rfqId); builds one PurchaseOrderMat per RFQ provider-mat (BudgetLine from Materials.ProcBudgetLineId). CreateByYesNo — only mats where IsAccepted && IsExisted && IsFinanceAccepted, also copies warranty / brand / model / country-of-origin. CreateJustification. Workflow: SetReset, SetSent, SetFinance/BudgetHolder/CEO Accepted/Refused, SetCancelled.
BGRN NKO.Main/NKO.Main/BAL/BGRN.cs (~1225 ln) Create(poGuid, …) — from a PurchaseOrder; FullId = PO.FullId + "-" + PoSeqId; one GoodReceivedNoteMat per PurchaseOrderMat. TransfareToWarehouse(id, userId) — resolves BWarehouse.CurrentWarehouse and writes CenterStock + StockDetails{Entry, RealEntry} (consumables) or Asset rows (assets) into NKO_DB_Warehouse, then sets GoodReceivedNote.IsTransfareToWarehouse. Workflow: SetReset, SetSent, SetRecipient Accepted/Refused, SetCancelled.
BPaymentOrder NKO.Main/NKO.Main/BAL/BPaymentOrder.cs (~1325 ln) Create(grnGuid, …) — only if the GRN is Accepted; IsDirect = false; copies SaleTax / OtherCharge / DeliveryCharge from the PO; one PaymentOrderMat per GRN mat. CreateManual — IsDirect = true; vendor name / address / e-mail / mobile, PaymentMethodId, TransferIbanNumber, Currency; Total = Quantity × Price. Workflow: SetReset, SetSent, SetBH/Finance/CEO/Payer Accepted/Refused, SetCancelled.
BProvider NKO.Main/NKO.Main/BAL/BProvider.cs (~86 ln) GetAll, Get(guid), GetQuotations(providerId) (Accepted RFQs), UpdateMobile.
ProcBudgetLineHandler NKO.Main/NKO.Main/BAL/ProcBudgetLineHandler.cs The finance bridge — BudgetReport (per line: Accepted PR / PO / PTO / PTO-paid totals) is what the Finance BudgetLines screens show. See Grant.

Data

PurchaseRequest, PurchaseOrder, PurchaseOrderMat, RFQs, RFQMat, RFQProvider, RFQProviderMats, RFQProviderJustification, RFQJustifiedMat, RFQJustifiedProvider, RFQTechnical, GoodReceivedNote, GoodReceivedNoteMat, PaymentOrder, PaymentOrderMat, Provider, Materials (AreaId, ReferenceId, ProcBudgetLineId, EstPrice, EstTotalPrice, SeqId). BudgetLine (Grant) exposes the NotMapped Balance / IsAvailable used advisorily on the PR detail screen.

Full column detail: Procurement database.

Permissions

Distinct keys: PurchaseRequest, PurchaseRequestCreate, PurchaseRequestAddMat, PurchaseRequestEditMat, PurchaseRequestDeleteMat, PurchaseRequestDelete, PurchaseRequestEdit, PurchaseRequestDetails, PurchaseRequestAddComment, PurchaseOrderIndex, PurchaseOrderCreate, PurchaseOrderDetails, PurchaseOrderEdit, PurchaseOrderEditMat, PurchaseOrderDelete, PurchaseOrderDeleteMat, PurchaseOrderProcTracker, RFQIndex, RFQCreate, RFQEdit, RFQEditProvider, RFQDetails, RFQProviders, RFQProvidersAnalyse, RFQProvidersDetails, RFQVerify. Data scoping: SharedPermissions.{PR = 4, PO = 13}. Every workflow action first requires an approved e-signature (BSign.HasSign) — except the provider-justification step, /PurchaseOrder/JustificationContextActions, which does not check it (R3-9).

Screenshots

PR list, lifecycle tracker, and the PO / Payment-Order signature timelines (/PurchaseRequest, /PurchaseOrder/Tracker, /PurchaseOrder/Details, /PaymentOrder/Details):

PR list with status tiles Procurement lifecycle tracker PO signature timeline — part 1 part 2 part 3 part 4 Payment Order signature timeline — part 1 part 2 part 3

Purchase Orders — /PurchaseOrder:

Purchase Order list

RFQs — /RFQ?type=2 (the bare /RFQ shows an empty state; pick Open or Closed — see Recommendations R7-11):

RFQ list

Goods Received Notes — /GRN ("Prepared By" name masked):

GRN list

Supplier registry — /Providers (contact name / e-mail / phone / address masked; ~520 suppliers across 26 pages):

Suppliers list