<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Robin</title>
    <description>The latest articles on DEV Community by Robin (@robinsinghvi).</description>
    <link>https://dev.to/robinsinghvi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3775861%2Fdfd1b007-1f63-4c43-bb31-f70537dea519.jpeg</url>
      <title>DEV Community: Robin</title>
      <link>https://dev.to/robinsinghvi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/robinsinghvi"/>
    <language>en</language>
    <item>
      <title>GST Compliance Calendar for April 2026: Every Deadline Indian Businesses Must Know</title>
      <dc:creator>Robin</dc:creator>
      <pubDate>Thu, 02 Apr 2026 16:12:02 +0000</pubDate>
      <link>https://dev.to/robinsinghvi/gst-compliance-calendar-for-april-2026-every-deadline-indian-businesses-must-know-5ag8</link>
      <guid>https://dev.to/robinsinghvi/gst-compliance-calendar-for-april-2026-every-deadline-indian-businesses-must-know-5ag8</guid>
      <description>&lt;p&gt;April 2026 is the first month of FY 2026-27. If you're running a business in India, missing a GST deadline this month means late fees from Day 1 of the new financial year.&lt;/p&gt;

&lt;p&gt;Here's every GST filing deadline for April 2026, organized by date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Critical Deadlines
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Return&lt;/th&gt;
&lt;th&gt;Period&lt;/th&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apr 7&lt;/td&gt;
&lt;td&gt;TDS Payment&lt;/td&gt;
&lt;td&gt;March 2026&lt;/td&gt;
&lt;td&gt;All TDS deductors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 10&lt;/td&gt;
&lt;td&gt;GSTR-7 (TDS)&lt;/td&gt;
&lt;td&gt;March 2026&lt;/td&gt;
&lt;td&gt;Govt bodies, PSUs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 10&lt;/td&gt;
&lt;td&gt;GSTR-8 (TCS)&lt;/td&gt;
&lt;td&gt;March 2026&lt;/td&gt;
&lt;td&gt;E-commerce operators&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 11&lt;/td&gt;
&lt;td&gt;GSTR-1 (Monthly)&lt;/td&gt;
&lt;td&gt;March 2026&lt;/td&gt;
&lt;td&gt;Turnover &amp;gt; ₹5 Cr&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 13&lt;/td&gt;
&lt;td&gt;GSTR-1 (Quarterly)&lt;/td&gt;
&lt;td&gt;Q4 Jan-Mar&lt;/td&gt;
&lt;td&gt;QRMP scheme&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 18&lt;/td&gt;
&lt;td&gt;CMP-08&lt;/td&gt;
&lt;td&gt;Q4 Jan-Mar&lt;/td&gt;
&lt;td&gt;Composition dealers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Apr 20&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;GSTR-3B (Monthly)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;March 2026&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;All regular taxpayers&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 22&lt;/td&gt;
&lt;td&gt;GSTR-3B (Quarterly)&lt;/td&gt;
&lt;td&gt;Q4 Jan-Mar&lt;/td&gt;
&lt;td&gt;QRMP — Maharashtra etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apr 24&lt;/td&gt;
&lt;td&gt;GSTR-3B (Quarterly)&lt;/td&gt;
&lt;td&gt;Q4 Jan-Mar&lt;/td&gt;
&lt;td&gt;QRMP — remaining states&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Late Fee Structure
&lt;/h2&gt;

&lt;p&gt;Missing GSTR-3B costs &lt;strong&gt;₹50/day&lt;/strong&gt; (₹25 CGST + ₹25 SGST), capped at ₹10,000. Nil returns attract ₹20/day, capped at ₹5,000. On top of that, &lt;strong&gt;18% annual interest&lt;/strong&gt; applies on unpaid tax from the due date.&lt;/p&gt;

&lt;p&gt;For detailed penalty calculations, you can use the &lt;a href="https://www.markitsolutions.in/tools/gst-interest-calculator" rel="noopener noreferrer"&gt;GST Interest Calculator&lt;/a&gt; or the &lt;a href="https://www.markitsolutions.in/tools/gst-late-fee-calculator" rel="noopener noreferrer"&gt;GST Late Fee Calculator&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  FY 2026-27 Setup Checklist
&lt;/h2&gt;

&lt;p&gt;Since April marks the start of a new financial year, businesses also need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create new financial year&lt;/strong&gt; in their accounting software&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Start new invoice series&lt;/strong&gt; — don't continue last year's numbering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify opening balances&lt;/strong&gt; carry forward correctly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update GST rates&lt;/strong&gt; if any changes were notified&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you use TallyPrime, here's a &lt;a href="https://www.markitsolutions.in/blog-details/new-financial-year-tallyprime-fy-2026-27-setup-guide" rel="noopener noreferrer"&gt;complete FY 2026-27 setup checklist&lt;/a&gt; and a guide on &lt;a href="https://www.markitsolutions.in/blog-details/new-invoice-series-april-2026-tallyprime-setup-guide" rel="noopener noreferrer"&gt;setting up new invoice series for April 2026&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  QRMP Scheme: Which Deadline Applies to You?
&lt;/h2&gt;

&lt;p&gt;If your turnover is under ₹5 crore, you're likely on the QRMP (Quarterly Return, Monthly Payment) scheme. Your GSTR-3B deadline depends on your state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;April 22:&lt;/strong&gt; Maharashtra, Gujarat, Karnataka, Tamil Nadu, Kerala, Telangana, AP, MP, Chhattisgarh, Goa&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;April 24:&lt;/strong&gt; All other states and UTs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mumbai businesses — your deadline is &lt;strong&gt;April 22&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Filing GST Returns from Accounting Software
&lt;/h2&gt;

