Feature Specification: Intelligent Supplier & Vendor Management

Overview

Feature Name: AI-Powered Supplier & Vendor Management System
Category: Procurement Intelligence (Phase 2)
Priority: High
Target Users: CFOs, Procurement Managers, Controllers, Category Managers
Dependencies: Procurement & Spend Control, Document & Contract Management V1, AI Invoice Processing


Executive Summary

Transform supplier relationships from reactive invoice processing to proactive strategic management. By combining invoice data, contract intelligence, and AI analysis, Orcha provides a complete 360° view of every supplier relationship—enabling procurement teams to optimize costs, reduce risks, and leverage buying power.

The Breakthrough:

Value Proposition:

"Know everything about every supplier: what you're paying, what you should be paying, when to renegotiate, and how much you can save. All powered by AI that reads your contracts and analyzes your spend patterns."


Business Problem

The Current State: Blind Supplier Relationships

What Companies Do Today:

  1. Contract Chaos

  2. Missed Savings Opportunities

  3. Reactive Renewal Management

  4. Limited Supplier Intelligence

Pain Points:


Solution: Intelligent Supplier Management System

What We Build

A comprehensive supplier intelligence platform that:

  1. AI Contract Analysis - Automatically extracts critical clauses from contracts
  2. Discount Tracking - Monitors proximity to volume/tier discounts
  3. Renewal Management - Predicts renewals 90+ days in advance
  4. Compliance Monitoring - Validates every invoice against contract terms
  5. Performance Scoring - Quantifies supplier reliability and value
  6. Risk Management - Identifies concentration and dependency risks
  7. Savings Identification - Surfaces optimization opportunities

Core Features

1. Supplier Master Data Management

Centralized Supplier Profile:

