NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
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ázovZdroj
weekdaysVstavaný: 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 kryptomien

Odoslaní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.