Documentation Index Fetch the complete documentation index at: https://mintlify.com/daecheverri9801/core-projects/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Core Projects provides comprehensive financial management for construction sales, including payment tracking, down payment amortization, commission calculation, and financial reporting.
Payment Management
Payments are tracked against sales with detailed recording:
Payment Model
class Pago extends Model
{
protected $table = 'pagos' ;
protected $primaryKey = 'id_pago' ;
protected $fillable = [
'fecha' , // Payment date
'id_venta' , // Related sale
'referencia_pago' , // Payment reference/transaction ID
'id_concepto_pago' , // Payment concept
'id_medio_pago' , // Payment method
'descripcion' , // Description/notes
'valor' , // Amount
'id_cuota' , // Related installment (if applicable)
];
protected $casts = [
'fecha' => 'datetime' ,
'valor' => 'decimal:2' ,
];
public function venta ()
{
return $this -> belongsTo ( Venta :: class , 'id_venta' );
}
public function conceptoPago ()
{
return $this -> belongsTo ( ConceptoPago :: class , 'id_concepto_pago' );
}
public function medioPago ()
{
return $this -> belongsTo ( MedioPago :: class , 'id_medio_pago' );
}
}
Payment Concepts
Payments are categorized by concept:
Separation Initial payment to reserve a property
Down Payment Installments toward the down payment
Additional Charges Extra fees or charges
Other Miscellaneous payments
Payment Methods
Multiple payment methods are supported:
class MedioPago extends Model
{
// Common payment methods:
// - Efectivo (Cash)
// - Transferencia (Bank transfer)
// - Cheque (Check)
// - Tarjeta de Crédito (Credit card)
// - Consignación (Bank deposit)
}
Amortization Plans
Down payments are managed through amortization schedules:
Amortization Plan Model
class PlanAmortizacionVenta extends Model
{
protected $table = 'planes_amortizacion_venta' ;
protected $primaryKey = 'id_plan' ;
protected $fillable = [
'id_venta' ,
'tipo_plan' , // 'cuota_inicial' or 'financiacion'
'valor_interes_anual' , // Annual interest rate
'plazo_meses' , // Term in months
'fecha_inicio' , // Start date
'observacion' , // Notes
];
protected $casts = [
'fecha_inicio' => 'date' ,
'valor_interes_anual' => 'decimal:2' ,
];
public function venta ()
{
return $this -> belongsTo ( Venta :: class , 'id_venta' );
}
public function cuotas ()
{
return $this -> hasMany ( PlanAmortizacionCuota :: class , 'id_plan' );
}
}
Installment Structure
class PlanAmortizacionCuota extends Model
{
protected $table = 'planes_amortizacion_cuota' ;
protected $primaryKey = 'id_cuota' ;
protected $fillable = [
'id_plan' ,
'numero_cuota' , // Installment number (1, 2, 3...)
'fecha_vencimiento' , // Due date
'valor_cuota' , // Installment amount
'saldo_pendiente' , // Remaining balance after this payment
'estado' , // 'pendiente', 'pagada', 'vencida'
];
protected $casts = [
'fecha_vencimiento' => 'date' ,
'valor_cuota' => 'decimal:2' ,
'saldo_pendiente' => 'decimal:2' ,
];
}
Generating Amortization Schedules
Amortization schedules are generated automatically:
public function regenerarPlanCuotaInicial ( $venta )
{
// Delete existing plan
if ( $plan = $venta -> planAmortizacion ) {
$plan -> cuotas () -> delete ();
$plan -> delete ();
}
// Calculate down payment details
$cuotaInicial = ( float )( $venta -> cuota_inicial ?? 0 );
$valorSeparacion = ( float )( $venta -> valor_separacion ?? 0 );
$proyecto = $venta -> proyecto ;
$valorMinSep = ( float )( $proyecto -> valor_min_separacion ?? 0 );
// Amount to amortize = down payment - separation
$montoAmortizar = $cuotaInicial - max ( $valorSeparacion , $valorMinSep );
if ( $montoAmortizar <= 0 ) {
return ; // Nothing to amortize
}
$plazo = ( int )( $venta -> plazo_cuota_inicial_meses ?? 1 );
$frecuencia = ( int )( $venta -> frecuencia_cuota_inicial_meses ?? 1 );
// Create plan
$plan = PlanAmortizacionVenta :: create ([
'id_venta' => $venta -> id_venta ,
'tipo_plan' => 'cuota_inicial' ,
'valor_interes_anual' => 0 , // No interest on down payments
'plazo_meses' => $plazo ,
'fecha_inicio' => $venta -> fecha_venta ,
]);
// Calculate number of payments
$numPagos = ( int ) ceil ( $plazo / $frecuencia );
$cuotaBase = floor ( $montoAmortizar / $numPagos );
$residuo = $montoAmortizar - ( $cuotaBase * $numPagos );
// Generate installments
$fechaPago = Carbon :: parse ( $venta -> fecha_venta ) -> addMonths ( $frecuencia );
$saldoPendiente = $montoAmortizar ;
for ( $i = 1 ; $i <= $numPagos ; $i ++ ) {
$valorCuota = $cuotaBase ;
// Add residue to last payment
if ( $i === $numPagos ) {
$valorCuota += $residuo ;
}
$saldoPendiente -= $valorCuota ;
PlanAmortizacionCuota :: create ([
'id_plan' => $plan -> id_plan ,
'numero_cuota' => $i ,
'fecha_vencimiento' => $fechaPago -> copy (),
'valor_cuota' => $valorCuota ,
'saldo_pendiente' => max ( 0 , $saldoPendiente ),
'estado' => 'pendiente' ,
]);
$fechaPago -> addMonths ( $frecuencia );
}
}
Payment Frequency Examples
Monthly (Frequency = 1) 10-month term, $10M to amortize
10 payments of $1M each
Payment every month
Months: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Bimonthly (Frequency = 2) 10-month term, $10M to amortize
5 payments of $2M each
Payment every 2 months
Months: 2, 4, 6, 8, 10
Quarterly (Frequency = 3) 12-month term, $12M to amortize
4 payments of $3M each
Payment every 3 months
Months: 3, 6, 9, 12
Custom Any frequency from 1-12 months can be configured based on client needs
Commission Management
Sales advisors earn commissions based on configurable policies:
Commission Policy Model
class PoliticaComision extends Model
{
protected $table = 'politicas_comision' ;
protected $primaryKey = 'id_politica_comision' ;
protected $fillable = [
'id_proyecto' ,
'aplica_a' , // 'asesor', 'director', etc.
'base_calculo' , // 'valor_venta', 'cuota_inicial', etc.
'porcentaje' , // Commission percentage
'valor_fijo' , // Fixed commission amount (if applicable)
'minimo_venta_estado' , // Minimum sale state required
'descripcion' , // Description
'vigente_desde' , // Effective from date
'vigente_hasta' , // Effective until date
];
protected $casts = [
'vigente_desde' => 'date' ,
'vigente_hasta' => 'date' ,
'porcentaje' => 'decimal:3' ,
'valor_fijo' => 'decimal:2' ,
];
public function proyecto ()
{
return $this -> belongsTo ( Proyecto :: class , 'id_proyecto' );
}
}
Commission Calculation Bases
Commission calculated on the full sale price including all add-ons.
Commission based only on the down payment amount, not the full price.
Commission on the base unit price excluding parking and other additions.
Commission Types
Percentage-Based Commission = Sale Value × Percentage Example: 3% commission on 100 M s a l e = 100M sale = 100 M s a l e = 3M
Fixed Amount Fixed commission regardless of sale value Example: $2M per sale, regardless of value
Applying Commissions by Role
Different roles can have different commission structures:
// Sales advisor commission
$politicaAsesor = PoliticaComision :: where ( 'id_proyecto' , $venta -> id_proyecto )
-> where ( 'aplica_a' , 'asesor' )
-> where ( 'vigente_desde' , '<=' , $venta -> fecha_venta )
-> where ( function ( $q ) use ( $venta ) {
$q -> whereNull ( 'vigente_hasta' )
-> orWhere ( 'vigente_hasta' , '>=' , $venta -> fecha_venta );
})
-> first ();
if ( $politicaAsesor ) {
if ( $politicaAsesor -> porcentaje ) {
$comision = $venta -> valor_total * ( $politicaAsesor -> porcentaje / 100 );
} else {
$comision = $politicaAsesor -> valor_fijo ;
}
}
Payment Plans Export
The system generates payment plan reports:
public function planPagosCI ( array $filtros , Carbon $desde , Carbon $hasta ) : array
{
$ventas = Venta :: with ([ 'proyecto' , 'apartamento' , 'local' , 'cliente' ])
-> where ( 'tipo_operacion' , 'venta' )
-> whereBetween ( 'fecha_venta' , [ $desde , $hasta ])
-> get ();
// Generate month columns based on sale terms
$encabezados = [];
$filas = [];
$totales = [];
foreach ( $ventas as $v ) {
$plazo = max ( 1 , ( int )( $v -> plazo_cuota_inicial_meses ?? 1 ));
$frecuencia = max ( 1 , ( int )( $v -> frecuencia_cuota_inicial_meses ?? 1 ));
$fechaBase = Carbon :: parse ( $v -> fecha_venta ) -> startOfMonth ();
$numPagos = ( int ) ceil ( $plazo / $frecuencia );
// Month 0: Separation
$mes0 = $fechaBase -> format ( 'Y-m' );
$separacion = ( float )( $v -> valor_min_separacion ?? 0 );
// Months 1-N: Down payment installments
$cuotaInicial = ( float )( $v -> cuota_inicial ?? 0 );
$saldoAmortizar = max ( 0 , $cuotaInicial - $separacion );
$cuotaPorPago = $numPagos > 0 ? floor ( $saldoAmortizar / $numPagos ) : 0 ;
// Month N+1: Remaining value (mortgage/financing)
$valorRestante = ( float )( $v -> valor_restante ?? 0 );
}
return [
'encabezados' => $encabezados ,
'filas' => $filas ,
'totales' => $totales ,
];
}
Payment Plan Report Shows expected cash flow by:
Month-by-month columns
Row per sale showing client and unit
Separation, installments, and remaining balance
Total expected payments per month
Exportable to Excel
Different payment forms are supported:
class FormaPago extends Model
{
// Common payment forms:
// - Contado (Cash/immediate)
// - Cuota Inicial + Financiación (Down payment + financing)
// - Subsidio (Government subsidy)
// - Leasing
// - Other custom forms
}
Cash (Contado) Full payment upfront. No amortization schedule needed.
Down Payment + Financing Down payment over time, then mortgage/financing for remainder.
Subsidy Government or company subsidy applied to reduce client’s payment.
Custom Flexible payment structures based on negotiations.
Recording Payments
Payments are recorded against sales and optionally linked to installments:
public function registrarPago ( Request $request )
{
$validated = $request -> validate ([
'id_venta' => 'required|exists:ventas,id_venta' ,
'fecha' => 'required|date' ,
'valor' => 'required|numeric|min:0' ,
'id_concepto_pago' => 'required|exists:conceptos_pago,id_concepto_pago' ,
'id_medio_pago' => 'required|exists:medios_pago,id_medio_pago' ,
'referencia_pago' => 'nullable|string|max:100' ,
'id_cuota' => 'nullable|exists:planes_amortizacion_cuota,id_cuota' ,
'descripcion' => 'nullable|string|max:300' ,
]);
$pago = Pago :: create ( $validated );
// Update installment status if linked
if ( $pago -> id_cuota ) {
$cuota = PlanAmortizacionCuota :: find ( $pago -> id_cuota );
$cuota -> update ([ 'estado' => 'pagada' ]);
}
return redirect ()
-> route ( 'ventas.show' , $validated [ 'id_venta' ])
-> with ( 'success' , 'Pago registrado exitosamente' );
}
Financial Reports
The system provides various financial reports:
Cash Flow Expected and actual payments by month
Commissions Due Calculated commissions by advisor and period
Outstanding Balances Clients with pending payments and amounts
Payment History Complete payment records by project or client
Best Practices
Enter payments into the system as soon as they’re received to maintain accurate financial records.
Link payments to installments
When recording a payment, link it to the specific installment it’s paying to track schedule compliance.
Review commission policies regularly
Ensure commission policies are current and aligned with business objectives.
Monitor overdue installments
Regularly check for overdue installments and follow up with clients.
Export payment plans monthly
Generate and review payment plan reports monthly to forecast cash flow.