Skip to content
ERPNext Data Model
Esc
navigateopen⌘Jpreview
On this page

GSTR-3B Summary Return Computation & Filing

A design reference for computing the statutory summary return from ledger data and presenting it for filing

1. Requirements

1.1 Functional requirements

  • Compute the statutory GSTR-3B summary for a chosen registration and period from ledger-linked source documents: outward taxable supplies by rate category, e-commerce operator supplies reported under a specific liability section, an inter-state supply breakdown by place of supply, and inward input-tax-credit figures (available, reversed, and ineligible) plus nil-rated/exempt/non-GST inward supplies split between intra- and inter-state.
  • Reuse the same outward-supply section/sub-category classification engine that prepares the outward return (documented separately) so that a transaction’s outward-return section and its summary-return bucket are derived from one shared rule set, not two independently maintained ones.
  • Classify every inward document (purchase invoices, import-of-goods records, and reversal/reclaim journal entries) into an input-tax-credit eligibility bucket using its own, inward-specific ordered predicate set — a different rule set per source document type, because a purchase invoice, an import record, and a journal entry each carry different signals for eligibility.
  • Track, per purchase-side document, a distinct “input-tax-credit claim period” that is separate from its posting period, honoring the statutory deadline on claiming input tax credit, and re-derive that claim period automatically whenever the document is matched or actioned by the inward reconciliation pipeline (documented separately) or whenever its currently-assigned period turns out to already be filed.
  • Present the computed return in three complementary, read-only forms: an on-screen worksheet keyed to the government’s own layout, a downloadable JSON payload shaped exactly like the government’s offline filing utility expects, and a populated copy of the government’s own offline Excel utility template.
  • Offer drill-through reporting for any single worksheet section (which underlying vouchers contributed to a figure) and two standing summaries — an account-wise breakdown of credit availed, and a category-wise breakdown of credit availed — for audit and review.
  • Track filing status per period by observing the portal’s own list of previously filed returns for the registration’s financial year (a sync shared with the outward-return pipeline), and expose a manual override so an operator can mark a period Filed or Unfiled directly when that sync is not sufficient.

1.2 Non-functional requirements

  • Honesty about scope. The figures here are computed and presented, never submitted on the registration’s behalf through this subsystem. No code path in the classes that assemble this return calls a save or submit endpoint against the government’s returns-filing API for this return type.
  • Consistency with the outward return by construction. Because both this summary and the outward return consume the same classification engine over the same ledger data, the outward figures produced here should agree with the outward return’s own aggregation for the same period as a direct consequence of sharing one rule set — not because a separate reconciliation pass checks the two against each other.
  • Auditability. Every summary figure must be traceable back to the specific vouchers that contributed to it through the drill-through reports, not just visible as a rolled-up total.
  • Protecting already-filed periods. Once a period’s summary return is recorded as Filed, no purchase-side document may have its input-tax-credit claim period set into, or changed out of, that period.

1.3 Constraints

  • There is no return-log-driven filing sequence for this return type analogous to the outward return’s reset/upload/confirm/file sequence. The only interaction with the government portal for this return type is read-only: fetching the registration’s list of already-filed returns.
  • The offline JSON and Excel outputs must match a specific, version-pinned government template exactly, because they exist to be fed into the government’s own offline filing utility or reviewed by a preparer — not consumed by any API call this subsystem makes.
  • The underlying tax computation on each source document (rates, splits between the tax components) is owned by the shared tax engine (documented separately); this subsystem only classifies and re-aggregates figures the tax engine already produced.

2. High-Level Design

2.1 Component diagram

2.2 External interaction — how filing status is ever known (there is no filing call)

This diagram is deliberately built around the absence of a filing round trip: contrast it with the outward-return pipeline’s four-action filing sequence (documented separately) to see exactly what this subsystem does not do.


3. Deep Dive

3.1 Data model

Summary Return Record — one row per (registration, period, company). Computed on demand, either synchronously or, if the operator opts in, as a queued background job, into a single JSON blob shaped exactly like the government’s own worksheet: outward taxable/zero-rated/nil-exempt/non-GST/reverse-charge supply totals, e-commerce liability-section supplies, an inter-state breakdown by place of supply, input-tax-credit available/reversed/ineligible totals, and inward nil-rated/exempt/non-GST supplies split intra- versus inter-state. Its filing status is not stored on the record at all — it is a computed property that reads the shared Return Log for the matching registration/period/return-type combination. The record holds no filing state of its own.

Return Log (shared record type, cross-referenced from the outward-return pipeline) — for this return type, the log is populated by exactly two paths: the portal filed-returns sync, and a manual override action that lets an operator set the status directly. No child action record analogous to the outward return’s per-action tracking is ever appended against a summary-return-type log entry anywhere in the code read for this document — the mechanism exists on the shared record type, but nothing in this subsystem’s own code populates it.

