Sales Vouchers With GST Without Inventory
Published
This exercise imports Sales Vouchers with GST — IGST for inter-state
sales, CGST and SGST for local sales — from Excel into Tally Prime. There are
no stock items. It builds on
the Sales Vouchers With Multiple Ledgers exercise
and shows how GROUPBY combines rows of the same invoice, how
SKIP leaves out the tax entries and tax ledgers that are not needed,
and how the GST details of the party and the tax ledgers are created.
The Excel sheet
Each row has the taxable Amount (column H), the tax percentages and tax amounts (columns I to N) and the ledger names (columns O to R). Invoice 2 spans two rows with different tax rates, so both rows go into one voucher. The tax amounts are already calculated in the sheet.
| A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | inv-no | inv-date | party | gstin | state | country | place-of-supply | amount | igst-perc | igst-amt | cgst-perc | cgst-amt | sgst-perc | sgst-amt | sales-ledger | igst-ledger | cgst-ledger | sgst-ledger | naration |
| 2 | 1 | 01/04/2026 | IGST Party | Maharashtra | India | 100 | 18 | 18 | 0 | 0 | 0 | 0 | Sales (IGST) @ 18% [TODO: Update Tax-rate in Ledger] | igst | cgst | sgst | Update Tax-type and Tax-rate in Sales ledger | ||
| 3 | 2 | 01/04/2026 | Local Party | Gujarat | India | Gujarat | 100 | 0 | 0 | 9 | 9 | 9 | 9 | Sales (Local) @ 18% [TODO: Update Tax-rate in Ledger] | igst | cgst | sgst | Update Tax-type and Tax-rate in Sales ledger | |
| 4 | 2 | 01/04/2026 | Local Party | Gujarat | India | Gujarat | 100 | 6 | 6 | 6 | 6 | Sales (Local) @ 18% [TODO: Update Tax-rate in Ledger] | igst | cgst | sgst |
Step 1 — Create the Party Ledger master
The party is created under Sundry Debtors with bill-wise tracking on.
Its GST registration type depends on the GSTIN in column D: Regular when a
GSTIN is given, otherwise Unregistered. The country defaults to India when
column F is empty. For Tally Prime 3.0, the GST details go into
LEDGSTREGDETAILS.LIST (registration type, state, place of supply and
GSTIN) and the address into LEDMAILINGDETAILS.LIST. The place of
supply is taken from column G, or from the state in column E when column G is empty.
<!-- Create Party Ledger Masters from Column C -->
<MASTER TYPE="LEDGER">
<NAME.LIST>
<NAME COLUMNREFERENCE="C"/>
</NAME.LIST>
<ADDITIONALNAME COLUMNREFERENCE="C"/>
<PARENT>Sundry Debtors</PARENT>
<ISBILLWISEON>Yes</ISBILLWISEON>
<ISCOSTCENTRESON>No</ISCOSTCENTRESON>
<GSTREGISTRATIONTYPE FORMULA="=if(len(trim(D#))=0,"Unregistered","Regular")"/>
<PARTYGSTIN FORMULA="=trim(D#)"/>
<COUNTRYNAME FORMULA="=if(len(trim(F#))=0,"India",F#)"/>
<STATENAME FORMULA="=proper(trim(E#))"/>
<LEDSTATENAME FORMULA="=proper(trim(E#))"/>
<!-- Tally Prime 3.0 -->
<LEDGSTREGDETAILS.LIST>
<APPLICABLEFROM>20260401</APPLICABLEFROM>
<GSTREGISTRATIONTYPE FORMULA="=if(len(trim(D#))=0,"Unregistered/Consumer","Regular")"/>
<STATE FORMULA="=proper(trim(E#))"/>
<PLACEOFSUPPLY FORMULA="=if(len(trim(G#))>0,proper(trim(G#)),proper(trim(E#)))"/>
<GSTIN FORMULA="=trim(D#)"/>
</LEDGSTREGDETAILS.LIST>
<LEDMAILINGDETAILS.LIST>
<APPLICABLEFROM>20260401</APPLICABLEFROM>
<MAILINGNAME COLUMNREFERENCE="C"/>
<STATE FORMULA="=proper(trim(E#))"/>
<COUNTRY FORMULA="=if(len(trim(F#))=0,"India",F#)"/>
</LEDMAILINGDETAILS.LIST>
</MASTER>
Step 2 — Create the Sales and Tax Ledger masters
The Sales ledger name is read from column O. Its tax type and tax rate must be updated manually in Tally after the import, as reminded in the narration column.
<!-- Create Sales Ledger Masters from Column O.
Tax-type and Tax-rate must be updated manually in Tally (see narration in CSV). -->
<MASTER TYPE="LEDGER">
<NAME.LIST>
<NAME COLUMNREFERENCE="O"/>
</NAME.LIST>
<PARENT>Sales Accounts</PARENT>
<TAXTYPE>Others</TAXTYPE>
<ISBILLWISEON>No</ISBILLWISEON>
<ISCOSTCENTRESON>No</ISCOSTCENTRESON>
<AFFECTSSTOCK>No</AFFECTSSTOCK>
<USEFORVAT>No</USEFORVAT>
<GSTAPPLICABLE FORMULA="="~[~ Applicable""/>
<GSTTYPEOFSUPPLY>Services</GSTTYPEOFSUPPLY>
</MASTER>
The IGST, CGST and SGST ledgers are created under Duties & Taxes,
with the duty head (Integrated, Central or State Tax) and the rate taken from the
percentage columns. An import ignores a MASTER whose name is empty,
so SKIP is placed on the NAME tag, not on the
MASTER tag. The IGST ledger is therefore not created when the IGST
amount (column J) is 0. The CGST (columns Q, L, K) and SGST (columns R, N, M)
masters follow the same pattern.
<!-- Create IGST Ledger Master from Column P (only when IGST amount is non-zero) -->
<MASTER TYPE="LEDGER">
<NAME.LIST>
<NAME SKIP="=Round(J#,2)=0" COLUMNREFERENCE="P"/>
</NAME.LIST>
<PARENT>Duties & Taxes</PARENT>
<ISCOSTCENTRESON>No</ISCOSTCENTRESON>
<AFFECTSSTOCK>No</AFFECTSSTOCK>
<GSTAPPLICABLE FORMULA="="~[~ Applicable""/>
<GSTDUTYHEAD>Integrated Tax</GSTDUTYHEAD>
<TAXTYPE>GST</TAXTYPE>
<RATEOFTAXCALCULATION COLUMNREFERENCE="I"/>
</MASTER>
Step 3 — Write the Voucher tags
One Sales voucher is created for each invoice number. The GST details of the party (GSTIN, registration type, state, country and place of supply) are repeated on the voucher. Then come the ledger entries:
-
Party debit —
GROUPBY="=A#"groups all rows of the invoice into one entry. Its amount is the taxable value plus IGST, CGST and SGST, shown as a negative amount, and the same amount goes to the bill allocation. -
Sales credit —
GROUPBY="=O#"sums the taxable values by Sales ledger. -
IGST, CGST and SGST credits — grouped by the tax ledger name when given,
otherwise by the tax percentage.
SKIPdrops the entry when its tax amount is 0 or blank, so a local sale carries no IGST entry and an inter-state sale carries no CGST or SGST entries.
<!-- One Sales Voucher per invoice number in Column A -->
<VOUCHER>
<GUID FORMULA="="udi-SPB1-" & A#"/>
<DATE COLUMNREFERENCE="B"/>
<EFFECTIVEDATE COLUMNREFERENCE="B"/>
<VOUCHERTYPENAME>Sales</VOUCHERTYPENAME>
<VOUCHERNUMBER COLUMNREFERENCE="A"/>
<REFERENCE COLUMNREFERENCE="A"/>
<NARRATION COLUMNREFERENCE="S"/>
<ISINVOICE>Yes</ISINVOICE>
<PERSISTEDVIEW>Invoice Voucher View</PERSISTEDVIEW>
<!-- GST details of the party -->
<PARTYGSTIN FORMULA="=trim(D#)"/>
<GSTREGISTRATIONTYPE FORMULA="=if(len(trim(D#))=0,"Unregistered","Regular")"/>
<STATENAME FORMULA="=proper(trim(E#))"/>
<COUNTRYOFRESIDENCE FORMULA="=if(len(trim(F#))=0,"India",F#)"/>
<PLACEOFSUPPLY FORMULA="=if(len(trim(G#))>0,proper(trim(G#)),proper(trim(E#)))"/>
<PARTYNAME COLUMNREFERENCE="C"/>
<PARTYLEDGERNAME COLUMNREFERENCE="C"/>
<BASICBASEPARTYNAME COLUMNREFERENCE="C"/>
<BASICBUYERNAME COLUMNREFERENCE="C"/>
<!--
Party debit: GROUPBY=A# groups all rows of the invoice (e.g. invoice 2 spans two rows
with different tax rates). Debit = Taxable value + IGST + CGST + SGST, shown as negative.
-->
<LEDGERENTRIES.LIST GROUPBY="=A#">
<LEDGERNAME COLUMNREFERENCE="C"/>
<ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
<AMOUNT FORMULA="={Round(H#,2)+Round(J#,2)+Round(L#,2)+Round(N#,2)}*-1"/>
<BILLALLOCATIONS.LIST SKIP="=Len(trim(A#))=0">
<NAME COLUMNREFERENCE="A"/>
<BILLTYPE>New Ref</BILLTYPE>
<AMOUNT FORMULA="={Round(H#,2)+Round(J#,2)+Round(L#,2)+Round(N#,2)}*-1"/>
</BILLALLOCATIONS.LIST>
</LEDGERENTRIES.LIST>
<!-- Sales credit: grouped by Sales Ledger (Column O) within the voucher -->
<LEDGERENTRIES.LIST GROUPBY="=O#">
<LEDGERNAME COLUMNREFERENCE="O"/>
<ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
<AMOUNT FORMULA="={Round(H#,2)}"/>
</LEDGERENTRIES.LIST>
<!--
CHANGE: Ledger names are taken directly from the CSV file, for both the MASTERs and the VOUCHER.
Sales ledger - Column O
IGST ledger - Column P
CGST ledger - Column Q
SGST ledger - Column R
Hence, LEDGERNAME of the tax entries below uses COLUMNREFERENCE (not a formula), so that it
always matches the NAME of the tax ledger MASTER created above.
GROUPBY: if the Tax Ledger name is given (Column P/Q/R), entries are grouped on that name;
otherwise they are grouped on the Tax-percentage (Column I/K/M).
Each tax entry is skipped when its tax amount (Column J/L/N) is 0 or blank.
-->
<!-- IGST credit: skipped when the IGST amount is 0 or blank -->
<LEDGERENTRIES.LIST GROUPBY="=if(len(trim(P#))=0,trim(I#),trim(P#))" SKIP="={Round(J#,2)}=0">
<LEDGERNAME COLUMNREFERENCE="P"/>
<ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
<AMOUNT FORMULA="={Round(J#,2)}"/>
</LEDGERENTRIES.LIST>
<!-- CGST credit: skipped when the CGST amount is 0 or blank -->
<LEDGERENTRIES.LIST GROUPBY="=if(len(trim(Q#))=0,trim(K#),trim(Q#))" SKIP="={Round(L#,2)}=0">
<LEDGERNAME COLUMNREFERENCE="Q"/>
<ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
<AMOUNT FORMULA="={Round(L#,2)}"/>
</LEDGERENTRIES.LIST>
<!-- SGST credit: skipped when the SGST amount is 0 or blank -->
<LEDGERENTRIES.LIST GROUPBY="=if(len(trim(R#))=0,trim(M#),trim(R#))" SKIP="={Round(N#,2)}=0">
<LEDGERNAME COLUMNREFERENCE="R"/>
<ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
<AMOUNT FORMULA="={Round(N#,2)}"/>
</LEDGERENTRIES.LIST>
</VOUCHER>
- The ledger names for Sales, IGST, CGST and SGST come from columns O to R, so the voucher always matches the ledgers created in the masters.
- Invoice 2 has two rows at different rates (9% + 9% and 6% + 6%). Both are combined into one voucher;
GROUPBYadds up the amounts per ledger. - The tax amounts are not calculated by the XML tags. Calculate them in the sheet, for example
=H2*I2/100. - After the import, update the Tax-type and Tax-rate of the Sales ledger in Tally, as mentioned in the Narration column.
- Leave the GSTIN blank for an unregistered party. Fill the Place-of-Supply only when it differs from the party's state.
Ready to import your Excel data into Tally?
Download udiMagic and start a 14-day free trial — no credit card required.
Download udiMagic View Pricing