Agency Flow · Prezentare de flux
A2 · Hourly flat — factura crește cu fiecare pontaj
Ca A1, dar cu o răsturnare: factura însăși e variabilă — o singură rată pe serviciu, înmulțită cu toate orele lunii. De aceea perioada A2 nu se poate naște ready: suma finală se află abia când luna se închide.
O singură dată · la vânzarea serviciului
Setup: o rată, nu o sumă
Account managerDiferența față de A1 e un singur câmp: în loc de sumă fixă, o rată orară facturată — una singură pe serviciu, nu per persoană și nu per task (decizie de spec v6: rata a urcat de pe task pe serviciu). Costul intern rămâne per angajat, din payroll.
1 august · automat
Luna se deschide — dar nu îngheață nimic
Engine
Aici A2 se desparte de A1: factura depinde de orele care abia urmează, deci perioada
se naște cost_entry (acumulare), cu ready_at NULL. Sumele de pe rând
sunt valori curente, nu snapshot-uri finale — se rescriu la fiecare pontaj.
ready_at înseamnă „sumele facturabile sunt înghețate".
La A1 suma e o constantă din setup — poate îngheța din ziua 1. La A2 suma e
rată × orele lunii, iar orele există abia la final. Stare = câtă încredere ai
în cifre, nu câtă muncă ai depus.
Pe parcursul lui august
Fiecare pontaj mișcă ambele talere
Echipa task & time_entry — pasul următor de implementare
La A1, pontajul mișca doar costul. La A2 mișcă și factura, și costul: orele intră
în client_amount cu rata serviciului (150) și în labour_cost
cu costul per angajat din payroll. Marja pe oră diferă per om — de-asta cele două
coloane evoluează diferit.
| angajat | task | ore | facturat @150 | cost/h intern | cost |
|---|---|---|---|---|---|
| Ana — SEO Lead | Outreach parteneri | 30,0 | 4.500 | 100 | 3.000 |
| Radu — SEO Junior | Prospectare linkuri | 12,0 | 1.800 | 80 | 960 |
| total august (planificat: 40 h) | 42,0 | 6.300 | 3.960 | ||
ready_at e NULL.clientInvoice: 150 × ctx.hours, // 150 × 42 = 6.300
supplierCost: 0, labourCost: ctx.labour // 3.960 din payroll
}
31 august → 1 septembrie
Închiderea lunii, apoi factura
Finance modulul Billing — urmeazăLa închiderea lunii orele sunt declarate finale: perioada trece ready și cele 6.300 îngheață. Fluxul de facturare o preia ca pe orice altă perioadă ready — de aici încolo A2 e identic cu A1.
invoiced_at.Oricând după aceea
Rezultatul lunii
Engineservice_billing_period — ce se scrie și ce se actualizează
A2 se naște cost_entry și se umple pe măsură ce se pontează; factura = rate × ore, finală abia la închiderea lunii (ready).
input_* rămân NULL; toate snapshot_* sunt încă necalculate.ready_at e NULL, strategia rescrie snapshot-urile la fiecare pontaj; net_profit e coloană generată de DB.client_amount + supplier + bucket-urile; orele sunt declarate finale pentru facturare.labour_cost + labour_hours. Între ready și invoiced labour-ul (cost + hours) încă se recalculează la pontaje întârziate; client_amount e deja înghețat.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.
Simulare · pontează tu luna
interactiv · doar vizual
Exact cum funcționează A2: o singură rată pe serviciu, înmulțită cu toate orele lunii.
Echipa adaugă pontaje (ore + cost intern/h) și factura crește cu fiecare oră —
spre deosebire de A1, unde suma e fixă din setup. Finance închide luna
(ready) și abia atunci suma îngheață, apoi emite. Nimic nu se salvează — e o schiță.
| angajat | ore | cost/h | cost linie | acțiune |
|---|---|---|---|---|
| total august | 0 | 0 |
ready). Cât perioada e cost_entry, orice
pontaj nou rescrie ambele coloane; după invoiced, luna e blocată.