Zenaton white logo

Real World Examples

Scrape & Analyze Restaurant Reviews

This Workflow scrapes all of the Tripadvisor reviews for a restaurant for the current month and then a sentiment analysis for each review to determine the positive or negative aspects. Finally, the results are saved to a Google sheet where they can be made into a report.

  • First, it gets the current month.
  • Then we pull all of the tripadvisor urls for that restaurant for that month.
  • Then a sentiment analysis script is launched for each review (in parallel) to determine if it is positive or negative.
  • Finally, the data is saved to a google sheet.

Flowchart of the workflow

This flowchart helps us to visualize the tasks and logic of the workflow.

review analysis workflow

Workflow Code

This workflow is the code that orchestrates tasks (through the Zenaton workflow engine) and executes them on your servers. Tasks inside the workflow are not detailled here.

ReviewAnalysisWorkflow.php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Parallel\Parallel;
use Zenaton\Traits\Zenatonable;
class ReviewAnalysisWorkflow implements WorkflowInterface
{
    use Zenatonable;
    public function __construct($restaurantName, $tripAdvisorUrl)
    {
        $this->restaurantName = $restaurantName;
        $this->tripAdvisorUrl = $tripAdvisorUrl;
    }
    public function handle()
    {
        $currentMonth = (new GetCurrentMonth())->execute();
        $reviews = (new ScrapeReviewsOfTheMonth($this->tripAdvisorUrl, $currentMonth))->execute();

        $postiveAndNegativeAspects = (new Parallel(
            ...array_map(
                function($review) { return new SentimentAnalysis($review); },
                $reviews
            )
        ))->execute();

        (new SaveToGoogleSheet(
            $this->restaurantName,
            $currentMonth,
            count($reviews),
            $postiveAndNegativeAspects
        ))->execute();
    }
}
const { Workflow, Parallel } = require("zenaton");
const GetCurrentMonth = require("../Tasks/GetCurrentMonth");
const ScrapeReviewsOfTheMonth = require("../Tasks/ScrapeReviewsOfTheMonth");
const SentimentAnalysis = require("../Tasks/SentimentAnalysis");
const SaveToGoogleSheet = require("../Tasks/SaveToGoogleSheet");

module.exports = Workflow("ReviewAnalysisWorkflow", {

    init(restaurantName, tripAdvisorUrl) {
        this.restaurantName = restaurantName;
        this.tripAdvisorUrl = tripAdvisorUrl;
    },
    async handle() {
        const currentMonth = await new GetCurrentMonth().execute();
        const reviews = await new ScrapeReviewsOfTheMonth(
            this.tripAdvisorUrl,
            this.currentMonth
        ).execute();

        const postiveAndNegativeAspects = new Parallel(
            ...reviews.map(review => new SentimentAnalysis(review))
        );

        await new SaveToGoogleSheet(
            this.restaurantName,
            currentMonth,
            reviews.length,
            postiveAndNegativeAspects
        ).execute();
    }
});
require "./tasks/get_current_month"
require "./tasks/scrape_reviews_of_the_month"
require "./tasks/sentiment_analysis"
require "./tasks/save_to_google_sheet"

class ReviewAnalysisWorkflow < Zenaton::Interfaces::Workflow
  include Zenaton::Traits::Zenatonable
  
  def initialize(restaurant_name, trip_advisor_url)
    @restaurant_name = restaurant_name
    @trip_advisor_url = trip_advisor_url
  end
  
  def handle
    current_month = GetCurrentMonth.new.execute

    reviews = ScrapeReviewsOfTheMonth.new(@trip_advisor_url, current_month).execute

    postive_and_negative_aspects = Zenaton::Parallel.new(*reviews.map { |review|
      SentimentAnalysis.new(review)
    }).execute

    SaveToGoogleSheet.new(@restaurant_name, current_month, reviews.length, postive_and_negative_aspects).execute
  end
end
from zenaton.abstracts.workflow import Workflow
from zenaton.traits.zenatonable import Zenatonable
from zenaton.parallel import Parallel
from tasks.get_current_month import GetCurrentMonth
from tasks.scrape_reviews_of_the_month import ScrapeReviewsOfTheMonth
from tasks.sentiment_analysis import SentimentAnalysis
from tasks.save_to_google_sheet import SaveToGoogleSheet

class ReviewAnalysisWorkflow(Workflow, Zenatonable):

    def __init__(self, restaurantName, tripAdvisorUrl):
        self.restaurantName = restaurantName
        self.tripAdvisorUrl = tripAdvisorUrl

    def handle(self):
        currentMonth = GetCurrentMonth().execute()
        reviews = ScrapeReviewsOfTheMonth(self.tripAdvisorUrl, currentMonth).execute()

        postiveAndNegativeAspects = Parallel(
            *list(map(lambda review: SentimentAnalysis(review), reviews))
        ).execute()

        SaveToGoogleSheet(
            self.restaurantName,
            currentMonth,
            len(reviews),
            postiveAndNegativeAspects
        ).execute()

Real-Time Monitoring on the Zenaton Dashboard

View a short snippet of the task executions from the dashboard.

review analysis animation

Amazon Dash Button Workflow

This example shows how to create a workflow similar to an Amazon Dash Button that allows customers to order an item and be charged for it - and if needed, also prompting them to update their payment information or cancel the order.

  • Charge customer for the order processed.
  • If customer is not charged, then ask for new payments details.
  • If payment details are not updated within two weeks, then cancel the order
  • Send customer an invoice when their payment is processed and send the order to shipping

Flowchart of the workflow

This flowchart helps visualize different tasks within the workflow.

Workflow Code

This workflow is the code that orchestrates tasks (through the Zenaton workflow engine) and executes them on your servers. Tasks will be dispatched as soon as the user presses the button to order something.

AmazonDashButton.php

use App\Events\OrderPaid;
use App\Order;
use App\Tasks\AskForNewPaymentDetails;
use App\Tasks\CancelOrder;
use App\Tasks\ChargeCustomerForOrder;
use App\Tasks\SendOrderInvoice;
use App\Tasks\SendOrderToShipping;
use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Tasks\Wait;
use Zenaton\Traits\Zenatonable;
final class OrderFromDashButton implements WorkflowInterface
{
    use Zenatonable;
    private $order;
    public function __construct(Order $order)
    {
        $this->order = $order;
    }
    public function handle()
    {
        $charged = (new ChargeCustomerForOrder($this->order))->execute();
        $event = null;
        if (!$charged) {
            (new AskForNewPaymentDetails($this->order))->dispatch();
            $event = (new Wait(OrderPaid::class))->days(14)->execute();
        }
        if ($charged || $event) {
            (new SendOrderInvoice($this->order))->dispatch();
            (new SendOrderToShipping($this->order))->dispatch();
        } else {
            (new CancelOrder($this->order))->dispatch();
        }
    }
    public function getId()
    {
        return $this->order->id;
    }
}
const { Wait, Workflow } = require("zenaton");
const AskForNewPaymentDetails = require("../Tasks/AskForNewPaymentDetails");
const ChargeCustomerForOrder = require("../Tasks/ChargeCustomerForOrder");
const SendOrderInvoice = require("../Tasks/SendOrderInvoice");
const SendOrderToShipping = require("../Tasks/SendOrderToShipping");

module.exports = Workflow("OrderFromDashButton", {
  init (order) {
    this.order = order;
  },
  id () {
    return this.order.id;
  },
  async handle () {
    const order = this.order
    const charged = await new ChargeCustomerForOrder(this.order).execute();
    let event = null;

    if (!charged) {
      await new AskForNewPaymentDetails(this.order).dispatch();
      event = await new Wait("OrderPaid").seconds(14).execute();
    }

    if (charged || event) {
      await new SendOrderInvoice(this.order).dispatch();
      await new SendOrderToShipping(this.order).dispatch();
    } else {
      await new CancelOrder(this.order).dispatch();
    }
  }
});
    
