Skip to content

[Feature] Cost Centers and Billing Functionality#1448

Open
behrinml wants to merge 11 commits into
maziggy:devfrom
behrinml:feature/billing
Open

[Feature] Cost Centers and Billing Functionality#1448
behrinml wants to merge 11 commits into
maziggy:devfrom
behrinml:feature/billing

Conversation

@behrinml
Copy link
Copy Markdown
Contributor

Description

This PR introduces a billing functionality to BamBuddy. This includes cost center creation/management (each user has a personal one as well as optional shared ones), wallet transactions, budget tracking, and financial reporting.

Related Issue

Fixes #1065

Documentation

Companion docs PRs (delete lines that don't apply):

Pick one:

  • Docs PR(s) linked above
  • No docs update required — reason: ___

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Test addition or update

Changes Made

  • Added database schemes for the billing functionality, e.g., CostCenter, WalletTransactions, etc.
  • Introduced multiple new API routes
  • Introduces multiple new permissions regarding billing
  • Added checks when starting a print/queueing a print regarding available budget and either rejects the print or reserves the budget for queue entries
  • Added a new finance page in the frontend (if the user has permission to see this page) capable of personal balance/available shared cost centers and transactions. Further, a admin view is added capable to see all transactions/cost centers/balances/etc. and the option to create cost centers/assign users/delete transactions, etc. (if permission is given).
  • Added settings entries for the billing functionality like reset day for monthly budget, kill switch, etc.
  • Introduced an optional "kill switch", i.e., if BamBuddy is not aware of a started print, this print is immediately stopped to prevent prints without billing.

Screenshots

Changes:
PrintModal (before):
print_before
PrintModal (after):
print_after
Queue (before):
queue_before
Queue (after)
queue_after
Queue with insufficient budget (same behavior for PrintModal)
insufficient_budget

Settings (before):
settings_before
Settings (after):
settings_after

New:
Create a new cost center:
create_cost_center
Manage cost center members:
manage_members
Adjust Wallet (Deposit/Withdraw):
adjust_wallet
Add a (historic) print:
add_manual_print
Personal View:
personal_view
Admin View:
admin_view

Testing

  • I have tested this on my local machine
  • I have tested with my printer model: H2C

Checklist

  • My code follows the project's coding style
  • I have commented my code where necessary
  • My changes generate no new warnings
  • I have tested my changes thoroughly

Additional Notes

The docs entry is currently kept very short but is obviously a candidate to be extended and explained a lot more.
I only have access to one printer, i.e., I am not aware if there are side effects using more printers. Likely I missed some cases for the tests.

behrinml added 5 commits May 18, 2026 20:48
- Introduced cost center permissions in permissions.py.
- Added finance-related fields and models in archive.py, finance.py, library.py, print_queue.py, and settings.py.
- Implemented database migrations for cost centers and wallet transactions in database.py.
…the backend

- Introduced CostCenter and related models for managing print costs and budgets.
- Updated PrintArchive and PrintQueueItem models to include cost_center_id and estimated_cost.
- Implemented budget reservation logic in finance services to validate and manage print costs.
- Enhanced ArchiveService and BackgroundDispatchService to handle cost center information during print jobs.
- Added wallet transaction handling for print charges, including partial charges based on filament usage.
- Created finance billing and budget services to manage user wallets and budget reservations.
- Ensured user finance defaults are created upon user registration, including wallets and private cost centers.
- Updated print scheduler to validate budget before processing print jobs.
Settings:
- Introduced billing enabled toggle with printer kill switch functionality in the settings.
- Added finance monthly budget reset day and timezone settings.

Other:
- Added cost center fields to PrintModal (if enabled)
- Switched sequence in PrintModal (cost center after estimated cost, and before print options)
- Implemented Finance Page
@behrinml behrinml requested a review from maziggy as a code owner May 19, 2026 15:56
@maziggy
Copy link
Copy Markdown
Owner

maziggy commented May 23, 2026

2026-05-23 13:28:33,480 INFO [root] [-] Bambuddy starting - debug=False, log_level=INFO
2026-05-23 13:28:34,351 ERROR [backend.app.core.database] [-] Migration statement failed: (sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.DatatypeMismatchError'>: column "wallet_charge_skipped" is of type boolean but default expression is of type integer
HINT: You will need to rewrite or cast the expression.
[SQL: ALTER TABLE print_archives ADD COLUMN wallet_charge_skipped BOOLEAN DEFAULT 0]
(Background on this error at: https://sqlalche.me/e/20/f405) | SQL: ALTER TABLE print_archives ADD COLUMN wallet_charge_skipped BOOLEAN DEFAULT 0
2026-05-23 13:28:41,326 INFO [root] [-] Logging to file: /opt/claude/projects/bambuddy/logs/bambuddy.log
2026-05-23 13:28:41,326 INFO [root] [-] Bambuddy starting - debug=False, log_level=INFO
2026-05-23 13:28:42,043 ERROR [backend.app.core.database] [-] Migration statement failed: (sqlalchemy.dialects.postgresql.asyncpg.ProgrammingError) <class 'asyncpg.exceptions.DatatypeMismatchError'>: column "wallet_charge_skipped" is of type boolean but default expression is of type integer
HINT: You will need to rewrite or cast the expression.
[SQL: ALTER TABLE print_archives ADD COLUMN wallet_charge_skipped BOOLEAN DEFAULT 0]
(Background on this error at: https://sqlalche.me/e/20/f405) | SQL: ALTER TABLE print_archives ADD COLUMN wallet_charge_skipped BOOLEAN DEFAULT 0

@behrinml
Copy link
Copy Markdown
Contributor Author

...should be fixed but I my setup is not using PostgreSQL so its an untested fix unfortunately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants