Všetky balíky
Workflows for Laravel
Pracovný čas a eskalácie
Kalendáre
Kalendár implementuje Contracts\BusinessCalendar: timezone(), isBusinessDay($date), isOpenAt($instant), nextOpen($instant), nextClose($instant).
| Názov | Zdroj |
|---|---|
weekdays | Vstavaný: celé dni podľa business_time.weekdays (predvolene po – pi) v časovom pásme verzie. |
opening_hours:<name> | Prepojenie s opening-hours: rozvrh otváracích hodín <name> vlastníka (vrátane sviatkov a výnimiek). |
| … | Čokoľvek, čo zaregistrujete: Workflows::calendars()->register('support', fn (?Model $owner, string $timezone): BusinessCalendar => …). |
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Workflows\Contracts\BusinessCalendar;
Workflows::calendars()->register('support', fn (?Model $owner, string $timezone): BusinessCalendar => new SupportCalendar($owner, $timezone));
Workflows::calendars()->names(); // ['weekdays', 'support', …]
Workflows::calendars()->find('support', $team, 'Europe/Bratislava');- Vlastníkom kalendára opening_hours: je vlastník inštancie, pri definíciách celej aplikácie model, ktorý vráti business_time.calendar_owner (invokable trieda).
- settings.calendar grafu je predvolený; calendar v trvaní ho prepíše.
- Chýbajúci kalendár je pri publikovaní unknown_calendar a za behu krok zlyhá s calendar_missing.
Počítanie pracovného času
- Pracovné dni: rovnaký miestny čas na n-tý pracovný deň ostro po dni začiatku. Pi 15:00 + 2 → ut 15:00. So 10:00 + 2 → ut 10:00. Čas, ktorý neexistuje (medzera pri prechode na letný čas), sa posunie na najbližší platný okamih; čas, ktorý nastane dvakrát (návrat na zimný čas), berie prvý výskyt.
- Pracovné hodiny a minúty spotrebúvajú otvorený čas — zatvorené obdobia sa preskočia a okamih presne v čase zatvorenia sa ráta ako zatvorený.
- Kalendár, ktorý implementuje Contracts\CountsBusinessTime (addBusinessDays(), addBusinessTime()), počíta sám — kalendáre opening_hours: to odovzdajú balíku opening-hours. Každý iný kalendár (weekdays, váš vlastný) počítajú hodiny balíka cez isOpenAt() / nextOpen() / nextClose().
- Hľadanie je obmedzené: hodiny balíka cez business_time.max_search_days (366), opening-hours cez opening-hours.search_days (366). Kalendár bez dostatku otvoreného času v tomto okne ukončí krok s calendar_never_open.
- Jeden rozdiel na hrane: opening-hours obmedzuje celé obdobie svojím search_days, aj pri kalendári, ktorý je stále otvorený, zatiaľ čo hodiny balíka sa pri kalendári, ktorý sa nikdy nezatvára, nezastavia. S predvolenými hodnotami (366 v oboch) sa výsledky zhodujú.
- Kalendárne jednotky (P1M od 31. januára) sa riadia Carbonom v časovom pásme verzie (→ 28./29. februára).
Eskalácie
Kroky, ktoré čakajú (wait, approval, vlastné typy so supportsEscalations()), prijímajú blok escalations:
"escalations": [
{ "after": { "amount": 2, "unit": "business_days" },
"actions": [
{ "type": "reassign", "to": [ { "kind": "field", "field": "subject.approver_manager" } ] },
{ "type": "notify", "notification": "purchase.escalated", "recipients": [ { "kind": "field", "field": "subject.requester" } ] } ] },
{ "after": "P1D",
"actions": [ { "type": "start_workflow", "definition": "purchase-escalation-board" } ] }
]use RoundlyConsulting\Workflows\Graph\Build\{After, Escalate, Party};
Workflows::graph()
->approval('approve', approvers: [Party::field('subject.approver')], expiresIn: After::businessDays(5))
->escalate(After::businessDays(2), Escalate::reassign(Party::field('subject.approver_manager')),
Escalate::notify('purchase.escalated', Party::field('subject.requester')))
->escalate(After::days(1), Escalate::startWorkflow('purchase-escalation-board'));- Najviac escalations.max_levels (5) úrovní, v každej najviac 5 akcií. notify (prepojenie s notifications) — {notification, recipients, data?}; reassign — {to: parties}, cez reassign() typu kroku (approval ho implementuje; na type bez neho sa pri publikovaní odmietne); start_workflow — {definition, input?}; dieťa dostane subjekt, ak nie je bez subjektu, a dieťa, ktoré odmietne limit spustení, sa ráta ako zlyhaná akcia (child_not_started): eskalácia sa opakuje s odstupom a neoznačí sa ako fired.
- Načasovanie: úroveň 1 je splatná v prvom started_at návštevy + after; úroveň n + 1 vo fired_at úrovne n + jej after. Ako riadok existuje len najbližšia čakajúca úroveň. Automatické opakovania reťazec zachovajú. Ručné opakovanie kroku, ktorému sa reťazec pri zlyhaní prerušil, ho spustí znova od úrovne 1, s časom od začiatku opakovaného pokusu.
- Spustenie (prevezme workflows:wake, vykoná FireEscalationJob v kontexte vlastníka): ak je krok medzi dvoma pokusmi, eskalácia ostane čakať a znova bude splatná minútu po naplánovaní pokusu; ak krok už nebeží, nečaká ani nie je vo fronte, eskalácia sa zruší. Inak sa každá akcia vykoná raz (idempotentne pre úroveň aj akciu), riadok je fired, vytvorí sa ďalšia úroveň a vyšle sa EscalationTriggered.
- Zlyhanie: zlyhaná akcia sa opakuje podľa politiky opakovania; po vyčerpaní je eskalácia failed a vyšle sa EscalationFailed. Krok aj inštancia bežia ďalej: eskalácia nikdy neukončí zlyhaním prácu, ktorú eskaluje.
- Čakajúce eskalácie sa zrušia, keď krok skončí (dokončený, zlyhaný alebo zrušený), v tej istej transakcii. Skúšobné behy vypíšu každú úroveň s vypočítaným časom splatnosti.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.