Input-Tax-Credit Claim Period — a field on each purchase-side or import document, distinct from its posting date. It defaults to the document’s own posting period, but is pushed forward one unfiled period at a time — skipping any period whose summary return is already recorded Filed — up to a computed statutory deadline (the period ending in November of the financial year following the one the original transaction falls in). It can also be explicitly deferred by an inward-reconciliation action recorded against the document (that reconciliation pipeline is documented separately). Two guards enforce the “protect a filed period” requirement from §1.2: one blocks setting the claim period into an already-filed period in the first place, and a second blocks changing it away from or into a filed period on any later update.

Inward/outward section maps — two independent, static lookup tables from a document’s classified category/sub-category pair to a specific worksheet location (a section key, a row key, and which tax-amount fields apply). The outward map’s keys are literally the same section/sub-category values the outward-return pipeline’s classification engine produces — the concrete mechanism that keeps this return’s outward figures aligned with the outward return’s own aggregation without a separate reconciliation step.

3.2 Algorithm

Outward. Every sales-invoice line runs through the identical classification used to prepare the outward return. The resulting category/sub-category pair is looked up in the outward section map to find which worksheet cell accumulates its taxable value and tax fields. A side computation groups inter-state supplies further, by (GST category, place of supply), into the worksheet’s separate state-wise table — a detail the outward return itself does not need, since it reports at invoice granularity rather than by state.

Inward. Three separate, source-type-specific ordered predicate sets classify inward documents — one for purchase invoices, one for import-of-goods records, one for journal entries — because each source carries different eligibility signals (a purchase invoice’s own ineligibility reason field; an import record’s simpler all-eligible-unless-flagged rule; a journal entry’s voucher-type-driven reversal/reclaim distinction). Each inward sub-category maps to one worksheet cell plus a sign — positive for available credit, negative for reversed credit, zero (display-only) for ineligible credit — that feeds a running net-credit total the worksheet also reports. The “ITC Reversed” predicate for purchase invoices is deliberately evaluated after “ITC Available” in the ordered set, so an already-available classification is not overridden by a broader reversal rule.

Input-tax-credit claim-period derivation. For a given document, the claim period is chosen in this preference order: an explicit signal from the inward reconciliation pipeline (a “rejected” or “pending” match defers the claim one period forward; an “accepted” match with its own supplied period uses that period outright); otherwise, the later of the document’s own posting period or the matched inward-supply record’s own reporting period; then, starting from whichever period that yields, the algorithm walks forward one period at a time — skipping any period the registration’s summary return already shows Filed — until it finds an open period, stopping hard at the statutory deadline period if every earlier candidate is already filed.

3.3 Presentation contract

The same computed JSON feeds three outputs, each serving a different downstream use:

on-screen worksheet   -> rendered directly from the computed JSON, keyed to match
                          the government worksheet's own section/row layout

downloadable JSON      -> the identical computed JSON, byte-for-byte, in the shape
                          the government's own offline filing utility expects to import

populated Excel        -> a template-driven writer that locates fixed row/column
                          coordinates on a copy of the government's own offline-utility
                          spreadsheet and writes each worksheet figure into the matching
                          cell, grouped by section (outward, e-commerce, inter-state,
                          input-tax-credit, inward nil-rated/non-GST)

None of these three outputs round-trips through the government portal. All three are meant to leave this system and be acted on elsewhere — reviewed by a preparer, imported into the offline utility, or filed by whatever channel the organization actually uses to submit the return.

3.4 Error handling

Because computation here never calls the government portal, none of the portal-specific error classes documented for the outward-return and credential/session layers (queued responses, invalid-session recovery, rate-limit rejection) apply to this pipeline at all. The error handling that does exist is local:

  • Synchronous failure surfaces directly. By default, computation runs in the same request as the operator’s action; an exception during computation is raised straight back to the caller.
  • An opt-in background mode exists for large computations. If the operator chooses to enqueue the computation, it runs as a background job instead, and the record’s own generation-status field (In Process / Generated / Failed) lets a waiting UI poll for completion — this is an ordinary background-job pattern, not a portal interaction, and carries none of the retry-safety concerns that apply to a non-idempotent government call.
  • Filing-status lookups fail soft. If the filed-returns sync has never run for a registration, or returns nothing for the period in question, filing status simply reads “Not Filed” rather than raising — the absence of portal data is treated as the safe default, not an error condition.

4. Scale and Reliability

