AutoOnSiteRepairs

Top  Previous  Next

This application is about "on site repair request". The requirement on the application is to automate the "procedure" of "repair requset". This means that the successive "steps" of the procedure are automatically forwarded from one employee to another without any kind of "manager" intervention. At any time the manager has the ability to see on what tasks (steps) the employees are engaged. He can also see what tasks are "scheduled" for the next days. After a certain period of time the manager has a complete report on what tasks each employee has been assigned, when has started and when has finished the tasks.

 

The requirements, put on the application from the supposed "technical manager", are the following:

 

"Every employee can put a repair request, in case a machinery breaks down. The technical department gets the request and info about the contractor and the contract. The contractor is called on site to repair the faulty machinery. The contractors personnel arrives at the company's gate at the specified date and time. The gate personnel gives him the permission to enter. The technician goes to the reception and from there to our service personnel that they wait for that.The repair process maybe repeated more than once in order to fix the damage. Parts and labor are added to the process. When the job is finished and payment is due to the contractor, the info goes to the accountant (contractor, contract, parts, labor) for the payment. That's all."

 

All of the above requirements are put on a coordinator agent. The action_code of the agent's is the following:

 

start_action

 

   call bpm_setprocedureowner(__activation_user)                   {.....set the procedure owner}

 

   callwait bpm_assign_job ( "new repair" , __activation_user , "" , 0)     {....start the new repair}

 

   rep_id = bpm_getrecid(1,__au_step)                           {......subactivity, activity}

   equip_id = LookUp("REPAIR","REPAIR",rep_id,"EQUIPMENT","")

   comm     = LookUp("EQUIPMENT","EQUIPMENT",equip_id,"DESCRIPTION","")

   contr_id = LookUp("EQUIPMENT","EQUIPMENT",equip_id,"CONTRACT","")

   sup_id   = LookUp("CONTRACT","CONTRACT",contr_id,"CONTRACTOR","")

   d1 = LookUp("CONTRACT","CONTRACT",contr_id,"DATE1","")

   d2 = LookUp("CONTRACT","CONTRACT",contr_id,"DATE2","")

   dat1 = DateToNum(d1)

   dat2 = DateToNum(d2)

   today = DateToNum(crDate)

 

   call bpm_setprocedurecomment(comm)                             {.....set the procedures comment}

 

   {.............................................forward request to the service department}

 

   callwait bpm_assign_job ( "repair request" , "" , "SERVICE DEPARTMENT" , 0 , rep_id, equip_id, contr_id, sup_id)

   app_date = LookUp("REPAIR","REPAIR",rep_id,"APPOINT_DATE","")

   app_date_num = DateToNum(app_date)

 

  {.............................................technician expected}

   for i = 1 to 1000

 

      split_in_branch

 

          callwait bpm_assign_job ( "technician expected" , "" , "GATE SECURITY" , app_date_num , sup_id)

          callwait bpm_assign_job ( "technician expected" , "" , "RECEPTION" , 0 , sup_id)

 

      and_branch

 

          callwait bpm_assign_job ( "technician appointment" , "" , "SERVICE DEPARTMENT" , 0 , rep_id, equip_id, contr_id, sup_id)

 

      join_branches

 

      callwait bpm_assign_job ( "on site repair" , "" , "SERVICE DEPARTMENT" , 0 , rep_id, equip_id, contr_id, sup_id)

 

      finish = LookUp("REPAIR","REPAIR",rep_id,"FINISHED","")

      if (finish = 1) then

          i = 1000

      else

          app_date = LookUp("REPAIR","REPAIR",rep_id,"APPOINT_DATE","")

          app_date_num = DateToNum(app_date)

      endif

 

   next

 

   parts = LookUp("REPAIR","REPAIR",rep_id,"PARTS_INCLUDED","")

   labor = LookUp("REPAIR","REPAIR",rep_id,"LABOR_INCLUDED","")

 

   if (parts = 0) or (labor = 0) then

       callwait bpm_assign_job ( "payment" , "" , "ACCOUNTANT" , 0 , rep_id, equip_id, contr_id, sup_id)

   endif

 

end_action

 

We can see the callwait or split_in_branch keywords. Those keywords give the opportunity to the agent to wait (until a job has been finished) or to have parallel code execution. Those are capabilities that are not presented every day in a programming language (ok script!). Notice that the callwait "calls" the user's activity as it would be a "program's subroutine". Notice also that we have flow of procedure that is defined by conditions into the code (who mechanic to assign). This is a case of ad hoc control flow (not known in advance to the programmer!)

 

The flow of procedure automatically is created and presented bellow.

 

clip0029

 