┌────────────────────────────────────────────────────────────────┐
│  SUPPLIER: Acme Office Supplies GmbH                           │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  📊 OVERVIEW                                                    │
│  ├─ Annual Spend: €245,000 (Rank: #12 of 215 suppliers)       │
│  ├─ Active Contracts: 2 (MSA + SaaS Subscription)             │
│  ├─ Invoices YTD: 147                                          │
│  ├─ Payment Terms: Net 30                                      │
│  ├─ Primary Contact: Johann Schmidt (johann@acme.de)           │
│  └─ Relationship Start: January 2019 (5 years)                 │
│                                                                │
│  🎯 PERFORMANCE SCORE: 87/100                                   │
│  ├─ On-Time Delivery: 94% (Target: 95%)                        │
│  ├─ Invoice Accuracy: 96% (Target: 98%)                        │
│  ├─ Contract Compliance: 92% (Target: 95%)                     │
│  ├─ Response Time: 4.2 hours avg (Target: 8 hours)             │
│  └─ Trend: ↑ +3 points vs last quarter                         │
│                                                                │
│  ⚠️  ALERTS (3)                                                 │
│  • Contract renewal in 67 days (Action required)               │
│  • €12,450 from next volume discount tier                      │
│  • 3 invoices exceeded contract pricing this month             │
│                                                                │
│  💰 SAVINGS OPPORTUNITIES (€18,500 identified)                  │
│  ├─ Volume consolidation: €8,500/year                          │
│  ├─ Early payment discount: €6,000/year                        │
│  ├─ Contract renegotiation: €4,000/year                        │
│  └─ Alternative sourcing: Evaluate 2 competitors               │
│                                                                │
│  [View Contracts] [View Invoices] [Contact Manager]            │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Data Model:

CREATE TABLE suppliers (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES tenants(id),
  
  -- Basic Info
  name TEXT NOT NULL,
  legal_name TEXT,
  tax_id TEXT, -- VAT number / Tax ID
  duns_number TEXT, -- D&B identifier
  
  -- Contact
  primary_contact_name TEXT,
  primary_contact_email TEXT,
  primary_contact_phone TEXT,
  website TEXT,
  
  -- Address
  street_address TEXT,
  city TEXT,
  postal_code TEXT,
  country TEXT DEFAULT 'DE',
  
  -- Classification
  category TEXT[], -- ['IT Services', 'Cloud Infrastructure']
  tags TEXT[], -- Custom tags
  tier TEXT, -- 'Strategic', 'Preferred', 'Approved', 'Restricted'
  
  -- Financial
  payment_terms TEXT, -- 'Net 30', 'Net 45', '2/10 Net 30'
  currency TEXT DEFAULT 'EUR',
  credit_limit DECIMAL(15,2),
  
  -- Relationship
  relationship_start_date DATE,
  relationship_manager_id UUID REFERENCES users(id),
  status TEXT DEFAULT 'active', -- 'active', 'inactive', 'blocked'
  
  -- Performance (cached aggregates)
  performance_score DECIMAL(5,2), -- 0-100
  annual_spend_current DECIMAL(15,2),
  annual_spend_prior DECIMAL(15,2),
  invoice_count_ytd INTEGER,
  
  -- Risk
  risk_score DECIMAL(5,2), -- 0-100 (higher = riskier)
  risk_factors JSONB, -- {'single_source': true, 'financial_risk': false}
  
  -- Metadata
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW(),
  created_by UUID REFERENCES users(id),
  updated_by UUID REFERENCES users(id)
);

CREATE INDEX idx_suppliers_tenant ON suppliers(tenant_id);
CREATE INDEX idx_suppliers_category ON suppliers USING GIN(category);
CREATE INDEX idx_suppliers_status ON suppliers(status);
CREATE INDEX idx_suppliers_tier ON suppliers(tier);

2. AI-Powered Contract Analysis

Automatically Extract Critical Clauses:

A. Contract Ingestion

Upload & OCR:

(defn ingest-contract
  "Process uploaded contract PDF"
  [supplier-id file-data]
  (let [;; 1. OCR + AI extraction
        extracted-text (google-document-ai/extract-text file-data)
        
        ;; 2. Claude AI analyzes contract
        contract-analysis (claude/analyze-contract
                            {:text extracted-text
                             :supplier-name (get-supplier-name supplier-id)
                             :extract-clauses [
                               :pricing
                               :volume-discounts
                               :payment-terms
                               :renewal-terms
                               :termination-clauses
                               :slas
                               :price-adjustment-clauses
                               :delivery-terms
                               :warranties
                               :liability-caps]})
        
        ;; 3. Store structured contract
        contract-id (db/insert :contracts
                               {:supplier-id supplier-id
                                :file-url (upload-to-s3 file-data)
                                :contract-type (:type contract-analysis)
                                :effective-date (:effective-date contract-analysis)
                                :expiry-date (:expiry-date contract-analysis)
                                :status "active"})
        
        ;; 4. Store extracted clauses
        (doseq [clause (:clauses contract-analysis)]
          (db/insert :contract-clauses
                     {:contract-id contract-id
                      :clause-type (:type clause)
                      :clause-text (:text clause)
                      :extracted-values (:values clause)
                      :confidence-score (:confidence clause)}))]
    
    {:contract-id contract-id
     :clauses-extracted (count (:clauses contract-analysis))
     :analysis contract-analysis}))

B. Critical Clause Identification

AI Prompt for Clause Extraction:

You are a procurement analyst extracting critical commercial terms from a supplier contract.

CONTRACT TEXT:
{{CONTRACT_TEXT}}

SUPPLIER: {{SUPPLIER_NAME}}

Extract the following clause types and provide structured data:

1. PRICING CLAUSES
   - Base pricing (unit prices, rates)
   - Volume discount tiers (thresholds and discount percentages)
   - Early payment discounts (e.g., "2% if paid within 10 days")
   - Price adjustment mechanisms (CPI indexation, annual increases)
   - Most Favored Customer clauses

2. VOLUME DISCOUNTS
   - Tier 1: Spend threshold + discount %
   - Tier 2: Spend threshold + discount %
   - Tier 3: Spend threshold + discount %
   - Calculation period (monthly, quarterly, annually)
   - Retroactive vs progressive discounts

3. RENEWAL TERMS
   - Initial term length
   - Renewal term length
   - Auto-renewal clause (yes/no)
   - Notice period for cancellation (days before expiry)
   - Price increase caps on renewal

4. TERMINATION CLAUSES
   - Termination for convenience (notice period)
   - Termination for cause (conditions)
   - Early termination fees
   - Wind-down obligations

5. PAYMENT TERMS
   - Standard payment terms (Net X days)
   - Early payment discount options
   - Late payment penalties
   - Payment method requirements

6. SERVICE LEVEL AGREEMENTS (SLAs)
   - Delivery time commitments
   - Quality standards
   - Response time requirements
   - Penalties for non-performance

7. PRICE PROTECTION
   - Price freeze periods
   - Maximum annual increase (% cap)
   - Price decrease triggers (e.g., raw material costs)

8. MINIMUM COMMITMENTS
   - Minimum order quantities
   - Minimum annual spend
   - Consequences of not meeting minimums

Output as JSON with exact values extracted:
{
  "pricing": {...},
  "volume_discounts": [...],
  "renewal_terms": {...},
  "termination": {...},
  "payment_terms": {...},
  "slas": [...],
  "price_protection": {...},
  "minimum_commitments": {...}
}

C. Clause Storage & Tracking

Data Model:

CREATE TABLE contracts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES tenants(id),
  supplier_id UUID NOT NULL REFERENCES suppliers(id),
  
  -- Document
  contract_number TEXT UNIQUE,
  contract_name TEXT NOT NULL,
  contract_type TEXT NOT NULL, -- 'MSA', 'SaaS', 'Framework', 'Spot'
  file_url TEXT NOT NULL, -- S3 URL to PDF
  
  -- Dates
  effective_date DATE NOT NULL,
  expiry_date DATE,
  renewal_date DATE,
  notice_period_days INTEGER, -- Days before expiry to give notice
  auto_renews BOOLEAN DEFAULT FALSE,
  
  -- Financial
  total_contract_value DECIMAL(15,2),
  annual_value DECIMAL(15,2),
  currency TEXT DEFAULT 'EUR',
  
  -- Status
  status TEXT DEFAULT 'active', -- 'draft', 'active', 'expired', 'terminated'
  
  -- Tracking
  next_review_date DATE,
  renewal_alert_sent BOOLEAN DEFAULT FALSE,
  
  -- Metadata
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW(),
  created_by UUID REFERENCES users(id)
);

