Overriding a module: Setting a required attribute field to True

Hey guys

I have been reading and practicing with coopengo tryton-training, and wow, what a tutorial. It’s been an awesome help to develop the account_ao module in a more or less straightforward way. It does a pretty good job on developing a module in Tryton ERP.

After pretty much finishing the development of the module, there are fields that I need to make them required, so I can export the data of the field to an XML file. In the tutorial, specifically in the last step, it explains how can we override some module, which IMHO is one of the best developer feature Tryton offers.

So after reading and following the last step, specifically this step, I could change the description field, for example, of the product to be a required field in this way:

class Product(ModelSQL, metaclass=PoolMeta):
    __name__ = 'product.product'

    def __setup__(cls):
        super(Product, cls).__setup__()
        cls.description.required = True

And it works fine. However, I don’t know whether it’s the best way to do this.

I say this because after I start implementing other required needed fields, there are situations that this approach does not work as expected. For example, one of the fields that I need to make it required is in the party module in which I need to make, for example, the name of the product field as a required field. So following the same approach as before I did the following:

class Party(ModelSQL, metaclass=PoolMeta):
    __name__ = 'party.party'

    def __setup__(cls):
        super(Party, cls).__setup__()
        cls.name.required = True

However, for some reason it does not work. The field still not required, and works as if I didn’t make the party name field required and the user can save a product without the name field.

Can you guys help me with this.

Thank you all for the great work.

First when extending class, you should not inherit from ModelSQL. This may create a more compex __mro__.
Second it is probably not a good idea to change some fields as required because other module may not fill them. It may work for referential data because they are often created by user and not code. But you may think about having a different approach to fulfill the requirements.

Now about the party name being required. You should know that such constraint was removed in 4.0 series so the SQL constraint will be removed (and re-add later) on each database update.
Also be sure if you register an extension for a class defined in a module that your custom module depends on this module. It is important that the main class is registered first.

Hey @ced,

Ohhhh, I didn’t know that as I’m still a noob on developing on Tryton :neutral_face:. Thus, it’s already fixed.

Because I am developing this module mainly to comply with Angolan authorities, on their requirements they ask for a way to alert users if users of the software do not fill some required fields. Do you have any other ideia on how can I guarantee that certain field must be filled?

So there is no way that I can add such constraint in the party module??

When I run trytond I get the following results:
$ trytond -c trytond.conf -v

INFO trytond.config using trytond.conf as configuration files
INFO trytond.modules ir:registering classes
INFO trytond.modules res:registering classes
INFO trytond.modules country:registering classes
INFO trytond.modules currency:registering classes
INFO trytond.modules tests:registering classes
INFO trytond.modules party:registering classes
INFO trytond.modules company:registering classes
INFO trytond.modules account:registering classes
INFO trytond.modules product:registering classes
INFO trytond.modules account_product:registering classes
INFO trytond.modules account_invoice:registering classes
INFO trytond.modules account_ao:registering classes
INFO werkzeug  * Running on http://localhost:8000/ (Press CTRL+C to quit)

Is it what you referring when you say that I need to register my module, and the main class should be registered first?

Thanks for all

Yes, you can add the required constraint to the name field. All i think @ced is saying here is that each time you update the database (by activating or updating a module or using trytond-admin) the required constraint will get removed from the name field (because of the change made in series 4.0), and then it will see your customization and so will re-add the required constraint again.

However, as mentioned, you may want to consider using a different method to alert users to fields that should be filled in. One suggestion could be that, if for example the name is required because it must be shown on an invoice, then perhaps you could check the name is filled in before an invoice is posted, by raising a UserError for a blank party name during the validate_invoice or post method from account.invoice? Or maybe when a sale is confirmed?

You need to include the module that your module depends on in the tryton.cfg file. So if you are overriding things in the Party class then you need to make sure that the module where the Party class is defined (the party module) is included in the list of depends in tryton.cfg.

You also need to make sure you register your customized Party class in the register method in your __init__.py file with the correct module and type_ arguments.

These two things together should then mean that the main Party class from the party module is registered first, and then your customization of the Party class is registered afterwards.

hey @dave,

Humm I get you :wink:

Or maybe I can raise a UserError every time a user saves a party without a name? Can I do this? What do you think?

Yes indeed. Following coopengo tryton-training tutorial, I could understand how Tryton works on that.

Not really different than adding a required=True. I think we could help you if you could explain exactly the requirement.

I thought the problem was about adding required=True, because this would set an SQL database restriction. And raising a UserError would just throw an error without making an SQL database restriction.

The reason I have to make some fields required is the fact that I have to export data from Tryton to an XML file to create the SAF-T file to send to the Angolan financial institution. If some of the fields are empty, the file would be invalid and the authority systems will not accept the file.
For example, one of the documents that Tryton should export to this XML SAF-T file is the list of all invoices with specific information about each invoice. If some party in one invoice does not have a name, the system will not accept the file because the XML file will not be valid according to its XSD file.

So what I thought of doing was enforcing the user to fill all the required SAF-T XML file making all those fields required. Thus, forcing the user to fill the field to be able to save.

For me, you must not make all parties name required but only check that the party of posted invoices have a name filled. Also this check should be performed only for companies that need (or are configured) to export such file.
It is always a bad idea to add constraint about other models in a custom module because as I said this can break other workflows. Then the best is to put the constraint only at the place where we know it will have the lower impact.

Hey @noosanon!

Yes :+1:, and from experience, if you accidentally forget to do either of these things (or forget to activate your module :crazy_face:) then:

Hey @ced and @dave,

Yeah, it seems the best place to put all restrictions, because this file is all about posted and paid invoices.

What do you mean with this? Should parties, for example, have a field in which users can configure if the party is to be included in the SAF-T XML file?

Humm got it :wink:
But is there a way to enforce a must fill field at client side only and not influence the database without disturbing the workflow of other modules? Something that happens at the client side only and do not affect the server side. I say this because sometimes some users may not have privileges to access some fields that are required and thus they cannot change it. If we could have a way to warn users that certain fields must be filled would be great because it would be like a guidance to fill a form.

Actually, the problem was exactly that. Lol, I forgot to include Party in the __init__.py file. However, have I not created this topic I would create all required fields as required=True, which is not the best practice lol :wink:

I mean that the module could be activated on a multi-company system for example. And not all those companies would need this constraint.

No we do not accept such thing because it could block a user to edit such “user-invalid” form.

That’s one more reason to limit usage of requirement.

Not all parties in the system will be exported to the SAF-T XML file, just the parties in the invoices to be exported. So each company will have a different SAF-T XML file according to the its invoices.

Let’s say we have an invoice ready to be posted. When some user with all account module privileges tries to post the invoice, if the user who’s responsible for creating parties has not given a name to the invoice party, the system will not allow him to post the invoice because the party has no name. Thus, the party must be edited by other people and not the account user because (s)he does not have the right privileges. This would create delays in the workflow just because the party name is not filled, not to say other not so obvious but important fields.
IMO, what the account user expects is that all the information needed to post the invoice is completely filled and ready to be posted.