&lt;p&gt;Modern accounting software like TallyPrime can generate GSTR-1 and GSTR-3B data in the JSON format required by the GST portal. The workflow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reconcile your books (check for HSN code errors, rate mismatches)&lt;/li&gt;
&lt;li&gt;Export the JSON file from your software&lt;/li&gt;
&lt;li&gt;Upload to gst.gov.in&lt;/li&gt;
&lt;li&gt;Verify and submit using DSC, EVC, or e-Sign&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This eliminates manual data entry and reduces filing errors significantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.markitsolutions.in/blog-details/gst-due-dates-april-2026-compliance-calendar" rel="noopener noreferrer"&gt;Full April 2026 Compliance Calendar&lt;/a&gt; — detailed guide with all 14 deadlines&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.markitsolutions.in/tools/gst-return-due-date-finder" rel="noopener noreferrer"&gt;GST Return Due Date Finder&lt;/a&gt; — look up any return's due date&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.markitsolutions.in/blog-details/what-is-tallyprime-complete-guide-indian-businesses" rel="noopener noreferrer"&gt;What is TallyPrime?&lt;/a&gt; — complete guide for Indian businesses&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This is part of an ongoing series on GST compliance for Indian businesses. Follow for monthly deadline updates and practical compliance guides.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>gst</category>
      <category>india</category>
      <category>accounting</category>
      <category>tax</category>
    </item>
    <item>
      <title>How to Automate GSTR-2A Reconciliation with Python: A Practical Guide for Indian Accountants</title>
      <dc:creator>Robin</dc:creator>
      <pubDate>Tue, 17 Feb 2026 07:47:39 +0000</pubDate>
      <link>https://dev.to/robinsinghvi/how-to-automate-gstr-2a-reconciliation-with-python-a-practical-guide-for-indian-accountants-mpo</link>
      <guid>https://dev.to/robinsinghvi/how-to-automate-gstr-2a-reconciliation-with-python-a-practical-guide-for-indian-accountants-mpo</guid>
      <description>&lt;p&gt;If you work in accounts payable at an Indian company, you already know the dread: every month, someone opens a spreadsheet, pulls up the GSTR-2A from the GST portal, and spends the next two or three days manually ticking off purchase invoices one by one. For mid-sized businesses with hundreds of vendors, that process can easily eat 15–20 hours a month — and still produce errors.&lt;/p&gt;

&lt;p&gt;This guide shows you how to automate GSTR-2A reconciliation using Python. We'll load real-world-style data, normalize it, do exact and fuzzy matching, and generate a color-coded Excel report your accountant can actually use.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is GSTR-2A and Why Does It Need Reconciliation?
&lt;/h2&gt;

&lt;p&gt;For readers who aren't accountants: GSTR-2A is an auto-populated return on India's GST portal. Every time one of your suppliers files their outward supply return (GSTR-1), their invoices addressed to your GSTIN automatically appear in your GSTR-2A.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why it matters:&lt;/strong&gt; You can only claim Input Tax Credit (ITC) on purchases that appear in your GSTR-2A &lt;em&gt;and&lt;/em&gt; match your purchase register (the book of invoices your accounting software records). If your books say you paid ₹50,000 in GST to a supplier but the portal doesn't show it, you can't claim that ITC. Under Rule 36(4), excess ITC claims can attract demand notices and interest.&lt;/p&gt;

&lt;p&gt;The reconciliation task is: compare every row in your purchase register against every row in your GSTR-2A, flag the matches, and investigate the gaps.&lt;/p&gt;




&lt;h2&gt;
  
  
  Data Sources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Purchase Register (from Tally/ERP)
&lt;/h3&gt;

&lt;p&gt;Exported from TallyPrime or any ERP as CSV or Excel, it typically has these columns:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;supplier_gstin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;27AABCU9603R1ZX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;invoice_no&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;INV/2025-26/0042&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;invoice_date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;15-Apr-2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;taxable_amount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;42372.88&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;igst&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7627.12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cgst&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sgst&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;total_amount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  2. GSTR-2A (from GST Portal)
&lt;/h3&gt;