require "./events/order_paid"
require "./order"
require "./tasks/ask_for_new_payment_details"
require "./tasks/cancel_order"
require "./tasks/charge_customer_for_order"
require "./tasks/send_order_invoice"
require "./tasks/send_order_to_shipping"
require "zenaton"

class OrderFromDashButton < Zenaton::Interfaces::Workflow
  include Zenaton::Traits::Zenatonable

  def initialize(order)
    @order = order
  end

  def id
    @order.id
  end

  def handle
    charged = ChargeCustomerForOrder.new(@order).execute
    event = nil

    unless charged
      AskForNewPaymentDetails.new(@order).dispatch
      event = Zenaton::Tasks::Wait.new(OrderPaid).days(14).execute
    end

    if charged || event
      SendOrderInvoice.new(@order).dispatch
      SendOrderToShipping.new(@order).dispatch
    else
      CancelOrder.new(@order).dispatch
    end
  end
end
from zenaton.abstracts.workflow import Workflow
from zenaton.traits.zenatonable import Zenatonable
from events.order_paid import OrderPaid
from tasks.ask_for_new_payment_details import AskForNewPaymentDetails
from tasks.cancel_order import CancelOrder
from tasks.charge_customer_for_order import ChargeCustomerForOrder
from tasks.send_order_invoice import SendOrderInvoice
from tasks.send_order_to_shipping import SendOrderToShipping

class OrderFromDashButton(Workflow, Zenatonable):
    def __init__(order):
        self.order = order
    def handle(self):
    
      charged = ChargeCustomerForOrder(self.order).execute()
      
      event = None

      if not charged:
          AskForNewPaymentDetails(self.order).dispatch()
          event = Wait(OrderPaid).days(14).execute()
      if charged or event:
          SendOrderInvoice(self.orderh).dispatch()
          SendOrderInvoice(self.orderh).dispatch()
      else:
          CancelOrder(self.order).dispatch()   
    

Workflow in Action

View the real time execution of this workflow as recorded on the Zenaton dashboard.

Amazon Dash Button Dashboard

Document Validation

This Workflow illustrates how to implement a document validation process using a third party API/service to verify a user's identity based on the documents that they upload.

  • A user signs up and opens an account and is prompted to upload their documents.
  • According to the account type, some additional documents may be needed. In this example, the user must upload 2 documents : an ID and a proof of address.
  • After 3 days, if the user has not uploaded the documents, a reminder is sent to tell them that they must import the remaining documents.
  • We’ll send a maximum of 3 reminders spaced 3 days apart.
  • If the user does not import their documents the account will not be opened, and we would email the user to notify them that they needs to sign in again and create the account.
  • When a user does import the documents, we would check with our third party service to make sure that they are valid.
  • If the documents are not valid, we would notify the user by email and tell them the reason.
  • When the documents have been validated, we will notify the user that the process is complete.

Flowchart of the workflow

This flowchart is a visual representation of the different tasks in the workflow.

Workflow Code

This workflow is the code that orchestrates the tasks through the Zenaton workflow engine and are then executed on your servers. Tasks will be dispatched as soon as a user is prompted to upload their documents and the tasks will be executed "behind the scenes" on your workers.

DocumentValidation.php

use Zenaton\Interfaces\EventInterface;
use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Tasks\Wait;
use Zenaton\Traits\Zenatonable;

class DocumentValidationWorkflow implements WorkflowInterface
{
    use Zenatonable;

    protected $requestId;
    protected $remainingReminders = 3;
    protected $documents = [];

    public function __construct($requestId)
    {
        $this->requestId = $requestId;
    }

    public function handle()
    {
        $request = (new GetRequestInformation($this->requestId))->execute();

        $this->documents = $request->documents;

        while (count($this->documents) > 0 && $this->remainingReminders > 0) {        
            $event = (new Wait(ProofReceivedEvent::class))->days(3)->execute();

            if (!$event) {
                (new SendReminderEmail($request))->dispatch();
                --$this->remainingReminders;
            }
        }

        if (count($this->documents) === 0) {
            (new SendSuccessValidationEmail($request))->dispatch();
        } else {
            (new SendFailureValidationEmail($request))->dispatch();
        }
    }

    public function getId()
    {
        return $this->requestId;
    }
}
require "./tasks/get_request_information"
require "./tasks/send_reminder_email"
require "./tasks/send_success_validation_email"
require "./tasks/send_failure_validation_email"
require "./events/proof_received_event"

class DocumentValidationWorkflow < Zenaton::Interfaces::Workflow
  include Zenaton::Traits::Zenatonable
  def initialize(requestId)
    @request_id = requestId
    @documents = []
    @remaining_reminders = 3
  end

  def handle
    counter = 0
    request = GetRequestInformation(@request_id).new.execute
    @documents = request.documents

    loop do
      event = Zenaton::Tasks::Wait.new(ProofReceivedEvent).days(3).execute
      if !event
        SendReminderEmail.new.execute
        @remaining_reminders -= 1
      end
      break if @documents.length == 0 || @remaining_reminders == 0
    end

    if @documents.length == 0
      SendSuccessValidationEmail.new.dispatch
    else
      SendFailureValidationEmail.new.dispatch
    end
  end

  def id
    @request_id
  end
end
from zenaton.abstracts.workflow import Workflow
from zenaton.traits.zenatonable import Zenatonable
from zenaton.tasks.wait import Wait
from tasks.get_request_information import GetRequestInformation
from tasks.send_reminder_email import SendReminderEmail
from tasks.send_success_validation_email import SendSuccessValidationEmail
from tasks.send_failure_validation_email import SendFailureValidationEmail
from events.proof_received_event import ProofReceivedEvent


class DocumentValidationWorkflow(Workflow, Zenatonable):
    def __init__(self, requestId):
        self.requestId = requestId
        self.remainingReminders = 3
        self.documents = []
    def handle(self):

        GetRequestInformation(self.requestId).execute()
        self.documents = request.documents
    
        while count(self.documents) > 0 and self.remainingReminders > 0:
            event = Wait(ProofReceivedEvent).days(3).execute()
            if not event
                SendReminderEmail(self.request).dispatch()
                self.remainingReminders -= 1
            break

        if count(self.documents) == 0:
            SendSuccessValidationEmail().dispatch()
        else:
            SendFailureValidationEmail().dispatch()
        
    def id(self):
        return self.requestId
const { Wait, Workflow } = require('zenaton')
const GetRequestInformation = require('../Tasks/GetRequestInformation')
const SendReminderEmail = require('../Tasks/SendReminderEmail')
const SendSuccessValidationEmail = require('../Tasks/SendSuccessValidationEmail')
const SendFailureValidationEmail = require('../Tasks/SendFailureValidationEmail')

module.exports = Workflow('DocumentValidationWorkflow', {
  init (requestId) {
    this.requestId = requestId
    this.counter = null
  },

  async handle () {
    let remainingReminders = 3
    const request = await new GetRequestInformation(this.requestId).execute()

    this.counter = request.documents.length

    while (this.counter > 0 && remainingReminders > 0) {
      const event = await new Wait('ProofReceivedEvent').days(3).execute()

      if (!event) {
        await new SendReminderEmail(request).dispatch()
        remainingReminders--
      }
    } 

    if (this.counter === 0) {
      await new SendSuccessValidationEmail().dispatch()
    } else {
      await new SendFailureValidationEmail().dispatch()
    }
  },

  id () {
    return this.requestId
  },

  onEvent (name, data) {
    if (name === 'ProofReceivedEvent') {
      if (data.isValid) {
        this.counter--
      }
    }
  }
})

Real-time executions of the workflow from the Zenaton Dashboard

View the real-time tasks executions of this workflow.

Triggering An Email After 3 Days of Cold Weather