We have to admit that the effect (coordination and historic data collection of the service procedure) is far too big for the  lines of code that are written by the application programmer. To be precise the code is a little bigger (the agent contains the code that "describes" the task (activities) assigned to employees). The complete agent (code and declarations) is given bellow:

 

{-----------------------------------------------------------------------

'

' procedure for the repair manager

'

'----------------------------------------------------------------------------------}

 

    {....................................AGENT INFO..............................................}

 

    start_agent_info

       AgentName        = "REPAIR_MANAGER"

       AgentDescr       = ""

       AgentLanguage    = ""

       __timer_interval = 0

       __is_registered  = 1

       __delete_on_termination = 0

    end_agent_info

 

{....................................PRODUCTION CODE..................................................}

 

    {..............................................................................new repair}

    start_bpm_activity   "new repair"

 

         start_bpm_subactivity  "new repair request"

              rec = bpm_getrecid()

              if (rec = 0) then

                 call OpenForm("ptAppend","REPAIR_E.FM","WORK.REPAIR",1,"?=REPAIR")

              else

                 expr = strcat(rec,"=REPAIR")

                 call OpenForm("ptEdit","REPAIR_E.FM","WORK.REPAIR",1,expr)

              endif

         end_bpm_subactivity

         start_bpm_validation

              result = 1

              rec = bpm_getrecid(1)

              if (rec = 0) then

                 call message("You havent created a new repair request!")

                 result = 0

              endif

              if (rec > 0) then

                 equip = LookUp("REPAIR","REPAIR",rec,"EQUIPMENT","")

                 if (equip = 0) then

                    call message("Equipment must be defined!")

                    result = 0

                 endif

              endif

         end_bpm_validation

 

    end_bpm_activity

 

    {..............................................................................repair request}

    start_bpm_activity   "repair request"

 

         start_bpm_subactivity  "repair request"

              rec = __params[1]

              expr = strcat(rec,"=REPAIR")

              call OpenForm("ptEdit","REPAIR_E.FM","WORK.REPAIR",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "equipment"

              rec = __params[2]

              expr = strcat(rec,"=EQUIPMENT")

              call OpenForm("ptEdit","EQUIPMENT_E.FM","WORK.EQUIPMENT",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "contract"

              rec = __params[3]

              if (rec = 0) then

                  call message("There is no contract!")

              else

                  expr = strcat(rec,"=CONTRACT")

                  call OpenForm("ptEdit","CONTRACT_E.FM","WORK.CONTRACT",1,expr)

              endif

         end_bpm_subactivity

         start_bpm_subactivity  "contractor"

              rec = __params[4]

              if (rec = 0) then

                  call message("There is no contractor!")

              else

                  expr = strcat(rec,"=CONTRACTOR")

                  call OpenForm("ptEdit","CONTACTOR_E.FM","WORK.CONTRACTOR",1,expr)

              endif

         end_bpm_subactivity

         start_bpm_validation

              result = 1

              rec = bpm_getrecid(1)

              app_date = LookUp("REPAIR","REPAIR",rec,"APPOINT_DATE","")

              if (app_date = "") then

                  call message("Yoy must defined an appointment date.")

                  result = 0

              endif

         end_bpm_validation

 

    end_bpm_activity

 

    {..............................................................................technician expected}

    start_bpm_activity   "technician expected"

 

         start_bpm_subactivity  "contractor"

              rec = __params[1]

              expr = strcat(rec,"=CONTRACTOR")

              call OpenForm("ptEdit","CONTACTOR_E.FM","WORK.CONTRACTOR",1,expr)

         end_bpm_subactivity

 

    end_bpm_activity

 

    {..............................................................................on site repair}

    start_bpm_activity   "on site repair"

 

         start_bpm_subactivity  "repair request"

              rec = __params[1]

              expr = strcat(rec,"=REPAIR")

              call OpenForm("ptEdit","REPAIR_E.FM","WORK.REPAIR",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "equipment"

              rec = __params[2]

              expr = strcat(rec,"=EQUIPMENT")

              call OpenForm("ptEdit","EQUIPMENT_E.FM","WORK.EQUIPMENT",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "contract"

              rec = __params[3]

              if (rec = 0) then

                  call message("There is no contract!")

              else

                  expr = strcat(rec,"=CONTRACT")

                  call OpenForm("ptEdit","CONTRACT_E.FM","WORK.CONTRACT",1,expr)

              endif

         end_bpm_subactivity

         start_bpm_subactivity  "contractor"

              rec = __params[4]

              if (rec = 0) then

                  call message("There is no contractor!")

              else

                  expr = strcat(rec,"=CONTRACTOR")

                  call OpenForm("ptEdit","CONTACTOR_E.FM","WORK.CONTRACTOR",1,expr)

              endif

         end_bpm_subactivity

 

    end_bpm_activity

 

    {..............................................................................technician appointment}

    start_bpm_activity   "technician appointment"

 

         start_bpm_subactivity  "repair request"

              rec = __params[1]

              expr = strcat(rec,"=REPAIR")

              call OpenForm("ptEdit","REPAIR_E.FM","WORK.REPAIR",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "equipment"

              rec = __params[2]

              expr = strcat(rec,"=EQUIPMENT")

              call OpenForm("ptEdit","EQUIPMENT_E.FM","WORK.EQUIPMENT",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "contract"

              rec = __params[3]

              if (rec = 0) then

                  call message("There is no contract!")

              else

                  expr = strcat(rec,"=CONTRACT")

                  call OpenForm("ptEdit","CONTRACT_E.FM","WORK.CONTRACT",1,expr)

              endif

         end_bpm_subactivity

         start_bpm_subactivity  "contractor"

              rec = __params[4]

              if (rec = 0) then

                  call message("There is no contractor!")

              else

                  expr = strcat(rec,"=CONTRACTOR")

                  call OpenForm("ptEdit","CONTACTOR_E.FM","WORK.CONTRACTOR",1,expr)

              endif

         end_bpm_subactivity

 

    end_bpm_activity

 

    {..............................................................................payment}

    start_bpm_activity   "payment"

 

         start_bpm_subactivity  "repair request"

              rec = __params[1]

              expr = strcat(rec,"=REPAIR")

              call OpenForm("ptEdit","REPAIR_E.FM","WORK.REPAIR",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "equipment"

              rec = __params[2]

              expr = strcat(rec,"=EQUIPMENT")

              call OpenForm("ptEdit","EQUIPMENT_E.FM","WORK.EQUIPMENT",1,expr)

         end_bpm_subactivity

         start_bpm_subactivity  "contract"

              rec = __params[3]

              if (rec = 0) then

                  call message("There is no contract!")

              else

                  expr = strcat(rec,"=CONTRACT")

                  call OpenForm("ptEdit","CONTRACT_E.FM","WORK.CONTRACT",1,expr)

              endif

         end_bpm_subactivity

         start_bpm_subactivity  "contractor"

              rec = __params[4]

              if (rec = 0) then

                  call message("There is no contractor!")

              else

                  expr = strcat(rec,"=CONTRACTOR")

                  call OpenForm("ptEdit","CONTACTOR_E.FM","WORK.CONTRACTOR",1,expr)

              endif

         end_bpm_subactivity

 

    end_bpm_activity

 

{.....................................CONTROL CODE......................................................}

                       

{.................................ACTION CODE................................................

 

 Every user can activate a new repair request

 The request goes to "service department"

 The technical personnel calls the contractor

 The contractor arriver at a specified date

 The contractor works on site

 In case he/she does not finish, repeats the visits again (until the faulty machinery works)

 During the repair parts and labor are added

 After finish, in case a payment is required, the finished repair goes to the accountant

 

}

 

start_action

 

   call bpm_setprocedureowner(__activation_user)                     {.....set the procedure owner}

 

   callwait bpm_assign_job ( "new repair" , __activation_user , "" , 0)     {....start the new repair}

 

   rep_id = bpm_getrecid(1,__au_step)                           {......subactivity, activity}

   equip_id = LookUp("REPAIR","REPAIR",rep_id,"EQUIPMENT","")

   comm     = LookUp("EQUIPMENT","EQUIPMENT",equip_id,"DESCRIPTION","")

   contr_id = LookUp("EQUIPMENT","EQUIPMENT",equip_id,"CONTRACT","")

   sup_id   = LookUp("CONTRACT","CONTRACT",contr_id,"CONTRACTOR","")

   d1 = LookUp("CONTRACT","CONTRACT",contr_id,"DATE1","")

   d2 = LookUp("CONTRACT","CONTRACT",contr_id,"DATE2","")

   dat1 = DateToNum(d1)

   dat2 = DateToNum(d2)

   today = DateToNum(crDate)

 

   call bpm_setprocedurecomment(comm)                             {.....set the procedures comment}

 

   {.............................................forward request to the service department}

 

   callwait bpm_assign_job ( "repair request" , "" , "SERVICE DEPARTMENT" , 0 , rep_id, equip_id, contr_id, sup_id)

   app_date = LookUp("REPAIR","REPAIR",rep_id,"APPOINT_DATE","")

   app_date_num = DateToNum(app_date)

 

   {.............................................technician expected}

   for i = 1 to 1000

 

      split_in_branch

 

          callwait bpm_assign_job ( "technician expected" , "" , "GATE SECURITY" , app_date_num , sup_id)

          callwait bpm_assign_job ( "technician expected" , "" , "RECEPTION" , 0 , sup_id)

 

      and_branch

 

          callwait bpm_assign_job ( "technician appointment" , "" , "SERVICE DEPARTMENT" , 0 , rep_id, equip_id, contr_id, sup_id)

 

      join_branches

 

      callwait bpm_assign_job ( "on site repair" , "" , "SERVICE DEPARTMENT" , 0 , rep_id, equip_id, contr_id, sup_id)

 

      finish = LookUp("REPAIR","REPAIR",rep_id,"FINISHED","")

      if (finish = 1) then

          i = 1000

      else

          app_date = LookUp("REPAIR","REPAIR",rep_id,"APPOINT_DATE","")

          app_date_num = DateToNum(app_date)

      endif

 

   next

 

   parts = LookUp("REPAIR","REPAIR",rep_id,"PARTS_INCLUDED","")

   labor = LookUp("REPAIR","REPAIR",rep_id,"LABOR_INCLUDED","")

 

   if (parts = 0) or (labor = 0) then

       callwait bpm_assign_job ( "payment" , "" , "ACCOUNTANT" , 0 , rep_id, equip_id, contr_id, sup_id)

   endif

 

{------------------------------------  end of procedure ---------------------------------------------}

 

end_action

 

The agent (agent prototype precisely) can be viewd form Right Mouse Click on Application's Background->Popup Menu->Developer->Resources->Agent Prototypes. The system creates, for every "service" requested, a new "alive" agent that starts to execute his action_code.

 

Where we define users and roles?

 

Another issue is that the jobs are assigned to users (employees) not only by name but also (and mainly) by their roles into the company. The users and roles as they are defined into the application can be found at Menu->System->Users/Positions.

 

How we activate the agent?

 

A "new service appointment" can be activated on the application from Menu->Files->NEW SERVICE. In order the users see the activities (jobs) that are assigned to them exit the demo application and logon as the user in question. The same can be run in debug mode from Menu->Tables->New Repair (DEBUG). The programmer has to press (F8) in order the agent continues the execution. In debug mode also the activities are not forwarded to the employees (users) but are presented to the programmer in order to complete the forms with data and forward them to the next step.

 

How can the user see the incoming jobs?

 

Every user has the "incoming activities" window. This window refreshes itself every 30 seconds (it can be changed) and contains all the activities that the agent has assigned to the user either directly (by user name) or (frequently) indirectly (by role that the user has). Notice that the same activity is send to all users that happen to have the same role into the company or organization. When the user "completes" the data that the activity required, he/she "forwards" the completed activity to the next step. Then the activity disappears from the window.

 

In order a user to see activities that assigned to him for today or are uncompleted from yesterday he/she has to activate Menu->Personal Secr->Activities for today.  For activities that are assigned to user for future time (for example pending appointments) the user has to activate Menu->Personal Secr->Activities that Pending.

 

How the manager can see the current jobs?

 

By activating Menu->Personal Secr->Activities In Progress we see every activity (job) that is assigned at the time and is in phase of completion, i.e. presented to users "incoming activities" and are worked by them.

 

How we get the procedure's progress?

 

Every window that presents "user activities" has a button captioned as "History". By activating it we see the steps that have completed (with date and time data) by user and role. The steps that are "finished" are flagged by (1) while those that are unfinished by (0). Near the button "History" there is the button "Flowchart". By activating it we have automatically a picture as below. By "red" are colored the finished activities, by "green" the activities that are assigned and worked now and by "blue" the activities that are going to follow as next steps.

 

clip0031

 

How we can evaluate our employees?

 

When we activate Menu->System->Users we can see a button captioned "Have Done". By activating it we get all the activities that the user (employee) has finished and by witch role. The time of staring and completing for each activity is also available. This way the real effort that the user has given to the company can be estimated.

 

How we can improve the demo application?

 

The demo application comes with "Developer" capabilities. That means we have the opportunity to change the database schema (Right Click->Developer->Resources->Database Manager->Edit Schema). We can also change the forms (Right Click over a form->Designing).

 

How we run the demo application in multi user configuration?

 

We described above that to "emulate" multi user behavior we have to exit and login the application with a different user name. In order to run the application in real multi user configuration (over TCP/IP breaking thus the barriers of the local area network) we have to replace the "kosmos.exe" with a real multi user server (starting from 3 users). For this reason see the "Products" page in our site. We have also to install clients (any number). For this reason see the "Downloads" page in our site.

 

Download Application