Exercise 17

Sales Vouchers With GST With Inventory

Published


This exercise imports Sales Vouchers with GST and stock items from Excel into Tally Prime. It builds on the Sales Vouchers With GST Without Inventory exercise and adds the Unit and Stock Item masters, the inventory lines of the voucher (SCROLL) and the GST rate on each item. As before, GROUPBY combines the rows of one invoice and SKIP leaves out the tax entries and tax ledgers that are not needed.

The Excel sheet

Each row is one item of an invoice: Item (column H), HSN (I), GST rate (J), Unit (K), Qty (L), Rate (M) and the taxable Amount (N), followed by the tax percentages and amounts (columns O to T) and the ledger names (columns U to X). Invoice 2 has two items at different rates (18% and 12%), so both rows go into one voucher. The tax amounts are already calculated in the sheet.

ABCDEFGHIJKLMNOPQRSTUVWXY
1inv-noinv-datepartygstinstatecountryplace-of-supplyitemhsn-codegst-rateunitqtyrateamountigst-percigst-amtcgst-perccgst-amtsgst-percsgst-amtsales-ledgerigst-ledgercgst-ledgersgst-ledgernarration
2101/04/2026IGST PartyMaharashtraIndiaItem A99831318Nos110010018180000Sales (IGST)igstcgstsgstGST rate applied at item level
3201/04/2026Local PartyGujaratIndiaGujaratItem B99831318Nos250100009999Sales (Local)igstcgstsgstGST rate applied at item level
4201/04/2026Local PartyGujaratIndiaGujaratItem C99831312Nos425100006666Sales (Local)igstcgstsgst

Step 1 — Create the Unit and Stock Item masters

The Unit is created from column K and the Stock Item from column H, with its unit (column K) and HSN code (column I). The GST rate sits on the item: the Central Tax and State Tax rates are taken from the CGST / SGST percentages (columns Q and S), or half of the IGST percentage (column O) when those are empty, and the Integrated Tax rate from column O, or the sum of CGST and SGST. Repeated item names are created only once.

  <!-- Unit Master from Column K -->
<MASTER TYPE="UNIT">
    <NAME>NOS</NAME>
    <ISSIMPLEUNIT>Yes</ISSIMPLEUNIT>
    <GSTREPUOM>NOS-NUMBERS</GSTREPUOM>
    <REPORTINGUQCDETAILS.LIST>
        <APPLICABLEFROM>20260401</APPLICABLEFROM>
        <REPORTINGUQCNAME>NOS-NUMBERS</REPORTINGUQCNAME>
    </REPORTINGUQCDETAILS.LIST>
</MASTER>
  
 <!-- Stock Item Master from Column H; GST rate comes from the item (Column J) -->