&lt;p&gt;Downloaded as Excel (or JSON via the GST API). The Excel download has sheets like &lt;code&gt;B2B&lt;/code&gt;, &lt;code&gt;B2BA&lt;/code&gt;, &lt;code&gt;CDN&lt;/code&gt;, etc. We'll focus on &lt;code&gt;B2B&lt;/code&gt; (regular B2B invoices). Columns from the portal:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GSTIN of Supplier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;27AABCU9603R1ZX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Invoice Number&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;INV-2025-26-0042&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Invoice date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;15-04-2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Invoice Value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Taxable Value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;42372.88&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Integrated Tax&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;7627.12&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice already: the invoice number format differs between the two sources (&lt;code&gt;INV/2025-26/0042&lt;/code&gt; vs &lt;code&gt;INV-2025-26-0042&lt;/code&gt;). This is the single biggest cause of failed matches, and it's why we need fuzzy matching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Python Setup
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pandas openpyxl rapidfuzz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pandas&lt;/strong&gt; — data loading, merging, filtering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;openpyxl&lt;/strong&gt; — write formatted Excel output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;rapidfuzz&lt;/strong&gt; — fast fuzzy string matching (drop-in replacement for fuzzywuzzy, no C compiler needed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Python 3.9+ recommended.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Load and Normalize the Data
&lt;/h2&gt;

&lt;p&gt;The first step is the most important one: get both datasets into a clean, comparable form. GSTIN formatting varies (spaces, lowercase, leading zeros), and dates come in half a dozen formats across different ERPs and the portal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="c1"&gt;# ── Load data ──────────────────────────────────────────────────────────────
&lt;/span&gt;&lt;span class="n"&gt;purchase_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;purchase_register.xlsx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# GSTR-2A B2B sheet (portal download has a few header rows to skip)
&lt;/span&gt;&lt;span class="n"&gt;gstr2a_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GSTR2A_Apr2025.xlsx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sheet_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;B2B&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;skiprows&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# portal puts metadata in first 4 rows
&lt;/span&gt;    &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ── Rename columns to consistent internal names ────────────────────────────
&lt;/span&gt;&lt;span class="n"&gt;purchase_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;purchase_df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;supplier_gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;invoice_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;invoice_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;igst&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;           &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;igst&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;gstr2a_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gstr2a_df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GSTIN of Supplier&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invoice Number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invoice date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invoice Value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Integrated Tax&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;igst&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Keep only needed columns
&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;igst&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;purchase_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;purchase_df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;gstr2a_df&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gstr2a_df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;normalize_gstin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;normalize_inv_no&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Fold separators: 'INV/2025/001', 'INV-2025-001', 'INV 2025 001' -&amp;gt; 'INV2025001'
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isna&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[\\s/\\-_.,]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;normalize_amount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;except &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;


&lt;span class="c1"&gt;# ── Apply normalizations ───────────────────────────────────────────────────
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;purchase_df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gstr2a_df&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalize_gstin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# keep original for report
&lt;/span&gt;    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalize_inv_no&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalize_amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_datetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dayfirst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coerce&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Purchase register rows : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;purchase_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GSTR-2A rows           : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gstr2a_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After normalization, &lt;code&gt;INV/2025-26/0042&lt;/code&gt; and &lt;code&gt;INV-2025-26-0042&lt;/code&gt; both become &lt;code&gt;INV202526004​2&lt;/code&gt; — ready for matching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Exact Matching
&lt;/h2&gt;

&lt;p&gt;We merge on three fields simultaneously: GSTIN + normalized invoice number + amount. This catches the majority of clean, well-entered records.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ── Exact merge ────────────────────────────────────────────────────────────
&lt;/span&gt;&lt;span class="n"&gt;merged&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;purchase_df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;gstr2a_df&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;outer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;suffixes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_books&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_portal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;indicator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Categorize each row
&lt;/span&gt;&lt;span class="n"&gt;matched&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_merge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;both&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;only_books&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_merge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left_only&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;only_portal&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;merged&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;_merge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;right_only&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;n── Exact match results ──────────────────────&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Matched (exact)        : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matched&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Only in books          : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;only_books&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Only in GSTR-2A        : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;only_portal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Match rate             : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matched&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;purchase_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sample output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;── Exact match results ──────────────────────
Matched (exact)        : 312
Only in books          : 47
Only in GSTR-2A        : 19
Match rate             : 86.9%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 47 "only in books" entries are your ITC-at-risk items — the supplier hasn't filed, or there's a data mismatch. The 19 "only in portal" entries are invoices suppliers uploaded that you haven't booked yet (possible missed purchases or duplicate supplier filings).&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Fuzzy Matching for Near-Misses
&lt;/h2&gt;

&lt;p&gt;The ~13% unmatched often contains legitimate invoices that failed due to minor formatting differences that survive normalization — extra zeros, financial year notation differences, or plain typos. We'll use &lt;code&gt;rapidfuzz&lt;/code&gt; to score every unmatched book entry against every unmatched portal entry &lt;em&gt;for the same GSTIN&lt;/em&gt;, then accept matches above a confidence threshold.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rapidfuzz&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fuzz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;

&lt;span class="n"&gt;FUZZY_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;   &lt;span class="c1"&gt;# lower = more matches but more false positives
&lt;/span&gt;
&lt;span class="n"&gt;fuzzy_matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;unmatched_books&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;unmatched_portal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_portal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;unmatched_books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterrows&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Candidate pool: same GSTIN, amount within ±1% (absorbs rounding differences)
&lt;/span&gt;    &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unmatched_portal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unmatched_portal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unmatched_portal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;between&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.01&lt;/span&gt;
        &lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;

    &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extractOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;scorer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fuzz&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token_sort_ratio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;# handles word-order differences too
&lt;/span&gt;        &lt;span class="n"&gt;score_cutoff&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;FUZZY_THRESHOLD&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;matched_inv_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;
        &lt;span class="n"&gt;portal_row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;matched_inv_no&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;fuzzy_matches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gstin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_books&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_portal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;portal_row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;portal_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="n"&gt;book_row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fuzzy_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;match_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fuzzy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="n"&gt;fuzzy_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_matches&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;n── Fuzzy match results ──────────────────────&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Additional fuzzy matches : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_books&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_portal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;fuzzy_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Threshold guidance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;≥ 95&lt;/strong&gt;: Very strict — only catches separator/case differences&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;88–94&lt;/strong&gt;: Recommended — catches typos, extra zeros, format differences&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;80–87&lt;/strong&gt;: Liberal — may produce false positives; review manually&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 4: Generate the Reconciliation Report
&lt;/h2&gt;

&lt;p&gt;Export everything to a single Excel workbook with three sheets and color-coded rows so your CA or finance team can work through it without touching Python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openpyxl&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_workbook&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openpyxl.styles&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PatternFill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Font&lt;/span&gt;

&lt;span class="c1"&gt;# Remove fuzzy-matched rows from unmatched lists
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fuzzy_book_invs&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_books&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;fuzzy_portal_invs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_portal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;inv_no_raw_books&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;only_books&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;inv_no_raw_portal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_portal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no_raw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;only_portal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inv_no&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;only_books_final&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_books&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;inv_no_raw_books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_book_invs&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;only_portal_final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_portal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="n"&gt;inv_no_raw_portal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_portal_invs&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;only_books_final&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_books&lt;/span&gt;
    &lt;span class="n"&gt;only_portal_final&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;only_portal&lt;/span&gt;

&lt;span class="n"&gt;output_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GSTR2A_Reconciliation_Apr2025.xlsx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ExcelWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;openpyxl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;matched&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="n"&gt;sheet_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Matched&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="n"&gt;sheet_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fuzzy_Matched&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;only_books_final&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;sheet_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Only_In_Books&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;only_portal_final&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_excel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sheet_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Only_In_Portal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;GREEN&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PatternFill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;solid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fgColor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C6EFCE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;YELLOW&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PatternFill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;solid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fgColor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FFEB9C&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;RED&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PatternFill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;solid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fgColor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FFC7CE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ORANGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PatternFill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;solid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fgColor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FCE4D6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;wb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_workbook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;color_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_rows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_row&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fill&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;font&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bold&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;color_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Matched&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;        &lt;span class="n"&gt;GREEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;color_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fuzzy_Matched&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="n"&gt;ORANGE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;color_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Only_In_Books&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="n"&gt;RED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;color_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Only_In_Portal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;YELLOW&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;wb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Report saved → &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;output_path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  ✅ Exact matched  : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matched&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  🟠 Fuzzy matched  : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fuzzy_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  🔴 Only in books  : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;only_books_final&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  ← ITC at risk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  🟡 Only in portal : &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;only_portal_final&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; ← not yet booked&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What to Do With the Mismatches
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Red rows — only in your books (ITC at risk):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contact the supplier and ask them to file or amend their GSTR-1&lt;/li&gt;
&lt;li&gt;If the supplier is under the composition scheme or is unregistered, ITC isn't available regardless — pass the cost to P&amp;amp;L&lt;/li&gt;
&lt;li&gt;Document your follow-up trail. If the portal still doesn't show the invoice by the time you file your annual return, you'll need to reverse the ITC in GSTR-3B with interest under Rule 42/43&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Yellow rows — only in GSTR-2A (not in your books):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-check against pending GRNs — goods may have been received but not entered in Tally yet&lt;/li&gt;
&lt;li&gt;Watch for duplicate entries: some suppliers accidentally file the same invoice twice with a slightly different amount&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tax head mismatches:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes a supplier files an intra-state supply as interstate (or vice versa). The total amount matches, but the IGST vs CGST+SGST split is wrong. Add a column-level check on the tax fields for matched rows to catch these before they cause problems in GSTR-3B.&lt;/p&gt;




&lt;h2&gt;
  
  
  Taking It Further
&lt;/h2&gt;

&lt;p&gt;This Python pipeline gives you full control and works with any accounting system that can export to Excel or CSV. For businesses using TallyPrime, the process is even simpler — &lt;a href="https://www.markitsolutions.in/blog-details/automated-gst-compliance-sme-implementation-guide.html" rel="noopener noreferrer"&gt;Mark IT Solutions&lt;/a&gt; has documented how TallyPrime's built-in reconciliation handles most of this automatically, including direct GST portal connectivity. But for teams on other systems — SAP, Zoho Books, custom ERPs — or who want full programmatic control over the matching logic, this approach is hard to beat.&lt;/p&gt;

&lt;p&gt;Some ways to extend the script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Schedule it monthly&lt;/strong&gt; with a cron job or Windows Task Scheduler and pipe the output to email&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supplier-wise ITC risk summary&lt;/strong&gt;: group &lt;code&gt;only_books_final&lt;/code&gt; by GSTIN, aggregate unmatched tax amounts, and flag suppliers with repeat mismatches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GST API integration&lt;/strong&gt;: instead of manual downloads, pull GSTR-2A data programmatically via a GST Suvidha Provider (GSP) — this makes the workflow fully automated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamlit front-end&lt;/strong&gt;: wrap the script in a simple web UI so non-technical staff can upload files and run reconciliation with a button click&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push results back to Tally&lt;/strong&gt;: &lt;a href="https://www.markitsolutions.in/services/tally-customization.html" rel="noopener noreferrer"&gt;custom Tally integrations&lt;/a&gt; can write reconciliation outcomes back into TallyPrime ledgers automatically, eliminating the manual journal entry step entirely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 15–20 hours your accountant spends on this every month can realistically drop to 30 minutes of file uploads and a focused review of the flagged rows. The Python part runs in seconds even for thousands of invoices.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have questions or want to share how you've adapted this for GSTR-2B? Drop a comment below — the matching logic is nearly identical, just with different column names and stricter ITC cut-off rules.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>gst</category>
      <category>india</category>
      <category>accounting</category>
    </item>
    <item>
      <title>5 Signs Your Business Has Outgrown Its Accounting Software</title>
      <dc:creator>Robin</dc:creator>
      <pubDate>Tue, 17 Feb 2026 05:09:24 +0000</pubDate>
      <link>https://dev.to/robinsinghvi/5-signs-your-business-has-outgrown-its-accounting-software-2b6d</link>
      <guid>https://dev.to/robinsinghvi/5-signs-your-business-has-outgrown-its-accounting-software-2b6d</guid>
      <description>&lt;h1&gt;
  
  
  5 Signs Your Business Has Outgrown Its Accounting Software
&lt;/h1&gt;

&lt;p&gt;Every business starts somewhere. Maybe it was a spreadsheet. Maybe a basic accounting tool a friend recommended. It worked fine when you had 10 invoices a month and one bank account. But businesses grow — and the tools that got you here won't get you there.&lt;/p&gt;

&lt;p&gt;The challenge is recognizing &lt;em&gt;when&lt;/em&gt; your accounting software has become a liability rather than an asset. Many business owners don't realize they're working around their software's limitations until those workarounds are consuming hours every week.&lt;/p&gt;

&lt;p&gt;Here are five clear signs it's time to upgrade — and what that upgrade actually looks like for Indian businesses in 2026.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. You're Spending More Time on Compliance Than on Business
&lt;/h2&gt;

&lt;p&gt;India's GST regime has added real complexity to business accounting. With GSTR-1, GSTR-3B, GSTR-9, TDS returns, and now Input Tax Credit reconciliation through IMS (Invoice Management System), compliance is a multi-step, multi-deadline obligation that runs every single month.&lt;/p&gt;

&lt;p&gt;If your accountant spends the majority of their time preparing GST returns rather than analyzing your business performance, your software is working against you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's actually happening:&lt;/strong&gt; When software doesn't integrate with GSTN, your team manually downloads reports, re-enters data into the government portal, cross-checks figures, and hopes nothing was missed. A single mismatch between GSTR-1 and GSTR-3B can trigger a notice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The statistics tell the story:&lt;/strong&gt; According to surveys of Indian SMEs, businesses using non-integrated accounting software spend an average of 2–3 days per month on GST compliance tasks that could be reduced to a few hours with integrated software. That's 24–36 days per year of accountant time lost to preventable manual work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What modern software does instead:&lt;/strong&gt; TallyPrime generates GSTR-1, GSTR-3B, and annual returns directly from your transaction data. No re-entry, no manual calculations, no last-minute panic before filing deadlines. The new IMS module in TallyPrime 7.0 even lets businesses review, accept, or reject supplier invoices directly, ensuring ITC claims are accurate before filing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical tip:&lt;/strong&gt; Track how many hours per month your team spends on GST-related tasks that aren't transaction entry or analysis. If it's more than 8 hours, you're likely paying for manual workarounds that integrated software would eliminate.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Bank Reconciliation Takes Days, Not Minutes
&lt;/h2&gt;

&lt;p&gt;Bank reconciliation is one of those tasks that sounds simple — match your bank statement to your books — but becomes a nightmare as transaction volumes grow. A business processing 200+ transactions a month, with multiple bank accounts, can spend an entire day or more on reconciliation each month.&lt;/p&gt;

&lt;p&gt;The classic pain points: downloading statements in PDF format, converting them to Excel, manually matching entries, hunting for that one Rs 500 mismatch that throws off the entire reconciliation, and then repeating the process for each bank account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this matters beyond the time cost:&lt;/strong&gt; Delayed reconciliation means your cash position is always outdated. Decisions about vendor payments, purchase commitments, or credit lines are being made on stale data. In a business where cash flow is everything, this creates real risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TallyPrime 7.0's Connected Banking&lt;/strong&gt; addresses this directly. The feature auto-imports transactions from supported banks and matches them with existing vouchers in your books. What used to take a full day now takes 15 minutes. Unmatched entries are flagged for review rather than buried in a spreadsheet.&lt;/p&gt;

&lt;p&gt;For businesses managing multiple current accounts, OD facilities, or sweep accounts, this feature alone often justifies the upgrade cost within the first quarter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical tip:&lt;/strong&gt; Before your next reconciliation, time how long it takes from start to finish. Include the time spent on follow-ups with the bank or finding missing entries. That number — multiplied by 12 — is your annual cost of manual reconciliation.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. You Can't Get Real-Time Business Insights
&lt;/h2&gt;

&lt;p&gt;"How did we do last month?" shouldn't be a question that requires two days to answer.&lt;/p&gt;

&lt;p&gt;Yet for many businesses running older accounting software, the answer to basic management questions involves waiting for the accountant to pull data, format it into a report, and send it over. By that time, the month is already two weeks old and decisions being made are based on information that's weeks out of date.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gap between data and decisions:&lt;/strong&gt; Modern business requires faster responses. Your top customer's payment terms, your current inventory turnover, your receivables aging, your gross margin by product line — these are all numbers you should be able to access in under a minute, at any time, without asking anyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What good accounting software provides:&lt;/strong&gt; Instant access to P&amp;amp;L, balance sheet, cash flow statement, receivables and payables aging, stock summary, and cost center analysis — all live, all current, all accessible without generating a formal report.&lt;/p&gt;

&lt;p&gt;TallyPrime's connected reports let you drill down from a summary to the individual transaction that created it. If the cash balance looks wrong, you're two clicks away from finding out why. If one product is dragging down margins, you can isolate it immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For multi-product businesses, this is transformative.&lt;/strong&gt; A manufacturer with 50 SKUs needs to know which items are slow-moving and tying up working capital. A trader needs to know which customers are stretching payment terms beyond agreed limits. These insights are available in real time with modern software — not two weeks after month-end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical tip:&lt;/strong&gt; Ask yourself: if you wanted to know your current receivables aging right now, how long would it take? If the answer isn't "under two minutes," your software is limiting your decision-making speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Multi-Location or Multi-User Access Is a Nightmare
&lt;/h2&gt;

&lt;p&gt;In 2010, it was acceptable to run accounting on one computer in the office. The accountant sat at that machine, entered data, and everyone else waited for reports. That model doesn't work anymore.&lt;/p&gt;

&lt;p&gt;Today's businesses operate across multiple locations, with owners who travel, finance teams split between offices, and accountants who need remote access. The classic workarounds — shared drives, USB data files, email exports, remote desktop connections — all create their own problems: data conflicts, version control issues, security risks, and constant coordination overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signs you've outgrown single-user access:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone has to "check out" the Tally data file before others can use it&lt;/li&gt;
&lt;li&gt;The accountant can only work from the office&lt;/li&gt;
&lt;li&gt;You can't see live numbers while travelling&lt;/li&gt;
&lt;li&gt;Creating consolidated reports for multi-branch operations requires manual merging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TallyPrime's multi-user mode allows simultaneous access across your network. For businesses that need remote access, TallyPrime on cloud (available through authorized partners) provides browser-based access from any location, with the same feature set and without the performance issues of traditional remote desktop setups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For growing businesses specifically:&lt;/strong&gt; If you're planning to open a second location, or already managing one, centralized accounting with branch-level reporting is essential. Without it, consolidation is always manual, always delayed, and always prone to error.&lt;/p&gt;

&lt;p&gt;You can learn more about the differences between local and cloud deployment options in this detailed comparison: &lt;a href="https://www.markitsolutions.in/blog-details/tally-on-cloud-vs-local-server-mumbai-traders-2026.html" rel="noopener noreferrer"&gt;Tally on Cloud vs Local Server: What Mumbai Traders Need to Know&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. You're Manually Handling E-Invoicing and E-Way Bills
&lt;/h2&gt;

&lt;p&gt;E-invoicing became mandatory for businesses with turnover above Rs 5 crore in August 2023. E-way bills are required for goods movement above Rs 50,000. If you're in either category, these aren't optional — and how you generate them has a direct impact on your team's efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The manual approach is fragile:&lt;/strong&gt; Log in to the government portal, copy your invoice details, submit, download the IRN and QR code, attach it to your invoice, send to the customer. Repeat for every sales invoice. For a business raising 30+ invoices a day, this is an hour or more of daily work — and any connectivity issue with the portal can create delays that hold up your shipments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The integrated approach eliminates the portal workflow entirely.&lt;/strong&gt; TallyPrime generates IRNs directly from your sales vouchers. The QR code is embedded in your printed invoice. E-way bills are generated in the same flow. Your team doesn't need to log into a government portal, and there's no data re-entry that could introduce errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The compliance risk of manual handling:&lt;/strong&gt; When IRN generation is separate from your invoicing software, mismatches between what's in your books and what's registered on the portal are common. These discrepancies create ITC issues for your customers and can trigger scrutiny from the GST department.&lt;/p&gt;

&lt;p&gt;If you're still navigating e-invoicing as a manual process, this is one of the strongest arguments for upgrading. The &lt;a href="https://www.markitsolutions.in/blog-details/what-is-tallyprime-complete-guide-indian-businesses.html" rel="noopener noreferrer"&gt;complete TallyPrime guide for Indian businesses&lt;/a&gt; covers exactly how integrated e-invoicing works and what setup it requires.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Upgrade Doesn't Have to Be Painful
&lt;/h2&gt;

&lt;p&gt;The biggest fear businesses have about switching accounting software — or upgrading from an older version — is data migration. Will they lose years of financial records? Will the transition disrupt operations during a busy period? Will the team need weeks of training?&lt;/p&gt;

&lt;p&gt;These fears are understandable but largely unfounded when the upgrade is handled properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For TallyPrime specifically:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Migration from Tally.ERP 9 or older TallyPrime versions is automatic — your existing data converts without manual re-entry&lt;/li&gt;
&lt;li&gt;The interface is familiar to anyone who has used Tally before; the learning curve is minimal&lt;/li&gt;
&lt;li&gt;New features are additive, not replacing workflows your team already knows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The real question isn't whether to upgrade — it's when.&lt;/strong&gt; Every month you delay is a month of manual reconciliation, compliance hours, and delayed decisions. The cost of staying on outdated software compounds quietly until it becomes obvious.&lt;/p&gt;

&lt;p&gt;For businesses in Mumbai and Maharashtra, working with an experienced implementation partner makes the transition significantly smoother. A good partner doesn't just install the software — they configure it to match your specific business workflows, migrate your historical data cleanly, and train your team on the features most relevant to your operations.&lt;/p&gt;

&lt;p&gt;Mark IT Solutions (markitsolutions.in) is a 5-Star Certified Tally Partner based in Mumbai with over 25 years of implementation experience. From single-user retail setups to multi-branch manufacturing enterprises, they handle the complete transition — installation, configuration, data migration, and ongoing support.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Quick Self-Assessment
&lt;/h2&gt;

&lt;p&gt;Ask yourself these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does GST filing feel like a crisis every month?&lt;/li&gt;
&lt;li&gt;Do you know your current cash balance without asking your accountant?&lt;/li&gt;
&lt;li&gt;Can your finance team access the books from home or a different office?&lt;/li&gt;
&lt;li&gt;Is e-invoicing a manual, multi-step process for your team?&lt;/li&gt;
&lt;li&gt;Did your last bank reconciliation take more than 2 hours?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you answered yes to two or more, your accounting software is holding your business back. The good news: the upgrade path is clear, the migration is painless, and the productivity gains typically show up within the first month.&lt;/p&gt;

&lt;p&gt;The tools that got you here have done their job. It's time for the ones that will take you further.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Running a business in India and evaluating your accounting software options? The team at &lt;a href="https://markitsolutions.in" rel="noopener noreferrer"&gt;Mark IT Solutions&lt;/a&gt; offers a free consultation and demo for businesses considering TallyPrime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tally</category>
      <category>accounting</category>
      <category>india</category>
      <category>sme</category>
    </item>
    <item>
      <title>How TallyPrime's Connected Banking Is Automating Bank Reconciliation for Indian Businesses</title>
      <dc:creator>Robin</dc:creator>
      <pubDate>Mon, 16 Feb 2026 14:00:02 +0000</pubDate>
      <link>https://dev.to/robinsinghvi/how-tallyprimes-connected-banking-is-automating-bank-reconciliation-for-indian-businesses-3b0g</link>
      <guid>https://dev.to/robinsinghvi/how-tallyprimes-connected-banking-is-automating-bank-reconciliation-for-indian-businesses-3b0g</guid>
      <description>&lt;h1&gt;
  
  
  How TallyPrime's Connected Banking Feature Is Automating Bank Reconciliation for Indian Businesses
&lt;/h1&gt;

&lt;p&gt;Bank reconciliation has traditionally been one of the most tedious tasks in accounting. For businesses using Tally software in India, this meant manually downloading bank statements, importing them, and matching transactions one by one. With TallyPrime's Connected Banking feature, that workflow has fundamentally changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Old Way: Manual Reconciliation Pain Points
&lt;/h2&gt;

&lt;p&gt;If you've ever managed books for an Indian SME, you know the drill:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log into your bank portal&lt;/li&gt;
&lt;li&gt;Download statements in CSV/Excel format&lt;/li&gt;
&lt;li&gt;Import into your accounting software&lt;/li&gt;
&lt;li&gt;Manually match each transaction&lt;/li&gt;
&lt;li&gt;Investigate discrepancies&lt;/li&gt;
&lt;li&gt;Repeat for every bank account&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For a business processing hundreds of transactions monthly, this could consume days of work. And the error rate? Let's just say manual matching is where mistakes love to hide.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Connected Banking Changes Everything
&lt;/h2&gt;

&lt;p&gt;TallyPrime's Connected Banking integrates directly with major Indian banks, pulling transaction data automatically into your accounting software. Here's what that looks like in practice:&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Statement Fetching
&lt;/h3&gt;

&lt;p&gt;Instead of downloading CSV files, TallyPrime connects to your bank via secure APIs. Transactions appear in your books within hours of clearing, not days.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intelligent Matching
&lt;/h3&gt;

&lt;p&gt;The software uses pattern recognition to automatically match bank transactions with ledger entries. Regular payments like rent, salaries, and vendor payments get matched without human intervention after the first few cycles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exception-Based Workflow
&lt;/h3&gt;

&lt;p&gt;Rather than reviewing every transaction, accountants only need to look at unmatched or flagged items. This transforms reconciliation from a full-day exercise into a 30-minute review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Implementation
&lt;/h2&gt;

&lt;p&gt;For businesses looking to set up Connected Banking, the process involves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Update to TallyPrime 4.0 or later
2. Navigate to Banking &amp;gt; Connected Banking Setup
3. Select your bank from the supported list
4. Complete the bank-side authorization
5. Configure auto-fetch schedules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setup typically takes under an hour, but the time savings compound quickly. A business processing 500+ transactions monthly can save 15-20 hours per month on reconciliation alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Banks and Limitations
&lt;/h2&gt;

&lt;p&gt;As of 2026, Connected Banking supports most major Indian banks including SBI, HDFC, ICICI, Axis, and Kotak. However, support for cooperative banks and newer fintech platforms is still limited.&lt;/p&gt;

&lt;p&gt;For businesses using multiple banks, each account needs separate configuration, but the reconciliation dashboard provides a unified view across all connected accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Impact
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://www.markitsolutions.in" rel="noopener noreferrer"&gt;Mumbai-based Tally service provider&lt;/a&gt; reported that their clients implementing Connected Banking saw:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;70% reduction&lt;/strong&gt; in reconciliation time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;90% fewer&lt;/strong&gt; manual data entry errors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster month-end closing&lt;/strong&gt; by 3-5 business days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest impact was on businesses with high transaction volumes—retailers, distributors, and trading companies where daily bank entries run into the hundreds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Automated Reconciliation Rules
&lt;/h2&gt;

&lt;p&gt;One of the underutilized features is custom reconciliation rules. You can define matching criteria based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transaction amount (exact or range)&lt;/li&gt;
&lt;li&gt;Narration keywords&lt;/li&gt;
&lt;li&gt;Date proximity&lt;/li&gt;
&lt;li&gt;Reference numbers
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Conceptual example of matching logic
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;match_transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bank_entry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ledger_entries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ledger_entries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bank_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.01&lt;/span&gt;
            &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bank_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
            &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bank_entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;narration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;narration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting up these rules upfront means the system gets smarter over time, reducing manual intervention with each passing month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration with GST Returns
&lt;/h2&gt;

&lt;p&gt;Connected Banking also simplifies GST reconciliation. When bank transactions are automatically matched with invoices, the data flows seamlessly into GST return preparation. This is particularly valuable for businesses dealing with &lt;a href="https://www.markitsolutions.in/blog-details/gst-compliance-guide-indian-businesses" rel="noopener noreferrer"&gt;complex GST compliance requirements&lt;/a&gt; where accurate transaction records are essential.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;If you're running TallyPrime and haven't enabled Connected Banking yet, it's worth the hour of setup time. The feature is included in all TallyPrime editions with an active TSS (Tally Software Services) subscription.&lt;/p&gt;

&lt;p&gt;For businesses that need help with implementation or customization of their Tally setup, working with a certified Tally partner ensures the configuration is optimized for your specific banking relationships and transaction patterns.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you implemented Connected Banking in your business? Share your experience in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tally</category>
      <category>fintech</category>
      <category>india</category>
      <category>automation</category>
    </item>
    <item>
      <title>7 Critical GST Compliance Challenges That Indian SMEs Face in 2026</title>
      <dc:creator>Robin</dc:creator>
      <pubDate>Mon, 16 Feb 2026 13:59:17 +0000</pubDate>
      <link>https://dev.to/robinsinghvi/7-critical-gst-compliance-challenges-that-indian-smes-face-in-2026-13eb</link>
      <guid>https://dev.to/robinsinghvi/7-critical-gst-compliance-challenges-that-indian-smes-face-in-2026-13eb</guid>
      <description>&lt;h1&gt;
  
  
  7 Critical GST Compliance Challenges That Indian SMEs Face in 2026
&lt;/h1&gt;

&lt;p&gt;The Goods and Services Tax (GST) system has been operational in India for nearly nine years now, yet small and medium enterprises (SMEs) continue to grapple with compliance complexities that can make or break their business operations. As we progress through 2026, these challenges have evolved but remain as pressing as ever for the backbone of India's economy.&lt;/p&gt;

&lt;p&gt;Recent data from the Ministry of MSME shows that over 63 million SMEs contribute approximately 30% to India's GDP and 48% to exports. However, a significant portion of these businesses still struggle with GST compliance, leading to penalties, cash flow disruptions, and operational inefficiencies that could be avoided with proper understanding and systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem in Detail
&lt;/h2&gt;

&lt;p&gt;GST compliance isn't just about filing monthly returns—it's a comprehensive framework that touches every aspect of business operations. When SMEs fail to manage this effectively, the consequences extend far beyond immediate penalties. Businesses face cash flow crunches due to delayed input tax credit (ITC) claims, lose valuable time dealing with notices and rectifications, and often miss out on growth opportunities while firefighting compliance issues.&lt;/p&gt;

&lt;p&gt;The complexity stems from multiple factors: frequent changes in rules and rates, technical requirements for digital compliance, integration challenges with existing business processes, and the sheer volume of documentation required. For SMEs operating with limited resources and staff, these challenges can quickly become overwhelming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 1: The Documentation Nightmare
&lt;/h2&gt;

&lt;p&gt;One of the most persistent challenges facing Indian SMEs is maintaining accurate and complete documentation for GST compliance. The requirement extends beyond simple invoice generation to encompass detailed records of purchases, sales, input tax credits, and various exemptions or deductions claimed.&lt;/p&gt;

&lt;p&gt;Many businesses still operate with manual or semi-automated systems that make it difficult to maintain the level of detail required by GST authorities. This becomes particularly problematic during audits or when responding to GST notices, where businesses must produce comprehensive documentation dating back several years.&lt;/p&gt;

&lt;p&gt;The challenge is compounded by the fact that different types of transactions require different documentation standards. For instance, inter-state transactions, export documentation, and job work arrangements each have specific requirements that many SMEs find difficult to track consistently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 2: Input Tax Credit Management Complexities
&lt;/h2&gt;

&lt;p&gt;Input Tax Credit (ITC) represents one of the most valuable aspects of the GST system for businesses, yet it's also one of the most complex to manage correctly. SMEs often struggle with understanding which expenses qualify for ITC, how to claim credits on time, and most importantly, how to maintain the documentation trail required to substantiate their claims.&lt;/p&gt;

&lt;p&gt;The matching requirements between purchase and sales records create additional complexity. When suppliers fail to file their returns on time or report transactions incorrectly, buying businesses find their legitimate ITC claims blocked or reversed. This creates cash flow challenges that can be particularly severe for SMEs operating with tight margins.&lt;/p&gt;

&lt;p&gt;Many businesses discover ITC eligibility issues only during reconciliation exercises or audits, by which time it may be too late to claim legitimate credits. The time-bound nature of ITC claims means that delays in proper documentation or filing can result in permanent loss of tax credits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 3: Technology Integration Challenges
&lt;/h2&gt;

&lt;p&gt;The digital-first approach of GST requires businesses to integrate their operations with government portals and maintain electronic records. For many traditional SMEs, this represents a significant technological leap that requires both system upgrades and staff training.&lt;/p&gt;

&lt;p&gt;Integration between existing ERP systems and GST portals often presents technical challenges that small businesses lack the resources to address effectively. This results in manual data entry across multiple systems, increasing the risk of errors and consuming valuable time that could be better spent on business development.&lt;/p&gt;

&lt;p&gt;The frequent updates to GST portal functionalities and filing requirements mean that businesses must continuously adapt their systems and processes. SMEs without dedicated IT support find it particularly challenging to keep pace with these changes while maintaining business continuity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 4: Penalty Management and Compliance Costs
&lt;/h2&gt;

&lt;p&gt;The penalty structure under GST can be particularly harsh for businesses that fail to maintain proper compliance. Late filing fees, interest on delayed tax payments, and penalties for incorrect returns can quickly accumulate into significant amounts that strain SME finances.&lt;/p&gt;

&lt;p&gt;Beyond direct penalties, the indirect costs of non-compliance include time spent dealing with notices, professional fees for tax consultants, and opportunity costs from management attention diverted from core business activities. These hidden costs often exceed the direct penalty amounts and can significantly impact business profitability.&lt;/p&gt;

&lt;p&gt;The unpredictability of GST audits and the retroactive nature of many compliance requirements mean that businesses must maintain higher cash reserves to handle potential compliance costs, further straining working capital availability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 5: What the Solution Looks Like
&lt;/h2&gt;

&lt;p&gt;Effective GST compliance for SMEs requires a combination of proper systems, processes, and expertise. The solution isn't about finding shortcuts or workarounds, but about building robust compliance frameworks that can adapt to changing requirements while supporting business growth.&lt;/p&gt;

&lt;p&gt;A comprehensive compliance solution should include automated data capture and validation, real-time integration between business operations and tax filing requirements, and regular reconciliation processes that identify and resolve discrepancies before they become major issues.&lt;/p&gt;

&lt;p&gt;The ideal system would also provide predictive insights, alerting businesses to potential compliance issues before they occur and suggesting corrective actions. This proactive approach helps avoid penalties while ensuring that businesses can claim all eligible benefits under the GST system.&lt;/p&gt;

&lt;p&gt;Modern accounting software solutions have evolved to address many of these challenges. Platforms like TallyPrime have integrated GST compliance features that help automate much of the documentation and filing process while maintaining the flexibility that SMEs need for their diverse business operations.&lt;/p&gt;

&lt;p&gt;Companies like &lt;a href="https://www.markitsolutions.in/tally-customization" rel="noopener noreferrer"&gt;Mark IT Solutions&lt;/a&gt; in Mumbai have specialized in helping businesses implement and customize accounting solutions that streamline GST compliance while integrating with existing business processes. Their approach focuses on creating scalable solutions that grow with the business rather than requiring complete system overhauls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 6: Implementation Tips for SMEs
&lt;/h2&gt;

&lt;p&gt;Successfully managing GST compliance starts with establishing clear processes and responsibilities within the organization. Businesses should designate specific team members for compliance activities and ensure they receive regular training on GST requirements and system operations.&lt;/p&gt;

&lt;p&gt;Regular internal audits help identify compliance gaps before they become serious issues. These audits should cover all aspects of GST compliance, from invoice accuracy to ITC claims and return filing timeliness. The key is to make these audits routine rather than reactive exercises triggered by external notices.&lt;/p&gt;

&lt;p&gt;Businesses should also maintain regular communication with their tax advisors and stay informed about changes in GST rules and procedures. This proactive approach helps ensure that compliance systems evolve along with regulatory requirements.&lt;/p&gt;

&lt;p&gt;For detailed guidance on implementing automated GST compliance systems, businesses can refer to comprehensive resources such as &lt;a href="https://www.markitsolutions.in/blog-details/automated-gst-compliance-sme-implementation-guide" rel="noopener noreferrer"&gt;this implementation guide&lt;/a&gt; that covers step-by-step approaches to building robust compliance frameworks.&lt;/p&gt;

&lt;p&gt;Investment in proper training for staff members involved in GST-related activities pays dividends in terms of reduced errors and improved efficiency. This training should cover not just technical aspects of GST compliance but also the business implications of various decisions and their compliance consequences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;GST compliance doesn't have to be a burden that constrains business growth. With proper systems, processes, and expertise, SMEs can transform compliance from a reactive necessity into a competitive advantage that supports business expansion and profitability.&lt;/p&gt;

&lt;p&gt;The key is to approach compliance as an integral part of business operations rather than an external requirement to be managed separately. By investing in robust systems and building compliance capabilities, SMEs can focus on what they do best—growing their businesses and serving their customers—while ensuring they meet all regulatory requirements effectively.&lt;/p&gt;

&lt;p&gt;As India's economy continues to evolve and digitize, businesses that master GST compliance today will be better positioned to capitalize on tomorrow's opportunities. The investment in proper compliance infrastructure today pays dividends in terms of reduced risks, improved cash flows, and enhanced business credibility for years to come.&lt;/p&gt;

</description>
      <category>gst</category>
      <category>india</category>
      <category>sme</category>
      <category>accounting</category>
    </item>
  </channel>
</rss>
