Skip to main content

Бизнес-процессы

  1. Предназначены для управления заказами.
  2. Привязаны к услугам. Один процесс может быть привязан к нескольким услугам.
  3. При создании заказа создается копия бизнес-процесса выбранной услуги, после чего заказ управляется этой копией. Необходимо для обратной совместимости изменяемых процессов и уже запущенных по заказам.
  4. В созданном заказе процесс всегда находится в определенном состоянии.
  5. Доступны 4 роли пользователей для управления процессами (роли назначаются администратором провайдера в личном кабинете):
    • customer - заказчик,
    • executor - исполнитель,
    • courier - курьер,
    • moderator - модератор
  6. Могут запускать в тестовом режиме - проходят тестовые транзакции оплаты без фактического списания средств. См. https://developers.cloudpayments.ru/#testirovanie.
  7. Синтаксис представлен в json-формате.

Пример настроенного бизнес-процесса

image-1727457358440.15.49@2x.png

JSON-файл в котором производится настройка

{
  "state0": {
    "label": "Создание заказа",
    "onStart": {
      "bp": {
        "step0": {
          "next": "step1",
          "type": "setData",
          "fields": {
            "field*": []
          }
        },
        "step1": {
          "next": "step2",
          "text": "Заказ #{{ order.code }}<br/><br/><strong>Услуга</strong>: {{ order.service.title }}<br/><strong>Доставка</strong>: {{ order.delivery }}<br/><strong>Оплачен</strong>: {{ order.payed }}<br/><strong>Сумма к оплате</strong>: {{ order.sum }}<br/><strong>Выплаченная сумма</strong>: {{ order.sum_payed }}<br/><strong>Общая сумма</strong>: {{ order.sum_total }}<br/><strong>Организация заказчика</strong>: {{ order.customer.title }}<br/><strong>Заказчик</strong>: {{ order.customerUser.title }} {{ order.customerUser.phone_number }}<br/><strong>Провайдер</strong>: {{ order.executor.title }}<br/><strong>Исполнитель</strong>: {{ order.executorUser.title }}<br/><strong>Статус</strong>: {{ order.status.title }}<br/><strong>Дата запланированного завершения</strong>: {{ order.deadline }}<br/><br/>{% for item in order.fieldsData %}<strong>{{ item.field.title }}</strong>: {{ item.valueFormatted }}<br/>{% endfor %}<br/>Детали заказа доступны в <a href=\"https://lk.crabler.com/site/{{ order.executor.communityProvider.id }}/jump\">личном кабинете</a>.",
          "type": "email",
          "subject": "Новый заказ",
          "recipients": [
            "zakaz@crabler.com",
            "moderator"
          ]
        },
        "step2": {
          "type": "setState",
          "state": "state1"
        }
      }
    }
  },
  "state1": {
    "label": "Оплата заказа",
    "actions": [
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "pay"
          },
          "step1": {
            "type": "if",
            "conditions": [
              [
                {
                  "service.need_moderation": true
                },
                "step2"
              ],
              [
                true,
                "step3"
              ]
            ]
          },
          "step2": {
            "type": "setState",
            "state": "state2"
          },
          "step3": {
            "type": "setState",
            "state": "state3"
          }
        },
        "code": "pay",
        "allow": [
          "customer"
        ],
        "label": "Оплатить"
      },
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateCancel"
          }
        },
        "code": "cancel",
        "allow": [
          "customer"
        ],
        "label": "Отменить"
      }
    ]
  },
  "state2": {
    "label": "На модерации",
    "actions": [
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "state3"
          }
        },
        "code": "action1",
        "allow": [
          "moderator"
        ],
        "label": "Модерация пройдена"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "executor_user_id": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "Вас назначили исполнителем. Свяжитесь с клиентом и подтвердите выезд.",
            "next": "step2",
            "type": "push",
            "title": "Заказ #{{ order.code }}",
            "recipients": [
              "executor"
            ]
          },
          "step2": {
            "type": "setState",
            "state": "state4"
          }
        },
        "code": "action2",
        "allow": [
          "moderator"
        ],
        "label": "Назначить исполнителя"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.customerUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "moderator"
            ]
          }
        },
        "code": "action1_chat",
        "allow": [
          "customer"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.moderatorUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          }
        },
        "code": "action2_chat",
        "allow": [
          "moderator"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateCancel"
          }
        },
        "code": "cancel",
        "allow": [
          "customer"
        ],
        "label": "Отменить"
      },
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateReject"
          }
        },
        "code": "cancel",
        "allow": [
          "moderator"
        ],
        "label": "Отклонить"
      }
    ]
  },
  "state3": {
    "label": "Поиск исполнителя",
    "actions": [
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "executor_user_id": {
                "value": "_CURRENT_USER_"
              },
              "hidden_customer_contact": {
                "value": false
              }
            }
          },
          "step1": {
            "type": "setState",
            "state": "state4"
          }
        },
        "code": "action1",
        "allow": [
          "executor"
        ],
        "label": "Взять в работу"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.customerUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "moderator"
            ]
          }
        },
        "code": "action1_chat",
        "allow": [
          "customer"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.moderatorUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          }
        },
        "code": "action2_chat",
        "allow": [
          "moderator"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateCancel"
          }
        },
        "code": "cancel",
        "allow": [
          "customer"
        ],
        "label": "Отменить"
      },
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateReject"
          }
        },
        "code": "cancel",
        "allow": [
          "moderator"
        ],
        "label": "Отклонить"
      }
    ],
    "onStart": {
      "bp": {
        "step0": {
          "body": "{{ order.service.title}}, {{ order.fieldDeliveryAddress }} {{ order.fieldDateTimeDelivery }} - {{ order.service.organization.currency.sum }} {{ order.service.organization.currency.short_title }}",
          "type": "push",
          "title": "Новый заказ #{{ order.code }}",
          "recipients": [
            "executor"
          ]
        }
      }
    }
  },
  "state4": {
    "label": "Исполнитель назначен",
    "actions": [
      {
        "bp": {
          "step0": {
            "body": "Исполнитель {{ order.executor.title }} подтвердил выезд",
            "next": "step1",
            "type": "push",
            "title": "Заказ #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          },
          "step1": {
            "type": "setState",
            "state": "state5"
          }
        },
        "code": "action1",
        "allow": [
          "executor"
        ],
        "label": "Подтвердить выезд"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "executor_user_id": {
                "value": "_NULL_"
              }
            }
          },
          "step1": {
            "body": "На заказ будет назначен другой исполнитель, ожидайте",
            "next": "step2",
            "type": "push",
            "title": "Заказ #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          },
          "step2": {
            "type": "setState",
            "state": "state3"
          }
        },
        "code": "action2",
        "allow": [
          "executor"
        ],
        "label": "Отменить выезд"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "executor_user_id": {
                "value": "_NULL_"
              }
            }
          },
          "step1": {
            "body": "На заказ будет назначен другой исполнитель, ожидайте",
            "next": "step2",
            "type": "push",
            "title": "Заказ #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          },
          "step2": {
            "type": "setState",
            "state": "state3"
          }
        },
        "code": "action2",
        "allow": [
          "moderator"
        ],
        "label": "Вернуть в поиск"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.customerUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "executor",
              "moderator"
            ]
          }
        },
        "code": "action1_chat",
        "allow": [
          "customer"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.executorUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          }
        },
        "code": "action2_chat",
        "allow": [
          "executor"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.moderatorUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          }
        },
        "code": "action3_chat",
        "allow": [
          "moderator"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateReject"
          }
        },
        "code": "cancel",
        "allow": [
          "moderator"
        ],
        "label": "Отклонить"
      }
    ],
    "onStart": {
      "bp": {
        "step0": {
          "body": "Исполнитель найден, ожидайте звонка",
          "type": "push",
          "title": "Заказ #{{ order.code }}",
          "recipients": [
            "customer"
          ]
        }
      }
    }
  },
  "state5": {
    "label": "В работе",
    "actions": [
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateDone"
          }
        },
        "code": "action2",
        "allow": [
          "executor"
        ],
        "label": "Завершить заказ"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "executor_user_id": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "Вас назначили исполнителем. Свяжитесь с клиентом и подтвердите выезд.",
            "next": "step2",
            "type": "push",
            "title": "Заказ #{{ order.code }}",
            "recipients": [
              "executor"
            ]
          },
          "step2": {
            "type": "setState",
            "state": "state4"
          }
        },
        "code": "action2",
        "allow": [
          "moderator"
        ],
        "label": "Заменить исполнителя"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.customerUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "executor",
              "moderator"
            ]
          }
        },
        "code": "action1_chat",
        "allow": [
          "customer"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "next": "step1",
            "type": "setData",
            "fields": {
              "field1416182395": {
                "required": true
              }
            }
          },
          "step1": {
            "body": "{{ clientData['field1416182395'] }}",
            "type": "push",
            "title": "Сообщение от {{ order.executorUser.title }} к заказу #{{ order.code }}",
            "recipients": [
              "customer"
            ]
          }
        },
        "code": "action2_chat",
        "allow": [
          "executor"
        ],
        "label": "Написать сообщение"
      },
      {
        "bp": {
          "step0": {
            "type": "setState",
            "state": "stateReject"
          }
        },
        "code": "cancel",
        "allow": [
          "moderator"
        ],
        "label": "Отклонить"
      }
    ],
    "onStart": {
      "bp": {
        "step0": {
          "type": "setData",
          "fields": {
            "status_id": {
              "value": "ACCEPTED"
            }
          }
        }
      }
    }
  },
  "stateDone": {
    "label": "Выполнен",
    "actions": [
      {
        "bp": [],
        "code": "rate",
        "allow": [
          "customer",
          "executor"
        ],
        "label": "Оценить выезд"
      }
    ],
    "onStart": {
      "bp": {
        "step0": {
          "next": "step1",
          "type": "setData",
          "fields": {
            "status_id": {
              "value": "DONE"
            }
          }
        },
        "step1": {
          "body": "Заказ #{{ order.code }} выполнен, пожалуйста, оцените",
          "type": "push",
          "title": "{{ order.executor.title }}",
          "recipients": [
            "customer"
          ]
        }
      }
    }
  },
  "stateCancel": {
    "label": "Отменен",
    "onStart": {
      "bp": {
        "step0": {
          "next": "step1",
          "type": "setData",
          "fields": {
            "status_id": {
              "value": "REJECTED"
            }
          }
        },
        "step1": {
          "body": "Заказ #{{ order.code }} отменен",
          "type": "push",
          "title": "{{ order.executor.title }}",
          "recipients": [
            "executor"
          ]
        }
      }
    }
  },
  "stateReject": {
    "label": "Отклонен",
    "onStart": {
      "bp": {
        "step0": {
          "next": "step1",
          "type": "setData",
          "fields": {
            "status_id": {
              "value": "REJECTED"
            }
          }
        },
        "step1": {
          "body": "Заказ #{{ order.code }} отклонен",
          "type": "push",
          "title": "{{ order.executor.title }}",
          "recipients": [
            "customer"
          ]
        }
      }
    }
  }
}

