Перейти к основному содержанию
`Ctrl`+`K`

# Практические примеры

В этом разделе рассмотрены два практических сценария: автоматическое создание пунктов маршрута для складов и обработка перехода состояний документов с валидацией бизнес-правил.

## Создание пункта маршрута для каждого склада

1. SQL-запрос для получения списка складов. Получим ID и коды складов, у которых тип объекта «Склад» (stock) или «Склад в пути» (StockInWay). Полученные записи преобразуем в список с помощью метода `asList()`.

    var sqlStock = sql(`
        SELECT stk.id as id, stk.sCode as sCode FROM stk_stock stk
        JOIN btk_objecttype ot ON ot.id = stk.idObjectType
        where ot.sCode = 'stock' OR ot.sCode = 'StockInWay'
    `).asList()

2. Поиск пункта маршрута по коду склада. С помощью цикла `for` сделаем преобразование над полученными записями. По коду нашего склада получим id пункта маршрута.

    var sqlStock = sql(`
        SELECT stk.id as id, stk.sCode as sCode FROM stk_stock stk
        JOIN btk_objecttype ot ON ot.id = stk.idObjectType
        where ot.sCode = 'stock' OR ot.sCode = 'StockInWay'
    `).asList()

    for(r: sqlStock) {
        var idvPoint = Tms_PointApi.findByMnemoCode(r.scode);
    }

3. Создание нового пункта маршрута (если не найден). Если вернувшееся значение пункта маршрута равно null, то нужно создать его, заполнив код, название и привязку текущего склада.

    var sqlStock = sql(`
        SELECT stk.id as id, stk.sCode as sCode FROM stk_stock stk
        JOIN btk_objecttype ot ON ot.id = stk.idObjectType
        where ot.sCode = 'stock' OR ot.sCode = 'StockInWay'
    `).asList()

    for(r: sqlStock) {
        var idvPoint = Tms_PointApi.findByMnemoCode(r.scode);
        if (isNull(idvPoint)) {
            var ropPoint = Tms_PointApi.insert();
            Tms_PointApi.setsCode(ropPoint, r.scode);
            Tms_PointApi.setsCaption(ropPoint, r.scode);
            Tms_PointApi.setidStock(ropPoint, r.id);
        }
    }

4. Обновление существующего пункта маршрута (если не привязан к складу). Если полученный пункт маршрута существует, то загружаем его по полученному ранее id. Далее проверяем у полученного пункта маршрута привязку к складу, если значение равно null, то устанавливаем значение текущего склада.

    var sqlStock = sql(`
        SELECT stk.id as id, stk.sCode as sCode FROM stk_stock stk
        JOIN btk_objecttype ot ON ot.id = stk.idObjectType
        where ot.sCode = 'stock' OR ot.sCode = 'StockInWay'
    `).asList()

    for(r: sqlStock) {
        var idvPoint = Tms_PointApi.findByMnemoCode(r.scode);
        if (isNull(idvPoint)) {
            var ropPoint = Tms_PointApi.insert();
            Tms_PointApi.setsCode(ropPoint, r.scode);
            Tms_PointApi.setsCaption(ropPoint, r.scode);
            Tms_PointApi.setidStock(ropPoint, r.id);
        } else {
            var ropPointW = Tms_PointApi.load(idvPoint);
            if (isNull(ropPointW.idStock)) {
                Tms_PointApi.setidStock(ropPointW, r.id);
            }
        }
    }

## Пример расширения обработки состояния документа

1. Проверка на пустое старое значение:

    if(isNull(oldValue)) return 0;

Если текущее состояние документа `oldValue` не задано, обработка прекращается (возвращается 0).

2. Получение порядковых номеров состояний:

    var idStateFromOrder = Btk_ClassStateApi.getOrder(oldValue);
    var idStateToOrder = Btk_ClassStateApi.getOrder(value);

