lambda-erp 0.1.21__tar.gz → 0.1.22__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 (68) hide show
  1. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/PKG-INFO +1 -1
  2. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/chat.py +11 -2
  3. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/selling/proposal.py +10 -0
  4. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/pyproject.toml +1 -1
  5. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/.gitignore +0 -0
  6. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/LICENSE +0 -0
  7. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/README.md +0 -0
  8. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/__init__.py +0 -0
  9. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/attachments.py +0 -0
  10. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/auth.py +0 -0
  11. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/bootstrap.py +0 -0
  12. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/demo_limits.py +0 -0
  13. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/deps.py +0 -0
  14. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/errors.py +0 -0
  15. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/main.py +0 -0
  16. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/pdf.py +0 -0
  17. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/providers.py +0 -0
  18. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/__init__.py +0 -0
  19. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/accounting.py +0 -0
  20. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/admin.py +0 -0
  21. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/analytics.py +0 -0
  22. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/bank_reconciliation.py +0 -0
  23. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/documents.py +0 -0
  24. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/masters.py +0 -0
  25. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/proposals.py +0 -0
  26. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/reports.py +0 -0
  27. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/routers/setup.py +0 -0
  28. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/services.py +0 -0
  29. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/templates/document.html +0 -0
  30. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/api/templates/proposal.html +0 -0
  31. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/docs/agents/README.md +0 -0
  32. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/frontend/README.md +0 -0
  33. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/frontend/src/api/client.ts +0 -0
  34. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/__init__.py +0 -0
  35. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/__init__.py +0 -0
  36. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/bank_transaction.py +0 -0
  37. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/budget.py +0 -0
  38. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/chart_of_accounts.py +0 -0
  39. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/general_ledger.py +0 -0
  40. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/journal_entry.py +0 -0
  41. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/payment_entry.py +0 -0
  42. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/pos_invoice.py +0 -0
  43. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/purchase_invoice.py +0 -0
  44. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/revaluation.py +0 -0
  45. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/sales_invoice.py +0 -0
  46. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/accounting/subscription.py +0 -0
  47. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/buying/__init__.py +0 -0
  48. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/buying/purchase_order.py +0 -0
  49. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/controllers/__init__.py +0 -0
  50. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/controllers/currency.py +0 -0
  51. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/controllers/defaults.py +0 -0
  52. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/controllers/pricing_rule.py +0 -0
  53. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/controllers/taxes_and_totals.py +0 -0
  54. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/database.py +0 -0
  55. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/exceptions.py +0 -0
  56. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/hooks.py +0 -0
  57. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/model.py +0 -0
  58. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/selling/__init__.py +0 -0
  59. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/selling/quotation.py +0 -0
  60. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/selling/sales_order.py +0 -0
  61. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/simulation.py +0 -0
  62. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/stock/__init__.py +0 -0
  63. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/stock/delivery_note.py +0 -0
  64. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/stock/purchase_receipt.py +0 -0
  65. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/stock/stock_entry.py +0 -0
  66. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/stock/stock_ledger.py +0 -0
  67. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/lambda_erp/utils.py +0 -0
  68. {lambda_erp-0.1.21 → lambda_erp-0.1.22}/terraform/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lambda-erp
3
- Version: 0.1.21
3
+ Version: 0.1.22
4
4
  Summary: Core ERP logic - accounting, sales, purchasing, inventory
5
5
  Author: TORUS INVESTMENTS AG
6
6
  License-Expression: MIT
