# For an online version, see http://wiki.bestpractical.com/?RulesetWorkflow

_*This is a design document for a work in progress.
It describes features that do not exist today and may never exist*_

== Text Description

* The user of PurchaseOrder queue fill in a numeric "CF", called "Price".
* On creation, it needs to create following approvals:
** "ManagerApproval" if CF.Price is > 1000
** "PresidentApproval" if CF.Price is > 2000
* When all of "M", "P" are resolved (or if there were none to begin with), Create "FinanceApproval".
* If any approvals above is rejected, reject the original ticket.
* If "FinanceApproval" is resolved, resolve original ticket.
* If "FinanceApproval" is rejected, create an approval for "CEOApproval".
* If "CEOApproval" is resolved, resolve the original ticket.
* If "CEOApproval" is rejected, reject the original ticket.

== ASCII Diagram

       ,----------.      ,---------------------->[DONE]
       |           \    /                           ^
 [TOP]-+-?---->[M]---->[F]                          |
       |        |  /    \                           |
       `-?->[P]-+-'      `-(!)->[C]-----------------'
             |  |                |
             |  |                `-(!)---------->[FAIL]
             |  |                                   ^
             `-(!)----------------------------------'

== Objects

Note that "Scrips" are now called "Rules".

=== RuleAction "AquireMyLocks"

  FOREACH $Scrip IN $TicketObj->Scrips
    WHERE $Scrip.Action.Type == "TryCreateTicketWithRuleset"
       DO LockRuleset $Scrip.Action.Argument

=== RuleAction "TryCreateTicketWithRuleset"

  DO ReleaseMyLockOnRuleset $Argument
  UNLESS RulesetLocked $Argument
      DO CreateTicketWithRuleset $Argument

=== RuleAction "CreateTicketWithRuleset"

  GIVEN $Ticket AS CreateTicket(@OtherArguments)
     DO SetTicketRuleSet $Argument
     DO RunTicketRuleSet $Argument
  
=== GlobalRule "AquireLocks"

* AppliesTo: All Objects
* Condition: OnCreate
* Action: AquireMyLocks

=== Queue "PurchaseOrder"

* Rule:
** Condition: OnCreate
** Action: SetTicketRuleSet "PurchaseFlow"
** Action: RunTicketRuleSet "PurchaseFlow"

=== RuleSet "PurchaseFlow"

* Rule (implicitly run by AcquireMyLocks):
** Condition: OnCreate
** Action: LockRuleSet "ManagerApproval"
** Action: LockRuleSet "PresidentApproval"
** Action: LockRuleSet "FinanceApproval"

* Rule:
** Condition: OnCreate 
** Condition: CF.Price > 1000
** Action: TryCreateTicketWithRuleset "ManagerApproval"

* Rule:
** Condition: OnCreate 
** Condition: CF.Price > 2000
** Action: TryCreateTicketWithRuleset "PresidentApproval"

* Rule:
** Condition: OnCreate 
** Condition: "Finance" is not blocked
** Action: TryCreateTicketWithRuleset "FinanceApproval"

* Rule:
** Condition: OnReject
** Action: DeleteTree

=== RuleSet: "ManagerApproval"

* Rule (implicitly run by AcquireMyLocks):
** Condition: OnCreate
** Action: LockRuleSet "FinanceApproval"

* Rule:
** Condition: OnResolve
** Action: TryCreateTicketWithRuleset "FinanceApproval"

* Rule:
** Condition: OnReject
** Action: RejectTicket "PurchaseFlow"

=== RuleSet: "PresidentApproval"

* Rule (implicitly run by AcquireMyLocks):
** Condition: OnCreate
** Action: LockRuleSet "FinanceApproval"

* Rule:
** Condition: OnResolve
** Action: TryCreateTicketWithRuleset "FinanceApproval"

* Rule:
** Condition: OnReject
** Action: RejectTicket "PurchaseFlow"

=== RuleSet: "FinanceApproval"

* Rule:
** Condition: OnResolve
** Action: ResolveTicket "PurchaseFlow"

* Rule:
** Condition: OnReject
** Action: ForceCreateTicketWithRuleset "CEOApproval"

=== RuleSet: "CEOApproval"

* Rule:
** Condition: OnResolve
** Action: ResolveTicket "PurchaseFlow"

* Rule:
** Condition: OnReject
** Action: RejectTicket "PurchaseFlow"

### FNORD FNORD FNORD FNORD FNORD FNORD FNORD FNORD FNORD ###

== Another Text Description

* I have a MonitoredQueue that sets tickets to "Monitored" if its subject matches /monitored/.
* I want to have a kind of Ticket that are 'Monitored'.
* I want all monitored tickets, when they are overdue for 14 days, to:
** Send notification to manager
** Mark as stalled
* I want all monitored tickets, when they are overdue for 28 days, to:
** Mark as rejected
* I want to query all tickets that are monitored as such
* I want to modify 14 => 15 and have it affect all existing tickets that are monitored
* I want to add a new "overdue for 27 days, add a 'ultimatum' correspondence to it" rule
** For all monitored tickets.
* I want to add a new "overdue for 27 days, add a 'ultimatum' correspondence to it" rule
** For all _new_ monitored tickets.
** Without affecting existing ones.