Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/lerichardv/patolab-platform/llms.txt

Use this file to discover all available pages before exploring further.

Every specimen that enters PatoLab must receive a unique, human-readable identifier — the sequence_code — that appears on printed reports, patient receipts, and the public specimen-lookup URL (/specimen/{sequence_code}). Sequence records define the rules for generating those identifiers: which location and specimen type they apply to, what prefix to use, how many zero-padded digits the counter should have, and the current counter value. Separately, labs operating in Honduras must comply with the Servicio de Administración de Rentas (SAR) fiscal invoice requirements. Every invoice must reference a valid CAI (Código de Autorización de Impresión) range issued by SAR. PatoLab stores and manages these ranges in the CaiRange model, automatically tracking usage and flagging ranges that are about to expire or become exhausted.

Sequences

How sequence codes are generated

When a specimen is created, PatoLab looks up the active Sequence record matching the specimen’s location_id and specimen_type. It then constructs the sequence_code by combining:
{prefix}{separator}{month:2}{separator}{year:4}{separator}{counter:fill digits}
Example with prefix=BIO, separator=-, fill=4, month=7, year=2025, current_sequence=42:
BIO-07-2025-0042
After a specimen is created the counter is incremented automatically. The prefix must be unique across all active sequences to prevent collisions.

Sequence model fields

The Sequence model (app/Models/Sequence.php) exposes the following fillable fields:
FieldTypeDescription
location_idintegerForeign key to locations. Each branch can have its own sequences.
specimen_typeintegerForeign key to specimen_type table. Sequences are scoped per specimen type.
prefixstring (max 10)Short uppercase code that prefixes every identifier (e.g. BIO, CIT, HIS). Must be unique among active sequences.
separatorstring (max 5)Character placed between the prefix, date parts, and counter (e.g. -).
fillinteger (1–10)Total digit width of the numeric counter, left-padded with zeros (e.g. fill=40042).
monthinteger (1–12)Month component embedded in the code. Update this at the start of each month or use a scheduled task.
yearintegerFour-digit year component embedded in the code.
current_sequenceinteger (≥ 1)The next counter value that will be used. Incremented after each specimen creation.
activebooleanSoft-delete flag. Destroying a sequence sets active=false rather than deleting the row.

Managing sequences via UI

Navigate to /sequences to create, edit, or deactivate sequence records. The page lists all active sequences and supports search by prefix, location, or specimen type. Required permissions:
ActionPermission slug
View listsequences.view
Createsequences.create
Editsequences.edit
Delete (soft)sequences.delete
Deleting a sequence in the UI sets active=false rather than removing the database row. This preserves historical data for specimens that were already numbered against it. The deleted sequence no longer appears in the active list and will not be used for new specimens.

Seed default sequences

The SequenceSeeder auto-generates one sequence per specimen type for the first registered location, deriving the prefix from the first three letters of the specimen type name:
php artisan db:seed --class=SequenceSeeder
SequenceSeeder calls Sequence::truncate() before seeding, which deletes all existing sequences. Only run it on a fresh installation or a test database.

CAI Fiscal Ranges

What is a CAI?

The Código de Autorización de Impresión is a government-issued authorization code that Honduras SAR assigns to a block of consecutive invoice numbers for a specific taxpayer establishment and document type. Every printed invoice must carry:
  1. The CAI code
  2. The invoice number within the authorized range
  3. The range validity deadline (deadline)
PatoLab stores all this information in a CaiRange record and automatically tracks last_used_number as invoices are issued. When the range is exhausted or the deadline passes, the status transitions automatically to exhausted or expired respectively (checked on every visit to /cai-ranges).

CaiRange model fields