This example shows how to create a workflow that triggers a promotional email about a tropical vacation after 3 days of cold weather. It can be useful for an agency or anyone who wants to trigger notification based on external data and timing.

  • Calls a weather API to get the temperature of the current day for a specific period (ie. number of days)
  • If the temperature is less than 40°F for three days in a row, then it sends an email to users using gmail.
  • If not, it keeps checking everyday until the end of the period
  • If during the period of days, the temperature hasn't dropped below 40°F for 3 days, then it sends a different promotional email.

Flowchart of the workflow

This flowchart shows a visual representation of the workflow tasks.

Flowchart of triggering emails weather

Workflow Code

This workflow is the code that orchestrates tasks (through the Zenaton workflow engine) and executes them on your servers. Tasks will be dispatched as soon as three days of cold weather occurs.

TriggerEmailsWeather.php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Tasks\Wait;
use Zenaton\Traits\Zenatonable;

class TemperatureCampaignWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function __construct($days, $minTemp, $minRep, $city, $emailRecipients)
    {
        $this->days = $days;
        $this->minTemp = $minTemp;
        $this->minRep = $minRep;
        $this->city = $city;
        $this->emailRecipients = $emailRecipients;
    }

    public function handle()
    {
        $repCount = 0;

        do {
            $currentTemp = (new CheckTemperatureTask($this->city))->execute();
            if ($currentTemp < $this->minTemp) {
                ++$repCount;
            } else {
                $repCount = 0;
            }

            (new Wait())->days(1)->execute();

            --$this->days;
        } while ($repCount < $this->minRep && $this->days > 0);

        if ($repCount === $this->minRep) {
            (new SendEmailCampaign($this->emailRecipients, $this->city))->execute();
        } else {
            (new SendAnotherEmailCampaign($this->emailRecipients, $this->city))->execute();
        }
    }
}
    
const { Workflow, Wait } = require('zenaton')
const CheckTemperature = require('../Tasks/CheckTemperature')
const SendEmailCampaign = require('../Tasks/SendEmailCampaign')
const SendAnotherEmailCampaign = require('../Tasks/SendAnotherEmailCampaign')

module.exports = Workflow('TemperatureCampaignWorkflow', {
  init (days, minTemp, minRep, city, emailRecipients) {
    this.days = days
    this.minTemp = minTemp
    this.minRep = minRep
    this.city = city
    this.emailRecipients = emailRecipients
  },

  async handle () {
    let repCount = 0
    do {
      if ((await new CheckTemperature(this.city).execute()) < this.minTemp) {
        repCount++
      } else {
        repCount = 0
      }
      Wait().days(1).execute()
      this.days--
    } while (repCount < this.minRep && this.days > 0)

    if (repCount === this.minRep) {
      await new SendEmailCampaign(this.emailRecipients, this.city).execute()
    } else {
      await new SendAnotherEmailCampaign(this.emailRecipients,this.city).execute()
    }
  }
})
require "./tasks/send_email_campaign"
require "./tasks/check_temperature"
require "./tasks/send_another_email_campaign"

class TemperatureCampaignWorkflow < Zenaton::Interfaces::Workflow
  include Zenaton::Traits::Zenatonable

  def initialize(days, min_temp, min_rep, city, email_recipients)
    @days = days
    @min_temp = min_temp
    @min_rep = min_rep
    @city = city
    @email_recipients = email_recipients
  end

  def handle
    rep_count = 0
    loop do
      if CheckTemperature.new(@city).execute < @min_temp
        rep_count += 1
      else
        rep_count = 0
      end

      Zenaton::Tasks::Wait.new.days(1).execute
      @days -= 1

      break if rep_count == @min_rep || @days == 0
    end

    if rep_count == @min_rep
      SendEmailCampaign.new(@email_recipients, @city).execute
    else
      SendAnotherEmailCampaign.new(@email_recipients, @city).execute
    end
  end
end
    
from tasks.check_temperature import CheckTemperature
from tasks.send_email_campaign import SendEmailCampaign
from tasks.send_another_email_campaign import SendAnotherEmailCampaign

from zenaton.abstracts.workflow import Workflow
from zenaton.traits.zenatonable import Zenatonable
from zenaton.tasks.wait import Wait


