Skip to content
All projects
Freelance
Freelance

ERPs web app

An ERP for a real estate developer that sells lots on long-term financing: payments, late interest, reports and an audit trail, with a Flutter client and a Node.js API on MySQL.

ERPs web app

Jardines del Cortijo is a real estate development project in Uruguay, specifically a residential “barrio jardín” (garden neighborhood) located about 5 minutes from the center of Florida, Uruguay. It’s designed as a residential community with lots around 300 m² in size, set in a tranquil, green environment intended to offer families a quieter lifestyle near urban services.

The developer sells its lots on long-term financing, in Uruguayan indexed units (UI) or US dollars. I built the ERP that replaced spreadsheets for that business: who holds each lot, what they owe, what they paid, how much late interest they owe, and what the company will collect in the coming years.

Architecture

A Flutter client, with web and desktop builds, talks to a Node.js and Express API over HTTPS. The API is layered into routes, controllers and repositories that run hand-written SQL against MySQL 8. Everything runs with Docker Compose on a Hostinger VPS behind nginx.

UML deployment diagram: the Flutter ERP client on an office PC reaches nginx over HTTPS on a Hostinger VPS running Docker; nginx proxies to the Node.js and Express API, which uses MySQL 8 and an uploads folder; payment slips go to the RedPagos collection network and collection statements come back as Excel files.
Deployment view (UML 2 deployment diagram). Click to open at full resolution.

Importing collection statements

Most payments come in through the RedPagos collection network. Each month the ERP generates the payment slips the network collects, and the accountant uploads the resulting collection statement back into the ERP.

  • Safe to re-import: a payment’s primary key is the statement’s movement number, so importing the same statement twice cannot count a payment twice. Rows that fail are returned to the accountant.
  • One payment, several lots: a reference such as A12+A13 splits the amount evenly across the lots it names.
  • Applied installment by installment: for lots in UI, the amount is first converted at the payment date’s UI quote. Each whole installment it covers pays that installment’s late interest and then the installment itself; special installments override the regular amount; what remains is recorded as a fraction of the next installment.
  • Per-lot locking: applying or deleting a payment takes a lock on each lot involved, so two operations never update the same lot’s balance at the same time.
UML sequence diagram ImportCollectionStatement: the accountant uploads the statement; the controller reads each row; the payment repository inserts the payment keyed by its movement number; for each lot in the reference, the relations repository locks the lot, records the payment, applies it installment by installment and releases the lot; a duplicate movement number adds the row to the failed list.
Importing a collection statement (UML sequence diagram).

Late interest

An installment that is n months late accrues installment × ((1 + rate)n/12 − 1), compounding the annual rate monthly. A lot can carry its own rate or use the maximum legal rate published by the Central Bank of Uruguay (BCU) for its currency, which staff keep up to date. Balances are recalculated once per calendar month, on the first login of the month, and a record per month guarantees the run happens only once.

Reports and documents

  • Payment slips: one slip per installment owed, each including its late interest and converted at the month’s UI quote. A partly paid installment is billed together with the next one instead of taking a slip of its own.
  • Lots report: financed lots and expected collections for any month, using the lots’ change history to undo edits made after that month.
  • Future cash flow: projected collections month by month until the last installment, in pesos and in dollars.
  • Financing quotes: for a new sale, a schedule with a UI option and a USD option, built from the lot’s price, down payment, number of installments and rates.
  • Collections by month for any year, and Excel exports of clients and lots.

Data and accountability

Every change to a lot’s terms first copies the previous version into a history table, so the client can show a lot’s full timeline. Changes to clients and users are logged with who made them, and every payment records the user who loaded it.

Logical data model: clientes have many solares (financed lots); each lot has special installments, a change history and payment links; pagos link to lots through pagos_solares; audit tables record changes to clients and users; quotes, legal maximum rates, monthly late-interest runs and reminders are reference data.
Logical data model in crow’s-foot notation (MySQL 8).

Key features

  • Client and financed-lot management, one by one or imported from Excel
  • Manual and bulk payment loading, and payment deletion with balance rollback
  • Automatic late-interest calculation with legal maximum rates
  • Payment slips, accounting reports, revenue projections and financing quotes as Excel files
  • Full history of lot changes and user accountability for every action

Gallery