lambda-erp 0.2.3__tar.gz → 0.2.5__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.
Files changed (82) hide show
  1. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/PKG-INFO +1 -1
  2. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/masters.py +16 -3
  3. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/reports.py +26 -5
  4. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/pyproject.toml +1 -1
  5. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/.gitignore +0 -0
  6. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/LICENSE +0 -0
  7. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/README.md +0 -0
  8. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/__init__.py +0 -0
  9. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/attachments.py +0 -0
  10. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/auth.py +0 -0
  11. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/bootstrap.py +0 -0
  12. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/chat.py +0 -0
  13. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/demo_limits.py +0 -0
  14. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/deps.py +0 -0
  15. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/errors.py +0 -0
  16. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/main.py +0 -0
  17. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/oauth.py +0 -0
  18. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/pdf.py +0 -0
  19. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/providers.py +0 -0
  20. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/remarks_md.py +0 -0
  21. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/__init__.py +0 -0
  22. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/accounting.py +0 -0
  23. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/admin.py +0 -0
  24. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/analytics.py +0 -0
  25. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/bank_reconciliation.py +0 -0
  26. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/chat_api.py +0 -0
  27. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/documents.py +0 -0
  28. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/proposals.py +0 -0
  29. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/routers/setup.py +0 -0
  30. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/services.py +0 -0
  31. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/templates/document.html +0 -0
  32. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/api/templates/proposal.html +0 -0
  33. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/docs/agents/README.md +0 -0
  34. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/frontend/README.md +0 -0
  35. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/frontend/src/api/client.ts +0 -0
  36. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/__init__.py +0 -0
  37. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/__init__.py +0 -0
  38. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/bank_transaction.py +0 -0
  39. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/budget.py +0 -0
  40. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/chart_of_accounts.py +0 -0
  41. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/general_ledger.py +0 -0
  42. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/journal_entry.py +0 -0
  43. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/payment_entry.py +0 -0
  44. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/pos_invoice.py +0 -0
  45. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/purchase_invoice.py +0 -0
  46. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/revaluation.py +0 -0
  47. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/sales_invoice.py +0 -0
  48. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/__init__.py +0 -0
  49. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/engine.py +0 -0
  50. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/pack.py +0 -0
  51. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/packs/__init__.py +0 -0
  52. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/packs/ch.py +0 -0
  53. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/packs/de_common.py +0 -0
  54. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/packs/de_skr03.py +0 -0
  55. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/packs/de_skr04.py +0 -0
  56. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/packs/generic.py +0 -0
  57. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/profiles.py +0 -0
  58. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/setup/spine.py +0 -0
  59. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/accounting/subscription.py +0 -0
  60. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/buying/__init__.py +0 -0
  61. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/buying/purchase_order.py +0 -0
  62. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/controllers/__init__.py +0 -0
  63. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/controllers/currency.py +0 -0
  64. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/controllers/defaults.py +0 -0
  65. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/controllers/pricing_rule.py +0 -0
  66. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/controllers/taxes_and_totals.py +0 -0
  67. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/database.py +0 -0
  68. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/exceptions.py +0 -0
  69. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/hooks.py +0 -0
  70. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/model.py +0 -0
  71. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/selling/__init__.py +0 -0
  72. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/selling/proposal.py +0 -0
  73. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/selling/quotation.py +0 -0
  74. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/selling/sales_order.py +0 -0
  75. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/simulation.py +0 -0
  76. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/stock/__init__.py +0 -0
  77. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/stock/delivery_note.py +0 -0
  78. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/stock/purchase_receipt.py +0 -0
  79. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/stock/stock_entry.py +0 -0
  80. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/stock/stock_ledger.py +0 -0
  81. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/lambda_erp/utils.py +0 -0
  82. {lambda_erp-0.2.3 → lambda_erp-0.2.5}/terraform/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lambda-erp
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: Core ERP logic - accounting, sales, purchasing, inventory
5
5
  Author: TORUS INVESTMENTS AG
6
6
  License-Expression: MIT
@@ -388,8 +388,16 @@ def delete_master(master_type: str, name: str, _user: dict = _admin):
388
388
 
389
389
 
390
390
  @router.get("/account/tree")
