Показать сообщение отдельно
Старый 28.01.2008, 13:50   #4  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,971 / 3267 (116) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от kashperuk Посмотреть сообщение
А приведите пожалуйста перечень проводок и их Тип (TransType), которые на момент вызова запроса у вас добавлены в RecordViewCache.

Надо ж воспроизвести, чтоб починили

Как воспроизвести глюк.

1. Создаем заказ
Строки заказа
Лот1 Количество 4 (2 физрезерв; 2 скомплектовано)
Лот2 Количество 5 (5 физрезерв)

2. Обрабатываем накладную по заказу (SalesformLetterInvoice) по скомплектованному.
Перед обработкой в SalesParmLine должна быть одна запись которая соответсвует Лот1.
Взводим галку SalesParmLine.closed (для воспроизведения бага галку взводить необязательно - но с ней будет проще - меньше проводок перебирать. Так как с взведенной SalesParmLine.closed после обработки по строке Лот1 не будет проводок в физрезерве - меньеш строк в отладчике перебирать)

3. Смотрим отладчик.
В методе SalesformLetterInvoice.Updatenow()
После цикла
X++:
    while (salesParmLine)
    {
    ...
    }
Стоит наш код (кастомизация)
1. Цикл по всем строкам заказа по которым осталось необработанное количество.
Для каждой строки такой запрос

X++:
    select sum(qty) from inventTrans
        index hint TransIdIdx
        where inventTrans.inventTransId         == _inventTransId   &&
            (inventTrans.statusIssue == StatusIssue::ReservPhysical ||
             inventTrans.statusIssue == StatusIssue::ReservOrdered  ||
             inventTrans.statusIssue == StatusIssue::OnOrder
            );
В нашем примере для строки Лот2 он вернет 0.
Если отключить кеш,
InventTrans.disablecache(true);
то вернет -5.

Если поставить точное равенство

X++:
    select sum(qty) from inventTrans
        index hint TransIdIdx
        where inventTrans.inventTransId         == _inventTransId   &&
            (inventTrans.statusIssue == StatusIssue::ReservPhysical);
то вернет -5

Если поставить диапазон значений

X++:
    select sum(qty) from inventTrans
        index hint TransIdIdx
        where inventTrans.inventTransId         == _inventTransId   &&
                       inventTrans.StatusIssue >= StatusIssue::ReservPhysical
                    && inventTrans.StatusIssue <= StatusIssue::OnOrder;
что эквивалентно перечислению, так как значения в енуме идут подряд
то тоже вернет -5

И теперь внимание !
Если принудительно перед выполнением запроса создать RecordViewCache
X++:
    object             object;
    ;
...
    object = InventTrans::viewCacheInventTransId(_InventTransId, true);
    select sum(qty) from inventTrans
        index hint TransIdIdx
        where inventTrans.inventTransId         == _inventTransId   &&
            (inventTrans.statusIssue == StatusIssue::ReservPhysical ||
             inventTrans.statusIssue == StatusIssue::ReservOrdered  ||
             inventTrans.statusIssue == StatusIssue::OnOrder
            );
то тоже вернет -5 !!!
(в этом случае если посмотреть InventTrans.wasCached() то видно что запись закеширована - во всех предыдущих случаях - она незакеширована, потому что Лот2 вообще небыло в salesParmLine)


Итог :
Если по InventTrans создан RecordViewCache для какого то конкретного запроса (запрос по Лот1)

то при других запросах ядро может глючить и возвращать пустую выборку (запрос по Лот2)

Глюк исчезает если
1. отключить кеширование на буфере перед выполнением запроса
или
2. прнудительно создать RecordViewCache перед выполнением запроса (В нашем примере Лот2)
или
3. Изменить запрос так чтобы в нем не было перечисления через ||
За это сообщение автора поблагодарили: gl00mie (5).