Skip to main content
This guide will help you set up NominaSoft and process your first payroll calculation from start to finish.

Prerequisites

Before you begin, ensure you have:
  • PostgreSQL 12 or higher installed
  • Database access with CREATE privileges
  • Basic understanding of SQL

Step 1: Initialize the Database

1

Create the Database Schema

Run the complete database schema script to create all necessary tables. The system includes tables for employees, positions, concepts, parameters, and payroll records.
-- Execute the complete schema from script_nomina.sql
-- This creates all core tables: tab_conceptos, tab_cargos, tab_meses, 
-- tab_pmtros, tab_emplea, tab_novedades, and tab_nomina
Key tables created:
  • tab_conceptos: Payroll concepts (earnings/deductions)
  • tab_cargos: Job positions
  • tab_meses: Month definitions
  • tab_pmtros: System parameters (SMLV, transport allowance, etc.)
  • tab_emplea: Employee records
  • tab_novedades: Payroll adjustments/novelties
  • tab_nomina: Final payroll calculations
2

Load Core Functions

Install all payroll calculation functions from the func/ directory, including:
  • Employee management functions
  • Concept management functions
  • Position management functions
  • The main payroll calculation function fun_act_nomina()

Step 2: Configure System Parameters

Set up your company parameters using the fun_insert_pmtros() function:
SELECT fun_insert_pmtros(
    'EMPRESA LA COSITA RICA',  -- Company name
    'Q',                        -- Payment period: 'Q' (biweekly) or 'M' (monthly)
    1423500,                    -- SMLV (minimum wage)
    200000,                     -- Transportation allowance
    2,                          -- Transport multiplier
    2025,                       -- Year
    1,                          -- Month (January)
    12,                         -- Interest rate for severance
    30                          -- Days per month
);
The transport allowance is automatically applied to employees earning up to 2x the minimum wage (SMLV × ind_num_trans).

Step 3: Set Up Months

Insert month definitions for payroll processing:
SELECT fun_insert_meses('Enero');
SELECT fun_insert_meses('Febrero');
SELECT fun_insert_meses('Marzo');
SELECT fun_insert_meses('Abril');
SELECT fun_insert_meses('Mayo');
SELECT fun_insert_meses('Junio');
SELECT fun_insert_meses('Julio');
SELECT fun_insert_meses('Agosto');
SELECT fun_insert_meses('Septiembre');
SELECT fun_insert_meses('Octubre');
SELECT fun_insert_meses('Noviembre');
SELECT fun_insert_meses('Diciembre');

Step 4: Create Job Positions

Define the job positions in your organization:
SELECT fun_insert_cargos('Gerente General');
SELECT fun_insert_cargos('Secretaria General');
SELECT fun_insert_cargos('Gerente Comercial');
SELECT fun_insert_cargos('Gerente Financiero');
SELECT fun_insert_cargos('Gerente de TI');
SELECT fun_insert_cargos('Scrum Master');
SELECT fun_insert_cargos('Desarrollador Front Senior');
SELECT fun_insert_cargos('Desarrollador Back Junior');
SELECT fun_insert_cargos('Diseñador');
SELECT fun_insert_cargos('Servicios Generales');
SELECT fun_insert_cargos('Vigilante');

Step 5: Define Payroll Concepts

Create the payroll concepts that will be used in calculations:
-- Basic Salary (Concept ID: 1)
SELECT fun_insert_conceptos(
    'Salario Básico',    -- Concept name
    TRUE,                -- Operation: TRUE=add, FALSE=subtract
    'Q',                 -- Period: 'Q'=biweekly, 'M'=monthly
    FALSE,               -- Is net paid amount
    0,                   -- Percentage value
    0,                   -- Fixed value
    TRUE                 -- Mandatory by law
);

-- Transportation Allowance (Concept ID: 2)
SELECT fun_insert_conceptos(
    'Auxilio de Transporte',
    TRUE, 'Q', FALSE, 0, 0, TRUE
);
Concept IDs are auto-generated sequentially. The order of insertion matters for maintaining the correct ID references in the parameters table.

Step 6: Add Employees

Register employees using the fun_insert_emplea() function:
SELECT fun_insert_emplea(
    'Carlos Eduardo',      -- First name
    'Perez Rueda',        -- Last name
    FALSE,                -- Gender: TRUE=female, FALSE=male
    'Calle 20',           -- Address
    3503421739,           -- Phone
    4,                    -- Socioeconomic level (1-6)
    0,                    -- Marital status: 0=single, 1=married, 2=divorced, 3=widowed, 4=other
    3,                    -- Number of children
    'A+',                 -- Blood type
    61,                   -- Age
    5,                    -- Position ID (Gerente de TI)
    10000000,             -- Base salary
    '2024-01-01'          -- Start date
);