Структура

{
    "state0": { // Состояние (индексация всегда должна начинаться с 0).
        "label": "Заголовок состояния",
        "onState": { // Действия, выполняемые при переходе в состояние (каждый раз)
            "bp": {
                "step0": { // Индексация шагов всегда должна начинаться с 0 
                    "type": "Тип действия",
                    "next": "step1", // Переход к следующему шагу (необязательный параметр)
                    // Дополнительные параметры шага
                },
                "step1": {},
                ...
            }
        },
        "actions": [ // Действия пользователей
            {
                "label": "Заголовок кнопки",
                "code": "action1", // Код действия в формате `[\w]+`
                "allow": [ // Доступ к действию для роли / ролей
                    "customer",
                    "executor",
                    "courier",
                    "moderator"
                ],
                "bp": [], // Действия, выполняемые после нажатия кнопки пользователем.
                "visible": { // Условия отображения кнопки (необязательный параметр).
                    "conditions": []
                }
            },
            ...
        ]
    },
    ...
}

Типы действий

Действие Описание
if Проверка условия.
setData Установка значений заказа (включая значения доп. полей).
setState Переход к состоянию.
pay Оплата заказчиком:
  • При одностадийной оплате средства списываются сразу.
  • При двустадийсной оплате происходит заморозка средств, после чего их можно списать с помощью метода confirmPay либо вернуть средства с помощью voidPay.
