Overridding existing classes in a plugin

816 views
Skip to first unread message

Antoni Ten Monrós

unread,
Dec 1, 2014, 6:32:36 AM12/1/14
to idem...@googlegroups.com
Dear iDempierans

As part of my effort to migrate an ADempiere customization to iDempiere (having pay schedules include fixed day of the month), I added two new columns to the C_PaySchedule, and re-exported the models using the model generator. I'm now modifying mInvoicePaySchedule.java to include this extra calculation possibility. I included the modified models in my plugin, under the same package as the original ones (org.compiere.model). However, when I try to access the getters for the new columns in my modified MInvoicePaySchedule.java, Eclipse doesn't find them, as it's still searching for them in their initial location. What am I doing wrong? What's the proper method of overriding existing classes (in particular models) with new ones?


P.S.: I'm still new to the iDempiere way of doing things, still used to the ADempiere ways, were one just tossed the modified files into the customization.jar file, so maybe I'm approaching this from the wrong end. If so, please guide me on how to properly approach the issue

Yours
Antoni Ten

Heng Sin Low

unread,
Dec 1, 2014, 10:54:23 AM12/1/14
to idem...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "iDempiere" group.
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/idempiere/8e55e343-1f42-497b-87a1-339aeada2acc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Antoni Ten Monrós

unread,
Dec 3, 2014, 3:49:19 AM12/3/14
to idem...@googlegroups.com
On Monday, December 1, 2014 4:54:23 PM UTC+1, hengsin wrote:

Thanks for the information. This, along with the linked docs, really helped clarify what I need to do. It seems that I'll need to create some new interfaces and use the powrapper method instead. However, for MInvoicePaySchedule, I'll need to create a model factory instead, as I need to have other parts of ADempiere to use that instead of the standard one. I see that I have more reading to do though.

Antoni Ten Monrós

unread,
Dec 4, 2014, 3:59:46 AM12/4/14
to idem...@googlegroups.com
Been experimenting with POWrapper, but I really can't get my head around it. Where do I define what the methods do? Does POWrapper automagically implement the methods? Do I need to generate the X class (seems like no, from that explanation you linked to before, but it feels weird that POWrapper can implement an interface without actually knowing what the interface does)?

Alan Lescano

unread,
Dec 4, 2014, 5:32:12 AM12/4/14
to idem...@googlegroups.com
Antoni,

You can do it in a simple way (with some disadvantages in maintenance of bigger projects, but fully functional):
- Create a Model Factory, as explained here: http://wiki.idempiere.org/en/Developing_Plug-Ins_-_IModelFactory Your new model should extends the original model. Don't create I_ and X_.
- Use the methods get_Value...() and set_Value...() of your new model class as getters and setters for your columns.

Alan 

2014-12-04 6:59 GMT-02:00 Antoni Ten Monrós <kuro...@gmail.com>:
Been experimenting with POWrapper, but I really can't get my head around it. Where do I define what the methods do? Does POWrapper automagically implement the methods? Do I need to generate the X class (seems like no, from that explanation you linked to before, but it feels weird that POWrapper can implement an interface without actually knowing what the interface does)?

--
You received this message because you are subscribed to the Google Groups "iDempiere" group.
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+...@googlegroups.com.

Heng Sin Low

unread,
Dec 4, 2014, 7:02:56 AM12/4/14
to idem...@googlegroups.com
Yes, just define or generate the interface for the columns you added and powrapper will supply the implementation.

On Thu, Dec 4, 2014 at 4:59 PM, Antoni Ten Monrós <kuro...@gmail.com> wrote:
Been experimenting with POWrapper, but I really can't get my head around it. Where do I define what the methods do? Does POWrapper automagically implement the methods? Do I need to generate the X class (seems like no, from that explanation you linked to before, but it feels weird that POWrapper can implement an interface without actually knowing what the interface does)?

--
You received this message because you are subscribed to the Google Groups "iDempiere" group.
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+...@googlegroups.com.

redhuan d. oon

unread,
Dec 4, 2014, 7:03:32 PM12/4/14
to idem...@googlegroups.com

Antoni Ten Monrós

unread,
Dec 9, 2014, 11:10:19 AM12/9/14
to idem...@googlegroups.com
Hengsin, RedHuan, Alan, many thanks

I've decided to do things in a slightly different way (please point any possible pitfalls to my solution)

-I exported the I_ and X_ classes for the C_PaySchedule table
-Renamed them with AAU_I_PaySchedule and AAU_X_PaySchedule
-Removed any methods that already existed in the original model files, leaving only the members relevant to my custom fields
-Set AAU_I_PaySchedule to extend I_PaySchedule and AAU_X_PaySchedule to extend MPaySchedule
-Created AAU_MPaySchedule extending AAU_X_PaySchedule and implemented my businedd logic that used those fields there
-Created a ModelFactory for my package and exported the model for the table

Now it seems that it works properly! This way, I keep the I_*->X_*->M* structure, keep the generated files in the X and I files (no POWrapper magic, so I control the getters/setters, and so I can change the column names if needed, without hard to debug issues due to the automagic functionality of POWrapper [It already bit me in the backside]), and it should be as maintenable as the POWrapper method, as it extends the base classes instead of overwriting them.

