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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.05.2021, 10:01   #1  
axm2017 is offline
axm2017
Участник
 
1,914 / 313 (14) ++++++
Регистрация: 15.05.2017
О рукожо..ах (?). И немножко ER
В силу того что люди таки начали осваивать ER ( и довольно на удивление успешно, напоминая порой тетенек-бухгалтерш ака виртуозов Excel) приходится анализировать и их неудачи.

Одна из них оказалась связана с отчетом "Sales tax declaration info report for HU":

Кто то талантливый из видимо в MS (в терминах одного самокритичного коллеги работавшего на данную контору - см заголовок) не стал как обычно выводить название в параметры или использовать константы, смог как то обойти кодревью, проверки и втиснуть шедевр в класс SalesTaxDeclarationInformationReportService который как понимаю таки венгерский отчет но без всяких суффиксов.

Благодаря его столь решительному подходу попытки сделать свое в виде derive ов и прочего у консультантов обрекались на неудачу.

X++:
/// <summary>
    /// Called by service controller.
    /// </summary>
    /// <param name = "_dataContract">The report parameters.</param>
    [Microsoft.Dynamics.BusinessPlatform.SharedTypes.InternalUseOnlyAttribute]
    public void run(SalesTaxDeclarationInfoReportContract _dataContract)
    {
        dataContract = _dataContract;

        this.processReport();

        this.runER();
    }

    /// <summary>
    /// Called by service controller.
    /// </summary>
    private void runER()
    {
        ERIModelDefinitionParamsAction parameters = new ERModelDefinitionParamsUIActionComposite()
                    .add(
                        new ERModelDefinitionDatabaseContext()
                            .addTemporaryTable(this.getTmpTaxReport()))
                    .add(
                        new ERModelDefinitionDatabaseContext()
                            .addValue(tableNum(CompanyInfo), fieldNum(CompanyInfo, DataArea), curext()))
                   .add(
                        new ERModelDefinitionInputParametersAction()
                            .addParameter('ParameterReportMode', dataContract.parmReportMode()))
                    .add(
                        new ERModelDefinitionInputParametersAction()
                            .addParameter('model/ParameterFromDateRange',dataContract.parmTaxReportPeriodFromDate()))
                   .add(
                        new ERModelDefinitionInputParametersAction()
                            .addParameter('model/ParameterToDateRange', dataContract.parmTaxReportPeriodToDate()));

        // Call ER to generate the report.
        ERFormatMappingTable eRFormatMappingTable;
        select RecId from eRFormatMappingTable where eRFormatMappingTable.Name == "Sales tax declaration info report for HU";
        ERFormatMappingId formatMapping = eRFormatMappingTable.RecId;

        ERObjectsFactory::createFormatMappingRunByFormatMappingId(formatMapping)
            .withFileDestination(ERObjectsFactory::createFileDestinationBrowser())
                .withParameter(parameters)
                        .withCreatingObjectParameter(SalesTaxDeclarationInfoReportContract::parmERModelname(),
                                                     classStr(SalesTaxDeclarationInfoReportContract),
                                                     dataContract).run();
    }
Вопрос в том как это можно безболезненно и с минимумом кода поправить?
Старый 06.05.2021, 10:18   #2  
Stitch_MS is offline
Stitch_MS
Участник
Аватар для Stitch_MS
Соотечественники
 
397 / 478 (16) +++++++
Регистрация: 27.02.2006
Адрес: Дания
Может, что-то типа этого?

X++:
[ExtensionOf(classStr(SalesTaxDeclarationInformationReportService))]
final class SalesTaxDeclarationInformationReportServiceNNN_Extension // <-- new extension
{
    public void run(SalesTaxDeclarationInfoReportContract _dataContract)
    {
        try
        {
            throw Exception::Numeric;

            next run(_dataContract);
        }
        catch (Exception::Numeric)
        {
            dataContract = _dataContract;

            this.processReport();

            this.nnnRunER(); // <- new method
        }
    }

    private void nnnRunER()
    {
        // ...
    }

}
За это сообщение автора поблагодарили: Ace of Database (3), axm2017 (4).
Старый 06.05.2021, 10:33   #3  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Я бы порекомендовал завести нам багу.

Можно сделать свою копию (copy-on-write, как выражается fed).

В качестве извратного нестабильного воркэраунда теоретически можно было бы подменять recID после загрузки записи, проанализировав коллстек на предмет вызова именно из этого класса.

Еще можно у стандартного мепинга заменить имя на другое где-то (в xml файле или БД) а у кастомного сделать такое, как требует код.

Но это теоретические возможности которые я не могу порекомендовать.
За это сообщение автора поблагодарили: pitersky (2), axm2017 (4).
Старый 06.05.2021, 14:07   #4  
axm2017 is offline
axm2017
Участник
 
1,914 / 313 (14) ++++++
Регистрация: 15.05.2017
PS На всякий случай домохозяйкам на заметку в SalesTaxDeclarationInfoItemizedExcel_HU та же фигня (отчет Sales tax declaration info Itemized Excel for HU).
Старый 06.05.2021, 15:28   #5  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,909 / 5730 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от belugin Посмотреть сообщение
Я бы порекомендовал завести нам багу.