confirmPay Подтверждение оплаты заказчика.
confirmPayWithoutPayment Подтверждение оплаты заказчика без фактической оплаты.
confirmPayExecutorWithoutPayment Подтверждение оплаты исполнителя без фактической оплаты.
voidPay Отмена оплаты.
registerExecutor Регистрация исполнителя.
createEntity Создание сущности.
push Отправка push-уведомления.
sms Отправка sms-сообщения.
email Отправка email-сообщения.

Проверка условия (if)

{
    "type": "if",
    "conditions": [ // Список условий, выполняемых по порядку, до первого истинного 
        [
            [], // Условие в json-формате с поддержкой twig-переменных. См. https://www.yiiframework.com/doc/guide/2.0/ru/db-query-builder#where
            "step1" // Переход к шагу, если условие истинно 
        ],
        // Другие условия
        [
            true, // Выполняется всегда, когда неистинны все предыдущие условия
            "step2"
        ]
    ]
}

Установка значений заказа (включая значения доп. полей) (setData)

{
    "type": "setData",
    "fields": {
        "field*": [], // Вывести все поля заказа и его доп. поля для заполнения со своими настройками обязательности и контекста (необязательный параметр)
        // Управление конкретными доп. полями
        "field<Code>": { // Управление конкретным полем (необязательный параметр)
            "required": false, // Переписывает значение обязательности доп. поля (необязательный параметр)
            "value": "Значение" // Установка конкретного значения (необязательный параметр)
        },
        // Управление полями заказа
        "<code>": [] // См. структуру заказа в https://admin.crabler.com/constructor/object/view?id=order
    }
}