The CaiRange model (app/Models/CaiRange.php) stores the following fillable fields:
FieldTypeDescription
location_idintegerBranch location this CAI was issued for.
caistring (max 100)The CAI authorization code as printed on the official resolution (e.g. 3B82F6-8B5CF6-F59E0B-…).
full_prefixstring (max 20)Invoice number prefix format as authorized by SAR (e.g. 000-001-01-).
emissionstring (max 3)Emission point code (3 digits, e.g. 000).
establishmentstring (max 3)Establishment code (3 digits, e.g. 001).
document_typestring (max 2)Document type code (2 digits, e.g. 01 for invoice).
start_numberintegerFirst invoice number in the authorized range.
end_numberintegerLast invoice number in the authorized range. Must be greater than start_number.
last_used_numberintegerTracks the most recently issued invoice number. Incremented automatically when invoices are created.
deadlinedateSAR-assigned expiry date for the authorization. Invoices cannot be issued under this range after this date.
statusenumactive, exhausted, expired. Updated automatically when /cai-ranges is visited.
limit_percentage_warninginteger (0–100)Trigger an alert when the remaining invoices fall to this percentage of the total range (e.g. 10 = alert at 10% remaining).
limit_days_warningintegerTrigger an alert this many days before deadline.
warning_notifications_amountintegerTotal number of warning notifications to send before a range expires/exhausts.
warning_notifications_sentintegerRunning count of warnings already dispatched.

Status lifecycle

           create


          [ active ]
          /        \
   deadline         last_used_number
   in past          >= end_number
       │                  │
       ▼                  ▼
   [ expired ]       [ exhausted ]
The controller re-evaluates every active range when the /cai-ranges index page loads — no cron job is required for the transition, though you may add one for proactive alerting.

Relationship to invoices

Each Invoice record stores a cai_range_id foreign key. When generating an invoice, PatoLab selects the active CaiRange for the specimen’s location, increments last_used_number, and embeds the CAI, full prefix, and invoice number into the printable invoice PDF.
CAI ranges have a hard expiry date and a fixed invoice count. If your active range reaches its end_number or its deadline passes before you create a replacement, new invoices cannot be issued until an active range exists for that location. Monitor the limit_percentage_warning and limit_days_warning thresholds and create a new CAI range as soon as SAR issues the next authorization — do not wait until the current one is exhausted.

Adding a new CAI range

1

Obtain the CAI authorization from SAR

Log in to the SAR portal (Declaraguate / Sistema de Facturación) and request a new printing authorization for the relevant establishment. Download or note the issued CAI code, the authorized number range, and the validity deadline.
2

Navigate to the CAI Ranges page

In PatoLab go to /cai-ranges. You will see a table of existing ranges with their current status. Click New CAI Range (requires the cai_ranges.create permission).
3

Fill in the authorization details

Complete all required fields in the creation form:
  • Location — select the branch this authorization was issued for
  • CAI — paste the full CAI code exactly as issued by SAR
  • Full Prefix — e.g. 000-001-01-
  • Emission — 3-digit emission point code
  • Establishment — 3-digit establishment code
  • Document Type — 2-digit code (usually 01)
  • Start Number / End Number — the invoice number range
  • Last Used Number — set to start_number - 1 for a brand-new range, or to the last issued number if continuing a partially used range
  • Deadline — the expiry date on the SAR resolution
  • Status — set to active
4

Configure warning thresholds

Set the three warning fields to control when PatoLab alerts administrators:
  • Limit Percentage Warning — e.g. 10 to warn when only 10 % of invoices remain
  • Limit Days Warning — e.g. 15 to warn 15 days before deadline
  • Warning Notifications Amount — e.g. 3 to send up to three notifications
Leave warning_notifications_sent at 0 for a new range.
5

Save and verify

Submit the form. The new range appears in the list with status active. Verify that the old range is listed as exhausted or expired (PatoLab updates statuses automatically on page load). New invoices for that location will now use the new range.

Managing CAI ranges via UI

ActionRoutePermission
View listGET /cai-rangescai_ranges.view
CreatePOST /cai-rangescai_ranges.create
EditPUT /cai-ranges/{id}cai_ranges.edit
DeleteDELETE /cai-ranges/{id}cai_ranges.delete
The list supports filtering by status (active, exhausted, expired, or all) and full-text search against the cai and full_prefix columns.

Build docs developers (and LLMs) love