- idStateFromOrder - порядковый номер старого состояния документа.

- idStateToOrder - порядковый номер нового состояния.

Получим текущее состояние документа, воспользовавшись API-методом класса состояния.

3. Проверка условий для обработки:

    if(idStateFromOrder <= 100 && idStateToOrder > 100 && rop.idObjectType == Btk_ObjectTypeApi.findByMnemoCode("Tms_DeliveryAct"))

- `idStateFromOrder <= 100` - проверяет, что текущее состояние документа имеет порядковый номер <= 100. Обычно это соответствует статусам «Аннулировано» или «Формируется».

- `idStateToOrder > idStateFromOrder` - гарантирует, что новое состояние действительно является переходом ВВЕРХ по workflow. Исключает случаи, когда статус меняется на равный или более ранний.

- `rop.idObjectType == Btk_ObjectTypeApi.findByMnemoCode("Tms_DeliveryAct")` - убеждается, что работаем именно с документом типа «Рейс» (Tms_DeliveryAct).

4. Получение заказа (Stm_OrderOut):

    var ropOO = Stm_OrderOutApi.loadByGid(rop.gidSrc);
    if(ropOO.idObjectType != Btk_ObjectTypeApi.findByMnemoCode("OrderOut_Service"))

Получаем ропу заказа с помощью Api-метода loadByGid по gidSrc(родитель) текущего документа. Если тип заказа НЕ «OrderOut_Service» (то есть это не сервисный заказ), выполняется дальнейшая проверка.

5. Определение договора:

    var ropContract = null;
    if(isNotNull(rop.idAddContract))
        ropContract = Cnt_ContractApi.load(rop.idAddContract);
    else
        ropContract = Cnt_ContractApi.load(rop.idContract);

Если у заказа `rop` есть доп. договор `idAddContract`, он загружается. Иначе загружается основной договор (idContract).

6. Проверка отложенного ценообразования:

    var bDeferredPricing = Cnt_ContractApi.getObjAttrValue(ropContract, "bDeferredPricing");
    if(bDeferredPricing == true)

Получаем значение атрибута bDeferredPricing (флаг «Отложенное ценообразование»). Если флаг true, выполняется проверка даты.

7. Проверка даты отложенного ценообразования:

    var dDeferredPricing = Stm_ActOutApi.getObjAttrValue(rop, "dDeferredPricing");
    if(isNull(dDeferredPricing) || dDeferredPricing < sysDate())
        raise("Требуется выполнить корректировку цены");

Получаем дату dDeferredPricing (когда должна быть выполнена корректировка цены). Если дата не задана или уже прошла, выводится ошибка.

Общий код:

    if(isNull(oldValue))return 0;
    var idStateFromOrder = Btk_ClassStateApi.getOrder(oldValue)
    var idStateToOrder = Btk_ClassStateApi.getOrder(value);

    if(idStateFromOrder <= 100 && idStateToOrder > 100 && rop.idObjectType == Btk_ObjectTypeApi.findByMnemoCode("Tms_DeliveryAct")){
        var ropOO = Stm_OrderOutApi.loadByGid(rop.gidSrc)
        if(ropOO.idObjectType != Btk_ObjectTypeApi.findByMnemoCode("OrderOut_Service")){
            var ropContract = null
            if(isNotNull(rop.idAddContract))
                ropContract = Cnt_ContractApi.load(rop.idAddContract)
            else
                ropContract = Cnt_ContractApi.load(rop.idContract)
            var bDeferredPricing = Cnt_ContractApi.getObjAttrValue(ropContract, "bDeferredPricing")
            if(bDeferredPricing == true){
                var dDeferredPricing = Stm_ActOutApi.getObjAttrValue(rop, "dDeferredPricing")
                if(isNull(dDeferredPricing) || dDeferredPricing < sysDate()){
                    raise("Требуется выполнить корректировку цены")
                }
            }
        }
    }