class TemperatureCampaignWorkflow(Workflow, Zenatonable):

    def __init__(self, days, min_temp, min_rep, city, email_recipients):
        self.days = days
        self.min_temp = min_temp
        self.min_rep = min_rep
        self.city = city
        self.email_recipients = email_recipients

    def handle(self):
        rep_count = 0
        for _ in range(self.days):
            if CheckTemperature(city=self.city).execute() < self.min_temp:
                rep_count += 1
            else:
                rep_count = 0
            if rep_count == self.min_rep:
                SendEmailCampaign(self.email_recipients, self.city).execute()
                break
            Wait().days(1).execute()
        else:
            SendAnotherEmailCampaign(self.email_recipients, self.city).execute()
            pass
    

Real-time executions of the workflow from Zenaton Dashboard

View the real time execution of this workflow on the Zenaton dashboard.

Background jobs executions of triggering emails weather

Automated Onboarding for New Employees

This Workflow helps companies to better onboard new employees by scheduling usual meetings, creating accounts for specific tools, send them reading documents ..Even if tasks are automated, employees receive a personalize onboarding thanks to an onboarding form.

  • Prepare paperwork of the employee.
  • If the paperwork has been received, then schedule a pre-onboarding meeting.
  • A form must be completed by the employee.
  • When it has been completed, required accounts are created.
  • Wait until the first day and then send a welcome email to the employee.
  • Based on the entries in the employee's form, provide the relevant credentials and required readings.
  • Finally, schedule another onboarding meeting
  • If the paperwork was never been received, cancel the onboarding.

Flowchart of the workflow

This flowchart shows a visual representation of the different tasks in the workflow.

Flowchart of employee onboarding

Workflow Code

This workflow is the code that orchestrates tasks (through the Zenaton workflow engine) and executes them on your servers.

EmployeeOnboarding.php

use Zenaton\Interfaces\WorkflowInterface;
use Zenaton\Tasks\Wait;
use Zenaton\Traits\Zenatonable;

class OnboardingWorkflow implements WorkflowInterface
{
    use Zenatonable;

    public function __construct($employee)
    {
        $this->employee = $employee;
    }

    public function handle()
    {
        (new PreparePaperwork($this->employee))->dispatch();

        $paperworkEvent = (new Wait(PaperworkEvent::class))->execute();

        if ($paperworkEvent->success) {
            (new SchedulePreOnboardingMeeting($this->employee))->dispatch();

            $form = (new Wait(OnboardingFormEvent::class))->execute();

            $accounts = (new CreateAccounts($this->employee, $form->tools))->execute();
            (new OfficeManagement($this->employee, $form))->dispatch();

            (new Wait())->timestamp($form->onboardingDay)->execute();

            (new SendWelcome($this->employee))->dispatch();
            (new SendCredentials($this->employee, $accounts))->dispatch();
            (new SendRequiredReading($this->employee, $form->reading))->dispatch();
            (new ScheduleOnboardingMeetings($this->employee, $form->meetings))->dispatch();
        } else {
            (new CancelOnboarding($this->employee))->dispatch();
        }
    }

    public function getId()
    {
        return $this->employee->id;
    }
}
    
const { Workflow } = require("zenaton");
const PreparePaperwork = require("./Tasks/PreparePaperwork");
const SchedulePreOnboardingMeeting = require("./Tasks/SchedulePreOnboardingMeeting");
const CreateAccounts = require("./Tasks/CreateAccounts");
const OfficeManagement = require("./Tasks/OfficeManagement");
const SendWelcome = require("./Tasks/SendWelcome");
const SendCredentials = require("./Tasks/SendCredentials");
const SendRequiredReading = require("./Tasks/SendRequiredReading");
const ScheduleOnboardingMeetings = require("./Tasks/ScheduleOnboardingMeetings");
const CancelOnboarding = require("./Tasks/CancelOnboarding");