@@ -442,7 +442,7 @@ def api_rename_session(session_id: str, data: dict, user: dict = _Depends(get_cu
442
442
  # ---------------------------------------------------------------------------
443
443
 
444
444
  DOCUMENT_SLUGS = [
445
- "quotation", "sales-order", "sales-invoice",
445
+ "quotation", "proposal", "sales-order", "sales-invoice",
446
446
  "purchase-order", "purchase-invoice",
447
447
  "payment-entry", "journal-entry", "stock-entry",
448
448
  "delivery-note", "purchase-receipt", "pos-invoice",
@@ -1542,7 +1542,7 @@ Lambda ERP has four roles:
1542
1542
  When a user asks you to do something they don't have permission for, explain what role is needed instead of attempting the action (the API will reject it anyway).
1543
1543
 
1544
1544
  ## Available Document Types (use the slug when calling tools)
1545
- - **Selling:** quotation, sales-order, sales-invoice, pos-invoice
1545
+ - **Selling:** quotation, proposal, sales-order, sales-invoice, pos-invoice
1546
1546
  - **Buying:** purchase-order, purchase-invoice
1547
1547
  - **Accounting:** payment-entry, journal-entry, budget, subscription, bank-transaction
1548
1548
  - **Stock:** stock-entry, delivery-note, purchase-receipt
@@ -1560,6 +1560,15 @@ Shortcuts: Quotation can also convert directly to Sales Invoice or Delivery Note
1560
1560
  - **Sales Invoice:** Bills the customer. **Posts GL entries:** Debit Accounts Receivable, Credit Sales Revenue (+ Credit Tax Payable if taxes). Creates outstanding amount.
1561
1561
  - **Payment Entry (Receive):** Records customer payment. **Posts GL entries:** Debit Bank, Credit Accounts Receivable. Reduces invoice outstanding.
1562
1562
 
1563
+ ### Proposal (Sammelofferte) — combine several offers into one PDF
1564
+ A **Proposal** bundles several EXISTING quotations into one branded, customer-facing PDF, each shown as a lettered position (A, B, C…). It is **print-only**: no financial or stock impact, it references the quotations without changing them, and it is **never submitted** — to deliver it you just generate its PDF.
1565
+
1566
+ Shape (doctype slug `proposal`) — note it does NOT use `items`:
1567
+ - Parent fields: `title` (e.g. "Offerte"), `customer`, `company`, `proposal_date`, `partner_name`, `partner_email`, `cover_letter` (the intro/greeting letter text).
1568
+ - Child table `quotations[]` — one row per offer to include, in display order. Each row: `{"quotation": "<existing Quotation name>", "position_title": "...", "position_blurb": "...", "is_recommended": 0 or 1}`. Set `is_recommended: 1` on the offer you recommend (draws an "Empfehlung" badge). `position_title`/`position_blurb` are optional and default from the quotation.
1569
+
1570
+ To build one: ensure each offer already exists as its own Quotation (create them first if needed), then `create_document(doctype="proposal", data={...})` referencing those quotations by name in `quotations[]`. Do NOT submit it; link the user to the PDF at `/api/documents/proposal/<name>/pdf` (and the editor at `/app/proposal/<name>`).
1571
+
1563
1572
  ### Purchase Cycle
1564
1573
  Purchase Order → Purchase Receipt (receiving) / Purchase Invoice (billing) → Payment Entry
1565
1574
 
@@ -18,6 +18,7 @@ cover letter and per-position copy aren't retyped), not to link the offers.
18
18
 
19
19
  from lambda_erp.model import Document
20
20
  from lambda_erp.database import get_db
21
+ from lambda_erp.exceptions import DocumentStatusError
21
22
 
22
23
 
23
24
  class Proposal(Document):
@@ -39,6 +40,15 @@ class Proposal(Document):
39
40
  "quotations": {"quotation": "Quotation"},
40
41
  }
41
42
 
43
+ def submit(self):
44
+ # A Proposal is a print-only assembly — there is nothing to post. Guard
45
+ # against an accidental submit from the chat or API; you "deliver" it by
46
+ # generating its PDF, not by submitting.
47
+ raise DocumentStatusError(
48
+ "A Proposal (Sammelofferte) is print-only and is not submitted. "
49
+ "Generate its PDF instead."
50
+ )
51
+
42
52
  def before_save(self) -> None:
43
53
  # Denormalise the customer's display name so the list view has it without
44
54
  # a join. The PDF still looks the name up live at render time.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lambda-erp"
3
- version = "0.1.21"
3
+ version = "0.1.22"
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