mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-05-09 05:35:30 +02:00
[PR #1184] [MERGED] [Feature] Add Stock forecasting and Logistics view #1168
Labels
No labels
A1
automated
automated
bug
bug
Closed due to inactivity
contrib
dependencies
dependencies
duplicate
enhancement
feedback
hold
invalid
Notes
P1S
pull-request
security
security
ThumbsUp
user-report
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/bambuddy#1168
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/maziggy/bambuddy/pull/1184
Author: @Keybored02
Created: 5/1/2026
Status: ✅ Merged
Merged: 5/5/2026
Merged by: @maziggy
Base:
dev← Head:feature/stock_track📝 Commits (10+)
fbfa433Add stock prediction0fe972eAdd Logistics view, testing, locales, permission compliancebd5fda2Fix misc3c1ab14Fix misc 2306b4ecfix misc 3eb042c8refactor: simplify formatter functions in UsageChart and CartLogisticsRow337daeefeat: add RequireAnyPermissionIfAuthEnabled for flexible permission checksabcbe39feat: enhance permission checks in ForecastPanel and update database migration logicde32247feat: add alerts_snoozed field to FilamentSkuSettings and update related componentscef2bc8feat: add alerts_snoozed handling in ForecastRow component📊 Changes
28 files changed (+4242 additions, -25 deletions)
View changed files
📝
backend/app/api/routes/inventory.py(+256 -2)📝
backend/app/api/routes/settings.py(+1 -0)📝
backend/app/core/auth.py(+89 -0)📝
backend/app/core/database.py(+201 -0)📝
backend/app/core/permissions.py(+7 -0)➕
backend/app/models/filament_sku_settings.py(+28 -0)📝
backend/app/models/notification.py(+4 -0)📝
backend/app/models/notification_template.py(+13 -0)➕
backend/app/models/shopping_list.py(+22 -0)📝
backend/app/schemas/settings.py(+8 -0)📝
backend/app/services/notification_service.py(+54 -0)📝
frontend/src/__tests__/components/AddNotificationModal.test.tsx(+117 -0)➕
frontend/src/__tests__/components/ForecastPanelPermissions.test.tsx(+266 -0)📝
frontend/src/__tests__/components/NotificationProviderCard.test.tsx(+2 -0)➕
frontend/src/__tests__/components/NotificationProviderCardStockAlerts.test.tsx(+187 -0)📝
frontend/src/api/client.ts(+66 -0)📝
frontend/src/components/AddNotificationModal.tsx(+27 -0)➕
frontend/src/components/ForecastPanel.tsx(+1822 -0)📝
frontend/src/components/NotificationProviderCard.tsx(+33 -0)📝
frontend/src/i18n/locales/de.ts(+124 -0)...and 8 more files
📄 Description
Description
Adds a full Forecast & Reorder Intelligence tab to the Inventory page. The panel analyses historical filament consumption, computes statistical reorder points, projects stock runout dates, and integrates a shopping list workflow — all with permission controls and i18n coverage across 8 locales.
Related Issue
Fixes #1172
Documentation
Companion docs PRs (delete lines that don't apply):
Pick one:
Type of Change
Changes Made
1. Stock Consumption Forecast Engine
Daily rate calculation — two-tier:
computing
g/dayper interval. Each observation is weighted byexp(−λ × age_days)whereλ = ln(2)/30, giving a 30-day half-life so recent prints dominate. Computes weighted mean andweighted variance → std dev.
total_grams_used / days_since_spool_added— used when only oneprint event exists.
Per-SKU forecast object computed for every material/brand/subtype group:
Two alert levels:
reorderAlertdays_until_ROP ≤ 0stockBreakAlertdays_remaining ≤ effective_lead_time2. Forecast Table UI
Sortable table with columns: material, stock, rate, days remaining, empty-by date, reorder-by date.
Each row expands to show:
saved on confirm via
POST /inventory/sku-settingsand usage
trajectory, reorder point reference line, and safety stock band
3. Alert Banner
Collapsible banner above the table listing all active alerts (both tiers). Colour-coded: red for
stock-break risk, yellow for reorder-now. Hidden automatically when no alerts are present.
4. Alert Snooze per SKU
A
BellOfftoggle on each row (write-permission gated) mutes alerts for a specific SKU — usefulfor materials being intentionally wound down or kept at low stock. When snoozed:
Persisted as
alerts_snoozed: boolonFilamentSkuSettings. The toggle fires an upsertimmediately, carrying the current lead time and safety margin values through unchanged.
5. Shopping List
A slide-out panel (cart icon in toolbar) for managing filament purchase intent:
to 1 if no usage data)
pending/ordered/received), inline status cycling,and individual delete
matching an active
stockBreakAlertBackend endpoints:
GET/inventory/shopping-listPOST/inventory/shopping-listPATCH/inventory/shopping-list/{id}/statusDELETE/inventory/shopping-list/{id}DELETE/inventory/shopping-list6. Global Lead Time Setting
Editable field in the panel toolbar (write-permission gated) that sets
forecast_global_lead_time_daysviaPUT /settings/. Acts as a floor — per-SKU overrides onlyapply when they exceed the global value.
7. Permission System
Two new permissions:
inventory:forecast_readinventory:forecast_writeBackward compatibility via
RequireAnyPermissionIfAuthEnabled:A new dependency factory accepts a list of permissions and passes if the user holds any of them.
All forecast write routes accept either
inventory:forecast_writeor the pre-existinginventory:update, so existing users are not locked out after upgrade.Frontend:
ForecastPaneluseshasAnyPermission('inventory:forecast_write', 'inventory:update')for
canWrite, mirroring the backend logic exactly.Startup migration: on every startup, groups that have
inventory:readautomatically receiveinventory:forecast_read, and groups withinventory:updateautomatically receiveinventory:forecast_write. Idempotent — only adds if not already present.8. Database Schema & Migrations
filament_sku_settingsidmaterialsubtypebrandlead_time_days0safety_margin_value14safety_margin_unit'days'alerts_snoozedfalseUnique constraint on
(material, subtype, brand).filament_shopping_listidmaterialsubtypebrandquantity_spools1status'pending'notecreated_atnow()Startup migrations (idempotent)
safety_margin_value/safety_margin_unitcolumn additionssafety_margin_dayscolumn removal (SQLite table rebuild —ALTER TABLE DROP COLUMNnot supported pre-3.35)
alerts_snoozedcolumn addition9. i18n
~50 new keys added to the
forecast:namespace across all 8 locales(en, de, fr, it, ja, pt-BR, zh-CN, zh-TW):
alertCount_one/other,spoolCount_one/other,moreSpools_one/other,addNSpools_one/otheralertsSnoozed/alertsEnabled10. Tests
New test file
ForecastPanelPermissions.test.tsx:inventory:forecast_readinventory:forecast_readScreenshots
Testing
Checklist
Additional Notes
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.