stupa-pdf-api/docs/COMPARISON_OFFERS_FEATURE.md

6.4 KiB
Raw Permalink Blame History

Comparison Offers Feature Documentation

Overview

The comparison offers feature requires users to provide at least 3 comparison offers for each cost position in their application. This ensures transparency and cost-effectiveness in funding requests. Users can alternatively provide a justification if comparison offers are not applicable for specific cost positions.

Features

  • 3 Offers Requirement: Each cost position must have at least 3 comparison offers
  • Justification Alternative: Users can mark that no offers are required and provide a detailed justification
  • Attachment Support: Each offer can be linked to an uploaded attachment (e.g., quotes, invoices)
  • Visual Indicators: Cost positions without sufficient offers are highlighted with warning icons
  • Status Tracking: Real-time status display showing offer count and completion status

Database Schema

comparison_offers Table

Stores comparison offers for cost positions:

  • id (INT, PRIMARY KEY) - Unique identifier
  • application_id (INT) - References the application
  • cost_position_index (INT) - Index of the cost position in the costs array
  • supplier_name (VARCHAR 255) - Name of the supplier/vendor
  • amount (INT) - Offer amount in cents
  • description (TEXT) - Optional description of the offer
  • url (VARCHAR 500) - Optional URL to offer document or webpage
  • attachment_id (INT) - Optional reference to an attachment
  • created_at (DATETIME) - Creation timestamp
  • updated_at (DATETIME) - Last update timestamp

cost_position_justifications Table

Stores justifications for positions without offers:

  • id (INT, PRIMARY KEY) - Unique identifier
  • application_id (INT) - References the application
  • cost_position_index (INT) - Index of the cost position
  • no_offers_required (INT) - Boolean flag (0/1)
  • justification (TEXT) - Required explanation when no_offers_required is 1
  • created_at (DATETIME) - Creation timestamp
  • updated_at (DATETIME) - Last update timestamp

API Endpoints

Create Comparison Offer

POST /api/applications/{pa_id}/costs/{cost_position_index}/offers

  • Request body:
    {
      "supplier_name": "Supplier GmbH",
      "amount": 1500.50,
      "description": "Optional description",
      "url": "https://beispiel.de/angebot.pdf",
      "attachment_id": 123
    }
    
  • Returns: ComparisonOfferResponse with offer details

Get Cost Position Offers

GET /api/applications/{pa_id}/costs/{cost_position_index}/offers

  • Returns: CostPositionOffersResponse with all offers and justification info

Delete Comparison Offer

DELETE /api/applications/{pa_id}/costs/{cost_position_index}/offers/{offer_id}

  • Removes a specific offer

Update Cost Position Justification

PUT /api/applications/{pa_id}/costs/{cost_position_index}/justification

  • Request body:
    {
      "no_offers_required": true,
      "justification": "Detailed explanation why no offers are needed..."
    }
    

Frontend Components

ComparisonOffersDialog

Main dialog for managing offers for a cost position:

  • Add/remove comparison offers
  • Add URL links to online offers
  • Link attachments to offers (either URL or attachment required)
  • Mark position as not requiring offers
  • Provide justification when needed

CostPositionsList

Enhanced cost positions list with offer status:

  • Visual indicators for offer status
  • Warning icons for incomplete positions
  • Quick access to manage offers
  • Real-time status updates

User Interface

Status Indicators

  • Green checkmark: Position has 3+ offers
  • Blue info icon: Position marked as not requiring offers (with justification)
  • ⚠️ Yellow warning: Position needs more offers or justification
  • 🔄 Loading spinner: Status being loaded

Validation Rules

  1. Each cost position must have either:
    • At least 3 comparison offers, OR
    • Be marked as "no offers required" with a justification (min. 10 characters)
  2. Cost positions without sufficient offers are highlighted in the list
  3. Offers must include:
    • Supplier name (required, must be unique per cost position)
    • Amount (required, must be greater than 0)
    • Either URL or attachment (at least one required)
    • Description (optional)
  4. Duplicate suppliers: Each supplier can only have one offer per cost position
  5. URL format: Must be a valid HTTP/HTTPS URL (protocol is auto-added if missing)
  6. Amount format: Accepts both comma and period as decimal separator

Migration

To add the comparison offers tables to your database:

mysql -u your_user -p your_database < src/migrations/add_comparison_offers_tables.sql
mysql -u your_user -p your_database < src/migrations/add_url_to_comparison_offers.sql

Usage Example

In Cost Positions List

<CostPositionsList
  costs={formData.costs}
  paId={applicationId}
  paKey={applicationKey}
  isAdmin={false}
  readOnly={false}
  attachments={availableAttachments}
/>

Managing Offers

  1. Click "Angebote" button next to any cost position
  2. In the dialog:
    • Add up to 5 comparison offers
    • Link existing attachments to offers
    • OR check "no offers required" and provide justification
  3. Save changes

Best Practices

  1. Encourage Early Collection: Remind users to collect offers before starting the application
  2. Clear Instructions: Provide examples of valid justifications for positions without offers
  3. Attachment Organization: Name attachment files clearly to easily link them to offers
  4. Regular Validation: Check offer status before submission

Error Handling

  • Duplicate Suppliers: Shows user-friendly error message when trying to add the same supplier twice
  • Invalid URLs: Automatically prepends https:// if missing, validates format
  • Invalid Amounts: Real-time validation with support for German number format (comma as decimal)
  • Missing Data: Clear error messages when required fields are missing

Future Enhancements

  1. Bulk Import: Import multiple offers from CSV/Excel
  2. Templates: Save common suppliers for quick reuse
  3. Price Comparison: Automatic highlighting of best offer
  4. History Tracking: Track changes to offers over time
  5. Export Function: Export all offers as PDF/Excel report
  6. Smart Validation: Detect duplicate suppliers or suspicious patterns
  7. URL Validation: Automatic checking of URL availability and validity
  8. Screenshot Capture: Automatic capture of web-based offers for archival