module.exports = Workflow("OnboardingWorkflow", {
  init(employee) {
    this.employee = employee;
  },

  async handle() {
    await new PreparePaperwork(this.employee).dispatch();

    const paperworkEvent = await new Wait("PaperworkEvent").execute();

    if (paperworkEvent.success) {
      await new SchedulePreOnboardingMeeting(this.employee).dispatch();

      const form = await new Wait("OnboardingFormEvent").execute();

      this.accounts = await new CreateAccounts(employee, form.tools).dispatch();
      await new OfficeManagement(employee, form).dispatch();

      await new Wait().timestamp(form.onboardingDay).execute();

      await new SendWelcome(employee).dispatch();
      await new SendCredentials(employee, this.accounts).dispatch();
      await new SendRequiredReading(employee, form.reading).dispatch();
      await new ScheduleOnboardingMeetings(employee, form.meetings).dispatch();
    } else {
      await new CancelOnboarding(this.employee).dispatch();
    }
  }
});      
    
require "./Tasks/PreparePaperwork"
require "./Tasks/SchedulePreOnboardingMeeting"
require "./Tasks/CreateAccounts"
require "./Tasks/OfficeManagement"
require "./Tasks/SendWelcome"
require "./Tasks/SendCredentials"
require "./Tasks/SendRequiredReading"
require "./Tasks/ScheduleOnboardingMeetings"
require "./Tasks/CancelOnboarding"

class OnboardingWorkflow < Zenaton::Interfaces::Workflow
  include Zenaton::Traits::Zenatonable
  def initialize(employee)
    @employee = employee
  end
  def handle
    PreparePaperwork.new(employee).execute
    
    paperworkEvent = Zenaton::Tasks::Wait.new(PaperworkEvent).execute

    if paperworkEvent.success 
    
      SchedulePreOnboardingMeeting.new(employee).dispatch

      form = Zenaton::Tasks::Wait.new(OnboardingFormEvent).execute
      accounts = CreateAccounts.new(employee, form.tools).dispatch
      
      OfficeManagement.new(employee, form).dispatch
      Zenaton::Tasks::Wait.new.timestamp(form.onboardingDay).execute
      SendWelcome.new(employee).dispatch
      SendCredentials.new(employee, this.accounts).dispatch
      SendRequiredReading.new(employee, form.reading).dispatch
      ScheduleOnboardingMeetings.new(employee, form.meetings).dispatch
      
      else
      CancelOnboarding.new(employee).dispatch
      end
  end
end
    
from zenaton.abstracts.workflow import Workflow
from zenaton.traits.zenatonable import Zenatonable
from tasks.prepare_paper_work import PreparePaperwork
from tasks.schedule_pre_onboarding_meeting import SchedulePreOnboardingMeeting
from tasks.create_accounts import CreateAccounts
from tasks.office_management import OfficeManagement
from tasks.send_welcome import SendWelcome
from tasks.send_credentials import SendCredentials
from tasks.send_required_reading import SendRequiredReading
from tasks.schedule_onboarding_meetings import ScheduleOnboardingMeetings
from tasks.cancel_onboarding import CancelOnboarding


class OnboardingWorkflow(Workflow, Zenatonable):
    def __init__(self, employee):
        self.employee = employee
        
    def handle(self):
    PreparePaperwork(employee).dispatch()
    
    paperworkEvent = Wait(paperworkEvent).execute()

    if paperworkEvent.success
    
      SchedulePreOnboardingMeeting(employee).dispatch()

      formEvent = Wait(formEvent).execute()
      accounts = CreateAccounts(employee,form.tools).dispatch()
      newOfficeManagement(employee,form)).dispatch()
      
      Wait().timestamp(form.onboardingDay).execute()

      SendWelcome(employee).dispatch()
      SendCredentials(employee,accounts).dispatch()
      SendRequiredReading(employee,form.reading).dispatch()
      ScheduleOnboardingMeetings(employee,form.meetings).dispatch()
      
      else
      CancelOnboarding(employee).dispatch()
    

Real-time executions of the workflow from Zenaton Dashboard

View the real time execution of this workflow from the Zenaton dashboard.

Monitoring Dashboard of onboarding workflow