lambda-erp 0.1.11__tar.gz → 0.1.13__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 (65) hide show
  1. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/PKG-INFO +1 -1
  2. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/pdf.py +35 -3
  3. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/database.py +7 -0
  4. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/pyproject.toml +1 -1
  5. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/.gitignore +0 -0
  6. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/LICENSE +0 -0
  7. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/README.md +0 -0
  8. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/__init__.py +0 -0
  9. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/attachments.py +0 -0
  10. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/auth.py +0 -0
  11. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/bootstrap.py +0 -0
  12. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/chat.py +0 -0
  13. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/demo_limits.py +0 -0
  14. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/deps.py +0 -0
  15. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/errors.py +0 -0
  16. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/main.py +0 -0
  17. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/providers.py +0 -0
  18. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/__init__.py +0 -0
  19. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/accounting.py +0 -0
  20. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/admin.py +0 -0
  21. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/analytics.py +0 -0
  22. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/bank_reconciliation.py +0 -0
  23. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/documents.py +0 -0
  24. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/masters.py +0 -0
  25. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/reports.py +0 -0
  26. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/routers/setup.py +0 -0
  27. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/services.py +0 -0
  28. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/api/templates/document.html +0 -0
  29. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/docs/agents/README.md +0 -0
  30. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/frontend/README.md +0 -0
  31. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/frontend/src/api/client.ts +0 -0
  32. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/__init__.py +0 -0
  33. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/__init__.py +0 -0
  34. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/bank_transaction.py +0 -0
  35. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/budget.py +0 -0
  36. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/chart_of_accounts.py +0 -0
  37. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/general_ledger.py +0 -0
  38. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/journal_entry.py +0 -0
  39. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/payment_entry.py +0 -0
  40. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/pos_invoice.py +0 -0
  41. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/purchase_invoice.py +0 -0
  42. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/revaluation.py +0 -0
  43. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/sales_invoice.py +0 -0
  44. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/accounting/subscription.py +0 -0
  45. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/buying/__init__.py +0 -0
  46. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/buying/purchase_order.py +0 -0
  47. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/controllers/__init__.py +0 -0
  48. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/controllers/currency.py +0 -0
  49. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/controllers/defaults.py +0 -0
  50. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/controllers/pricing_rule.py +0 -0
  51. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/controllers/taxes_and_totals.py +0 -0
  52. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/exceptions.py +0 -0
  53. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/hooks.py +0 -0
  54. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/model.py +0 -0
  55. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/selling/__init__.py +0 -0
  56. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/selling/quotation.py +0 -0
  57. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/selling/sales_order.py +0 -0
  58. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/simulation.py +0 -0
  59. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/stock/__init__.py +0 -0
  60. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/stock/delivery_note.py +0 -0
  61. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/stock/purchase_receipt.py +0 -0
  62. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/stock/stock_entry.py +0 -0
  63. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/stock/stock_ledger.py +0 -0
  64. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/lambda_erp/utils.py +0 -0
  65. {lambda_erp-0.1.11 → lambda_erp-0.1.13}/terraform/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lambda-erp
3
- Version: 0.1.11
3
+ Version: 0.1.13
4
4
  Summary: Core ERP logic - accounting, sales, purchasing, inventory
5
5
  Author: TORUS INVESTMENTS AG
6
6
  License-Expression: MIT
@@ -37,6 +37,22 @@ def register_pdf_template_dir(path: str) -> None:
37
37
  _plugin_template_dirs.insert(0, path)
38
38
  _jinja_env.loader = _build_loader()
39
39
 
40
+
41
+ _pdf_context_providers = []
42
+
43
+
44
+ def register_pdf_context(fn) -> None:
45
+ """Register a provider that augments the PDF render context.
46
+
47
+ `fn(doctype, name, context)` is called just before rendering with the
48
+ assembled context (doc, company_info, party_info, currency, items, …) and
49
+ may return a dict of EXTRA keys to merge in — e.g. a computed Swiss QR-bill
50
+ image for invoices. Lets a deployment add per-document content the template
51
+ can't compute itself. Exceptions are swallowed so a buggy provider can't
52
+ break PDF generation.
53
+ """
54
+ _pdf_context_providers.append(fn)
55
+
40
56
  # Document type → (title, party_field, party_name_field, party_doctype, party_label)
