lambda-erp 0.2.6__tar.gz → 0.2.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/PKG-INFO +1 -1
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/chat.py +17 -4
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/pyproject.toml +1 -1
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/.gitignore +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/LICENSE +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/README.md +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/attachments.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/auth.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/bootstrap.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/demo_limits.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/deps.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/errors.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/main.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/oauth.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/pdf.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/providers.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/remarks_md.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/accounting.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/admin.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/analytics.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/bank_reconciliation.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/chat_api.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/documents.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/masters.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/proposals.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/reports.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/routers/setup.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/services.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/templates/document.html +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/api/templates/proposal.html +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/docs/agents/README.md +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/frontend/README.md +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/frontend/src/api/client.ts +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/bank_transaction.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/budget.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/chart_of_accounts.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/general_ledger.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/journal_entry.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/payment_entry.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/pos_invoice.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/purchase_invoice.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/revaluation.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/sales_invoice.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/engine.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/pack.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/packs/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/packs/ch.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/packs/de_common.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/packs/de_skr03.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/packs/de_skr04.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/packs/generic.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/profiles.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/setup/spine.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/accounting/subscription.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/buying/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/buying/purchase_order.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/controllers/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/controllers/currency.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/controllers/defaults.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/controllers/pricing_rule.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/controllers/taxes_and_totals.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/database.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/exceptions.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/hooks.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/model.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/selling/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/selling/proposal.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/selling/quotation.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/selling/sales_order.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/simulation.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/stock/__init__.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/stock/delivery_note.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/stock/purchase_receipt.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/stock/stock_entry.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/stock/stock_ledger.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/lambda_erp/utils.py +0 -0
- {lambda_erp-0.2.6 → lambda_erp-0.2.7}/terraform/README.md +0 -0
|
@@ -583,7 +583,7 @@ TOOLS = [
|
|
|
583
583
|
"type": "function",
|
|
584
584
|
"function": {
|
|
585
585
|
"name": "search_masters",
|
|
586
|
-
"description": "Search master data (customers, suppliers, items, warehouses, accounts, companies, cost centers). Case-insensitive, with fuzzy fallback for misspellings. By default matches across standard text fields (name, display name, address/city/zip); large free-text columns like description/templates are skipped unless named in `fields`. PREFER passing `fields` whenever you know which attribute you're matching on (e.g. a city, an email, a tax id) — it's faster, more precise, and avoids false hits from other columns. Returns matching records.",
|
|
586
|
+
"description": "Search master data (customers, suppliers, items, warehouses, accounts, companies, cost centers). Case-insensitive, with fuzzy fallback for misspellings. By default matches across standard text fields (name, display name, address/city/zip); large free-text columns like description/templates are skipped unless named in `fields`. PREFER passing `fields` whenever you know which attribute you're matching on (e.g. a city, an email, a tax id) — it's faster, more precise, and avoids false hits from other columns. Returns ALL matching records by default (no cap); pass `limit` only to bound a large list.",
|
|
587
587
|
"parameters": {
|
|
588
588
|
"type": "object",
|
|
589
589
|
"properties": {
|
|
@@ -594,6 +594,7 @@ TOOLS = [
|
|
|
594
594
|
"items": {"type": "string"},
|
|
595
595
|
"description": "Recommended: the column(s) to search, e.g. [\"city\"] or [\"customer_name\"]. Narrowing here is faster and avoids matching unrelated columns. Omit only when you genuinely don't know which field holds the value, to search all standard text fields.",
|
|
596
596
|
},
|
|
597
|
+
"limit": {"type": "integer", "description": "Optional max number of results. OMIT for no cap — returns ALL matches (e.g. to see the entire chart of accounts). Pass a number only to bound a large list."},
|
|
597
598
|
},
|
|
598
599
|
"required": ["master_type"],
|
|
599
600
|
},
|
|
@@ -1308,6 +1309,17 @@ def _handle_search_masters(args):
|
|
|
1308
1309
|
master_type = args["master_type"]
|
|
1309
1310
|
query = (args.get("query") or "").strip()
|
|
1310
1311
|
|
|
1312
|
+
# Optional result cap the caller sets per call; omit for NO cap (return all —
|
|
1313
|
+
# e.g. the whole chart of accounts). Coerced to int so the LIMIT clause below
|
|
1314
|
+
# can't be injected.
|
|
1315
|
+
_raw_limit = args.get("limit")
|
|
1316
|
+
limit = None
|
|
1317
|
+
if _raw_limit not in (None, "", 0):
|
|
1318
|
+
try:
|
|
1319
|
+
limit = max(1, int(_raw_limit))
|
|
1320
|
+
except (TypeError, ValueError):
|
|
1321
|
+
limit = None
|
|
1322
|
+
|
|
1311
1323
|
entry = services.MASTER_TABLES.get(master_type)
|
|
1312
1324
|
if not entry:
|
|
1313
1325
|
return {"error": f"Unknown master type: {master_type}"}
|
|
@@ -1317,7 +1329,7 @@ def _handle_search_masters(args):
|
|
|
1317
1329
|
|
|
1318
1330
|
if not query:
|
|
1319
1331
|
filters = {"disabled": 0} if has_disabled else None
|
|
1320
|
-
return db.get_all(doctype, filters=filters, fields=["*"], limit=
|
|
1332
|
+
return db.get_all(doctype, filters=filters, fields=["*"], limit=limit)
|
|
1321
1333
|
|
|
1322
1334
|
# Optional `fields` narrows the search to specific columns — cheaper, more
|
|
1323
1335
|
# precise, and the only way to reach bulk columns (description, templates)
|
|
@@ -1338,15 +1350,16 @@ def _handle_search_masters(args):
|
|
|
1338
1350
|
# silently broke prod search); CAST lets targeted non-text columns match too.
|
|
1339
1351
|
where = " OR ".join(f'lower(CAST("{col}" AS TEXT)) LIKE ?' for col in search_cols)
|
|
1340
1352
|
pattern = f"%{query.lower()}%"
|
|
1353
|
+
limit_sql = f" LIMIT {limit}" if limit else ""
|
|
1341
1354
|
rows = db.sql(
|
|
1342
|
-
f'SELECT * FROM "{doctype}" WHERE {active_prefix}({where})
|
|
1355
|
+
f'SELECT * FROM "{doctype}" WHERE {active_prefix}({where}){limit_sql}',
|
|
1343
1356
|
[pattern] * len(search_cols),
|
|
1344
1357
|
)
|
|
1345
1358
|
if rows:
|
|
1346
1359
|
return [dict(r) for r in rows]
|
|
1347
1360
|
|
|
1348
1361
|
# Nothing matched literally — try fuzzy matching to catch misspellings.
|
|
1349
|
-
return _fuzzy_master_search(db, doctype, search_cols, query, has_disabled, limit=
|
|
1362
|
+
return _fuzzy_master_search(db, doctype, search_cols, query, has_disabled, limit=limit)
|
|
1350
1363
|
|
|
1351
1364
|
|
|
1352
1365
|
def _ignored_master_fields(master_type: str, data: dict) -> list[str]:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|