Agency Flow · Prezentare de flux
B · Hourly tiered — două benzi, aplicate marginal
Același schelet ca A2 — perioadă născută cost_entry, ore din pontaje, înghețare la
închiderea lunii. Tot ce se schimbă e formula: primele cap_hours
ore la tariful de bază, orele de peste cap la tariful de depășire. Exact două benzi,
pragul mereu în ore.
Account manager — setup
Engine — automat
Echipa — pontaje
Finance — facturare
1
O singură dată · la vânzarea serviciului
Setup: trei parametri de tarifare
Account manager
Capul de ore incluse, tariful de bază și tariful de depășire — toate fixate la setup.
Capul e prag de tarifare, nu limită de lucru: echipa poate lucra oricât,
se schimbă doar prețul orelor de peste prag.
În baza de date · la Save
INSERT service + service_pricing_hourly_tiered
billing_type: 'hourly_tiered'
cap_hours: 30.00
base_rate: 140.00
over_rate: 170.00
planning_hours: 30.00
supplier_id: NULL (labor)
2
1 august → pe parcursul lunii
Perioada acumulează, ca la A2
Engine
Echipa
Perioada se naște cost_entry; orele curg din pontaje, iar strategia recalculează
factura la fiecare pontaj — marginal: cât timp totalul e sub 30 h, totul e la 140;
din ora 31 încolo, doar ce depășește trece la 170.
Time entries · august — 36 h în total
| angajat | ore | cost/h intern | cost |
| Ana — SEO Lead | 20,0 | 100 | 2.000 |
| Radu — SEO Junior | 16,0 | 80 | 1.280 |
| total august (cap: 30 h) | 36,0 | | 3.280 |
Calculul · HourlyTieredStrategy — marginal, nu retroactiv
| banda | ore | tarif | valoare |
| ≤ cap (primele 30 h) | 30,0 | 140 | 4.200 |
| peste cap (orele 31–36) | 6,0 | 170 | 1.020 |
| client_amount | 5.220 |
Capcana clasică: la 36 h factura NU e 36 × 170. Depășirea nu re-tarifează
retroactiv toate orele — doar pe cele de peste prag. La fix 30 h, cele două formule
coincid (30 × 140); de la ora 31, fiecare oră în plus valorează 170.
3
31 august → 1 septembrie
Închidere, factură, înghețare
Finance
modulul Billing — urmează
Identic cu A2: la închiderea lunii perioada trece ready (5.220 îngheață),
factura se generează din snapshot, la Issue perioada devine invoiced și
îngheață și labour-ul.
În baza de date
UPDATE service_billing_period · 2024-08
snapshot_client_amount: 5220.00
snapshot_labour_cost: 3280.00
state: cost_entry → ready → invoiced
ready_at / invoiced_at: setate pe rând
GENERATED calculate de DB
snapshot_net_profit: 1940.00
INSERT client_invoice_line
description: MBS RO — SEO — SEO Tehnic · aug (30 h + 6 h over)
amount: 5220.00
+ TVA 21%: 1.096,20 → total 6.316,20
4
Oricând după aceea
Rezultatul lunii
Engine
client_invoice
5.220
4.200 + 1.020 (marginal)
labour_cost
3.280
per angajat, din payroll
net_profit
1.940
calculat de DB
margin
37,2%
doar ratio de afișare
Cu asta se închide familia labor: A1 = sumă constantă, A2 = rată unică × ore,
B = două benzi marginale. Toate trei împart aceleași tabele, aceleași pontaje și
aceeași înghețare — diferă doar formula din strategie. Urmează familia supplier,
unde apare service_cost_line.
DB
service_billing_period — ce se scrie și ce se actualizează
B se naște cost_entry ca A2; diferă doar formula facturii — marginală, pe două benzi. Finală la închiderea lunii (ready).
service_billing_period · ciclul de scriere al rândului lunar
INSERT service_billing_period · la generare
state: 'cost_entry'
input_supplier_cost: NULL — B nu folosește inputuri de perioadă
input_supplier_hours: NULL
input_amount_spend: NULL
snapshot_client_amount: NULL — încă necalculat
snapshot_labour_cost: NULL
snapshot_labour_hours: NULL
ready_at: NULL
invoiced_at: NULL
UPDATE service_billing_period · la fiecare pontaj (recompute cât ready_at IS NULL)
snapshot_client_amount: min(ore,cap)×base_rate + max(ore−cap,0)×over_rate (marginal)
snapshot_labour_cost: Σ ore × cost/h
snapshot_labour_hours: Σ ore
snapshot_supplier_cost: 0
bucket direct / fee / labour_recovery: 0
snapshot_net_profit: calculat de DB
orele de sub cap nu se re-tarifează când depășești (marginal); la exact cap, benzile coincid.
UPDATE service_billing_period · la închiderea lunii
state: 'cost_entry' → 'ready'
ready_at: setat — îngheață client_amount + supplier + bucket-uri
UPDATE service_billing_period · la emitere
state: 'ready' → 'invoiced'
invoiced_at: setat — îngheață labour_cost + labour_hours
labour (cost + hours) se recalculează liber între ready și invoiced; client_amount deja înghețat.
DB
service_cost_line — niciuna la acest tip
A1/A2/B sunt labor pur (supplier_id NULL, impus de CHECK) — nu există cost de furnizor, deci zero linii în service_cost_line. Rândul lunar din service_billing_period e singura evidență: factura clientului + profitabilitatea din pontaje.
Contrast: la C–Platform engine-ul materializează o linie de cost (ancora AP (Accounts Payable) a facturii furnizorului); la F1 liniile sunt introduse de oameni, una per livrabil. Aici nu e cazul — nu ai către cine să emiți o factură de furnizor.
Simulare · pontează și vezi cele două benzi
interactiv · doar vizual
Exact cum funcționează B în realitate: echipa adaugă pontaje, iar strategia tarifează
marginal — primele cap ore la base_rate, restul la
over_rate. Schimbă parametrii sau orele și urmărește cum se mută pragul.
Închizi luna → ready, emiți factura → invoiced. Nimic nu se salvează.
Echipa — pontaje
Finance — închide & emite
Parametri de tarifare live
capul e prag de tarifare, nu limită de lucru — orele de peste trec la over rate
Time entries starea perioadei: cost_entry
| angajat | ore | cost/h intern |
cost linie | acțiune |
| total (labour) |
0 | |
0 | |
| banda | calcul în cap |
| ≤ cap | |
| peste cap | |
ore_total
0
Σ ore din pontaje
client_invoice
0
base + over (marginal)
labour_cost
0
Σ ore × cost/h intern
net_profit
0
client − labour
Tarifare marginală: orele de sub cap nu se re-tarifează retroactiv când depășești.
La fix cap ore ambele benzi coincid (ex. 30 h → 4.200); la cap+1 h
diferența față de o oră normală e exact over_rate. Pragul e mereu în ore.