391
- def account_tree(company: str | None = None, _user: dict = _viewer):
392
- """Return Chart of Accounts as a nested tree."""
391
+ def account_tree(company: str | None = None, include_disabled: bool = False,
392
+ _user: dict = _viewer):
393
+ """Return Chart of Accounts as a nested tree.
394
+
395
+ Disabled accounts are hidden by default (they already drop out of account
396
+ pickers, and a disabled account is one the user retired). Pass
397
+ ``include_disabled=true`` to show them. A disabled *group* is still shown if
398
+ it has any enabled descendant, so an active account is never hidden behind a
399
+ disabled parent. Each node carries a ``disabled`` bool for the UI.
400
+ """
393
401
  db = get_db()
394
402
  filters = {}
395
403
  if company:
@@ -398,7 +406,7 @@ def account_tree(company: str | None = None, _user: dict = _viewer):
398
406
  "Account",
399
407
  filters=filters if filters else None,
400
408
  fields=["name", "account_name", "parent_account", "root_type",
401
- "report_type", "account_type", "is_group"],
409
+ "report_type", "account_type", "is_group", "disabled"],
402
410
  )
403
411
 
404
412
  by_parent = {}
@@ -411,7 +419,12 @@ def account_tree(company: str | None = None, _user: dict = _viewer):
411
419
  result = []
412
420
  for acc in children:
413
421
  node = dict(acc)
422
+ node["disabled"] = bool(acc.get("disabled"))
414
423
  node["children"] = _build(acc["name"])
424
+ # Prune a disabled node only when nothing enabled survives beneath it,
425
+ # so an enabled child is never dropped along with its disabled parent.
426
+ if not include_disabled and node["disabled"] and not node["children"]:
427
+ continue
415
428
  result.append(node)
416
429
  return result
417
430
 
@@ -121,9 +121,13 @@ def trial_balance(
121
121
  company, presentation_currency, to_date)
122
122
 
123
123
 
124
- def _chart_of_accounts(db, company=None, from_date=None, to_date=None):
125
- """Chart of accounts (every account, incl. groups and zero-balance ones)
126
- with period balances the tree the GUI renders.
124
+ def _chart_of_accounts(db, company=None, from_date=None, to_date=None,
125
+ include_disabled=False):
126
+ """Chart of accounts (groups and zero-balance ones included) with period
127
+ balances — the tree the GUI renders. Disabled accounts are hidden by default
128
+ (``include_disabled=True`` to show them); balances still roll up over every
129
+ descendant (incl. disabled), and a disabled group with an enabled descendant
130
+ is kept so no active account is orphaned.
127
131
 
128
132
  Balance semantics follow standard presentation:
129
133
  - Balance Sheet accounts: CLOSING balance as of ``to_date`` (all postings
@@ -212,6 +216,19 @@ def _chart_of_accounts(db, company=None, from_date=None, to_date=None):
212
216
  row["balance"] = flt(row["balance"] + subtree_extra[row["name"]], 2)
213
217
  row["has_entries"] = row["has_entries"] or bool(subtree_extra[row["name"]])
214
218
 
219
+ # Hide disabled accounts by default, but keep any disabled ancestor of an
220
+ # enabled account so the enabled one isn't orphaned in the rendered tree.
221
+ if not include_disabled:
222
+ keep = set()
223
+ for row in rows:
224
+ if not row["disabled"]:
225
+ keep.add(row["name"])
226
+ parent = row["parent_account"]
227
+ while parent and parent in by_name and parent not in keep:
228
+ keep.add(parent)
229
+ parent = by_name[parent]["parent_account"]
230
+ rows = [r for r in rows if r["name"] in keep]
231
+
215
232
  return {"accounts": rows, "from_date": from_date, "to_date": to_date}
216
233
 
217
234
 
@@ -221,10 +238,14 @@ def chart_of_accounts(
221
238
  from_date: str | None = None,
222
239
  to_date: str | None = None,
223
240
  presentation_currency: str | None = None,
241
+ include_disabled: bool = False,
224
242
  ):
225
243
  db = get_db()
226
- return _present(db, _chart_of_accounts(db, company, from_date, to_date),
227
- company, presentation_currency, to_date)
244
+ return _present(
245
+ db,
246
+ _chart_of_accounts(db, company, from_date, to_date,
247
+ include_disabled=include_disabled),
248
+ company, presentation_currency, to_date)
228
249
 
229
250
 
230
251
  def _general_ledger(db, filters=None):
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lambda-erp"
3
- version = "0.2.3"
3
+ version = "0.2.5"
4
4
  description = "Core ERP logic - accounting, sales, purchasing, inventory"
5
5
  readme = "README.md"
6
6
  license = "MIT"
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