Переход к состоянию (setState)

{
    "type": "setState",
    "state": "stateN" // Указывается состояние, к которому осуществляется переход.
}

Оплата заказчиком (pay)

{
    "type": "pay"
}

Подтверждение оплаты заказчика (confirmPay)

{
    "type": "confirmPay"
}

Подтверждение оплаты заказчика без фактической оплаты (confirmPayWithoutPayment)

{
    "type": "confirmPayWithoutPayment"
}

Подтверждение оплаты исполнителя без фактической оплаты (confirmPayExecutorWithoutPayment)

{
    "type": "confirmPayExecutorWithoutPayment"
}

Отмена оплаты (voidPay)

{
    "type": "voidPay"
}

Регистрация исполнителя (registerExecutor)

{
    "type": "registerExecutor"
}

Создание сущности (createEntity)

{
    "type": "createEntity"
}

Отправка push-уведомления (push)

{
    "type": "push",
    "title": "Заголовок", // Поддерживает twig-переменные
    "body": "Текст", // Поддерживает twig-переменные
    "recipients": [ // Получатели (один либо несколько ролей / пользователей)
        "executor", // Название роли. Если у заказа задан исполнитель, то push-уведомление получает конкретно он иначе push-уведомление получают все исполнители провайдера, имеющих доступ к услуге. Аналогично для других ролей.
        "<uuid>", // В качестве получателя может быть передан UUID конкретного пользователя.
        "+70001234567" // В качестве получателя может быть передан номер телефона в свободном формате. Будет осуществлен поиск пользователя в базе по номеру телефона.
    ]
}

Отправка sms-сообщения (sms)

{
    "type": "sms",
    "message": "Текст сообщения", // Поддерживает twig-переменные
    "recipients": [ // Получатели (один либо несколько ролей / пользователей)
        "executor", // Название роли. Если у заказа задан исполнитель, то push-уведомление получает конкретно он иначе push-уведомление получают все исполнители провайдера, имеющих доступ к услуге. Аналогично для других ролей.
        "<uuid>", // В качестве получателя может быть передан UUID конкретного пользователя.
        "+70001234567" // В качестве получателя может быть передан номер телефона в свободном формате. Будет осуществлен поиск пользователя в базе по номеру телефона.
    ]
}

Отправка email-сообщения (email)

{
    "type": "email",
    "subject": "Тема письма", // Поддерживает twig-переменные
    "text": "Текст письма", // Поддерживает twig-переменные
    "recipients": [ // Получатели (один либо несколько ролей / пользователей)
        "executor", // Название роли. Если у заказа задан исполнитель, то push-уведомление получает конкретно он иначе push-уведомление получают все исполнители провайдера, имеющих доступ к услуге. Аналогично для других ролей.
        "<uuid>", // В качестве получателя может быть передан UUID конкретного пользователя.
        "example@crabler.com" // В качестве получателя может быть передан конкретный email.
    ]
}

Константы для значений полей

Константа Значение
_NULL_ null
_CURRENT_USER_ ID текущего пользователя

TWIG-переменные

Переменная Значение
order Текущий заказ. Можно обращаться к вложенным сущностям.
clientData Данные, полученные с клиента через POST.