<MASTER TYPE="STOCKITEM">
  <NAME.LIST>
    <NAME COLUMNREFERENCE="H"/>
  </NAME.LIST>
  <BASEUNITS COLUMNREFERENCE="K"/>
  <GSTAPPLICABLE FORMULA="=&quot;~[~ Applicable&quot;"/>
  <GSTTYPEOFSUPPLY>Goods</GSTTYPEOFSUPPLY>  
  <GSTDETAILS.LIST>
    <APPLICABLEFROM>20260401</APPLICABLEFROM>
    <CALCULATIONTYPE>On Value</CALCULATIONTYPE>
    <HSNCODE COLUMNREFERENCE="I"/>
    <TAXABILITY>Taxable</TAXABILITY>
    <!-- REMARK [Tally Prime 3.0+]: GST flags on the stock item (reverse charge, non-GST goods, ITC). -->
    <ISREVERSECHARGEAPPLICABLE>No</ISREVERSECHARGEAPPLICABLE>
    <ISNONGSTGOODS>No</ISNONGSTGOODS>
    <GSTINELIGIBLEITC>No</GSTINELIGIBLEITC>
    <!-- REMARK [Tally Prime 3.0+]: SRCOFGSTDETAILS = "Specify Details Here" (GST details set on the item itself). -->
    <SRCOFGSTDETAILS>Specify Details Here</SRCOFGSTDETAILS>
    <STATEWISEDETAILS.LIST>
      <STATENAME>~[~ Any</STATENAME>
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>Central Tax</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>Based on Value</GSTRATEVALUATIONTYPE>
        <GSTRATE FORMULA="=If(Round(Q#,2)&gt;0,Round(Q#,2),If(O#&gt;0,Round(O#/2,2),0))"/>
      </RATEDETAILS.LIST>
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>State Tax</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>Based on Value</GSTRATEVALUATIONTYPE>
        <GSTRATE FORMULA="=If(Round(S#,2)&gt;0,Round(S#,2),If(O#&gt;0,Round(O#/2,2),0))"/>
      </RATEDETAILS.LIST>
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>Integrated Tax</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>Based on Value</GSTRATEVALUATIONTYPE>
        <GSTRATE FORMULA="=If(Round(O#,2)&gt;0,Round(O#,2),Round(Q#+S#,2))"/>
      </RATEDETAILS.LIST>
      
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>Cess</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>~[~ Not Applicable</GSTRATEVALUATIONTYPE>
      </RATEDETAILS.LIST>
      
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>State Cess</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>~[~ Not Applicable</GSTRATEVALUATIONTYPE>
      </RATEDETAILS.LIST>
    </STATEWISEDETAILS.LIST>
  </GSTDETAILS.LIST>
  <HSNDETAILS.LIST>
    <APPLICABLEFROM>20230401</APPLICABLEFROM>
    <HSNCODE COLUMNREFERENCE="I"/>
    <SRCOFHSNDETAILS>Specify Details Here</SRCOFHSNDETAILS>
</HSNDETAILS.LIST>
</MASTER>

Step 2 — 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 given, otherwise Unregistered), the country defaults to India, and the place of supply is taken from column G or, when empty, from the state in column E.

  <!-- 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#))"/>
    <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 3 — Create the Sales and Tax Ledger masters

The Sales ledger (column U) is created with AFFECTSSTOCK set to Yes, as it is used on inventory lines. The IGST, CGST and SGST ledgers (columns V, W, X) are created under Duties & Taxes; SKIP on the NAME tag avoids creating a tax ledger whose amount is 0. The CGST (columns W, R) and SGST (columns X, T) masters follow the same pattern as the IGST master shown below.

  <!-- Sales Ledger Masters from Column U -->
  <MASTER TYPE="LEDGER">
    <NAME.LIST>
      <NAME COLUMNREFERENCE="U"/>
    </NAME.LIST>
    <PARENT>Sales Accounts</PARENT>
    <TAXTYPE>Others</TAXTYPE>
    <ISBILLWISEON>No</ISBILLWISEON>
    <ISCOSTCENTRESON>No</ISCOSTCENTRESON>
    <AFFECTSSTOCK>Yes</AFFECTSSTOCK>
    <USEFORVAT>No</USEFORVAT>
    <GSTTYPEOFSUPPLY>Goods</GSTTYPEOFSUPPLY>
  </MASTER>
  <!-- IGST Ledger Master from Column V -->
  <MASTER TYPE="LEDGER">
    <NAME.LIST>
      <NAME SKIP="=Round(P#,2)=0" COLUMNREFERENCE="V"/>
    </NAME.LIST>
    <PARENT>Duties &amp; Taxes</PARENT>
    <ISCOSTCENTRESON>No</ISCOSTCENTRESON>
    <AFFECTSSTOCK>No</AFFECTSSTOCK>
    <GSTDUTYHEAD>Integrated Tax</GSTDUTYHEAD>
    <TAXTYPE>GST</TAXTYPE>
  </MASTER>

Step 4 — Write the Voucher tags

One Sales voucher is created for each invoice number, in Item Invoice mode.

  <!-- 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="Y"/>
    <ISINVOICE>Yes</ISINVOICE>
    <PERSISTEDVIEW>Invoice Voucher View</PERSISTEDVIEW>
    <!-- REMARK [Tally Prime 3.0+]: item-invoice mode and GST-override flag on the voucher. -->
    <VCHENTRYMODE>Item Invoice</VCHENTRYMODE>
    <ISGSTOVERRIDDEN>No</ISGSTOVERRIDDEN>

    <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"/>

    <!-- Invoice total is the taxable amount plus all applicable GST amounts. -->
    <LEDGERENTRIES.LIST GROUPBY="=A#">
      <LEDGERNAME COLUMNREFERENCE="C"/>
      <ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
      <AMOUNT FORMULA="={Round(N#,2)+Round(P#,2)+Round(R#,2)+Round(T#,2)}*-1"/>
      <BILLALLOCATIONS.LIST SKIP="=Len(trim(A#))=0">
        <NAME COLUMNREFERENCE="A"/>
        <BILLTYPE>New Ref</BILLTYPE>
        <AMOUNT FORMULA="={Round(N#,2)+Round(P#,2)+Round(R#,2)+Round(T#,2)}*-1"/>
      </BILLALLOCATIONS.LIST>
    </LEDGERENTRIES.LIST>

    <!-- One inventory line per CSV row; sales ledger is allocated inside the line. -->
    <ALLINVENTORYENTRIES.LIST SCROLL="YES">
      <STOCKITEMNAME COLUMNREFERENCE="H"/>
      <!-- REMARK [Tally Prime 3.0+]: GST override, supply type, GST/HSN source tags and HSN on the inventory line. -->
      <GSTOVRDNISREVCHARGEAPPL>No</GSTOVRDNISREVCHARGEAPPL>
      <GSTOVRDNTAXABILITY>Taxable</GSTOVRDNTAXABILITY>
      <GSTOVRDNTYPEOFSUPPLY>Goods</GSTOVRDNTYPEOFSUPPLY>
      <GSTSOURCETYPE>Stock Item</GSTSOURCETYPE>
      <HSNSOURCETYPE>Stock Item</HSNSOURCETYPE>
      <GSTHSNNAME COLUMNREFERENCE="I"/>
      <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
      <RATE FORMULA="=M# &amp; &quot;/&quot; &amp; K#"/>
      <AMOUNT FORMULA="=Round(N#,2)"/>
      <ACTUALQTY FORMULA="=L# &amp; &quot; &quot; &amp; K#"/>
      <BILLEDQTY FORMULA="=L# &amp; &quot; &quot; &amp; K#"/>
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>Central Tax</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>Based on Value</GSTRATEVALUATIONTYPE>
        <GSTRATE FORMULA="=If(Round(Q#,2)&gt;0,Round(Q#,2),If(O#&gt;0,Round(O#/2,2),0))"/>
      </RATEDETAILS.LIST>
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>State Tax</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>Based on Value</GSTRATEVALUATIONTYPE>
        <GSTRATE FORMULA="=If(Round(S#,2)&gt;0,Round(S#,2),If(O#&gt;0,Round(O#/2,2),0))"/>
      </RATEDETAILS.LIST>
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>Integrated Tax</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>Based on Value</GSTRATEVALUATIONTYPE>
        <GSTRATE FORMULA="=If(Round(O#,2)&gt;0,Round(O#,2),Round(Q#+S#,2))"/>
      </RATEDETAILS.LIST>
      
      <RATEDETAILS.LIST>
        <GSTRATEDUTYHEAD>State Cess</GSTRATEDUTYHEAD>
        <GSTRATEVALUATIONTYPE>~[~ Not Applicable</GSTRATEVALUATIONTYPE>
      </RATEDETAILS.LIST>
      <ACCOUNTINGALLOCATIONS.LIST>
        <LEDGERNAME COLUMNREFERENCE="U"/>
        <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
        <AMOUNT FORMULA="=Round(N#,2)"/>
      </ACCOUNTINGALLOCATIONS.LIST>
      <BATCHALLOCATIONS.LIST>
        <GODOWNNAME>Main Location</GODOWNNAME>
        <BATCHNAME>Primary Batch</BATCHNAME>
        <DESTINATIONGODOWNNAME>Main Location</DESTINATIONGODOWNNAME>
        <AMOUNT FORMULA="=Round(N#,2)"/>
        <ACTUALQTY FORMULA="=L# &amp; &quot; &quot; &amp; K#"/>
        <BILLEDQTY FORMULA="=L# &amp; &quot; &quot; &amp; K#"/>
      </BATCHALLOCATIONS.LIST>
    </ALLINVENTORYENTRIES.LIST>

    <!-- Tax credits are skipped when their amounts are zero or blank. -->
    <LEDGERENTRIES.LIST GROUPBY="=if(len(trim(V#))=0,trim(O#),trim(V#))" SKIP="={Round(P#,2)}=0">
      <LEDGERNAME COLUMNREFERENCE="V"/>
      <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
      <AMOUNT FORMULA="={Round(P#,2)}"/>
    </LEDGERENTRIES.LIST>

    <LEDGERENTRIES.LIST GROUPBY="=if(len(trim(W#))=0,trim(Q#),trim(W#))" SKIP="={Round(R#,2)}=0">
      <LEDGERNAME COLUMNREFERENCE="W"/>
      <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
      <AMOUNT FORMULA="={Round(R#,2)}"/>
    </LEDGERENTRIES.LIST>

    <LEDGERENTRIES.LIST GROUPBY="=if(len(trim(X#))=0,trim(S#),trim(X#))" SKIP="={Round(T#,2)}=0">
      <LEDGERNAME COLUMNREFERENCE="X"/>
      <ISDEEMEDPOSITIVE>No</ISDEEMEDPOSITIVE>
      <AMOUNT FORMULA="={Round(T#,2)}"/>
    </LEDGERENTRIES.LIST>
  </VOUCHER>
Remarks:
  1. The sales amount is not posted as a separate ledger entry: it is allocated inside each inventory line through ACCOUNTINGALLOCATIONS.LIST.
  2. Invoice 2 has two items at different rates. Both go into one voucher; GROUPBY adds up the party and tax amounts.
  3. The tax amounts are not calculated by the XML tags. Calculate them in the sheet, for example =N2*O2/100.
  4. Tags marked Tally Prime 3.0+ in the comments are needed only for Tally Prime 3.0 and later.
  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-with-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