Можно сделать свою копию (copy-on-write, как выражается fed).
Мне тут понадобилось подправить по-мелочи функциональность банковских курсовых разниц. Выяснилось что авторы этого произведения, не только породили код, где на каждый метод заведено по отдельному классу, но и повесили на вообще все классы и методы, которые были созданы в ходе разработки, аттрибут internal и nohook. Так что в итоге мне пришлось copy-on-writeить порядка 25 классов и расширения нескольких таблиц.
Ты там поинтересуйся при случае, не было ли у ваших зарубежных коллег случаев хронической икоты ? А то я вот совсем не понимаю, ЗАЧЕМ было делать такую мелкогранулированную систему, а потом ее же наглухо закрывать от расширений...
Старый 06.05.2021, 15:47   #6  
Stitch_MS is offline
Stitch_MS
Участник
Аватар для Stitch_MS
Соотечественники
 
397 / 478 (16) +++++++
Регистрация: 27.02.2006
Адрес: Дания
Мне в таких случаях приходилось писать и такое (вместо трех строчек кода):
X++:
SysDictClass sysDictClassCredManCreditControl_WHS = SysDictClass::newName(classStr(CredManCreditControl_WHS));

Object creditControl = sysDictClassCredManCreditControl_WHS.callStatic(
	staticMethodStr(CredManCreditControl_WHS, newFromDocumentStatusCheck),
	CredManDocumentStatusCheck::WHSShipment);

sysDictClassCredManCreditControl_WHS.callObject(
	methodStr(CredManCreditControl, parmSalesTable), 
	creditControl, 
	origSalesTable);

checkOK = sysDictClassCredManCreditControl_WHS.callObject(
	methodStr(CredManCreditControl, run), 
	creditControl);
За это сообщение автора поблагодарили: trud (1).
Старый 07.05.2021, 09:05   #7  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от fed Посмотреть сообщение
А то я вот совсем не понимаю, ЗАЧЕМ было делать такую мелкогранулированную систему, а потом ее же наглухо закрывать от расширений...
Понятно зачем закрывают для расширений - чтобы не поддерживать точки расширения которые могут быть никому не нужны. Если все-таки нужны, есть возможность сделать extensibility request.

Вот, например, сделали вы метод

X++:
public void test(str _arg)
И хочется добавить параметр:
  • добавить обязательный параметр - breaking change (может быть вызов из расширения)
  • добавить необязательный параметр - breaking change (может быть обернут расширением)
  • добавить новый метод с дополнительным параметром можно, но прекратить вызывать старый метод - breaking change (на вызов может быть подписано расширение, котрое перестанет работать)
  • можно использовать disposable context, это приемлемо, но ломает рекурсию.

Решения:
  • Hookable(false) - если надо чтобы можно было подписаться на метод, то сделать отдельное событие (это не блокирует создание нового метода, вызывающеего то же событие)
  • Передавать аргументы при помощи класса (как в дотнете события сделаны XXXEventArgs) - добавление свойства в класс это не breaking change
  • Продумывать для каких сценариев нужны расширения, а для каких нет

Последний раз редактировалось belugin; 07.05.2021 в 09:15.
Старый 07.05.2021, 10:52   #8  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,039 / 1633 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от belugin Посмотреть сообщение
[*]Передавать аргументы при помощи класса (как в дотнете события сделаны XXXEventArgs) - добавление свойства в класс это не breaking change
Кстати можно еще через временную таблицу передавать(тоже расширяется, плюс можно отобразить в диалоге), довольно удобно получается.
Но это не отменяет замечания что каждый метод создан отдельный класс. Вроде как цель ООП - это упросить сопровождение, а не сделать его более сложным. В последнее время очень много такого кода стало встречаться
Старый 07.05.2021, 11:40   #9  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от trud Посмотреть сообщение
Кстати можно еще через временную таблицу передавать(тоже расширяется, плюс можно отобразить в диалоге),
В таблице нельзя делать private поля, поля ссылочного типа и, думаю, что создание записи, это более медленное действие.

Доступ к полям таблицы происходит через конверсию в object - соответственно boxing/unboxing. Так же там есть всякая проверка доступа и т.д.

Цитата:
довольно удобно получается.
Но это не отменяет замечания что каждый метод создан отдельный класс. Вроде как цель ООП - это упросить сопровождение, а не сделать его более сложным. В последнее время очень много такого кода стало встречаться
Я не знаю, зачем там создан класс на метод. И даже не очень понимаю, о каком коде идет речь.
Старый 07.05.2021, 11:53   #10  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,909 / 5730 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от belugin Посмотреть сообщение
Я не знаю, зачем там создан класс на метод. И даже не очень понимаю, о каком коде идет речь.
Посмотри на классы BankCurrencyReval* и все что с ними связано. Я когда-то эту задачу делал в один класс. Наверное по-хорошему можно было бы там логику класса на 3-4 реструктурировать (с учетом изменений в работе с финансовыми аналитиками в DAX2012). Но Микрософт создал 28 классов BankCurrencyReval*, три класса BankAccount*, добавил около 5-6 методов в разные таблицы и тщательно закрыл все это internal и hookable(false)
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
erconsult: Electronic Reporting (ER) Cookbook 4: References in a model Blog bot DAX Blogs 0 04.12.2020 06:14
cleverax: ER: Add product image to your Business documents Blog bot DAX Blogs 0 17.04.2020 13:11
erconsult: Electronic Reporting (ER) Cookbook 2: new tips from the kitchen Blog bot DAX Blogs 0 06.08.2018 17:11
powerobjects: Electronic Reporting in Dynamics 365 for Finance and Operations Blog bot DAX Blogs 0 14.02.2018 03:28
erconsult: Electronic Reporting (ER) Cookbook Blog bot DAX Blogs 24 09.10.2017 08:47
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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