""" Tax Articles Verification Script Run: bench --site [site-name] console Then copy this code into the console """ import frappe import unicodedata print("=" * 100) print("TAX ARTICLES VERIFICATION") print("=" * 100) # 1. Check for curly quotes print("\n1. CURLY QUOTES (should be 0):") print("-" * 100) curly_count = frappe.db.sql(""" SELECT COUNT(*) as count FROM `tabTax Article` WHERE HEX(article_name) LIKE '%E2809C%' OR HEX(article_name) LIKE '%E2809D%' """)[0][0] if curly_count == 0: print("✓ No curly quotes found") else: print(f"✗ Found {curly_count} articles with curly quotes!") # Show problematic articles articles = frappe.db.sql(""" SELECT name FROM `tabTax Article` WHERE HEX(article_name) LIKE '%E2809C%' OR HEX(article_name) LIKE '%E2809D%' LIMIT 5 """, as_dict=True) for a in articles: print(f" - {a['name'][:70]}...") # 2. Check NFD/NFC normalization print("\n2. NFD/NFC NORMALIZATION:") print("-" * 100) articles = frappe.db.sql(""" SELECT name, article_name FROM `tabTax Article` WHERE article_name IS NOT NULL AND article_name != '' """, as_dict=True) nfd_issues = [] for article in articles: original = article['article_name'] normalized = unicodedata.normalize('NFC', original) if len(original) != len(normalized): nfd_issues.append({ 'name': article['name'], 'len_original': len(original), 'len_normalized': len(normalized) }) if not nfd_issues: print("✓ All articles are in NFC form") else: print(f"✗ Found {len(nfd_issues)} articles requiring normalization:") for issue in nfd_issues[:5]: print(f" - {issue['name'][:60]}... ({issue['len_original']} → {issue['len_normalized']})") # 3. Check matching with report code print("\n3. MATCHING WITH REPORT CODE:") print("-" * 100) from taxes_az.taxes_az.report.tax_articles_revenue_report.tax_articles_revenue_report import get_tax_articles_mapping code_mapping = get_tax_articles_mapping() problem_keys = ['164.1.34-1', '164.1.41-2', '164.1.42', '164.1.47', '164.1.51'] mismatches = [] for key in problem_keys: articles = frappe.db.sql(""" SELECT name, article_name FROM `tabTax Article` WHERE name LIKE %s """, (f'%{key}%',), as_dict=True) for article in articles: if article['article_name'] not in code_mapping: mismatches.append({ 'key': key, 'name': article['name'], 'article_name': article['article_name'] }) if not mismatches: print("✓ All problem articles found in code") else: print(f"✗ {len(mismatches)} articles NOT found in code mapping:") for m in mismatches: print(f" - {m['key']}: {m['name'][:60]}...") # 4. Check data in Sales Invoice Items print("\n4. DATA IN SALES INVOICE ITEMS:") print("-" * 100) for key in problem_keys: count = frappe.db.sql(""" SELECT COUNT(*) as count FROM `tabSales Invoice Item` sii JOIN `tabSales Invoice` si ON sii.parent = si.name WHERE si.docstatus = 1 AND sii.tax_article LIKE %s """, (f'%{key}%',))[0][0] status = "✓" if count > 0 else "✗" print(f" {status} {key}: {count} records") # 5. Final summary print("\n" + "=" * 100) print("SUMMARY:") print("=" * 100) total_issues = curly_count + len(nfd_issues) + len(mismatches) if total_issues == 0: print("✓✓✓ ALL CHECKS PASSED! Tax Articles are OK.") else: print(f"⚠ Found {total_issues} issues:") if curly_count > 0: print(f" - Curly quotes: {curly_count}") if nfd_issues: print(f" - NFD normalization: {len(nfd_issues)}") if mismatches: print(f" - Not in code: {len(mismatches)}") print("\nRun normalization:") print("from taxes_az.normalize_tax_articles import normalize_tax_articles") print("normalize_tax_articles()") print("=" * 100)