About Experience Engineering Projects Infrastructure Blog Contact
ERPNext & Frappe ๐Ÿงฉ 9-Part Course ยท Part 9: Capstone Project

Capstone Project: Build a Custom ERPNext Laboratory Management System

Published: Aug 30, 2026

๐ŸŽ“ Series Recap

Before building the capstone, make sure the concepts below are familiar โ€” each references the part that covers it.

This project builds out the Lab Sample example first introduced in Part 7, taking it from a foreshadowed sketch to a fully specified custom Frappe app โ€” master data, transactions, ERPNext integration, and a workflow โ€” using the exact same architecture Part 7 taught. It also leans on the accounting theory behind invoicing from Invoice vs Payment: The Complete ERP Accounting Architecture and the Accounting to ERP curriculum.

๐Ÿ“ Project Brief

The goal: build a Laboratory Management extension to ERPNext as a proper custom Frappe app โ€” never as core edits โ€” covering master data, transactions, ERPNext integration, and a workflow, exactly following the app architecture from Part 7. A diagnostic lab needs to register patients, capture samples, run tests, record and approve results, issue reports, and bill for all of it โ€” without the custom app reinventing anything ERPNext already does well.

Master Data

  • Patient โ€” the person being tested
  • Test โ€” a billable lab test definition
  • Sample Type โ€” blood, urine, swab, etc.
  • Department โ€” the lab section running the test (hematology, microbiology, โ€ฆ)
  • Doctor โ€” the referring/ordering physician

Transactions

  • Lab Request โ€” the order for one or more tests on a patient
  • Sample Collection โ€” the physical sample taken against a request
  • Test Assignment โ€” routing a sample/test pair to a technician
  • Result Entry โ€” the raw result value recorded by the technician
  • Result Approval โ€” sign-off by a supervising role
  • Lab Report โ€” the finished, patient-facing document

Integration

  • Customer โ€” every Patient is billed as an ERPNext Customer
  • Item โ€” every billable Test maps to an Item
  • Sales Invoice โ€” generated automatically off a released Lab Report
  • Payment Entry โ€” settles that invoice through the standard AR flow
  • Employee โ€” every collection, assignment, and approval step references one
  • Accounts โ€” the GL Entry rows the Sales Invoice ultimately produces

๐Ÿงฌ DocType Design

Six transaction DocTypes carry the workflow. A couple reuse the naming-series convention from Part 4 โ€” e.g. LAB-REQ-.YYYY.-.##### for Lab Request and LAB-RPT-.YYYY.-.##### for Lab Report โ€” so records sort chronologically and stay human-readable.

DocTypeKey fieldsChild table
Lab Request
LAB-REQ-.YYYY.-.#####
patient (Link โ†’ Patient), doctor (Link โ†’ Doctor), requested_testsLab Request Test โ€” one row per requested Test
Sample Collectionlab_request (Link โ†’ Lab Request), sample_type (Link โ†’ Sample Type), collected_by (Link โ†’ Employee), collection_datetimeโ€”
Test Assignmentsample (Link โ†’ Sample Collection), test (Link โ†’ Test), assigned_to (Link โ†’ Employee)โ€”
Result Entrytest_assignment (Link โ†’ Test Assignment), result_value, result_unit, reference_range, flagged (Check)โ€”
Result Approvalresult_entry (Link โ†’ Result Entry), approved_by (Link โ†’ Employee), approval_datetimeโ€”
Lab Report
LAB-RPT-.YYYY.-.#####
patient (Link โ†’ Patient), lab_request (Link โ†’ Lab Request), tests, statusLab Report Test โ€” rows pulled from the linked Result Entry records

Every Link field here is the same "reference, don't duplicate" pattern from Part 1's master/transaction table split and the full relationship model in Part 4: a Result Entry doesn't copy patient details, it links back through Test Assignment โ†’ Sample Collection โ†’ Lab Request โ†’ Patient.

๐Ÿ”— ERPNext Integration Map

The new DocTypes link back into ERPNext core via ordinary Link fields, following that same pattern as Part 7's core-linking section: Patient.customer โ†’ Customer (a lab patient is billed as an ERPNext Customer), each billable Test maps to an Item, Lab Report.company โ†’ Company, and every collection, assignment, and approval step references an Employee.

ERPNext Core

Customer

Item

Company

Employee

โ†‘Link fields

Patient

Sample

Lab Report

Lab Management App

๐Ÿ”„ Workflow

Request
โ†’
Sample Collected
โ†’
Testing
โ†’
Result Entered
โ†’
Verified
โ†’
Approved
โ†’
Report Released

Each transition is gated to a specific role, the same state/role modeling covered in Part 6's workflow deep-dive:

Current stateRole allowedActionNext state
RequestFront DeskCollect SampleSample Collected
Sample CollectedLab TechnicianBegin TestingTesting
TestingLab TechnicianEnter ResultResult Entered
Result EnteredLab SupervisorVerifyVerified
VerifiedPathologistApproveApproved
ApprovedSystem / Front DeskRelease ReportReport Released

