AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 17.11.2020, 19:47   #1  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
D365FO queryBuildDataSource.FindRange() не работает??
D365FO 10.0.12

Пишу RunBaseBatch. который делает автоматичские платежи по custTransOpen. где due date <= сегодня.

Хотелось бы добавить возможность для пользователя выбрать вручную dueDate в фильтре запроса.

Задумывалась такая логика:
Изначально due date range очищается,
Если пользователь выбирает вручную due date, то используем его.
В данном случае пользователь выбрал неправильно- просто значение вместо диапазона: - due date == 2020-11-16
Если пользователь ничего не выбрал, автоматически добавляем диапазон: due date <= сегодня (2020-11-17)

В реальности, пользователь выбрал значение вручную, но система все равно добавляет автоматический диапазон...
Разве if(!qbds.findRange(fieldnum(CustTransOpen, dueDate))) не должен был увидеть уже имеющееся условие?

X++:
void run()
    {
    ....
    q = QueryRun.query();

/*в дебаггере: текущее значение имеет выбранный пользователем DueDate=2020-11-16:
{SELECT MIN(dataAreaId), MIN(AccountNum), SUM(AmountCur) 
FROM CustTransOpen(CustTransOpen_1) 
GROUP BY CustTransOpen.AccountNum 
WHERE ((CustTransOpen(CustTransOpen_1).AccountNum = N'000000001')) 
AND ((CustTransOpen(CustTransOpen_1).DueDate = {ts '2020-11-16 00:00:00.000'}))}
*/

    QueryBuildDataSource qbds = q.dataSourceTable(tableNum(CustTransOpen));
    if(!qbds.findRange(fieldnum(CustTransOpen, dueDate)))
    {
       //несмотря на наличие DueDate range, дебаггер идет сюда и  добавляется новый range
       qbds.addRange(fieldnum(CustTransOpen, dueDate)).value(queryRange(dateNull(), systemDateGet()));
    }
    Info(strFmt("Due date used: %1", qbds.rangeField(fieldnum(CustTransOpen, dueDate)).value()));

/*в итоге получаем странный запрос с двумя разными фильтрами по due date:
{SELECT MIN(dataAreaId), MIN(AccountNum), SUM(AmountCur) 
FROM CustTransOpen(CustTransOpen_1) 
GROUP BY CustTransOpen.AccountNum 
WHERE ((DueDate<={ts '2020-11-17 00:00:00.000'})) 
AND ((CustTransOpen(CustTransOpen_1).AccountNum = N'000000001')) 
AND ((CustTransOpen(CustTransOpen_1).DueDate = {ts '2020-11-16 00:00:00.000'}))}
*/
    .....
    }

