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. Se agregă numai pontajele din zile eligibile; nici ratele, nici
cap_hours lunar nu se proratează într-o lună parțială.
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.
Înghețarea aparține perioadei lunare a acestui Service, nu Service-ului și nu formularului
de pontaj. Utilizatorii pot introduce în continuare ore billable după ready; ele sunt
pontaje întârziate și, până la invoicing, actualizează labour-ul/profitabilitatea, fără să
schimbe tăcut suma client sau ecuația de billed hours deja ready. Dacă trebuie facturate în
aceeași lună, Finance redeschide și recalculează explicit perioada înainte de invoicing.
În baza de date
UPDATE service_billing_period · 2024-08
snapshot_client_amount: 5220.00
snapshot_pricing_cap_hours / base_rate / over_rate: 30.00 / 140.00 / 170.00
snapshot_billed_hours: 36.00 — îngheață cu client amount
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_pricing_cap_hours / base_rate / over_rate: termenii contractuali folosiți; îngheață cu billables
snapshot_billed_hours: orele folosite în benzile facturabile; îngheață la ready
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
billed hours · freeze la ready
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.
Freeze per perioadă: la ready simularea fixează billed hours, cap-ul și
ratele care produc factura. Pontajele întârziate rămân posibile până la invoiced
și actualizează labour-ul/profitabilitatea, fără să schimbe factura înghețată.