41
57
  DOC_CONFIG = {
42
58
  "Quotation": ("Quotation", "customer", "customer_name", "Customer", "Customer"),
@@ -114,7 +130,7 @@ def generate_pdf(doctype_slug: str, name: str) -> bytes:
114
130
  company_info = {}
115
131
  if company_id:
116
132
  row = db.get_value("Company", company_id,
117
- ["company_name", "email", "phone", "address", "city", "zip_code", "country", "tax_id"])
133
+ ["company_name", "email", "phone", "address", "city", "zip_code", "country", "tax_id", "iban"])
118
134
  if row:
119
135
  company_info = _get_dict(row)
120
136
  # Show the company's CURRENT display name from the master.
@@ -160,7 +176,11 @@ def generate_pdf(doctype_slug: str, name: str) -> bytes:
160
176
 
161
177
  # Render
162
178
  template = _jinja_env.get_template("document.html")
163
- html_str = template.render(
179
+ # base_url = the resolved template's own directory, so a template (e.g. a
180
+ # plugin's branded override) can reference sibling assets — logo.png, fonts,
181
+ # CSS — by relative path. Falls back to the built-in templates dir.
182
+ base_url = template.filename or os.path.join(TEMPLATE_DIR, "document.html")
183
+ context = dict(
164
184
  doc=doc,
165
185
  title=title,
166
186
  company_name=company_name,
@@ -176,4 +196,16 @@ def generate_pdf(doctype_slug: str, name: str) -> bytes:
176
196
  page_size=page_size,
177
197
  )
178
198
 
179
- return HTML(string=html_str).write_pdf()
199
+ # Let deployment plugins augment the context (e.g. a Swiss QR-bill image for
200
+ # invoices). A provider that raises must not break PDF generation.
201
+ for provider in _pdf_context_providers:
202
+ try:
203
+ extra = provider(doctype, name, context)
204
+ if extra:
205
+ context.update(extra)
206
+ except Exception:
207
+ pass
208
+
209
+ html_str = template.render(**context)
210
+
211
+ return HTML(string=html_str, base_url=base_url).write_pdf()
@@ -270,6 +270,7 @@ class Database:
270
270
  zip_code TEXT,
271
271
  country TEXT,
272
272
  tax_id TEXT,
273
+ iban TEXT,
273
274
  default_cost_center TEXT,
274
275
  round_off_account TEXT,
275
276
  round_off_cost_center TEXT,
@@ -1707,6 +1708,11 @@ def _m013_unrealized_exchange_account(db: "Database") -> None:
1707
1708
  )
1708
1709
 
1709
1710
 
1711
+ def _m014_company_iban(db: "Database") -> None:
1712
+ """Add Company.iban (bank account for payment instructions / QR-bills)."""
1713
+ db._add_column_if_missing("Company", "iban", "TEXT")
1714
+
1715
+
1710
1716
  Database.MIGRATIONS = [
1711
1717
  (1, "chat_message_session_id", _m001_chat_message_session_id),
1712
1718
  (2, "chat_session_user_id", _m002_chat_session_user_id),
@@ -1721,6 +1727,7 @@ Database.MIGRATIONS = [
1721
1727
  (11, "payment_entry_currency", _m011_payment_entry_currency),
1722
1728
  (12, "exchange_gain_loss_account", _m012_exchange_gain_loss_account),
1723
1729
  (13, "unrealized_exchange_account", _m013_unrealized_exchange_account),
1730
+ (14, "company_iban", _m014_company_iban),
1724
1731
  ]
1725
1732
 
1726
1733
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lambda-erp"
3
- version = "0.1.11"
3
+ version = "0.1.13"
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