boolean unpack(container packedClass)
    {
        Integer     locVersion     = conPeek(packedClass,1);
        container   locPackedQuery;

        switch (locVersion)
        {
            case #CurrentVersion:
                [locVersion,#CurrentList,locPackedQuery] = packedClass;
                break;
            default :
                return false;
        }

        if (locPackedQuery)
        {
            queryRun = new QueryRun(locPackedQuery);

            Query q = QueryRun.query();

            QueryBuildDataSource qbds = q.dataSourceTable(tableNum(CustTransOpen));
            if(qbds.findRange(fieldnum(CustTransOpen, dueDate)))
            {
                qbds.clearRange(fieldnum(CustTransOpen, dueDate));
            }
        }
        else
        {
            return false;
        }
        
    
        return true;
    }
Старый 17.11.2020, 20:48   #2  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Извините, что не по существу, а зачем вы вообще что-то программируете, когда появилось следующее:
https://docs.microsoft.com/en-us/dyn...yment-proposal
Старый 17.11.2020, 21:02   #3  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
Потому что платит не компания кому-то, а процессятся платежи от клиентов с использованием кредитных карт, данные о которых клиенты оставили компании.
Старый 17.11.2020, 21:30   #4  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Цитата:
Сообщение от alicedr Посмотреть сообщение
Потому что платит не компания кому-то, а процессятся платежи от клиентов с использованием кредитных карт, данные о которых клиенты оставили компании.
Для этого есть Customer payment proposal, широко используется для SEPA Direct Debit. Там, правда, есть интерактивный шаг, пользователь должен подтвердить предложение.
Старый 17.11.2020, 21:59   #5  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
есть набор требований и стандарный функционал для него не подходит:
1. платежи через кредитные карты
2, разные пеймент процессоры для разных карт в зависимости от месторасположения владельца карты
3. план платежей по датам с лимитом суммы
4. +установленный лимит по кредитной карте
5. возможность делать разные типы платежей по кредитной карте в зависимости от наличия авторизации и ее статуса
6. Вишенка - один батч который работает по всем хх+ имеющимся компаниям
7. Очень большие обьемы. никто вручную подтверждать ничего не будет - это физически невозможно.
Старый 17.11.2020, 23:07   #6  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Понимаю.
По существу:
Цитата:
Изначально due date range очищается
Как очищается?

.findRange() возвращает объект, если он уже изначально прошит в Query (или не возвращает в противном случае, но обычно в таких задачах, как ваша, задается предопределенное условие). А значение его - строка - будет .findRange().value(). Оно может быть пустым или непустым. Почему бы вам не зафиксировать Range и не стирать просто его значение:

X++:
SysQuery::findOrCreateRange(qbds, fieldnum(CustTransOpen, dueDate)).value(SysQuery::emptyValue())
(пишу по памяти, извините за ошибки, если что)

https://community.dynamics.com/ax/f/...agment-96834=1

Последний раз редактировалось EVGL; 17.11.2020 в 23:15.
За это сообщение автора поблагодарили: alicedr (1).
Старый 17.11.2020, 23:17   #7  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
Спасибо за идею, добрый человек!!!
Задача вроде элементарная, а мудохаюсь уже несколько часов (((
Сейчас попробую.
Старый 18.11.2020, 09:46   #8  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Есть универсальный способ находить заданные пользователем фильтры в то числе если пользователь задал фильтр по полю, изначально не прошитому в Query.

Данная функция возвращает значение фильтра по заданному Query, коду таблицы и коду поля в таблице.Если фильтр не найден или не задан, то возвращает пустую строку.

X++:
    str     getRangeValue(Query _query, TableId _tableId, FieldId _fieldId)
    {
        QueryBuildDataSource    innerQbds;
        QueryBuildRange         innerQbr;
        int                     idx;
        str                     ret;

        innerQbds = _query.dataSourceTable(_tableId);

        if (innerQbds && innerQbds.enabled())
        {
            innerQbr = innerQbds.findRange(_fieldId);
            if (innerQbr && innerQbr.value())
            {
                ret = innerQbr.value();
            }
            else
            {
                for (idx = 1; idx <= _query.queryFilterCount(); idx++)
                {
                    if (_query.queryFilter(idx).dataSource().name() == innerQbds.name() && _query.queryFilter(idx).value())
                    {
                        ret = _query.queryFilter(idx).value();
                        break;
                    }
                }
            }
        }

        return ret;
    }
Для вашего случая вызов этой функции будет выглядеть так:
X++:
getRangeValue(q, tableNum(CustTransOpen), fieldnum(CustTransOpen, dueDate));
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/

Последний раз редактировалось Ace of Database; 18.11.2020 в 09:52.
За это сообщение автора поблагодарили: sukhanchik (6), alicedr (1).
Старый 18.11.2020, 20:12   #9  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
Ссылочка уже в избранных )))
Решение EVGL "железобетонной привязки" работает на ура.

Спасибо огромное!
Старый 21.11.2020, 04:04   #10  
lvan is offline
lvan
Участник
Аватар для lvan
Лучший по профессии 2014
 
858 / 82 (4) ++++
Регистрация: 15.04.2011
Записей в блоге: 1
Цитата:
Сообщение от alicedr Посмотреть сообщение
D365FO 10.0.12

Пишу RunBaseBatch.
Уже неправильно.
Надо sysoperation framework использовать
Старый 21.11.2020, 07:28   #11  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1633 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от lvan Посмотреть сообщение
Уже неправильно.
Надо sysoperation framework использовать
Query и QueryBuildRange кстати с этих соображений тоже неправильно использовать, надо переходить на SysDa classes
X++:
Therefore, use of the SysDa classes carries no overhead, unlike use of the QueryRun object, for example
https://docs.microsoft.com/en-us/dyn.../dev-ref/sysda
Старый 21.11.2020, 09:39   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от lvan Посмотреть сообщение
Уже неправильно.
Надо sysoperation framework использовать
Его же реабилитировали в 365-й?
Старый 21.11.2020, 17:18   #13  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,319 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Его же реабилитировали в 365-й?
Реабилитировали как-раз таки RunBase, который зачем-то "осквернили" в 2012. Но SysOperation-ом также можно пользоваться - просто он большей частью для SSRS-отчетов используется
__________________
Возможно сделать все. Вопрос времени
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
littleax: Simple Rest API in D365FO, D365F, D365SCM Blog bot DAX Blogs 0 23.06.2020 14:12
sertandev: How to receive D365FO push notifications using Azure Notification Hubs Blog bot DAX Blogs 0 04.07.2019 18:11
sertandev: How to integrate D365FO with Microsoft Flow using the new Business Events Blog bot DAX Blogs 0 23.05.2019 16:11
erconsult: Copy-paste with keyboard script 2: from Excel to D365FO Blog bot DAX Blogs 0 03.08.2018 11:12

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 02:17.