Skip to main content

Overview

The Investment Opportunities feature allows administrators to create investment products by bundling multiple invoices into attractive investment packages. Each opportunity represents a collection of invoices that investors can fund, with defined returns (rendimiento) and internal rate of return (TIR) calculations.

Key Capabilities

Bundle Invoices

Combine multiple invoices into a single investment opportunity with automated tracking

Track Funding

Monitor funding progress with real-time monto recaudado (collected amount) updates

Lifecycle Management

Manage opportunity status from creation through activation to completion

Risk Assessment

Calculate and display TIR and rendimiento for investor decision-making

Data Model

The OportunidadInversion entity contains the following key fields:
FieldTypeDescription
idOportunidadintUnique identifier (auto-generated)
rendimientodoubleExpected return percentage
tirdoubleInternal Rate of Return (Tasa Interna de Retorno)
montoDoubleTarget investment amount
montoRecaudadoDoubleAmount collected so far
fechaCaducidadDateOpportunity expiration date
fechaRegistroDateCreation date
fechaPagoDateCalculated payout date (2 months before fechaCaducidad)
enableStringStatus: “Activo” or “No Activo”
idEmpresaintAssociated company ID
idUsulongCreator user ID
The fechaPago is automatically calculated as 2 months before the fechaCaducidad to ensure timely payment processing.

Workflow

Creating an Investment Opportunity

The creation process follows these steps:
  1. Add Invoices to Temporary List
    • Admin selects active invoices
    • Invoices are validated and added to a session-scoped list
    • Duplicate prevention ensures each invoice appears only once
  2. Submit Opportunity Details
    • Define rendimiento and TIR
    • Set target monto and fechaCaducidad
    • Associate with a company
  3. Automatic Processing
    • System sets montoRecaudado to 0.0
    • Status automatically set to “Activo”
    • fechaPago calculated (fechaCaducidad - 2 months)
    • Each invoice linked via OportunidadFactura junction table
    • Linked invoices marked as “No Activo” (no longer available for other opportunities)
// From OportunidadInversionController.java:183-247
@PostMapping("/insertaOportunidadInversion")
public ResponseEntity<?> insertaOportunidadInversion(@RequestBody OportunidadInversion obj, HttpSession session) {
    if (facturaList.isEmpty()) {
        return new ResponseEntity<>("Must add invoices first", HttpStatus.CONFLICT);
    }
    
    // Set automatic fields
    obj.setIdidUsu((long) session.getAttribute("idUsuActual"));
    obj.setEnable("Activo");
    obj.setFechaRegistro(new Date());
    obj.setMontoRecaudado(0.0);
    
    // Calculate payment date (2 months before expiration)
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(obj.getFechaCaducidad());
    calendar.add(Calendar.MONTH, -2);
    obj.setFechaPago(calendar.getTime());
    
    // Save opportunity
    OportunidadInversion objsalida = oportunidadInversionservice.insertaActualizaOportunidadInversion(obj);
    
    // Link invoices and disable them
    for (Factura f : facturaList) {
        OportunidadFactura oFactura = new OportunidadFactura();
        oFactura.setIdFactura(f.getIdFactura());
        oFactura.setIdOportunidad(objsalida.getIdOportunidad());
        oportunidadFacturanservice.insertarOportunidaFactura(oFactura);
        
        f.setEnable("No Activo");
        facturaService.insertarActualizarFactura(f);
    }
    
    facturaList.clear();
    return ResponseEntity.ok(objsalida);
}

Main API Endpoints

Admin Endpoints

GET /api/admin/listarOportunidadInversion
Returns all active investment opportunities (excluding “No Activo” status).Response:
[
  {
    "idOportunidad": 1,
    "rendimiento": 8.5,
    "tir": 12.3,
    "monto": 50000.0,
    "montoRecaudado": 25000.0,
    "fechaCaducidad": "2026-12-31",
    "fechaRegistro": "2026-03-01",
    "fechaPago": "2026-10-31",
    "enable": "Activo"
  }
]