Does this subsystem actually file GSTR-3B? No. The transport layer this application shares across return types defines the save and submit calls for this return type, but nothing in the classes that assemble, present, or track this summary return ever calls them — a search across the whole codebase turns up zero callers for either. What exists instead is a compute-and-present pipeline: a summary is calculated from ledger data, exported as JSON or as a populated Excel workbook matching the government’s own offline utility, and the only way this application later learns a period was filed is by observing the portal’s own list of already-filed returns for the registration. The actual act of filing happens entirely outside this application — through the government’s offline utility, through a preparer’s own channel, or by some other means this codebase has no visibility into.

  • Filing window. The return’s own statutory due date — the calendar deadline by which a period must be submitted — is not modeled or enforced anywhere in this subsystem; there is no “file” action here to gate in the first place. The one filing-window concept that is code-enforced is narrower and different: the statutory deadline for claiming input tax credit against a purchase (a cutoff computed as November of the following financial year). That deadline bounds how far forward the claim-period algorithm in §3.2 will walk, and a save-time guard throws if an operator tries to set or move a document’s claim period into a period already recorded as filed.
  • Asynchronous portal processing. There is none to track, because there is no filing call. The closest analogue — the opt-in enqueue-and-poll pattern for a slow computation — is a local background-job status, not a portal round trip, and none of the async-download or queued-filing-action machinery documented for the outward-return pipeline has a counterpart here.
  • Double-file prevention. Does not apply. Nothing in this subsystem submits a return, so there is nothing here for a duplicate-submission guard to protect. This should be stated plainly rather than inferred: the absence of such a guard is a direct consequence of the absence of a filing call, not an oversight in an otherwise-complete filing feature.
  • Amendment/revision. Not modeled. Every time an operator opens the summary for a period, it is recomputed fresh from whatever the ledger currently contains — there is no stored prior snapshot to diff against, no version history, and no concept of “the version that was filed” separate from “whatever the ledger says today.” If a ledger correction lands after a period is (externally) filed, the on-screen summary silently reflects the corrected figures with nothing flagging that they now disagree with whatever was actually submitted.
  • Reconciliation against GSTR-1/2B. The plan for this subsystem anticipated an automated comparison against the outward return and against the government’s own inward-supply statement before filing. That comparison does not exist in the code read for this document. What exists instead is structural consistency by shared computation: because the outward side of this summary reuses the outward return’s own classification engine and section maps, its outward totals agree with the outward return’s totals by construction, not by a diff step. Nothing here downloads or compares against the government’s inward-supply statement at all — the closest adjacent feature is a “regenerate” trigger for that statement, which belongs to the separately-documented inward reconciliation pipeline and has no comparison logic in this scope. This is a genuine gap relative to the stated plan, not an alternate implementation of the same idea, and it is called out here rather than assumed.
  • Coupling risk. Sharing one classification engine between the outward return and this summary is a deliberate consistency win, but it is a two-way door: a rule change made for outward-return purposes changes this summary’s outward figures too, with no separate test or review gate specific to the summary-return consumer of that engine.
  • Concurrency. The claim-period bulk-update routines group changes by target period before writing, which avoids most write contention within a single reconciliation batch, but two independent matching operations racing against the same document from two different entry points are not separately guarded beyond that grouping.

5. Trade-off Analysis

Decision Trade-off
Compute-and-present only; no filing call implemented for this return type Keeps this subsystem simple and free of the non-idempotent-submission risk the outward return has to manage carefully, but it means “prepare GSTR-3B” and “file GSTR-3B” are not actually the same workflow here — an operator must leave this application to complete filing, and nothing in-app confirms that step happened beyond a later, indirect status sync.
Filing status derived entirely from an external sync rather than tracked as this subsystem’s own state No risk of this subsystem’s filing status drifting from what was actually filed, since it never originates a filing claim of its own — but it also means filing status can be stale or simply absent for long stretches if that sync has not run, with only a manual override to compensate.
Sharing the outward classification engine with the outward-return pipeline instead of a second, summary-specific rule set Guarantees the two returns’ outward figures cannot silently diverge, at the cost of coupling this summary’s correctness to a rule set that is tuned and reviewed primarily for the outward return’s own purposes.
Recomputing fresh from the ledger on every view, with no stored snapshot Always reflects the current state of the books, which is convenient for a preparer chasing down a discrepancy, but means there is no durable record of “what this looked like on the day it was (externally) filed” for later comparison.
A single statutory deadline (input-tax-credit claim window) enforced, while the return’s own filing due date is not Protects the one consequence that is cheap and unambiguous to check in-database (has this period’s return already been marked filed), while leaving the harder, calendar-driven due-date tracking entirely to the operator or to tooling outside this scope.
Three presentation formats generated from one computed JSON rather than three independent computations Only one place to fix a computation bug, but any format-specific mistake (a wrong Excel cell coordinate, for instance) is invisible to the other two formats and must be caught by inspecting that format specifically.

6. What to Revisit as the System Grows

  • Decide, deliberately, whether this subsystem should ever file. Today it stops at computation and export by design or by omission — that is not fully clear from the code alone. If the intent is for an operator to always file through some other channel, say so explicitly in the operator-facing workflow; if the intent was eventually to wire up the existing (currently uncalled) save/submit transport methods, that is a scoped, contained piece of work given the adapter already exists.
  • Build a genuine reconciliation against the outward return and the government’s inward-supply statement, rather than relying on shared computation alone for consistency — a real, portal-data-informed diff would catch the case where the books themselves are wrong, which structural consistency between two locally computed views cannot.
  • Snapshot the computed summary at the point an operator treats it as final, so a later ledger correction does not silently rewrite what was actually filed without at least flagging the divergence.
  • Track the statutory filing due date for the return itself, not only the narrower input-tax-credit claim deadline, so an operator gets an in-app signal before a period’s filing window closes rather than discovering it only through whatever channel they use to actually file.
  • Add a stronger concurrency guard around claim-period assignment once the inward reconciliation pipeline’s matching volume grows enough that two overlapping batch operations touching the same document becomes a realistic occurrence rather than a theoretical one.

Was this page helpful?