Exercise 16

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.

ABCDEFGHIJKLMNOPQRS
1inv-noinv-datepartygstinstatecountryplace-of-supplyamountigst-percigst-amtcgst-perccgst-amtsgst-percsgst-amtsales-ledgerigst-ledgercgst-ledgersgst-ledgernaration
2101/04/2026IGST PartyMaharashtraIndia10018180000Sales (IGST) @ 18% [TODO: Update Tax-rate in Ledger]igstcgstsgstUpdate Tax-type and Tax-rate in Sales ledger
3201/04/2026Local PartyGujaratIndiaGujarat100009999Sales (Local) @ 18% [TODO: Update Tax-rate in Ledger]igstcgstsgstUpdate Tax-type and Tax-rate in Sales ledger
4201/04/2026Local PartyGujaratIndiaGujarat1006666Sales (Local) @ 18% [TODO: Update Tax-rate in Ledger]igstcgstsgst

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,&quot;Unregistered&quot;,&quot;Regular&quot;)"/>
  <PARTYGSTIN FORMULA="=trim(D#)"/>
  <COUNTRYNAME FORMULA="=if(len(trim(F#))=0,&quot;India&quot;,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,&quot;Unregistered/Consumer&quot;,&quot;Regular&quot;)"/>
    <STATE FORMULA="=proper(trim(E#))"/>
    <PLACEOFSUPPLY FORMULA="=if(len(trim(G#))&gt;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,&quot;India&quot;,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="=&quot;~[~ Applicable&quot;"/>
  <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 &amp; Taxes</PARENT>
  <ISCOSTCENTRESON>No</ISCOSTCENTRESON>
  <AFFECTSSTOCK>No</AFFECTSSTOCK>
  <GSTAPPLICABLE FORMULA="=&quot;~[~ Applicable&quot;"/>
  <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:

<!-- One Sales Voucher per invoice number in Column A -->
<VOUCHER>
  <GUID FORMULA="=&quot;udi-SPB1-&quot; &amp; 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,&quot;Unregistered&quot;,&quot;Regular&quot;)"/>
  <STATENAME FORMULA="=proper(trim(E#))"/>
  <COUNTRYOFRESIDENCE FORMULA="=if(len(trim(F#))=0,&quot;India&quot;,F#)"/>
  <PLACEOFSUPPLY FORMULA="=if(len(trim(G#))&gt;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>
Remarks:
  1. 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.
  2. Invoice 2 has two rows at different rates (9% + 9% and 6% + 6%). Both are combined into one voucher; GROUPBY adds up the amounts per ledger.
  3. The tax amounts are not calculated by the XML tags. Calculate them in the sheet, for example =H2*I2/100.
  4. After the import, update the Tax-type and Tax-rate of the Sales ledger in Tally, as mentioned in the Narration column.
  5. Leave the GSTIN blank for an unregistered party. Fill the Place-of-Supply only when it differs from the party's state.
Sample files: Download the sample Excel sheet and matching XML tags file for this exercise. Download sales-with-gst-without-inventory.zip

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