-- Add more employees
SELECT fun_insert_emplea(
    'Laura Juliana', 'Perez Barrera', TRUE,
    'Calle 138 Carrera 54', 3102454737, 5,
    0, 0, 'A+', 25, 3, 8000000, '2024-10-01'
);

SELECT fun_insert_emplea(
    'Paula Sofia', 'Perez Moscoso', TRUE,
    'Arboretto Piedecuesta', 3133216625, 4,
    0, 0, 'O+', 16, 8, 6500000, '2024-01-01'
);

SELECT fun_insert_emplea(
    'Juan Pablo', 'Lopez Bobito', FALSE,
    'Piedecuesta', 3104444444, 4,
    0, 1, 'A+', 18, 12, 5000000, '2024-01-01'
);

SELECT fun_insert_emplea(
    'Juana', 'La Loca', TRUE,
    'Calle 28 Cra. 18', 3106666666, 3,
    0, 3, 'A-', 25, 16, 2500000, '2024-01-01'
);

Step 7: Add Payroll Novelties (Optional)

Register any payroll adjustments for the period, such as bonuses, overtime, or deductions:
-- Format: (year, month, period, employee_id, concept_id, days_worked, hours_worked)

-- Bonuses for January, Period 1
INSERT INTO tab_novedades VALUES(2025, 1, 1, 91423627, 6, 15, 1);
INSERT INTO tab_novedades VALUES(2025, 1, 1, 1032505813, 6, 15, 1);

-- Daytime overtime
INSERT INTO tab_novedades VALUES(2025, 1, 1, 1015000000, 7, 15, 5);

-- Holiday overtime
INSERT INTO tab_novedades VALUES(2025, 1, 1, 1015000001, 9, 15, 10);

-- Multiple concepts for one employee
INSERT INTO tab_novedades VALUES(2025, 1, 1, 1015000004, 6, 15, 1);
INSERT INTO tab_novedades VALUES(2025, 1, 1, 1015000004, 10, 15, 10);
Novelties are optional adjustments. If no novelties are added, the system will calculate standard payroll based on base salaries and mandatory deductions.

Step 8: Calculate Payroll

Run the main payroll calculation function:
-- Calculate payroll for January 2025, Period 1
SELECT fun_act_nomina(2025, 1, 1);
Parameters:
  • 2025 - Year (must match tab_pmtros.ano_nomina)
  • 1 - Month (must match tab_pmtros.mes_nomina)
  • 1 - Period (1 or 2 for biweekly pay)
The function will:
  1. Validate parameters against tab_pmtros
  2. Delete any existing payroll for the period
  3. Calculate base salary (prorated for biweekly)
  4. Apply transportation allowance if salary ≤ 2×SMLV
  5. Calculate mandatory deductions (EPS 4%, AFP 4%)
  6. Insert all results into tab_nomina

Step 9: View Results

Query the payroll results:
-- View all payroll records
SELECT * FROM tab_nomina 
WHERE ano_nomina = 2025 
  AND mes_nomina = 1 
  AND per_nomina = 1
ORDER BY id_emplea, id_concepto;

Expected Output

After running the payroll calculation, you should see records in tab_nomina with:
  • Base salary: Prorated for 15 days (biweekly) or 30 days (monthly)
  • Transportation allowance: Applied to employees earning ≤ 2×SMLV
  • EPS deduction: 4% of base salary (monthly)
  • AFP deduction: 4% of base salary (monthly)
  • Optional concepts: Any bonuses or overtime from tab_novedades

Next Steps

Employee Management

Learn how to manage employee records

Concepts Configuration

Configure payroll concepts and rules

Payroll Calculation

Deep dive into payroll calculations

Database Schema

Explore the complete database structure

Troubleshooting

Ensure the parameters you pass to fun_act_nomina() match the values in tab_pmtros:
SELECT ano_nomina, mes_nomina FROM tab_pmtros;
The transportation allowance is only applied if:
  • Base salary ≤ (SMLV × ind_num_trans)
  • Default: salary ≤ 2,847,000 (2 × 1,423,500)
Check your employee’s base salary in tab_emplea.
Before adding employees, ensure the position exists:
SELECT * FROM tab_cargos;
Create missing positions with fun_insert_cargos().
Check the PostgreSQL NOTICE messages for specific error details:
  • 22008: Invalid year/month/period
  • 23502: NULL value in required field
  • 23503: Foreign key violation (position doesn’t exist)
  • 23505: Duplicate record

Build docs developers (and LLMs) love