Invoice Management for Opportunities

POST /api/addFactura
Adds an invoice to the temporary list for opportunity creation.Request Body:
{
  "idFactura": 15
}
Success Response:
{
  "Facturas": [
    {
      "idFactura": 15,
      "codFactura": "F-015",
      "monto": 10000.0,
      "enable": "Activo"
    }
  ]
}
See controller implementation at OportunidadInversionController.java:72-101
DELETE /api/deleteFacturalist/{id}
Removes an invoice from the temporary list before opportunity creation.Path Parameters:
  • id - Invoice ID to remove
See controller implementation at OportunidadInversionController.java:103-131
GET /api/refrescarListaFactura
Clears the entire invoice list (useful for starting over).See controller implementation at OportunidadInversionController.java:63-70

User Endpoints

GET /api/user/listarOportunidadInversion
Returns opportunities available for investment (excludes “No Activo”).See implementation at OportunidadInversionController.java:133-138
GET /api/listarFacXIdOpo/{idOportunidad}
Retrieves all invoices bundled in a specific opportunity via the OportunidadFactura junction table. See implementation at OportunidadInversionController.java:54-59

Access Patterns

Admin Access

  • Full CRUD operations on investment opportunities
  • Can create opportunities by bundling invoices
  • Can update opportunity parameters (rendimiento, TIR, monto, dates)
  • Can soft-delete opportunities (mark as “No Activo”)
  • Manages the invoice selection list during opportunity creation

User (Inversionista) Access

  • Read-only access to active opportunities
  • Can view detailed information including:
    • Expected returns (rendimiento)
    • TIR calculations
    • Funding progress (monto vs montoRecaudado)
    • Associated company information
    • Payment dates
  • Can filter and paginate through available opportunities

Use Cases

Use Case 1: Creating a New Investment Opportunity

Scenario: An admin wants to create an investment opportunity for Company XYZ’s invoices.
  1. Admin searches for available invoices from Company XYZ
  2. Admin adds 3 invoices totaling $50,000 using POST /api/addFactura
  3. Admin sets rendimiento to 8.5%, TIR to 12.3%, and expiration date to Dec 31, 2026
  4. Admin submits via POST /api/insertaOportunidadInversion
  5. System:
    • Creates opportunity with status “Activo”
    • Sets montoRecaudado to 0
    • Calculates fechaPago as Oct 31, 2026 (2 months before expiration)
    • Links the 3 invoices to the opportunity
    • Marks those invoices as “No Activo” (unavailable for other opportunities)
    • Clears the temporary invoice list

Use Case 2: Investor Browsing Opportunities

Scenario: An investor wants to find attractive investment opportunities.
  1. Investor calls GET /api/user/listarOportunidadInversion/page/0
  2. System returns first 8 active opportunities with:
    • Expected returns (rendimiento and TIR)
    • Target vs collected amounts
    • Company information
    • Payment dates
  3. Investor clicks on opportunity #5 to see details
  4. Investor calls GET /api/detalleOportunidadInversion/5
  5. Investor views complete information and decides whether to invest

Use Case 3: Monitoring Funding Progress

Scenario: Admin wants to check which opportunities are close to being fully funded.
  1. Admin calls GET /api/admin/listarOportunidadInversion
  2. System returns all active opportunities with current montoRecaudado
  3. Admin identifies opportunities where montoRecaudado is close to monto
  4. Admin can take action (e.g., promote heavily-funded opportunities or adjust terms for under-funded ones)

Best Practices

Invoice Validation

Always verify invoices are active and not already assigned before adding them to opportunities.

Date Management

Ensure fechaCaducidad provides sufficient time for funding. The system automatically calculates fechaPago 2 months prior.

Return Calculations

Calculate rendimiento and TIR accurately based on invoice values and timeframes to ensure investor trust.

Status Monitoring

Regularly monitor montoRecaudado to track funding progress and make timely adjustments.

Build docs developers (and LLMs) love