31.03.2011, 16:49 | #1 |
Участник
|
Оповещение пользователю
Доброго времени года.
Не подскажите каким образом можно программно отправить уведомление пользователю, какой класс за это отвечает? Существует ли возможность в это уведомление вставить ссылку на MenuItem. Если нет, то реализуемо ли это с помощью почтового сообщения? |
|
31.03.2011, 17:12 | #2 |
Участник
|
с помощью классов EventNotification* можно создавать оповещения
Последний раз редактировалось ice; 31.03.2011 в 17:15. |
|
31.03.2011, 17:15 | #3 |
северный Будда
|
Ребята, вы не забывайте версии указывать. Не всегда классы 2009 есть в 3.0
__________________
С уважением, Вячеслав |
|
31.03.2011, 17:16 | #4 |
Участник
|
EventNotification* в 4.0 также нет.
|
|
31.03.2011, 17:38 | #5 |
Участник
|
2009 Ax, спасибо за ответы, попробую разобраться с классом EventNotification, а по поводу возможности вставки ссылки на MenuItem в данном классе она присутсвует?
|
|
31.03.2011, 17:50 | #6 |
Участник
|
Для 4.0 я выкладывал свой пример.
Для Ax 2009 можно написать наследника EventNotification. У него есть параметры: X++: notification.parmMenuFunction(_menuFunction); notification.parmRecord(_record); X++: new MenuFunction("LedgerTable", MenuItemType::Display),
__________________
Ivanhoe as is.. |
|
|
За это сообщение автора поблагодарили: someOne (5). |
04.04.2011, 10:51 | #7 |
Участник
|
Я использую следующий код для отправки уведомлений, уведомления приходят но вот ссылка не меню в нем нет, причем записи в таблице EventInboxData создаются, что я делаю не так?
X++: inbox.initValue(); inbox.UserId = 'ed13'; inbox.Subject = subject; inbox.Message = 'Текст'; inbox.EmailRecipient = sysUserInfo::find(inbox.UserId).Email; inbox.SendEmail = true; inbox.ShowPopup = NoYes::Yes; inbox.TypeId = classnum(EventType); inbox.CompanyId = CurExt(); inboxId = EventInbox::nextEventId(); inbox.InboxId = inboxId; inbox.AlertCreatedDateTime = DateTimeUtil::getSystemDateTime(); //Give any table and field values inbox.AlertedFor = "no links"; inbox.AlertTableId = TableNum(CustTable); inbox.AlertFieldId = FieldNum(CustTable, Name); inbox.TypeTrigger = EventTypeTrigger::FieldChanged; eci = new EventContextInformation(); if (!menuFunction) { menuFunction = new MenuFunction(menuitemdisplaystr(S_CustVendMainForm),MenuItemType::Display); } args.menuItemName(menuFunction.name()); args.menuItemType(MenuItemType::Display); eci.parmPackedArgs(args); inboxData.InboxId = inboxId; inboxData.DataType = EventInboxDataType::Context; inboxData.Data = eci.pack(); inboxData.insert(); inbox.insert(); |
|
04.04.2011, 11:18 | #8 |
Участник
|
А вы мой проект смотрели? В 4.0 по крайней мере нужно было явно создать контекст и ссылку на запись (по ключевым полям):
X++: // IF EventExtension 08.09.2009 static void tutorialCreateAlert(Args _args) { LedgerTable lt; Args args; Query q = new Query(); QueryBuildDataSource qbds; Common record; str name; EventInbox ei; EventInboxData eid; EventType eventType; EventContextInfo contextInfo; EventTypeValue typeValue; container cont; List list; ; ttsbegin; ei.clear(); ei.initValue(); ei.InboxId = EventInbox::nextEventId(); ei.UserId = "Admin"; // пользователь ei.Subject = "Тема!!!"; // тема ei.Message = "Сообщение"; // сообщение ei.AlertedFor = "В связи с событием"; // в связи с чем оповещение ei.AlertCreatedDate = systemdateget(); ei.AlertCreateTime = timenow(); ei.TypeId = classnum(EventTypeCUD); ei.AlertTableId = tableNum(LedgerTable); // таблица записи ei.AlertFieldId = fieldNum(LedgerTable, AccountName); // поле которое изменилось ei.AlertFieldLabel = "Наименование"; ei.ParentTableId = ei.AlertTableId; ei.TypeTrigger = EventTypeTrigger::FieldChanged; ei.ShowPopup = NoYes::Yes; // показывать оповещение ei.SendEmail = NoYes::No; // отсылать почту. Не реализовано в этом джобе. ei.EmailRecipient = ""; //Почтовый адрес. Не реализовано в этом джобе. select firstonly lt where lt.AccountNum == '01.000'; // запись которую будем потом показывать list = SysDictTable::getUniqueIndexFields(lt.TableId); if (list) { ei.KeyFieldList = list.pack(); ei.KeyFieldData = SysDictTable::mapFieldIds2Values(list, lt).pack(); } ei.insert(); eid.clear(); eid.InboxId = ei.InboxId; eid.DataType = EventInboxDataType::Context; qbds = q.addDataSource(ei.AlertTableId); cont = q.pack(); contextInfo = [1, //version, DAX 4.0 - 1 formstr(LedgerTable), //formname "", //designname 0, //dataset 0, //parmenumType 0, //parmItemName "", //например, "FavQuery:Статус" - favourite query MenuItemType::Display, //menuitemtype menuitemdisplaystr(LedgerTable), //menuitemname ei.TypeId, //typeid EventTypeTrigger::FieldChanged, //typetrigger ei.AlertTableId, //alerttableid 1, //alertformDSNo номер датасорса по которому потом искать будем. true, //alertFdsIsTop 1, //alertQbdsNo "", //control name cont //filterQueryCon ]; eid.Data = contextInfo; eid.insert(); eid.clear(); eid.InboxId = ei.InboxId; eid.DataType = EventInboxDataType::TypeData; eventType = EventType::construct(ei.TypeId, ei.TypeTrigger); eventType.parmOriginalValue(""); eventType.parmCurrentValue(""); eid.Data = eventType.pack(); eid.insert(); ttscommit; }
__________________
Ivanhoe as is.. Последний раз редактировалось Ivanhoe; 04.04.2011 в 11:20. |
|
04.04.2011, 11:27 | #9 |
Участник
|
а для чего пререпивываете код отправки уведомлений? почему не пользуетесь готовыми классами?
|
|
04.04.2011, 13:35 | #10 |
Участник
|
Цитата:
X++: inbox.AlertTableId = TableNum(CustTable); inbox.AlertFieldId = FieldNum(CustTable, Name); inbox.TypeTrigger = EventTypeTrigger::FieldChanged; X++: args.menuItemName(menuFunction.name()); args.menuItemType(MenuItemType::Display); eci.parmAlertBuffer(record); eci.parmAlertFormDsName('S_CustVendCommon'); eci.parmPackedArgs(args); inboxData.InboxId = inboxId; inboxData.DataType = EventInboxDataType::Context; inboxData.Data = eci.pack(); inboxData.insert(); X++: eci.parmAlertBuffer(record);
eci.parmAlertFormDsName('S_CustVendCommon'); |
|
04.04.2011, 14:08 | #11 |
Участник
|
|
|
04.04.2011, 14:15 | #12 |
Участник
|
|
|
04.04.2011, 15:26 | #13 |
Участник
|
|
|
04.04.2011, 15:54 | #14 |
Участник
|
Цитата:
Сообщение от AngelDominantes
Как я понимаю работу оповещений: Существует Таблица куда записываются оповещения(EventInbox), существует какой то класс который постоянно эти оповещения из этой таблицы считывает и доставляет пользователям. Оповещения туда помещаются при срабатывании какого то события на таблице,
Цитата:
Цитата:
В вашем примере еще не хватает вот этого: X++: list = SysDictTable::getUniqueIndexFields(table.id());
if (list)
{
inbox.KeyFieldList = list.pack();
inbox.KeyFieldData = SysDictTable::mapFieldIds2Values(list,record).pack();
}
__________________
Ivanhoe as is.. |
|
04.04.2011, 16:29 | #15 |
Участник
|
В вашем примере еще не хватает вот этого:
X++: list = SysDictTable::getUniqueIndexFields(table.id());
if (list)
{
inbox.KeyFieldList = list.pack();
inbox.KeyFieldData = SysDictTable::mapFieldIds2Values(list,record).pack();
} ПыСы: Если четно кроме этого форума не существует по моему никакой вменяемой документации Последний раз редактировалось AngelDominantes; 04.04.2011 в 16:35. |
|
04.04.2011, 16:43 | #16 |
Участник
|
inboxData и inbox - разные таблицы так что ваше "но" мне не понятно
Документация в данном случае - стандартный код. Когда я с этим разбирался, рассуждал по-другому - сначала всё повторил как в стандарте (и убедился, что работает), а уже потом пытался оптимизировать и "выкидывать лишнее"
__________________
Ivanhoe as is.. |
|
04.04.2011, 16:59 | #17 |
Участник
|
Цитата:
Сообщение от Ivanhoe
Неправильно понимаете. EventInbox - это и есть уже "доставленное" оповещение.
Как же так? Какая версия AX 2009? Точно смотрите метод create()?? Ну так сделайте наследника. В стандарте три примера для подражания. В вашем примере еще не хватает вот этого: X++: list = SysDictTable::getUniqueIndexFields(table.id());
if (list)
{
inbox.KeyFieldList = list.pack();
inbox.KeyFieldData = SysDictTable::mapFieldIds2Values(list,record).pack();
} Цитата:
Сообщение от Ivanhoe
inboxData и inbox - разные таблицы так что ваше "но" мне не понятно
Документация в данном случае - стандартный код. Когда я с этим разбирался, рассуждал по-другому - сначала всё повторил как в стандарте (и убедился, что работает), а уже потом пытался оптимизировать и "выкидывать лишнее" |
|
04.04.2011, 17:28 | #18 |
Участник
|
Извините, но я вашу логику не понимаю. Я пас
Удачи в разбирательствах.
__________________
Ivanhoe as is.. |
|
04.04.2011, 17:31 | #19 |
Участник
|
Логика по моему железная, раз кнопка не активна значит что то ее дезактивирует, значит надо найти это что-то и посмотреть какие критерии. Собственно вот в чем была загвоздка
X++: ... if (eventInbox.ParentTableId) goToContext.enabled(true); else goToContext.enabled(false); ... Последний раз редактировалось AngelDominantes; 04.04.2011 в 17:33. |
|
04.10.2011, 09:56 | #20 |
Участник
|
Подниму старую тему... Поясните пожалуйста, есть ли связь между созданием самого оповещения и выводом всплывающего окна для пользователя о новом оповещении ?
Что то я не смог с этим разобраться. Итак, как создать оповещение пользователю - понятно. Есть пример от Ivanhoe, джоб в котором добаляются записи в таблицу EventInbox. Так же ясно как вывести всплывающее окно пользователю об оповещении - делается с использованием класса EventAttentionGrabberParms. Но как создать оповещение пользователю, чтобы каждое новое оповещение "всплыло" для данного пользователя в данный момент (если у него запущена Аксапта, либо при следующем ее запуске) ??? Ведь создание оповещений через создание записи в таблице EventInbox никаких всплывающих окон не вызывает. (Или я не прав ?) (Происходит лишь изменение отображаемых не прочитанных оповещений в нижней части экрана Аксапта) Как все же сделать отображение всплывающих окон для пользователя о новых оповещениях ? Примеров на форуме для этого не нашел... Писать собственную обработку (вызов EventAttentionGrabberParms) с использованием какого то таймера ? Или есть "стандартный" споcоб ? Может что то в личных настройках пользователя не так ? |
|