CREATE TABLE contract_clauses (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  contract_id UUID NOT NULL REFERENCES contracts(id),
  
  -- Clause Type
  clause_type TEXT NOT NULL, -- 'pricing', 'volume_discount', 'renewal', etc.
  clause_category TEXT, -- 'commercial', 'legal', 'operational'
  
  -- Content
  clause_text TEXT NOT NULL, -- Original contract text
  clause_summary TEXT, -- AI-generated summary
  
  -- Extracted Structured Data
  extracted_values JSONB NOT NULL,
  /*
  Example for volume_discount:
  {
    "tiers": [
      {"threshold": 50000, "discount_pct": 5, "currency": "EUR"},
      {"threshold": 100000, "discount_pct": 10, "currency": "EUR"},
      {"threshold": 250000, "discount_pct": 15, "currency": "EUR"}
    ],
    "period": "annual",
    "type": "progressive"
  }
  */
  
  -- Importance & Confidence
  importance_score DECIMAL(3,2), -- 0-1 (AI-scored criticality)
  confidence_score DECIMAL(3,2), -- 0-1 (extraction confidence)
  
  -- Monitoring
  is_monitored BOOLEAN DEFAULT TRUE,
  compliance_status TEXT, -- 'compliant', 'non-compliant', 'at-risk'
  
  -- Metadata
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_clauses_contract ON contract_clauses(contract_id);
CREATE INDEX idx_clauses_type ON contract_clauses(clause_type);
CREATE INDEX idx_clauses_monitored ON contract_clauses(is_monitored) WHERE is_monitored = TRUE;

3. Discount Tracking & Proximity Alerts

Monitor All Discount Types:

A. Volume Discount Tracking

Real-Time Spend Aggregation:

(defn check-volume-discount-proximity
  "Check how close supplier spend is to next discount tier"
  [supplier-id]
  (let [;; Get active volume discount clauses
        discount-clauses (db/query
                           ["SELECT * FROM contract_clauses
                             WHERE contract_id IN (
                               SELECT id FROM contracts 
                               WHERE supplier_id = ? 
                               AND status = 'active'
                             )
                             AND clause_type = 'volume_discount'"
                            supplier-id])
        
        ;; Calculate current spend (by period defined in contract)
        current-spend (calculate-current-spend supplier-id)
        
        ;; For each tier, calculate proximity
        proximity-alerts (for [clause discount-clauses
                               :let [tiers (get-in clause [:extracted-values :tiers])
                                     period (get-in clause [:extracted-values :period])]]
                           (calculate-tier-proximity current-spend tiers period))]
    
    (filter :alert proximity-alerts)))

(defn calculate-tier-proximity
  [current-spend tiers period]
  (let [;; Find next tier above current spend
        next-tier (first (filter #(> (:threshold %) current-spend) 
                                 (sort-by :threshold tiers)))
        
        ;; Calculate distance
        distance (when next-tier
                   (- (:threshold next-tier) current-spend))
        
        ;; Calculate % to next tier
        progress-pct (when next-tier
                       (* 100 (/ current-spend (:threshold next-tier))))]
    
    (when (and next-tier (< distance (* (:threshold next-tier) 0.15))) ;; Within 15%
      {:alert true
       :type :volume-discount-proximity
       :current-spend current-spend
       :next-threshold (:threshold next-tier)
       :distance distance
       :progress-pct progress-pct
       :potential-discount-pct (:discount-pct next-tier)
       :potential-savings (* current-spend (/ (:discount-pct next-tier) 100))
       :message (format "You're €%,.0f from %d%% volume discount (%.1f%% there)"
                       distance
                       (:discount-pct next-tier)
                       progress-pct)})))

Alert Examples:

┌────────────────────────────────────────────────────────────────┐
│  🎯 VOLUME DISCOUNT PROXIMITY ALERTS                           │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  Acme Office Supplies                                          │
│  Current Spend: €87,500 (Jan 1 - Dec 31, 2026)                │
│                                                                │
│  Next Tier: €100,000 (10% discount)                            │
│  Distance: €12,500 (87.5% there)                               │
│  Potential Savings: €10,000/year                               │
│                                                                │
│  💡 RECOMMENDATION:                                             │
│  Consolidate orders to reach tier. Current pace: 3.2 months   │
│  to threshold. Consider accelerating €12,500 in planned       │
│  purchases to capture discount.                                │
│                                                                │
│  [View Spend Breakdown] [Simulate Consolidation]               │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  IT Services GmbH                                              │
│  Current Spend: €232,000 (Q1-Q3 2026)                         │
│                                                                │
│  Next Tier: €250,000 (15% discount)                            │
│  Distance: €18,000 (92.8% there)                               │
│  Potential Savings: €37,500/year                               │
│                                                                │
│  ⚠️  URGENT: Only 2 months left in annual period!              │
│                                                                │
│  💡 RECOMMENDATION:                                             │
│  You'll likely cross threshold naturally. Lock in pricing     │
│  now by pre-committing to €250K annual spend.                 │
│                                                                │
│  [Negotiate Pre-Commitment] [View Forecast]                    │
│                                                                │
└────────────────────────────────────────────────────────────────┘

B. Early Payment Discount Tracking

Identify Uncaptured Discounts:

-- Query for available early payment discounts
SELECT 
  s.name as supplier_name,
  COUNT(*) as eligible_invoices,
  SUM(i.amount) as total_eligible_amount,
  cc.extracted_values->>'discount_pct' as discount_pct,
  cc.extracted_values->>'payment_days' as early_payment_days,
  (SUM(i.amount) * (cc.extracted_values->>'discount_pct')::numeric / 100) as potential_savings,
  AVG(i.payment_date - i.invoice_date) as avg_days_to_pay
FROM invoices i
JOIN suppliers s ON i.supplier_id = s.id
JOIN contracts c ON c.supplier_id = s.id AND c.status = 'active'
JOIN contract_clauses cc ON cc.contract_id = c.id 
WHERE cc.clause_type = 'early_payment_discount'
  AND i.status = 'approved'
  AND i.payment_date IS NULL
  AND (CURRENT_DATE - i.invoice_date) < (cc.extracted_values->>'payment_days')::integer
GROUP BY s.id, s.name, cc.extracted_values
ORDER BY potential_savings DESC;

Dashboard Widget:

┌────────────────────────────────────────────────────────────────┐
│  💰 UNCAPTURED EARLY PAYMENT DISCOUNTS                         │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  This Month: €8,450 available (23 invoices)                   │
│  YTD Captured: €34,200 (42% of available)                     │
│  YTD Missed: €47,300 (58% missed)                             │
│                                                                │
│  TOP OPPORTUNITIES:                                            │
│                                                                │
│  1. Office Supplies Co - €45,000 eligible                     │
│     • 2% discount for payment within 10 days                  │
│     • Potential: €900/invoice                                  │
│     • Current avg payment: 28 days (too slow)                 │
│     [Enable Auto Early Payment]                                │
│                                                                │
│  2. IT Hardware GmbH - €32,000 eligible                       │
│     • 1.5% discount for payment within 7 days                 │
│     • Potential: €480/invoice                                  │
│     • Current avg payment: 35 days                            │
│     [Review Cash Flow]                                         │
│                                                                │
└────────────────────────────────────────────────────────────────┘

C. Promotional & Seasonal Discount Tracking

Track Limited-Time Offers:

CREATE TABLE promotional_discounts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  supplier_id UUID NOT NULL REFERENCES suppliers(id),
  
  -- Offer Details
  promotion_name TEXT NOT NULL,
  discount_type TEXT NOT NULL, -- 'percentage', 'fixed_amount', 'tiered'
  discount_value DECIMAL(10,2) NOT NULL,
  
  -- Validity
  valid_from DATE NOT NULL,
  valid_to DATE NOT NULL,
  
  -- Conditions
  minimum_order_value DECIMAL(15,2),
  applicable_categories TEXT[],
  applicable_products TEXT[],
  max_usage_count INTEGER,
  current_usage_count INTEGER DEFAULT 0,
  
  -- Tracking
  estimated_savings DECIMAL(15,2),
  actual_savings DECIMAL(15,2) DEFAULT 0,
  
  created_at TIMESTAMP DEFAULT NOW()
);

4. Renewal Date Management & Alerts

Predictive Renewal Intelligence:

A. Renewal Calendar

90-Day Advance Warning System:

(defn generate-renewal-alerts
  "Generate renewal alerts for contracts expiring in next 90 days"
  []
  (let [contracts-expiring (db/query
                             ["SELECT c.*, s.name as supplier_name,
                                      c.expiry_date,
                                      c.notice_period_days,
                                      c.auto_renews,
                                      (c.expiry_date - c.notice_period_days) as notice_deadline,
                                      CURRENT_DATE as today
                               FROM contracts c
                               JOIN suppliers s ON c.supplier_id = s.id
                               WHERE c.status = 'active'
                               AND c.expiry_date BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL '90 days'
                               AND c.renewal_alert_sent = FALSE
                               ORDER BY c.expiry_date"])]
    
    (for [contract contracts-expiring
          :let [days-to-expiry (days-between (:today contract) (:expiry-date contract))
                days-to-notice (days-between (:today contract) (:notice-deadline contract))
                urgency (calculate-urgency days-to-expiry days-to-notice)
                spend-history (get-supplier-spend-history (:supplier-id contract))
                performance (get-supplier-performance (:supplier-id contract))
                market-intel (get-market-intelligence (:supplier-id contract))]]
      
      {:contract-id (:id contract)
       :supplier-name (:supplier-name contract)
       :expiry-date (:expiry-date contract)
       :days-to-expiry days-to-expiry
       :days-to-notice days-to-notice
       :urgency urgency
       :auto-renews (:auto-renews contract)
       :annual-spend (:annual-value contract)
       :recommendation (generate-renewal-recommendation 
                         contract 
                         spend-history 
                         performance 
                         market-intel)})))

(defn generate-renewal-recommendation
  [contract spend-history performance market-intel]
  (let [spend-trend (:trend spend-history) ;; :increasing, :stable, :decreasing
        perf-score (:score performance) ;; 0-100
        market-rate (:competitive-rate market-intel) ;; comparison to market]
    
    (cond
      ;; High value, good performance → Renew but negotiate better terms
      (and (> (:annual-value contract) 100000)
           (> perf-score 85))
      {:action "renew-and-negotiate"
       :priority "high"
       :message "High-value supplier with strong performance. Leverage volume for better terms."
       :negotiation-points ["Request 5-10% price reduction"
                           "Add volume discount tiers"
                           "Extend payment terms to Net 45"
                           "Lock pricing for 2 years"]}
      
      ;; Low performance → Consider alternatives
      (< perf-score 70)
      {:action "evaluate-alternatives"
       :priority "medium"
       :message "Performance below threshold. Evaluate competitive options."
       :negotiation-points ["Address performance issues"
                           "Add SLA penalties"
                           "Shorten initial renewal term (6-12 months)"
                           "RFP to 2-3 alternatives"]}
      
      ;; Decreasing spend → Renegotiate or exit
      (= spend-trend :decreasing)
      {:action "renegotiate-or-exit"
       :priority "low"
       :message "Spend declining. Renegotiate for lower commitment or exit."
       :negotiation-points ["Remove minimum commitment"
                           "Switch to pay-per-use"
                           "Negotiate exit without penalty"]}
      
      ;; Auto-renewal approaching notice deadline → Urgent decision
      (and (:auto-renews contract)
           (< (days-between (now) (:notice-deadline contract)) 14))
      {:action "urgent-decision-required"
       :priority "critical"
       :message "Auto-renewal in 14 days! Decide: Renew, Renegotiate, or Cancel."
       :negotiation-points ["Send cancellation notice immediately if not renewing"
                           "Request 30-day extension to evaluate"
                           "Negotiate better terms before renewal"]}
      
      :else
      {:action "standard-renewal"
       :priority "medium"
       :message "Standard renewal process. Review terms and confirm."
       :negotiation-points ["CPI-linked price increases only"
                           "Maintain current terms"
                           "Add early exit clause"]})))

B. Renewal Dashboard

┌────────────────────────────────────────────────────────────────┐
│  📅 CONTRACT RENEWAL DASHBOARD                                 │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  URGENT (Next 30 Days) - 4 Contracts                           │
│                                                                │
│  🔴 Microsoft 365 Business - Expires in 12 days                │
│     Annual Value: €45,000 | Auto-Renews: YES                  │
│     Notice Deadline: PASSED (8 days ago)                       │
│     ⚠️  CRITICAL: Will auto-renew unless canceled by Jan 17    │
│     Performance: 92/100 | Spend Trend: ↑ +8%                   │
│                                                                │
│     💡 RECOMMENDATION: Renew but negotiate                      │
│     • Usage up 15% - justify volume discount                  │
│     • Lock 2-year pricing (avoid annual increases)            │
│     • Add Microsoft Teams Phone (better bundle rate)          │
│                                                                │
│     [Cancel Renewal] [Negotiate Terms] [Auto-Renew]            │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  🟡 Office Supplies Framework - Expires in 28 days             │
│     Annual Value: €85,000 | Auto-Renews: NO                   │
│     Notice Deadline: N/A                                       │
│     Performance: 78/100 | Spend Trend: → Stable               │
│                                                                │
│     💡 RECOMMENDATION: Evaluate alternatives                    │
│     • Performance below target (late deliveries: 12%)         │
│     • Prices 8% above market average                          │
│     • RFP to 3 competitors (draft ready)                      │
│                                                                │
│     [Send RFP] [Renegotiate] [Extend 90 Days]                  │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  UPCOMING (31-60 Days) - 7 Contracts                           │
│  FUTURE (61-90 Days) - 12 Contracts                            │
│                                                                │
│  [View All] [Export Calendar] [Set Reminders]                  │
│                                                                │
└────────────────────────────────────────────────────────────────┘

C. Negotiation Intelligence

AI-Powered Negotiation Insights:

(defn generate-negotiation-intel
  "Generate data-backed negotiation talking points"
  [contract-id]
  (let [contract (db/get-contract contract-id)
        supplier-id (:supplier-id contract)
        
        ;; Historical spend analysis
        spend-history (db/query
                        ["SELECT 
                            DATE_TRUNC('year', invoice_date) as year,
                            SUM(amount) as total_spend,
                            COUNT(*) as invoice_count,
                            AVG(amount) as avg_invoice_amount
                          FROM invoices
                          WHERE supplier_id = ?
                          GROUP BY DATE_TRUNC('year', invoice_date)
                          ORDER BY year DESC
                          LIMIT 3"
                         supplier-id])
        
        ;; Performance metrics
        performance (calculate-supplier-performance supplier-id)
        
        ;; Market intelligence
        market-data (get-market-benchmarks (:category contract))
        
        ;; Generate talking points
        talking-points (generate-talking-points 
                         contract 
                         spend-history 
                         performance 
                         market-data)]
    
    {:contract contract
     :spend-history spend-history
     :performance performance
     :market-data market-data
     :talking-points talking-points
     :suggested-terms (generate-suggested-terms contract spend-history)}))

(defn generate-talking-points
  [contract spend-history performance market-data]
  (let [current-spend (-> spend-history first :total-spend)
        prior-spend (-> spend-history second :total-spend)
        spend-growth (/ (- current-spend prior-spend) prior-spend)]
    
    [{:category "Volume Leverage"
      :strength (if (> spend-growth 0.1) :high :medium)
      :message (format "Our spend increased %.1f%% to €%,.0f this year. We expect continued growth and should receive volume pricing."
                      (* spend-growth 100)
                      current-spend)
      :ask "Request 5-10% volume discount for spend > €100K"}
     
     {:category "Performance Issues"
      :strength (if (< (:on-time-pct performance) 0.95) :high :low)
      :message (format "On-time delivery at %.1f%% (target: 95%%). This impacts our operations."
                      (* 100 (:on-time-pct performance)))
      :ask "Add SLA penalties: 2% credit for each late delivery"}
     
     {:category "Market Benchmarking"
      :strength (if (> (:price-vs-market market-data) 1.05) :high :low)
      :message (format "Your pricing is %.1f%% above market average for similar services."
                      (* 100 (- (:price-vs-market market-data) 1)))
      :ask "Match market rates or justify premium with value-adds"}
     
     {:category "Payment Terms"
      :strength :medium
      :message "We have strong payment history (98% on-time). Our cash position supports early payment."
      :ask "Offer 2% discount for payment within 10 days"}
     
     {:category "Contract Length"
      :strength :medium
      :message "Willing to commit to 2-year term for price certainty."
      :ask "Lock pricing for 24 months (no annual increases)"}]))

5. Supplier Performance Scoring

Comprehensive Performance Metrics:

A. Performance Scorecard

CREATE TABLE supplier_performance_metrics (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  supplier_id UUID NOT NULL REFERENCES suppliers(id),
  measurement_period TEXT NOT NULL, -- '2026-Q1', '2026-01', etc.
  
  -- Delivery Performance
  on_time_delivery_pct DECIMAL(5,2), -- % of orders delivered on-time
  early_delivery_pct DECIMAL(5,2),
  late_delivery_pct DECIMAL(5,2),
  avg_delivery_days DECIMAL(8,2),
  
  -- Quality Metrics
  invoice_accuracy_pct DECIMAL(5,2), -- % of invoices without errors
  dispute_rate DECIMAL(5,2), -- Disputes per 100 invoices
  rejection_rate DECIMAL(5,2), -- % of deliveries rejected
  
  -- Compliance
  contract_compliance_pct DECIMAL(5,2), -- % invoices compliant with contract
  price_compliance_pct DECIMAL(5,2), -- % invoices at contract pricing
  terms_compliance_pct DECIMAL(5,2), -- % invoices with correct payment terms
  
  -- Responsiveness
  avg_response_time_hours DECIMAL(8,2), -- Response to inquiries
  avg_resolution_time_hours DECIMAL(8,2), -- Resolution of issues
  
  -- Financial
  total_spend DECIMAL(15,2),
  invoice_count INTEGER,
  avg_invoice_amount DECIMAL(15,2),
  early_payment_discounts_captured DECIMAL(15,2),
  
  -- Composite Score
  overall_score DECIMAL(5,2), -- 0-100 weighted score
  
  -- Metadata
  calculated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_perf_supplier_period ON supplier_performance_metrics(supplier_id, measurement_period);

Performance Calculation:

(defn calculate-supplier-performance
  "Calculate comprehensive performance score"
  [supplier-id period]
  (let [;; Raw metrics
        delivery-metrics (calculate-delivery-metrics supplier-id period)
        quality-metrics (calculate-quality-metrics supplier-id period)
        compliance-metrics (calculate-compliance-metrics supplier-id period)
        responsiveness-metrics (calculate-responsiveness-metrics supplier-id period)
        
        ;; Weighted scoring (0-100)
        delivery-score (* 0.30 (:on-time-pct delivery-metrics))
        quality-score (* 0.25 (:accuracy-pct quality-metrics))
        compliance-score (* 0.25 (:compliance-pct compliance-metrics))
        responsiveness-score (* 0.20 (:responsiveness-pct responsiveness-metrics))
        
        overall-score (+ delivery-score quality-score 
                        compliance-score responsiveness-score)]
    
    {:period period
     :delivery-metrics delivery-metrics
     :quality-metrics quality-metrics
     :compliance-metrics compliance-metrics
     :responsiveness-metrics responsiveness-metrics
     :overall-score overall-score
     :rating (cond
               (>= overall-score 90) "Excellent"
               (>= overall-score 80) "Good"
               (>= overall-score 70) "Acceptable"
               (>= overall-score 60) "Needs Improvement"
               :else "Unacceptable")
     :trend (calculate-trend supplier-id overall-score)}))

B. Performance Dashboard

┌────────────────────────────────────────────────────────────────┐
│  SUPPLIER PERFORMANCE: Acme Office Supplies                    │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  OVERALL SCORE: 87/100 (Good) ↑ +3 vs last quarter            │
│                                                                │
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │
│                                                                │
│  📦 DELIVERY PERFORMANCE (30% weight) - Score: 92/100          │
│  ├─ On-Time Delivery: 94.2% (Target: ≥95%) ⚠️                  │
│  ├─ Average Delivery: 3.2 days (Target: ≤3 days)               │
│  ├─ Late Deliveries: 8 orders (5.8%)                           │
│  └─ Trend: ↑ Improving (+2.1% vs Q3)                           │
│                                                                │
│  📋 QUALITY METRICS (25% weight) - Score: 88/100               │
│  ├─ Invoice Accuracy: 96.3% (Target: ≥98%) ⚠️                  │
│  ├─ Disputes: 3 this quarter (2.2% rate)                       │
│  ├─ Common Errors: Missing PO number (5 invoices)              │
│  └─ Trend: → Stable                                            │
│                                                                │
│  ✅ COMPLIANCE (25% weight) - Score: 91/100                     │
│  ├─ Contract Compliance: 92.1% (Target: ≥95%)                  │
│  ├─ Pricing Compliance: 97.8% (3 invoices over contract)       │
│  ├─ Terms Compliance: 88.4% (sent Net 45 instead of Net 30)    │
│  └─ Trend: ↓ Declining (-1.2% vs Q3) ⚠️                         │
│                                                                │
│  ⚡ RESPONSIVENESS (20% weight) - Score: 78/100                │
│  ├─ Response Time: 4.2 hours (Target: ≤8 hours) ✅              │
│  ├─ Resolution Time: 18.5 hours (Target: ≤24 hours) ✅          │
│  ├─ Unresolved Issues: 1 open (12 days old) ⚠️                 │
│  └─ Trend: ↑ Improving (+5% vs Q3)                             │
│                                                                │
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │
│                                                                │
│  🎯 ACTION ITEMS                                                │
│  • Address 8 late deliveries (root cause: understaffing)      │
│  • Fix invoice accuracy issues (train on PO requirements)     │
│  • Review payment terms (using wrong Net 45 instead of 30)    │
│  • Resolve 12-day-old open issue (escalate to account mgr)    │
│                                                                │
│  [View Detailed Metrics] [Export Report] [Schedule Review]     │
│                                                                │
└────────────────────────────────────────────────────────────────┘

6. Risk Management & Dependency Analysis

Identify and Mitigate Supplier Risks:

A. Risk Scoring

(defn calculate-supplier-risk-score
  "Calculate comprehensive risk score (0-100, higher = riskier)"
  [supplier-id]
  (let [;; Concentration risk
        spend-concentration (calculate-spend-concentration supplier-id)
        
        ;; Single-source risk
        single-source? (is-single-source? supplier-id)
        
        ;; Performance risk
        performance-score (get-performance-score supplier-id)
        
        ;; Financial risk
        financial-health (get-financial-health supplier-id)
        
        ;; Compliance risk
        compliance-issues (count-compliance-issues supplier-id)
        
        ;; Geographic risk
        geo-risk (calculate-geographic-risk supplier-id)
        
        ;; Weighted risk calculation
        concentration-risk (* 0.25 spend-concentration) ;; 0-25 points
        single-source-risk (if single-source? 20 0) ;; 0 or 20 points
        performance-risk (* 0.20 (- 100 performance-score) 0.01) ;; 0-20 points
        financial-risk (* 0.15 (- 100 financial-health) 0.01) ;; 0-15 points
        compliance-risk (* 0.10 (min compliance-issues 10)) ;; 0-10 points max
        geographic-risk (* 0.10 geo-risk) ;; 0-10 points
        
        total-risk (+ concentration-risk single-source-risk performance-risk
                     financial-risk compliance-risk geographic-risk)]
    
    {:total-risk-score total-risk
     :risk-level (cond
                   (< total-risk 30) "Low"
                   (< total-risk 60) "Medium"
                   :else "High")
     :risk-factors {:concentration concentration-risk
                    :single-source single-source-risk
                    :performance performance-risk
                    :financial financial-risk
                    :compliance compliance-risk
                    :geographic geographic-risk}
     :mitigation-required (> total-risk 60)}))

B. Risk Dashboard

┌────────────────────────────────────────────────────────────────┐
│  ⚠️  SUPPLIER RISK ANALYSIS                                     │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  HIGH RISK SUPPLIERS (3)                                       │
│                                                                │
│  🔴 Critical Systems Inc - Risk Score: 78/100                  │
│     Annual Spend: €450,000 (12% of total)                     │
│                                                                │
│     Risk Factors:                                              │
│     • Single-source supplier (no alternatives) ⚠️              │
│     • High spend concentration (12% of budget)                 │
│     • Recent financial issues (credit rating downgrade)        │
│     • Geographic risk (single facility in one country)         │
│                                                                │
│     Mitigation Actions:                                        │
│     ✅ Qualified 2 backup suppliers (in progress)              │
│     ⏳ Negotiate 90-day inventory buffer                        │
│     ❌ Dual-sourcing strategy (not started)                    │
│                                                                │
│     [View Mitigation Plan] [Assign Owner] [Set Review]         │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  🔴 Cloud Services AG - Risk Score: 72/100                     │
│     Annual Spend: €280,000 (8% of total)                      │
│                                                                │
│     Risk Factors:                                              │
│     • Critical dependency (runs core infrastructure)           │
│     • Long contract lock-in (24 months remaining)              │
│     • Performance declining (81/100, was 92/100)               │
│     • Price increases: 18% in last 12 months                   │
│                                                                │
│     Mitigation Actions:                                        │
│     ⏳ Performance improvement plan (30 days)                   │
│     ⏳ Evaluate migration to alternative provider               │
│     ❌ Negotiate early exit clause                             │
│                                                                │
│     [Escalate to Procurement] [RFP Alternative] [Vendor Call]  │
│                                                                │
└────────────────────────────────────────────────────────────────┘

7. Savings Opportunity Identification

AI-Powered Savings Recommendations:

(defn identify-savings-opportunities
  "Analyze supplier relationships for cost optimization"
  [supplier-id]
  (let [supplier (db/get-supplier supplier-id)
        contracts (db/get-active-contracts supplier-id)
        invoices (db/get-invoices-last-12-months supplier-id)
        performance (calculate-supplier-performance supplier-id)
        market-data (get-market-benchmarks (:category supplier))]
    
    (concat
      ;; Volume consolidation opportunities
      (identify-volume-consolidation supplier invoices)
      
      ;; Price renegotiation opportunities
      (identify-price-renegotiation supplier invoices market-data)
      
      ;; Early payment discount opportunities
      (identify-early-payment-opportunities contracts invoices)
      
      ;; Alternative sourcing opportunities
      (identify-alternative-sourcing supplier performance market-data)
      
      ;; Contract optimization opportunities
      (identify-contract-optimization contracts invoices)
      
      ;; Waste reduction opportunities
      (identify-waste-reduction supplier invoices))))

Savings Dashboard:

┌────────────────────────────────────────────────────────────────┐
│  💰 SAVINGS OPPORTUNITIES - ALL SUPPLIERS                      │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  Total Identified: €1,245,000/year across 47 opportunities    │
│                                                                │
│  BY CATEGORY:                                                  │
│  ├─ Volume Consolidation: €485,000 (39%)                       │
│  ├─ Price Renegotiation: €340,000 (27%)                        │
│  ├─ Early Payment Discounts: €220,000 (18%)                    │
│  ├─ Alternative Sourcing: €150,000 (12%)                       │
│  └─ Waste Reduction: €50,000 (4%)                              │
│                                                                │
│  TOP 5 OPPORTUNITIES:                                          │
│                                                                │
│  1. Consolidate IT Services vendors (currently 8)              │
│     Potential Savings: €120,000/year                           │
│     Effort: Medium | Timeline: 3-6 months                      │
│     [View Analysis] [Start RFP]                                │
│                                                                │
│  2. Renegotiate Office Supplies contract                       │
│     Potential Savings: €85,000/year                            │
│     Reason: 12% above market, high volume leverage             │
│     Effort: Low | Timeline: 1-2 months                         │
│     [Prepare Negotiation] [View Benchmarks]                    │
│                                                                │
│  3. Capture early payment discounts (10 suppliers)             │
│     Potential Savings: €68,000/year                            │
│     Reason: Strong cash position, eligible discounts           │
│     Effort: Low | Timeline: Immediate                          │
│     [Enable Auto-Payment] [Review Cash Flow]                   │
│                                                                │
│  4. Switch to alternative cloud provider                       │
│     Potential Savings: €45,000/year                            │
│     Reason: 22% cheaper for equivalent service                 │
│     Effort: High | Timeline: 6-12 months                       │
│     [Evaluate Alternatives] [Migration Plan]                   │
│                                                                │
│  5. Reduce SaaS license waste                                  │
│     Potential Savings: €32,000/year                            │
│     Reason: 120 licenses, only 87 active users                 │
│     Effort: Low | Timeline: Immediate                          │
│     [Review Usage] [Downsize Plan]                             │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Business Value & ROI

For 500-Employee SME (€30M Addressable Spend)

Annual Value:

  1. Discount Optimization: €150-300K/year

  2. Contract Renegotiation: €300-600K/year

  3. Waste Reduction: €100-200K/year

  4. Risk Mitigation: €50-150K/year

Total Value: €600K-1.25M/year

Implementation Cost:


Implementation Roadmap

Phase 1: Foundation (Months 1-2)

Phase 2: Intelligence (Months 3-4)

Phase 3: Optimization (Months 5-6)


Success Metrics

Month 3:

Month 6:

Month 12:


Document Version: 1.0
Last Updated: January 5, 2026
Author: Orcha Product Team
Status: Ready for Development