This is a sample article, kept here so the page design can be reviewed. Replace it with the published piece by dropping the real markdown file into articles-src and running python build.py.
Every September, the same ritual: books on one screen, GSTR-1 and 3B summaries on another, and a junior somewhere matching line items into the night. The annual return does not reward this heroism. It rewards accuracy, and accuracy is a machine's job.
The shape of the problem
GSTR-9 reconciliation is fundamentally a joining problem: books versus returns, returns versus each other, and everything versus GSTR-2B. Joining is what dataframes are for.
import pandas as pd
books = pd.read_excel("sales_register.xlsx")
r1 = pd.read_excel("gstr1_summary.xlsx")
merged = books.merge(r1, on=["gstin", "invoice_no"], how="outer", indicator=True)
mismatches = merged[merged["_merge"] != "both"]
Four lines in, you already have the list every reviewer actually wants: the exceptions.
What changes when it takes 38 seconds
When the reconciliation is instant, you run it in April, not September. Differences get caught in the month they occur, vendor follow-ups happen while the vendor still remembers the invoice, and the annual return becomes a summary of a clean year instead of an archaeology project.
The published version of this piece walks through the full script, the edge cases (credit notes, amendments, rate changes), and how to package it so your article team can run it without touching the code.