EventModelValidator missing 7 Topics
Description
Environment
Attachments
- 26 Jun 2018, 02:37 PM
relates to
Activity
redhuan d. oon October 23, 2018 at 3:20 AMEdited
With the idea stated, I can now handle my own Kanban Board card movements freely.
1. My own Plugin Event:
protected void doHandleEvent(Event event) {
String type = event.getTopic();
if (type.equals(IEventTopics.DOCACTION)) {
DocActionEventData eventData = getEventData(event);
if (eventData.po instanceof MRD_Handler) {
MRD_Handler model = (MRD_Handler) eventData.po;
String docStatus = model.getDocStatus(); //from KanbanStatus
String newStatus = eventData.docStatus; //to new KanbanStatus
//choose your preferred action against the intended status
if (docStatus.equals(DocAction.STATUS_Completed) && newStatus.equals(DocAction.STATUS_Closed)){
//TODO fill in your logic before assigning new status
if (model.getName().equals("Good"))
model.setDocStatus(newStatus);
else
eventData.orderType = "Tell the world what happened here!";//customize your exception message
}else
model.setDocStatus(newStatus);//if no condition then let thru successfully
};
//end of your logic
2. Forked MKanbanCard, replacing ModelValidator with direct Event trigger:
public boolean changeStatus(String statusColumn, String newStatusValue) {
if (m_po == null)
return false;
boolean success=true;
if (statusColumn.equals(MKanbanBoard.STATUSCOLUMN_DocStatus)) {
if (m_po instanceof DocAction && m_po.get_ColumnIndex("DocAction") >= 0) {
try {
String p_docAction = kanbanBoard.getDocAction(newStatusValue);
//No valid action
if (p_docAction == null)
throw new IllegalStateException();
m_po.set_ValueOfColumn("DocAction", p_docAction);
KDB_ErrorMessage = "KDB_InvalidTransition";
//TODO trigger EventHandler but do we need to go thru its valid actions?
DocActionEventData eventData = new DocActionEventData(newStatusValue, null, "", "", m_po.get_Table_ID(),new ArrayList<String>(Arrays.asList(p_docAction)), new ArrayList<String>(Arrays.asList(new String[14])),new AtomicInteger(0), m_po);
Event event = EventManager.newEvent(IEventTopics.DOCACTION,new EventProperty(EventManager.EVENT_DATA, eventData),new EventProperty("tableName", m_po.get_TableName()));
EventManager.getInstance().sendEvent(event);
if ((m_po.get_Value("DocStatus")).equals(newStatusValue)) {
m_po.saveEx();
} else
throw new IllegalStateException();
Thus this Kanban use case request is fixed by using the idea given. There is no need to impose on IEventTopics or custom core DocActions, because they can all be handled in standalone and remote manner within a decoupled plugin.
Carlos Ruiz October 15, 2018 at 9:23 AM
Thanks @redhuan d. oon, answered in https://idempiere.atlassian.net/browse/IDEMPIERE-3599#icft=IDEMPIERE-3599
redhuan d. oon October 15, 2018 at 5:34 AMEdited
@Hiep Lq brought my attention to https://idempiere.atlassian.net/browse/IDEMPIERE-3599. It seems brilliant in trying to solve the same issue. But i can see in DocumentEngine, Line 968, there is a hard stop (return 0):
// Closed, Voided, REversed .. CL/VO/RE
else if (docStatus.equals(DocumentEngine.STATUS_Closed)
|| docStatus.equals(DocumentEngine.STATUS_Voided)
|| docStatus.equals(DocumentEngine.STATUS_Reversed))
return 0;
redhuan d. oon August 2, 2018 at 9:14 PM
Hi @Carlos Ruiz I am trying to make this a non specific use case. It is supposed to be abstract and allow any situation outside it's core and user no longer need to touch core code.
My use case is Kanban Board where user drags a card across all 12 status and may need action before and after each case.
Yes at the moment there is also specific logic governing statuses such as Void where user cannot unvoid. To me that should be allowed following the above separation of concern.
I thus forked Document Engine and Document Action to do that temporarily but I cannot fork out EventTopic framework.
Carlos Ruiz July 23, 2018 at 3:17 PM
Hi @redhuan d. oon, which is the use case for those?
The idea behind DOC_BEFORE and DOC_AFTER events is related to inject code during certain events that can be driven by the user.
So, for example BEFORE_DRAFT doesn't make sense - I think that would be a BEFORE_INSERT
Also, an AFTER_DRAFT doesn't make sense as there is not an action that user executes to make a document draft.
Same thinking about BEFORE/AFTER LOCK/UNLOCK - those are not document actions from the users.
Maybe you're confusing DocAction with DocStatus?
Regards,
Carlos Ruiz
Event Model Validator Reference List is not complete. They are useful for OSGi plugins that wish to handle these. There are 7 topics left (extracted from patch - AD_Ref_List, IEventTopics,ModelValidator):
DocumentBeforeInvalid = "DBIV";
DocumentAfterInvalid = "DAIV";
DocumentBeforeWaitPay = "DBWP";
DocumentAfterWaitPay = "DAWP";
DocumentBeforeWaitConfirm = "DBWC";
DocumentAfterWaitConfirm = "DAWC";
DocumentBeforeUnlock = "DBUL";
DocumentAfterUnlock = "DAUL";
DocumentBeforeReject = "DBRJ";
DocumentAfterReject = "DARJ";
DocumentBeforeApprove = "DBAP";
DocumentAfterApprove = "DAAP";
DocumentBeforeDraft = "DBDR";
DocumentAfterDraft = "DADR";
IEventTopics.DOC_BEFORE_INVALID, // TIMING_AFTER_POST = 17
IEventTopics.DOC_AFTER_INVALID, // TIMING_AFTER_POST = 18
IEventTopics.DOC_BEFORE_WAITPAY, // TIMING_AFTER_POST = 19
IEventTopics.DOC_AFTER_WAITPAY, // TIMING_AFTER_POST = 20
IEventTopics.DOC_BEFORE_INVALID, // TIMING_BEFORE_INVALID = 17
IEventTopics.DOC_AFTER_INVALID, // TIMING_AFTER_INVALID = 18
IEventTopics.DOC_BEFORE_WAITPAY, // TIMING_BEFORE_WAITPAY = 19
IEventTopics.DOC_AFTER_WAITPAY, // TIMING_AFTER_WAITPAY = 20
IEventTopics.DOC_BEFORE_WAITCONFIRM, // TIMING_BEFORE_WAITCONFIRM = 21
IEventTopics.DOC_AFTER_WAITCONFIRM, // TIMING_AFTER_WAITCONFIRM = 22
IEventTopics.DOC_BEFORE_UNLOCK, // TIMING_BEFORE_UNLOCK = 23
IEventTopics.DOC_AFTER_UNLOCK, // TIMING_AFTER_UNLOCK = 24
IEventTopics.DOC_BEFORE_REJECT, // TIMING_BEFORE_REJECT = 25
IEventTopics.DOC_AFTER_REJECT // TIMING_AFTER_REJECT = 26
IEventTopics.DOC_BEFORE_APPROVE, // TIMING_BEFORE_APPROVE = 27
IEventTopics.DOC_AFTER_APPROVE, // TIMING_AFTER_APPROVE = 28
IEventTopics.DOC_BEFORE_DRAFT, // TIMING_BEFORE_DRAFT = 29
IEventTopics.DOC_AFTER_DRAFT // TIMING_AFTER_DRAFT = 30