Add flat Tally group master alongside proven ledger master
This commit is contained in:
@@ -4,7 +4,7 @@ import io
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
ERP_LOCAL_AGENT_VERSION = "1.26.7"
|
ERP_LOCAL_AGENT_VERSION = "1.26.8"
|
||||||
ERP_LOCAL_AGENT_NAME = "ERP Local Agent"
|
ERP_LOCAL_AGENT_NAME = "ERP Local Agent"
|
||||||
RUNTIME_ROOT = Path(__file__).resolve().parent / "local_agent_runtime"
|
RUNTIME_ROOT = Path(__file__).resolve().parent / "local_agent_runtime"
|
||||||
_DETERMINISTIC_ZIP_TIMESTAMP = (2026, 1, 1, 0, 0, 0)
|
_DETERMINISTIC_ZIP_TIMESTAMP = (2026, 1, 1, 0, 0, 0)
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
__version__ = "1.26.7"
|
__version__ = "1.26.8"
|
||||||
AGENT_NAME = "ERP Local Agent"
|
AGENT_NAME = "ERP Local Agent"
|
||||||
|
|||||||
@@ -245,6 +245,53 @@ class AccountingMirrorEngine:
|
|||||||
value = _text(value)
|
value = _text(value)
|
||||||
values.append(value)
|
values.append(value)
|
||||||
db.execute(f"INSERT INTO {table} ({','.join(names)}) VALUES ({placeholders})", values)
|
db.execute(f"INSERT INTO {table} ({','.join(names)}) VALUES ({placeholders})", values)
|
||||||
|
# Common flat accounting master table. Keep the original
|
||||||
|
# ledger_master and group_master physical tables intact.
|
||||||
|
db.execute("DROP TABLE IF EXISTS accounting_master_flat")
|
||||||
|
db.execute("""
|
||||||
|
CREATE TABLE accounting_master_flat (
|
||||||
|
object_type TEXT NOT NULL,
|
||||||
|
guid TEXT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
parent TEXT,
|
||||||
|
opening_balance REAL,
|
||||||
|
closing_balance REAL
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
db.execute("""
|
||||||
|
INSERT INTO accounting_master_flat(
|
||||||
|
object_type,guid,name,parent,opening_balance,closing_balance
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'LEDGER',
|
||||||
|
COALESCE(ledger_guid,''),
|
||||||
|
COALESCE(ledger_name,''),
|
||||||
|
COALESCE(parent_group,''),
|
||||||
|
opening_balance,
|
||||||
|
closing_balance
|
||||||
|
FROM ledger_master
|
||||||
|
""")
|
||||||
|
db.execute("""
|
||||||
|
INSERT INTO accounting_master_flat(
|
||||||
|
object_type,guid,name,parent,opening_balance,closing_balance
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'GROUP',
|
||||||
|
COALESCE(master_guid,''),
|
||||||
|
COALESCE(name,''),
|
||||||
|
COALESCE(parent,''),
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
FROM group_master
|
||||||
|
""")
|
||||||
|
db.execute(
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_accounting_master_flat_type_name "
|
||||||
|
"ON accounting_master_flat(object_type,name)"
|
||||||
|
)
|
||||||
|
db.execute(
|
||||||
|
"CREATE INDEX IF NOT EXISTS idx_accounting_master_flat_parent "
|
||||||
|
"ON accounting_master_flat(parent)"
|
||||||
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
||||||
|
|||||||
+5
@@ -19,6 +19,11 @@
|
|||||||
Fetch : Name, Parent, GUID, AlterID, OpeningBalance, ClosingBalance, IsRevenue, PartyGSTIN, GSTRegistrationType
|
Fetch : Name, Parent, GUID, AlterID, OpeningBalance, ClosingBalance, IsRevenue, PartyGSTIN, GSTRegistrationType
|
||||||
Is ODBC Table : Yes
|
Is ODBC Table : Yes
|
||||||
|
|
||||||
|
[Collection : ERPAMFlatGroupMaster]
|
||||||
|
Type : Group
|
||||||
|
Fetch : Name, Parent, GUID
|
||||||
|
Is ODBC Table : Yes
|
||||||
|
|
||||||
[Collection : ERPAMStockMaster]
|
[Collection : ERPAMStockMaster]
|
||||||
Type : StockItem
|
Type : StockItem
|
||||||
Fetch : Name, Parent, GUID, AlterID, BaseUnits, OpeningBalance, OpeningValue, GSTApplicable, GSTRepUoM, GSTTypeofSupply, GSTItemHSNCodeEx
|
Fetch : Name, Parent, GUID, AlterID, BaseUnits, OpeningBalance, OpeningValue, GSTApplicable, GSTRepUoM, GSTTypeofSupply, GSTItemHSNCodeEx
|
||||||
|
|||||||
+11
-13
@@ -95,31 +95,29 @@ class TallyAccountingMirrorV301
|
|||||||
groupSec = 0;
|
groupSec = 0;
|
||||||
string path = Path.Combine(outDir, "group_master.csv");
|
string path = Path.Combine(outDir, "group_master.csv");
|
||||||
|
|
||||||
// Tally's built-in ODBC Groups table is queried on its own connection.
|
// Flat Group Master uses the same TDL/ODBC pattern as the proven
|
||||||
// This deliberately avoids a custom Group TDL collection and protects
|
// Ledger Master. It is deliberately queried only AFTER the core mirror
|
||||||
// the proven Ledger/Voucher extraction connection from being disabled.
|
// has finished and on a fresh connection, so a Group-side Tally error
|
||||||
|
// can never disable the Ledger/Voucher/Stock extraction connection.
|
||||||
if (TryExtractFresh(
|
if (TryExtractFresh(
|
||||||
dsn, "GROUP MASTER",
|
dsn, "GROUP MASTER",
|
||||||
|
"SELECT $GUID,$Name,$Parent FROM ERPAMFlatGroupMaster",
|
||||||
|
path, out groupRows, out groupSec) && groupRows > 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Compatibility fallback for builds that expose Groups directly.
|
||||||
|
if (TryExtractFresh(
|
||||||
|
dsn, "GROUP MASTER COMPAT",
|
||||||
"SELECT $GUID,$Name,$Parent FROM Groups",
|
"SELECT $GUID,$Name,$Parent FROM Groups",
|
||||||
path, out groupRows, out groupSec) && groupRows > 0)
|
path, out groupRows, out groupSec) && groupRows > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Some builds expose the table but not GUID. Name + Parent are all the
|
|
||||||
// ERP needs for recursive Fixed Assets / Capital hierarchy traversal.
|
|
||||||
if (TryExtractFresh(
|
if (TryExtractFresh(
|
||||||
dsn, "GROUP MASTER NAME/PARENT",
|
dsn, "GROUP MASTER NAME/PARENT",
|
||||||
"SELECT $Name,$Parent FROM Groups",
|
"SELECT $Name,$Parent FROM Groups",
|
||||||
path, out groupRows, out groupSec) && groupRows > 0)
|
path, out groupRows, out groupSec) && groupRows > 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Last compatibility attempt: singular built-in collection/table name,
|
|
||||||
// again on a NEW connection so a rejected query cannot poison the core.
|
|
||||||
if (TryExtractFresh(
|
|
||||||
dsn, "GROUP MASTER COMPAT",
|
|
||||||
"SELECT $GUID,$Name,$Parent FROM Group",
|
|
||||||
path, out groupRows, out groupSec) && groupRows > 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
WriteEmptyGroupCsv(path);
|
WriteEmptyGroupCsv(path);
|
||||||
Console.WriteLine("GROUP MASTER - NO GROUP ROWS EXTRACTED; CORE MIRROR DATA REMAINS VALID");
|
Console.WriteLine("GROUP MASTER - NO GROUP ROWS EXTRACTED; CORE MIRROR DATA REMAINS VALID");
|
||||||
Console.Out.Flush();
|
Console.Out.Flush();
|
||||||
|
|||||||
Reference in New Issue
Block a user