๐Ÿ’ณ Billing Automation (Level 3 Integration in Action)

A doc_events hook โ€” the same mechanism covered in Part 7's hooks & events deep-dive โ€” fires on Lab Report's on_submit. It creates a Sales Invoice for the linked Customer, with one Sales Invoice Item row per Test (each Test's linked Item), and links back to the Lab Report through a reference field so the two documents stay traceable to each other.

Lab Report submitted
โ†“
on_submit hook
โ†“
Sales Invoice createdCustomer = Patient.customer, one row per Test โ†’ Item
โ†“
Sales Invoice submitted
โ†“
GL Entry rows generated

That final step is the same mechanics as the GL Entry generation walkthrough in Part 5 โ€” the Sales Invoice's own submit is what actually creates the ledger postings, not the lab app. This keeps billing entirely inside ERPNext's standard AR flow rather than the lab app reinventing invoicing, which is exactly the "invoice = obligation, don't duplicate the concept" argument applied to a real custom app: the Lab Report records that a service was performed; the Sales Invoice, a separate and reusable ERPNext document, records what is owed for it.

๐Ÿฌ Second Scenario: Retail (ABC Electronics Ltd.)

Customer
โ†’
Quotation
โ†’
Sales Order
โ†’
Delivery
โ†’
Sales Invoice
โ†’
Payment

Running in parallel on the purchasing side, Supplier โ†’ Purchase Order โ†’ Purchase Receipt โ†’ Purchase Invoice โ†’ Payment follows the identical shape โ€” both chains automatically updating Stock and Accounting per the mechanics detailed in Part 5, without either team touching the other's documents directly.

๐Ÿญ Third Scenario: Manufacturing

Sales Order
โ†’
Production Planning
โ†’
BOM
โ†’
Work Order
โ†’
Raw Material Consumption
โ†’
Job Card
โ†’
Finished Product
โ†’
Delivery
โ†’
Invoice
โ†’
Payment

Every module gets involved in this one chain โ€” Selling, Manufacturing, Stock, and Accounting โ€” the same cross-module shape explored in Part 3's Manufacturing module section.

๐Ÿ–ผ๏ธ Illustrative UI Walkthrough (Not Real Screenshots)

These are mock, described-not-shown walkthroughs. No real screenshots from a specific installed version are included, consistent with the accuracy rules set out in Part 1 โ€” exact field layout, list-view chrome, and button placement vary by ERPNext version and by how this app's DocTypes are actually configured. Treat the table below as what a walkthrough of this project would demonstrate, not a literal UI reference.
ScreenWhat it demonstrates
Lab Request formLink fields to Patient and Doctor resolving and auto-filling related data as they're selected
Sample Collection list viewA list filtered by status, showing samples still awaiting collection or testing
Result Entry formInline validation via a Server Script โ€” e.g. flagging a result outside its reference range
Workflow action buttonsThe available action changing per state, exactly as mapped in the Workflow table above
Auto-created Sales InvoiceThe Level 3 integration payoff โ€” billing appearing automatically from the on_submit hook
Workspace with the Lab Management module iconThe Level 1 integration payoff โ€” the custom app sitting alongside core modules in the Desk sidebar

๐Ÿ›๏ธ Final Architecture Slide

One diagram meant to summarize the entire nine-part series โ€” every layer this course has walked through, stacked in the order a request actually travels:

USER

โ†“

ERPNext UI

โ†“

Frappe Framework

โ†“ โ†“ โ†“

Modules

DocTypes

API

โ†“

Business Logic

โ†“ โ†“ โ†“

Accounting

Stock

HR

โ†“

MariaDB

โ†“

Reports / BI

โ†“

Management

๐Ÿ’ป Final Cheat Sheet

Architecture

Frappe โ†’ ERPNext โ†’ Apps โ†’ Modules โ†’ DocTypes โ†’ Database

Core Concepts

DocType, Document, Field, Link, Child Table, Workflow, Role, Permission, Hook, API

Business Concepts

Customer, Supplier, Item, Warehouse, Account, Employee, Sales, Purchase, Stock, Accounting

Developer Concepts

Bench, App, Custom App, Hooks, Controller, Client Script, Server Script, REST API, Migration, Patch, Fixture

Deployment

Nginx, Redis, MariaDB, Supervisor, SSL, Backup, Worker, Scheduler

๐Ÿ Series Complete

Across nine parts, this series took the reader from an ERPNext beginner through Installation, System Setup, Users & Roles, Modules, DocTypes, Database, Business Workflows, Customization, Custom Apps, and API Integration โ€” and now, with this capstone, a complete custom Frappe app built and integrated end to end. This is the journey this series promised in Part 1, restated one last time:

ERPNext Beginner
โ†“
Installation
โ†“
System Setup
โ†“
Users & Roles
โ†“
Modules
โ†“
DocTypes
โ†“
Database
โ†“
Business Workflows
โ†“
Customization
โ†“
Custom Apps
โ†“
API Integration
โ†“
Intermediate ERPNext Developer

That is the whole series. Thank you for following it from Part 1 through the capstone.

โ†‘