However, I do have an issue. I also need to override MInvoicePaySchedule. I don't need to alter the model, I just need to add some logic to the constructor that takes an MInvoice and an MPaySchedule as the parameters. I extended MInvoicePaySchedule, and created the default constructors, calling super each time. I also edited the model factory, and set it to use my class instead of the default one. However, since the constructor I need to extend is not the default one, when iDempiere creates the payment terms on invoice complete, it calls the old constructor and not the one from my class. Every other part of the M Class works as expected, and my modifications produce the intended results, but this extra constructor is not correctly overridden.

How do I get to override this constructor, so the due dates are correctly calculated on invoice complete?

redhuan d. oon

unread,
Dec 9, 2014, 7:16:18 PM12/9/14
to idem...@googlegroups.com
You may be doing more that way. Points to remember:
1. Removing methods from renamed X/I classes are not necessary as you keep local version of I in your bundle, which are wrapped in your local M class.
2. As long as you extend the core M_ class you are reusing the core and reduce impact whenever either changes.

Antoni Ten Monrós

unread,
Dec 10, 2014, 2:42:28 AM12/10/14
to idem...@googlegroups.com
On Wednesday, December 10, 2014 1:16:18 AM UTC+1, redhuan d. oon wrote:
You may be doing more that way. Points to remember:
I assume that you mean that I might be doing more than necessary here, right?
1. Removing methods from renamed X/I classes are not necessary as you keep local version of I in your bundle, which are wrapped in your local M class.
It might not be strictly necessary, but it keeps the code cleaner and leaner.
2. As long as you extend the core M_ class you are reusing the core and reduce impact whenever either changes.
Assumed as much, glad that I correctly understood how to do it right.
However, I do have an issue. I also need to override MInvoicePaySchedule. I don't need to alter the model, I just need to add some logic to the constructor that takes an MInvoice and an MPaySchedule as the parameters. I extended MInvoicePaySchedule, and created the default constructors, calling super each time. I also edited the model factory, and set it to use my class instead of the default one. However, since the constructor I need to extend is not the default one, when iDempiere creates the payment terms on invoice complete, it calls the old constructor and not the one from my class. Every other part of the M Class works as expected, and my modifications produce the intended results, but this extra constructor is not correctly overridden.

How do I get to override this constructor, so the due dates are correctly calculated on invoice complete?
 Any hints on how to tackle this?

Antoni Ten Monrós

unread,
Dec 11, 2014, 2:44:13 AM12/11/14
to idem...@googlegroups.com
On Wednesday, December 10, 2014 8:42:28 AM UTC+1, Antoni Ten Monrós wrote:
However, I do have an issue. I also need to override MInvoicePaySchedule. I don't need to alter the model, I just need to add some logic to the constructor that takes an MInvoice and an MPaySchedule as the parameters. I extended MInvoicePaySchedule, and created the default constructors, calling super each time. I also edited the model factory, and set it to use my class instead of the default one. However, since the constructor I need to extend is not the default one, when iDempiere creates the payment terms on invoice complete, it calls the old constructor and not the one from my class. Every other part of the M Class works as expected, and my modifications produce the intended results, but this extra constructor is not correctly overridden.

How do I get to override this constructor, so the due dates are correctly calculated on invoice complete?
 Any hints on how to tackle this?
I sort of managed to get this working, but it involves implementing an event handler for PO_AFTER_NEW and that has some side effects (it recalculates due date for manually created invoice pay schedules, overwriting the duedate. The only solution I can imagine involves adding yet another custom field to control this, that is set when the schedule is created vis the standard constructors, but not when created via the special constructor) that would make it preferable to use some other method of accomplishing it.

Can anyone suggest some less hackish method of doing this?

redhuan d. oon

unread,
Dec 14, 2014, 8:43:29 AM12/14/14
to idem...@googlegroups.com
Perhaps this can complicate the code and we may need to think of further decoupling of such inherent logic behind PaySchedule as an external plugin.

Antoni Ten Monrós

unread,
Dec 15, 2014, 2:55:46 AM12/15/14
to idem...@googlegroups.com


On Sunday, December 14, 2014 2:43:29 PM UTC+1, redhuan d. oon wrote:
Perhaps this can complicate the code and we may need to think of further decoupling of such inherent logic behind PaySchedule as an external plugin.
Indeed, decoupling that logic from the constructor into it's own method would simplify adding new ways to handle due dates.

shiju01

unread,
Feb 12, 2018, 5:14:55 AM2/12/18
to iDempiere
Hi

In the sample project demonstrated by redhuan the model factory and the model are placed in different package namely idempiere and plugin

It is mentioned in the wiki http://wiki.idempiere.org/en/Developing_Plug-Ins_-_IModelFactory

Notice that your model factory and your model class must be implemented in different classes. It will not work if you try to implement IModelFactory in one of your models.

that the model factory and the model should be implemented in different classes

Could the model factory and model be implemented in same package ?

Heng Sin Low

unread,
Feb 13, 2018, 4:47:34 AM2/13/18
to idem...@googlegroups.com
Yes, if you want to ...

--
You received this message because you are subscribed to the Google Groups "iDempiere" group.
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/idempiere/7b884c8d-9aac-4d30-86c1-c172a4a57ca6%40googlegroups.com.

shiju01

unread,
Feb 14, 2018, 6:52:37 AM2/14/18
to iDempiere
Thanks hengsin
To unsubscribe from this group and stop receiving emails from it, send an email to idempiere+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages