Publication de mon mémoire de fin d’étude sur OpenERP

Bonjour à tous,

Cela fait quelques temps que j’avais promis de le faire mais sans jamais trouver le temps jusque là.

Je met aujourd’hui à disposition le mémoire de fin d’étude que j’ai présenté à mon école SUPINFO en octobre dernier. On peut dire que ce document est en quelque sorte le résumé et la conclusion de cette aventure entreprenariale qu’à pour moi représenté SYNERPGY.

J’y résume notamment pourquoi j’avais choisi à l’époque de me tourner vers OpenERP, les pièges à éviter quand on veut faire de l’intégration OpenERP (que j’ai souvent découvert à la dure) et enfin quelques recommandations pour l’avenir.

Ce document est sous licence Creative Common by-sa, c’est à dire que votre seule obligation est de ne pas changer la licence et de citer mon nom comme auteur du document. Pour le reste, vous pouvez vous en servir, le modifier etc… Au contraire, cela sera pour moi un plaisir que ce document soit repris dans d’autres circonstances.

Enfin, je précise que cela représentais mon opinion en septembre dernier. J’ai encore beaucoup évolué dans ma réflexion, notamment au niveau de la méthodologie qui est désormais beaucoup moins théorique (Je publierais la nouvelle version dès que j’en aurais l’occasion).
Merci donc de prendre simplement ce document comme une piste de réflexion et non comme forcément représentatif de mon opinion actuel (même si la grande majorité reste bien entendu d’actualité).

You can download it here : https://drive.google.com/file/d/0BwdMYBR15LiXejFxMnhLUHRSNUtDN0JCQ2M4N0hZUQ/view?usp=sharing

Enfin, j’en profite pour glisser un mot vu que la conclusion du mémoire porte dessus : Je prévois toujours de lancer, au moins en France, un site généraliste qui tenterai de centraliser les besoins en ERP de chaque secteur d’activité sur un site internet, pour ensuite comparer les ERPs du marché en fonction de ces besoins.
Comme je le marque en conclusion, le logiciel libre a besoin d’être précisément comparé aux alternatives propriétaires (de manière impartiale, précisons le) pour générer de la dynamique. Ce projet de site internet sera donc à la fois pour soutenir le libre et pour apporter un puissant outil de comparaisons aux utilisateurs.

Le projet est déjà défini, il ressemblera beaucoup au site openerp-universe.org que j’avais lancé l’année dernière. Il ne reste pour ainsi dire qu’à se mettre au travail, mais j’attend néanmoins si possible d’avoir la chance de convaincre quelques associations professionnelles d’adhérer au projet, leur soutien sera indispensable.

Si vous êtes intéressé par ce projet et souhaitez me donner un coup de main, n’hésitez pas à me contacter :), cela pourrait accélérer les choses.

———————————————————————-

Edit :
Après avoir reçu un petit mail de la part de Fabien, je pense qu’il convient de rétablir certaines vérités vis à vis de ma position à l’encontre de l’éditeur : Je suis désormais beaucoup moins à charge contre eux que je ne l’étais en septembre dernier, date de la rédaction du mémoire.

Même si mon avis sur l’éditeur ne représente qu’une petite partie du mémoire, je pense qu’il convient de leur rendre justice aussi je vous propose à la suite de ce billet le mail de réponse que j’ai envoyé à Fabien :

Bonjour Fabien, je te remercie d’avoir pris le temps de me faire parvenir tes remarques.

Avant toute chose, je précise que ma position vis-à-vis de l’éditeur a quand même pas mal évolué depuis septembre, date de la rédaction du mémoire, et dans l’ensemble effectivement on sent de l’amélioration. Mais j’avais promis de publier le mémoire, malheuresement sans avoir le temps de nuancer certaines parties pour refléter ma position actuelle. Je le précise d’ailleurs dans le billet : “Merci donc de prendre simplement ce document comme une piste de réflexion et non comme forcément représentatif de mon opinion actuelle”
Je ne te cache pas qu’en plus, le fait que la partie où j’analyse l’écosystème OpenERP étant situé à la fin du mémoire et avec la fatigue qui va avec, ceci ne m’a pas vraiment aidé à rester objectif.

Quelques remarques en vrac avant de commencer :

-Avoir le copyright sur le code noyau, tant que vous acceptez les merge proposal même avec copyright assignment, n’est pas sujet à critique selon moi. Ce qui le serait, et qui était ma crainte à l’époque, était que vous n’intégriez pas des modules complets et fonctionnels dans la branche addons simplement car vous n’en seriez pas l’auteur.

-Concernant la vitesse de traitement des bugs je suis désormais d’accord. Selon l’opinion générale, après des débuts parfois un peu difficile, il semble clair qu’aujourd’hui les processus au niveau du traitement des bugs sont désormais beaucoup plus efficaces.

-Sur la nécessité d’un organisme qui coordonne la communauté, où tu donne pour contre-exemple ce qui arrive actuellement à Drupal (que j’aime beaucoup d’ailleurs), je suis assez d’accord. Il semblerait qu’un tel organisme soit nécessaire, que ce soit un éditeur comme dans notre cas ou d’une fondation comme pour Linux ou Mozilla.

-Concernant l’exemple de PowerEmail que je donne dans mon mémoire, merci pour les explications. Je me garderai bien sûr de tout jugement, et me contenterai juste de noter avec satisfaction que le nom d’OpenLabs est bien présent sur l’actuel module email_template, ce qui remplit selon moi le contrat moral.
Après la seule question, c’est est-ce qu’il serait là s’il l’auteur n’avait pas tapé du poing sur la table à l’époque, mais cela je ne le saurais jamais et c’est aussi bien comme cela. L’essentiel c’est l’avenir.

-Je reconnais que par le passé, le temps de review des contributions était clairement plus dû à un manque de moyen que d’une politique de l’éditeur. Si je l’évoque dans mon mémoire, c’était plutôt dans l’objectif que cela ne devienne pas une politique de l’éditeur.

Concernant la prétendue volonté de l’éditeur de vouloir tout contrôler :

Lorsque j’ai écrit cette partie, j’avais en tête plusieurs choses :
-Le fait que sur quasiment tous les modules officiels à l’époque, seul le nom OpenERP était visible. Ceci donnait vraiment l’impression qu’OpenERP SA voulait que tout ce qui était certifié soit au nom d’OpenERP SA, et que les autres modules communautaires soient relégués dans les extra-addons.
Soyons clair, j’ai toujours eu confiance dans OpenERP SA (j’y reviens plus tard) mais quand je faisais cette analyse je me suis basé sur le pire scénario, que ce serait-il passé si la stratégie d’OpenERP SA était vraiment de vouloir à tout prix garder le contrôle sur la licence? Pas forcément en ayant de mauvaises intentions, mais même simplement pour pouvoir faire des ajustements à l’avenir. Et bien cela entrainerait forcément de mettre à l’écart certaines contributions de la communauté ce contre quoi je souhaitais lutter. C’est pour lutter contre ce potentiel scénario que j’ai présenté les choses sous cet angle.

-A cette période également, on avait eu quelques mois auparavant le changement de licence pour l’AGPL + exception (que je n’avais pas forcément mal accueilli comme tu le sais) mais qui avait aussi semble t’il provoqué de la réécriture d’une large partie du code juste pour contourner le copyright. Quelqu’en soient les raisons, même des très bonnes raisons et là je n’en sais rien, une réécriture de code unilatérale pour des raisons de licence aura toujours une mauvaise image.
J’avais également en tête les quelques scandales, justifiés ou non, comme PowerEmail, les commerciaux au Brésil, le départ du projet Medical etc… C’est pour tout cela, même si principalement par principe de précaution, que j’ai choisi à l’époque de partir sur le scénario “éditeur open-source, mais qui n’intègre pas toutes les contributions uniquement pour des raisons de licences”. J’avais tout simplement des craintes que j’estimais légitimes à l’époque.

Je précise également que je suis très loin d’être complètement à charge contre OpenERP SA dans mon mémoire. Je précise de nombreuses fois que vous êtes parmi les très rares dans les éditeurs de logiciels libres à destination des entreprises à ne pas être parti sur un modèle de double licence.
C’est très important pour moi, car tout spécialement dans le secteur des ERPs qui ne finira jamais de progresser, l’intégration des contributions de la communauté est capitale pour la compétitivité du logiciel à long terme. Cette dynamique serait complètement détruite en cas de double licence, et c’est pas pour rien que ceux qui ont tenté de faire un ERP en double licence sont aujourd’hui en difficulté.
Je pense que cela vous l’avez parfaitement compris. Je dirais même que vous avez fait preuve d’un véritable acharnement à éviter à tout prix ce modèle, testant modèle économique sur modèle économique (intégration pour démarrer, certification de module, SaaS, contrat de maintenance, partenariats etc etc…).

Je le dit sans arrière-pensée, vous êtes un vrai éditeur du libre, non un simple éditeur open-source. C’est pour cela que je soutiens toujours OpenERP.

Mais votre rôle est difficile, il est facile de faire des erreurs ou d’avoir à faire des mauvais choix pour le produit qui sont des bons choix pour la société. C’est pas forcément une mauvaise chose, vous devez survivre, mais il faut que des personnes dans la communauté soient vigilantes et jouent le rôle de contre-pouvoir si nécessaire car il faut des personnes qui soient là pour le produit (et les utilisateurs) et qui n’ont pas d’autres préoccupations.
J’espère faire parti de ces personnes, mais même si je suis intransigeant avec ce que j’estime être contre l’intérêt du produit (ex : les migrations, que j’estime contre l’intérêt du produit à long terme, mais qui vous a clairement permis de trouver un modèle économique stable à court terme) et que j’émets parfois des mises en garde, le fait que je sois sur OpenERP prouvera toujours que je soutiens OpenERP SA. Le jour où quelqu’un comme moi ne le fera plus, là vous pourrez commencer à vous inquiéter.

Cela étant dit et posé, maintenant que voyons-nous?

Dans la 6.1, sur les quelques 160 modules certifiés (j’entend par là, présents dans la branche “addons” et non “extra-addons”), une vingtaine sont des modules qui n’ont pas pour auteur OpenERP SA.
Dans les quelques échanges que j’ai eu avec d’autres partenaires, j’entend désormais beaucoup de “C’est mieux qu’avant quand même, les contributions sont intégrées plus facilement”.
Enfin moi-même, au moment où je travaillais sur la paye française (qu’il faut que je termine d’ailleurs…) j’ai bien senti que la dynamique propre à la contribution était bel et bien là, je n’avais aucun reproche à faire.

Je me permettrais juste une question : Les modules certifiés, donc présent dans la branche “addons” et dans l’installation de base d’OpenERP, peuvent être en simple AGPLv3 ou doivent être en AGPLv3+exception? Le cas échéant, cela signifierais que vous rejeteriez les contributions qui ne sont pas conforme à votre licence, ce qui ferai revenir en quelques sortes mes craintes.

En dehors de cela, il est désormais évident que mes craintes de l’époque ne sont plus justifiées, en tout cas pour le moment. Aujourd’hui, vous montrez bel et bien que pour vous l’intérêt du produit passe avant la licence.

J’avais tort de m’inquiéter à l’époque, et ce n’est là qu’une raison de me réjouir .

Je vais mettre de bon cœur ce message (sans citer ton mail) à la suite du billet de sorte à contrebalancer le contenu du mémoire sur les points évoqués.
L’analyse de l’écosystème d’OpenERP n’était qu’une partie du mémoire, je pense que ce message permettra de corriger ce qui n’est aujourd’hui plus d’actualité. Merci de m’avoir donné cette chance en pointant les points sujets à critique.

Pour le reste, je pense que ce ne sera pas la dernière fois que tu liras des critiques sur OpenERP SA sur mon blog, de même que ce ne sera pas la dernière fois que tu pourras retweet un billet en faisant l’éloge . Toujours dans un seul objectif : Qu’un jour, un ERP libre soit leader sur le marché, avec toutes les conséquences que cela entrainera sur le tissu économique en lui-même.

Bien cordialement,
Yannick.

A lack of seriousness in the framework evolution for some time?

Hi everyone,

It’s been a while since I didn’t post here. Since last summer period has been very busy for me because of the end of my studies and various works.

As some of you have heard me say, I claim to be a “functional consultant”, that is to say:

-Able to understand and gather the needs of the user company
-With this understanding and that of the main modules of OpenERP, I’m supposed to find the most sustainable way to develop a feature before sending the specification to the development.
-I am able to do basic developments, such as adding a new field, adapting a view, a right access, correct translation …. Anything that is supported by the framework as it is supposed to manage the most common needs of the ERPs. This allows to submit the interface to the customer early in the project which is a highly effective asset to save time on the project.
-I am not able to make pure Python development. I am still able to read and sometimes make minor corrections.

Why I am making this definition of functional consultant? Because I think anyone who has business expertise, can become a functional consultant on OpenERP, it will just take time.

This is possible because from the beginning, OpenERP has established the framework OpenObject that manages database objects, menus, views, access rights, etc. … Making feasible to just anyone to make key changes on the ERP’s process. This has always been the main strengh of OpenERP! Ease of access to code features

Ok Yannick, we already know all this, what do you mean?

I mean that I feel since the relocation of development teams in India this spirit has greatly lost.

I’ll show you an example that I was literally stunned the day I saw that, without finding the time to talk about it before today.
Here is the code for the statistical analysis of invoices:

def init(self, cr):
        tools.drop_view_if_exists(cr, 'account_invoice_report')
        cr.execute("""
            create or replace view account_invoice_report as (
                 select min(ail.id) as id,
                    ai.date_invoice as date,
                    to_char(ai.date_invoice, 'YYYY') as year,
                    to_char(ai.date_invoice, 'MM') as month,
                    to_char(ai.date_invoice, 'YYYY-MM-DD') as day,
                    ail.product_id,
                    ai.partner_id as partner_id,
                    ai.payment_term as payment_term,
                    ai.period_id as period_id,
                    (case when u.uom_type not in ('reference') then
                        (select name from product_uom where uom_type='reference' and active and category_id=u.category_id LIMIT 1)
                    else
                        u.name
                    end) as uom_name,
                    ai.currency_id as currency_id,
                    ai.journal_id as journal_id,
                    ai.fiscal_position as fiscal_position,
                    ai.user_id as user_id,
                    ai.company_id as company_id,
                    count(ail.*) as nbr,
                    ai.type as type,
                    ai.state,
                    pt.categ_id,
                    ai.date_due as date_due,
                    ai.address_contact_id as address_contact_id,
                    ai.address_invoice_id as address_invoice_id,
                    ai.account_id as account_id,
                    ai.partner_bank_id as partner_bank_id,
                    sum(case when ai.type in ('out_refund','in_invoice') then
                         ail.quantity / u.factor * -1
                        else
                         ail.quantity / u.factor
                        end) as product_qty,
                    sum(case when ai.type in ('out_refund','in_invoice') then
                         ail.quantity*ail.price_unit * -1
                        else
                         ail.quantity*ail.price_unit
                        end) / cr.rate as price_total,
                    sum(case when ai.type in ('out_refund','in_invoice') then
                         ai.amount_total * -1
                        else
                         ai.amount_total
                         end) / (CASE WHEN
                              (select count(l.id) from account_invoice_line as l
                               left join account_invoice as a ON (a.id=l.invoice_id)
                               where a.id=ai.id) <> 0
                            THEN
                              (select count(l.id) from account_invoice_line as l
                               left join account_invoice as a ON (a.id=l.invoice_id)
                               where a.id=ai.id)
                            ELSE 1
                            END) / cr.rate as price_total_tax,
                    (case when ai.type in ('out_refund','in_invoice') then
                      sum(ail.quantity*ail.price_unit*-1)
                    else
                      sum(ail.quantity*ail.price_unit)
                    end) / (CASE WHEN
                         (case when ai.type in ('out_refund','in_invoice')
                          then sum(ail.quantity/u.factor*-1)
                          else sum(ail.quantity/u.factor) end) <> 0
                       THEN
                         (case when ai.type in ('out_refund','in_invoice')
                          then sum(ail.quantity/u.factor*-1)
                          else sum(ail.quantity/u.factor) end)
                       ELSE 1
                       END)
                     / cr.rate as price_average,

                    cr.rate as currency_rate,
                    sum((select extract(epoch from avg(date_trunc('day',aml.date_created)-date_trunc('day',l.create_date)))/(24*60*60)::decimal(16,2)
                        from account_move_line as aml
                        left join account_invoice as a ON (a.move_id=aml.move_id)
                        left join account_invoice_line as l ON (a.id=l.invoice_id)
                        where a.id=ai.id)) as delay_to_pay,
                    sum((select extract(epoch from avg(date_trunc('day',a.date_due)-date_trunc('day',a.date_invoice)))/(24*60*60)::decimal(16,2)
                        from account_move_line as aml
                        left join account_invoice as a ON (a.move_id=aml.move_id)
                        left join account_invoice_line as l ON (a.id=l.invoice_id)
                        where a.id=ai.id)) as due_delay,
                    (case when ai.type in ('out_refund','in_invoice') then
                      ai.residual * -1
                    else
                      ai.residual
                    end)/ (CASE WHEN
                        (select count(l.id) from account_invoice_line as l
                         left join account_invoice as a ON (a.id=l.invoice_id)
                         where a.id=ai.id) <> 0
                       THEN
                        (select count(l.id) from account_invoice_line as l
                         left join account_invoice as a ON (a.id=l.invoice_id)
                         where a.id=ai.id)
                       ELSE 1
                       END) / cr.rate as residual
                from account_invoice_line as ail
                left join account_invoice as ai ON (ai.id=ail.invoice_id)
                left join product_template pt on (pt.id=ail.product_id)
                left join product_uom u on (u.id=ail.uos_id),
                res_currency_rate cr
                where cr.id in (select id from res_currency_rate cr2  where (cr2.currency_id = ai.currency_id)
                and ((ai.date_invoice is not null and cr.name <= ai.date_invoice) or (ai.date_invoice is null and cr.name <= NOW())) limit 1)
                group by ail.product_id,
                    ai.date_invoice,
                    ai.id,
                    cr.rate,
                    to_char(ai.date_invoice, 'YYYY'),
                    to_char(ai.date_invoice, 'MM'),
                    to_char(ai.date_invoice, 'YYYY-MM-DD'),
                    ai.partner_id,
                    ai.payment_term,
                    ai.period_id,
                    u.name,
                    ai.currency_id,
                    ai.journal_id,
                    ai.fiscal_position,
                    ai.user_id,
                    ai.company_id,
                    ai.type,
                    ai.state,
                    pt.categ_id,
                    ai.date_due,
                    ai.address_contact_id,
                    ai.address_invoice_id,
                    ai.account_id,
                    ai.partner_bank_id,
                    ai.residual,
                    ai.amount_total,
                    u.uom_type,
                    u.category_id
            )
        """)

134 lines of pure SQL query, just to create a statistical analysis …

Ok then it may be necessary, but it is in the framework we should find this code, not in one of the functional modules! Here we should just tell him that’s the name of the object, these are the fields to be analyzed and go on. I do not recognize any of the OpenERP code usually ultra-simple, this code just look like it was done without any forethought.What effect? What happen if me, a simple functional consultant,  I just want to add an additional field to analyze? Or create a new statistical analysis on another object?  I can’t, and so I have to send this to developers who will rewrite theses 134lines (which is a problem even worse, I come back).In recent years it seems there was no serious efforts in the framework improvement. Ok then I support 300% web client, payroll and even the POS. But I begin to see big problems in the future for OpenERP that could collapse on its foundation, that is to say the framework.

To be clear, I’m not saying that OpenERP is poorly written, it is not “pythonic” or another. I do not have the skills for that and others are already doing it (dedication to the Tryton people which I am sure must enjoy this post …).
What I mean is that the functional should be able to change a lot more features than now on OpenERP.

What happens when one places an order from one status to another, such as sending an email, can add a module in a configuration wizard, or transfer the value of the field that you just created in sale.order to his account.invoice etc. …
There are still lots of things we can do, manage by OpenObject even more prominent roles in the ERP so we limit the amount of Python code to a minimum.

Moreover, I think this will be a good way to limit the amount of code that is laid each day by the Indian teams. I am sorry to say this but a lot of places I sometimes feel, pardon the expression, they just “pissed code” as if they were paid to the line. I am very concerned that this is a big risk and that eventually we could  no longer maintain the software later.
Crop development teams in OpenObject developments is probably the easier way to make sure there is only one way to make the work done, the simpliest and the better. This will eventually be able to more easily maintain the software or especially deep module redesign.

And moreover for some features they are already managed by OpenObject. For example creating a new invoice with the values ​​of a purchase order via ir.actions.server. Unfortunately, as certified module not use it, nobody uses these features …

In short, let me be clear on what I suggest: First, rewrite all the modules so they use ir.actions.server or an equivalent system. Then continue to improve the framework until the Python code in the modules is reduced to a minimum.

I am sure that most readers will rebel against this idea, too much work, you should leave some functions in python to have more flexibility etc. … No worries, I just try to start the debate and I  just hope it will lead to interesting conclusions.

I would however point the finger on one last problem, I think the worst, and that can be solved just by extending features of OpenObject.

Take a Partner A highly experienced and top contributors. He developed a module that is widely used by other community members.

In his module, he created a field in X and sale.order account.invoice, and he made sure that its value is passed to its sale.order account.invoice.

Here is the code he had to do:

    def _make_invoice(self, cr, uid, order, lines, context=None):
        journal_obj = self.pool.get('account.journal')
        inv_obj = self.pool.get('account.invoice')
        obj_invoice_line = self.pool.get('account.invoice.line')
        if context is None:
            context = {}

        journal_ids = journal_obj.search(cr, uid, [('type', '=', 'sale'), ('company_id', '=', order.company_id.id)], limit=1)
        if not journal_ids:
            raise osv.except_osv(_('Error !'),
                _('There is no sales journal defined for this company: "%s" (id:%d)') % (order.company_id.name, order.company_id.id))
        a = order.partner_id.property_account_receivable.id
        pay_term = order.payment_term and order.payment_term.id or False
        invoiced_sale_line_ids = self.pool.get('sale.order.line').search(cr, uid, [('order_id', '=', order.id), ('invoiced', '=', True)], context=context)
        from_line_invoice_ids = []
        for invoiced_sale_line_id in self.pool.get('sale.order.line').browse(cr, uid, invoiced_sale_line_ids, context=context):
            for invoice_line_id in invoiced_sale_line_id.invoice_lines:
                if invoice_line_id.invoice_id.id not in from_line_invoice_ids:
                    from_line_invoice_ids.append(invoice_line_id.invoice_id.id)
        for preinv in order.invoice_ids:
            if preinv.state not in ('cancel',) and preinv.id not in from_line_invoice_ids:
                for preline in preinv.invoice_line:
                    inv_line_id = obj_invoice_line.copy(cr, uid, preline.id, {'invoice_id': False, 'price_unit': -preline.price_unit})
                    lines.append(inv_line_id)
        inv = {
            'name': order.client_order_ref or '',
            'origin': order.name,
            'type': 'out_invoice',
            'reference': order.client_order_ref or order.name,
            'account_id': a,
            'partner_id': order.partner_id.id,
            'journal_id': journal_ids[0],
            'address_invoice_id': order.partner_invoice_id.id,
            'address_contact_id': order.partner_order_id.id,
            'invoice_line': [(6, 0, lines)],
            'currency_id': order.pricelist_id.currency_id.id,
            'comment': order.note,
            'payment_term': pay_term,
            'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
            'date_invoice': context.get('date_invoice',False),
            'company_id': order.company_id.id,
            'user_id': order.user_id and order.user_id.id or False,
            'champ_x': order.champ_x
        }
        inv.update(self._inv_get(cr, uid, order))
        inv_id = inv_obj.create(cr, uid, inv, context=context)
        data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], pay_term, time.strftime('%Y-%m-%d'))
        if data.get('value', False):
            inv_obj.write(cr, uid, [inv_id], data['value'], context=context)
        inv_obj.button_compute(cr, uid, [inv_id])
        return inv_id
50 lines, when in fact the only line that he really coded is in red here. And yet we were lucky, the original function could have been much longer.
As it is not possible via the module to insert the code directly, he had to copy and paste the entire function to add this little line.And the real problem happens. No chance the OpenERP devs change after the original function and other functions elsewhere, so that the former causes a bug now. Our partner A must now repeat the copy and paste of the original function if it does not want his module to be considered buggy.This forces our partner to monitor all its modules, just to check that OpenERP SA didn’t modify the original function. And since the functions are becoming longer, the risk of the bugs are all the more. Finally, the ultimate case, imagine if a partner created a module B that inherits from the function module A … What I mean by that is that it is the entire ecosystem of community modules that is unstable due to this overuse of Python functions that are not AT ALL suitable for a modular system as OpenERP.

I think we’re right into it today, we see that more and more quality modules arrive on OpenERP, but they are buggy as soon as OpenERP SA made changes in the functions of certified modules, which themselves become increasingly long and complex.

We must at all costs find another solution for module developers to avoid having to copy the original function when they just want to add some details as a field to be transferred. And for me the only viable solution, as it is clear that we can not do that directly in the Python code, is to extend the OpenObject capabilities.

Thank you for taking the reading. I express my personal conviction, which is somewhat isolated. I am not a developer, so if I may say big shit, please tell me in comments.

Un manque de sérieux dans l’évolution du framework depuis quelque temps ?

Bonjour à tous,

Cela fait un moment que je n’avais pas posté de billet. Depuis l’été dernier la période a été très chargée pour moi du fait de la fin de mes études et de divers travaux sur lesquels j’aurais j’espère l’occasion de revenir plus tard.

Comme certains d’entre vous me l’ont déjà entendu dire, je me réclame d’être un « consultant fonctionnel », c’est-à-dire :

-Capable de comprendre et recueillir les besoins de l’entreprise utilisatrice
-Fort de cette compréhension et de celle des principaux modules d’OpenERP, je suis censé trouver la manière la plus pérenne pour développer une fonctionnalité et la modéliser avant d’envoyer en développement.
-Je suis capable de faire des développements basiques, comme rajouter un nouveau champ, adapter une vue, un droit d’accès, corriger une traduction…. Bref tout ce qui est pris en charge par le framework car celui-ci est censé gérer les besoins les plus courants de l’ERPs. Cela permet de soumettre l’interface au client dès le début du projet ce qui est un atout extrêmement efficace pour gagner du temps sur le projet.
-Je ne suis pas capable de faire du pur développement python. Je suis néanmoins capable de le lire et de faire parfois quelques corrections mineures.

Pourquoi je présente cette définition du consultant fonctionnel ? Car je pense que n’importe qui, qui a une expertise métier, peut devenir un consultant fonctionnel sur OpenERP, cela prendra juste du temps et au final vous ne serez bloqué que par les développements pointus.

C’est possible car depuis le départ, OpenERP a mis en place le framework OpenObject qui gère les objets en base de donnée, les menus, les vues, les droits d’accès, etc… Rendant pratiquement possible au premier venu de faire des modifications majeures sur le fonctionnement de l’ERP. Cela a toujours été la principale force d’OpenERP ! Sa simplicité d’accès au code des fonctionnalités

Ok Yannick, on sait déjà tout ça, où veux-tu en venir ?

Je veux en venir que j’ai l’impression que depuis la délocalisation des équipes de développements en Inde cet esprit s’est fortement perdu.

Je vais vous montrer un exemple qui m’avait littéralement assommé le jour où j’ai vu ça, sans trouver le temps avant aujourd’hui d’en parler.
Voici le code pour l’analyse statistique des factures :

def init(self, cr):
        tools.drop_view_if_exists(cr, 'account_invoice_report')
        cr.execute("""
            create or replace view account_invoice_report as (
                 select min(ail.id) as id,
                    ai.date_invoice as date,
                    to_char(ai.date_invoice, 'YYYY') as year,
                    to_char(ai.date_invoice, 'MM') as month,
                    to_char(ai.date_invoice, 'YYYY-MM-DD') as day,
                    ail.product_id,
                    ai.partner_id as partner_id,
                    ai.payment_term as payment_term,
                    ai.period_id as period_id,
                    (case when u.uom_type not in ('reference') then
                        (select name from product_uom where uom_type='reference' and active and category_id=u.category_id LIMIT 1)
                    else
                        u.name
                    end) as uom_name,
                    ai.currency_id as currency_id,
                    ai.journal_id as journal_id,
                    ai.fiscal_position as fiscal_position,
                    ai.user_id as user_id,
                    ai.company_id as company_id,
                    count(ail.*) as nbr,
                    ai.type as type,
                    ai.state,
                    pt.categ_id,
                    ai.date_due as date_due,
                    ai.address_contact_id as address_contact_id,
                    ai.address_invoice_id as address_invoice_id,
                    ai.account_id as account_id,
                    ai.partner_bank_id as partner_bank_id,
                    sum(case when ai.type in ('out_refund','in_invoice') then
                         ail.quantity / u.factor * -1
                        else
                         ail.quantity / u.factor
                        end) as product_qty,
                    sum(case when ai.type in ('out_refund','in_invoice') then
                         ail.quantity*ail.price_unit * -1
                        else
                         ail.quantity*ail.price_unit
                        end) / cr.rate as price_total,
                    sum(case when ai.type in ('out_refund','in_invoice') then
                         ai.amount_total * -1
                        else
                         ai.amount_total
                         end) / (CASE WHEN
                              (select count(l.id) from account_invoice_line as l
                               left join account_invoice as a ON (a.id=l.invoice_id)
                               where a.id=ai.id) <> 0
                            THEN
                              (select count(l.id) from account_invoice_line as l
                               left join account_invoice as a ON (a.id=l.invoice_id)
                               where a.id=ai.id)
                            ELSE 1
                            END) / cr.rate as price_total_tax,
                    (case when ai.type in ('out_refund','in_invoice') then
                      sum(ail.quantity*ail.price_unit*-1)
                    else
                      sum(ail.quantity*ail.price_unit)
                    end) / (CASE WHEN
                         (case when ai.type in ('out_refund','in_invoice')
                          then sum(ail.quantity/u.factor*-1)
                          else sum(ail.quantity/u.factor) end) <> 0
                       THEN
                         (case when ai.type in ('out_refund','in_invoice')
                          then sum(ail.quantity/u.factor*-1)
                          else sum(ail.quantity/u.factor) end)
                       ELSE 1
                       END)
                     / cr.rate as price_average,

                    cr.rate as currency_rate,
                    sum((select extract(epoch from avg(date_trunc('day',aml.date_created)-date_trunc('day',l.create_date)))/(24*60*60)::decimal(16,2)
                        from account_move_line as aml
                        left join account_invoice as a ON (a.move_id=aml.move_id)
                        left join account_invoice_line as l ON (a.id=l.invoice_id)
                        where a.id=ai.id)) as delay_to_pay,
                    sum((select extract(epoch from avg(date_trunc('day',a.date_due)-date_trunc('day',a.date_invoice)))/(24*60*60)::decimal(16,2)
                        from account_move_line as aml
                        left join account_invoice as a ON (a.move_id=aml.move_id)
                        left join account_invoice_line as l ON (a.id=l.invoice_id)
                        where a.id=ai.id)) as due_delay,
                    (case when ai.type in ('out_refund','in_invoice') then
                      ai.residual * -1
                    else
                      ai.residual
                    end)/ (CASE WHEN
                        (select count(l.id) from account_invoice_line as l
                         left join account_invoice as a ON (a.id=l.invoice_id)
                         where a.id=ai.id) <> 0
                       THEN
                        (select count(l.id) from account_invoice_line as l
                         left join account_invoice as a ON (a.id=l.invoice_id)
                         where a.id=ai.id)
                       ELSE 1
                       END) / cr.rate as residual
                from account_invoice_line as ail
                left join account_invoice as ai ON (ai.id=ail.invoice_id)
                left join product_template pt on (pt.id=ail.product_id)
                left join product_uom u on (u.id=ail.uos_id),
                res_currency_rate cr
                where cr.id in (select id from res_currency_rate cr2  where (cr2.currency_id = ai.currency_id)
                and ((ai.date_invoice is not null and cr.name <= ai.date_invoice) or (ai.date_invoice is null and cr.name <= NOW())) limit 1)
                group by ail.product_id,
                    ai.date_invoice,
                    ai.id,
                    cr.rate,
                    to_char(ai.date_invoice, 'YYYY'),
                    to_char(ai.date_invoice, 'MM'),
                    to_char(ai.date_invoice, 'YYYY-MM-DD'),
                    ai.partner_id,
                    ai.payment_term,
                    ai.period_id,
                    u.name,
                    ai.currency_id,
                    ai.journal_id,
                    ai.fiscal_position,
                    ai.user_id,
                    ai.company_id,
                    ai.type,
                    ai.state,
                    pt.categ_id,
                    ai.date_due,
                    ai.address_contact_id,
                    ai.address_invoice_id,
                    ai.account_id,
                    ai.partner_bank_id,
                    ai.residual,
                    ai.amount_total,
                    u.uom_type,
                    u.category_id
            )
        """)

134 lignes d’une pure requête SQL, juste pour créer une analyse statistique…
Alors ok c’est peut-être nécessaire, mais c’est dans le framework qu’on devrait retrouver ce code, pas dans l’un des modules fonctionnels ! Là on devrait juste lui dire voilà le nom de l’objet, voilà les champs à analyser et débrouille toi. Je ne reconnais pas du tout le code habituellement ultra-simple d’OpenERP dans ces 134 lignes, juste du code fait sans aucune réflexion préalable.

Quelle conséquence ? Moi, simple consultant fonctionnel, que ce passe-t il si je veux simplement rajouter un champ supplémentaire à analyser ? Ou créer une nouvelle analyse statistique sur un autre objet ? Ben je peux pas, obligé d’envoyer au développeurs qui vont me réécrire les 134lignes (ce qui pose un problème encore pire, j’y reviens).

Depuis quelques années, on constate qu’il n’y a plus de gros efforts au niveau du framework. Alors ok je soutiens à 300% le client web, la paye et encore plus le POS. Mais je commence à entrevoir de gros problèmes à l’avenir pour OpenERP qui risque de s’effondrer sur ses fondations, c’est-à-dire le framework.

Soyons clair, je ne suis pas en train de dire que OpenERP est mal codé, qu’il est pas « pythonic » ou autre. Je n’ai pas les compétences en développement pour ça et d’autres s’en chargent (dédicace aux gens de Tryton qui j’en suis sûr doivent se régaler avec ce billet…).
Ce que je veux dire c’est que les fonctionnels devraient pouvoir modifier encore beaucoup plus de fonctionnalités sur OpenERP que maintenant.

Ce qui se passe quand on passe une commande d’un statut à un autre, comme envoyer un mail, rajouter un module possible dans un wizard de configuration, ou encore transférer la valeur du champ qu’on vient de créer dans sale.order à son account.invoice etc…
Il y a encore plein de choses que nous pouvons faire, faire gérer  par OpenObject  encore plus de fonctions récurrentes dans les ERPs jusqu’à finir par limiter la part de code Python au strict minimum.

Qui plus est, cela sera je pense un bon moyen de limiter la quantité de code qui est pondu chaque jour par les équipes indiennes. Je suis désolé de dire ça mais à pas mal d’endroits j’ai parfois l’impression, pardonnez-moi l’expression, qu’ils ont juste « pissé du code » comme si ils étaient payé à la ligne. Je crains fortement que cela ne fasse courir un risque et qu’à terme on n’arrive plus à maintenir le logiciel.
Cadrer les équipes de développeurs dans OpenObject pour les développements les plus courants fera qu’ils n’auront qu’une manière de développer la fonctionnalité et qui sera la manière la plus simple. Cela permettra par la suite de pouvoir bien plus facilement maintenir le logiciel ou surtout refondre en profondeur un module (et cela arrivera pour certains, on peut en être sûr, on sera de plus en plus exigeant avec OpenERP au fur et à mesure que sa popularité grandit).

Et le pire c’est que pour certaines fonctionnalités elles sont déjà gérées par OpenObject. Par exemple la création d’une nouvelle facture avec les valeurs d’un bon de commande via ir.actions.server; mais comme dans les modules certifiés on ne l’utilise pas, personne n’utilise ces fonctionnalités…

Bref, je vais être clair sur ce que je propose : Dans un premier temps, il faut réécrire tous les modules certifiés pour qu’ils utilisent ir.actions.server ou utiliser un système équivalent. Ensuite continuer à améliorer le framework jusqu’à ce que le code Python dans les modules soit réduit au strict minimum.

Je suis certain que la majorité des lecteurs vont s’insurger contre cette idée, trop de travail, il vaut mieux laisser certaines fonctions en python pour avoir plus de flexibilité etc…  Pas de soucis, j’essaie juste de lancer le débat et j’espère juste qu’il va aboutir à des conclusions intéressantes.

J’aimerais néanmoins pointer du doigt un dernier problème, le pire je pense, et qui peut justement être résolu par une extension des possibilités d’OpenObject.

Prenons un partenaire A, très connu et top contributeur. Il a développé un module qui est très utilisé par d’autres membres de la communauté.

Dans son module, il a créé un champ X dans sale.order et dans account.invoice, et il a fait en sorte que sa valeur dans sale.order soit transmise à son account.invoice.

Voici le code qu’il a dû faire :

    def _make_invoice(self, cr, uid, order, lines, context=None):
        journal_obj = self.pool.get('account.journal')
        inv_obj = self.pool.get('account.invoice')
        obj_invoice_line = self.pool.get('account.invoice.line')
        if context is None:
            context = {}

        journal_ids = journal_obj.search(cr, uid, [('type', '=', 'sale'), ('company_id', '=', order.company_id.id)], limit=1)
        if not journal_ids:
            raise osv.except_osv(_('Error !'),
                _('There is no sales journal defined for this company: "%s" (id:%d)') % (order.company_id.name, order.company_id.id))
        a = order.partner_id.property_account_receivable.id
        pay_term = order.payment_term and order.payment_term.id or False
        invoiced_sale_line_ids = self.pool.get('sale.order.line').search(cr, uid, [('order_id', '=', order.id), ('invoiced', '=', True)], context=context)
        from_line_invoice_ids = []
        for invoiced_sale_line_id in self.pool.get('sale.order.line').browse(cr, uid, invoiced_sale_line_ids, context=context):
            for invoice_line_id in invoiced_sale_line_id.invoice_lines:
                if invoice_line_id.invoice_id.id not in from_line_invoice_ids:
                    from_line_invoice_ids.append(invoice_line_id.invoice_id.id)
        for preinv in order.invoice_ids:
            if preinv.state not in ('cancel',) and preinv.id not in from_line_invoice_ids:
                for preline in preinv.invoice_line:
                    inv_line_id = obj_invoice_line.copy(cr, uid, preline.id, {'invoice_id': False, 'price_unit': -preline.price_unit})
                    lines.append(inv_line_id)
        inv = {
            'name': order.client_order_ref or '',
            'origin': order.name,
            'type': 'out_invoice',
            'reference': order.client_order_ref or order.name,
            'account_id': a,
            'partner_id': order.partner_id.id,
            'journal_id': journal_ids[0],
            'address_invoice_id': order.partner_invoice_id.id,
            'address_contact_id': order.partner_order_id.id,
            'invoice_line': [(6, 0, lines)],
            'currency_id': order.pricelist_id.currency_id.id,
            'comment': order.note,
            'payment_term': pay_term,
            'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
            'date_invoice': context.get('date_invoice',False),
            'company_id': order.company_id.id,
            'user_id': order.user_id and order.user_id.id or False,
            'champ_x': order.champ_x
        }
        inv.update(self._inv_get(cr, uid, order))
        inv_id = inv_obj.create(cr, uid, inv, context=context)
        data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], pay_term, time.strftime('%Y-%m-%d'))
        if data.get('value', False):
            inv_obj.write(cr, uid, [inv_id], data['value'], context=context)
        inv_obj.button_compute(cr, uid, [inv_id])
        return inv_id

50 lignes, alors qu’en fait la seule ligne qu’il a vraiment codé c’est la ligne en rouge ici. Et encore on a eu de la chance, la fonction d’origine aurait pu être bien plus longue.
Comme il n’est pas possible via son module d’insérer son code directement, il a dû copier-coller l’ensemble de la fonction du module sale pour rajouter sa petite ligne.

Et là le vrai problème arrive. Pas de chance les devs de l’éditeur modifient par la suite la fonction d’origine et d’autres fonctions ailleurs, de sorte que l’ancienne provoque désormais un bug. Notre partenaire A doit désormais refaire le copier-coller de la fonction d’origine s’il ne veut pas que son module soit considéré comme buggé.

Cela oblige notre partenaire à faire de la veille permanente sur tous ses modules, juste pour vérifier qu’OpenERP SA n’a pas modifié la fonction d’origine. Et vu que les fonctions sont de plus en plus longues, les risques de bugs le sont d’autant plus. Enfin, cas ultime, imaginez si un partenaire B créé un module qui hérite de la fonction du module de A… Ce que je veux dire par là, c’est que c’est tout l’écosystème des modules communautaire qui est instable à cause de cette surutilisation des fonctions Python qui ne sont pas DU TOUT adaptées à un système aussi modulaire qu’OpenERP.

Je pense qu’on est en plein dedans aujourd’hui, on constate que de plus en plus de modules de qualité arrivent sur OpenERP, mais ils sont rapidement buggés dès que OpenERP SA fait des changements dans les fonctions des modules certifiés, qui deviennent eux-mêmes de plus en plus long et complexe.

Il faut à tout prix trouver une autre solution pour les développeurs de module pour ne pas avoir à recopier la fonction d’origine quand ils veulent juste rajouter quelques détails en plus comme un champ à transférer. Et pour moi la seule solution viable, comme il est clair qu’on ne pourra pas faire ça directement dans le code Python, c’est donc de diminuer la part de ce code Python en étendant et surtout utilisant les possibilités d’OpenObject qui peuvent je pense être encore améliorés.

Merci d’avoir tenu cette lecture. J’exprime ici ma conviction personnelle, qui est un peu isolée. Je ne suis pas développeur, aussi si j’ai peut-être dit de grosses conneries, n’hésitez pas à me l’indiquer dans les commentaires.

    def init(self, cr):
79
        tools.drop_view_if_exists(cr, 'account_invoice_report')
80
        cr.execute("""
81
            create or replace view account_invoice_report as (
82
                 select min(ail.id) as id,
83
                    ai.date_invoice as date,
84
                    to_char(ai.date_invoice, 'YYYY') as year,
85
                    to_char(ai.date_invoice, 'MM') as month,
86
                    to_char(ai.date_invoice, 'YYYY-MM-DD') as day,
87
                    ail.product_id,
88
                    ai.partner_id as partner_id,
89
                    ai.payment_term as payment_term,
90
                    ai.period_id as period_id,
91
                    (case when u.uom_type not in ('reference') then
92
                        (select name from product_uom where uom_type='reference' and active and category_id=u.category_id LIMIT 1)
93
                    else
94
                        u.name
95
                    end) as uom_name,
96
                    ai.currency_id as currency_id,
97
                    ai.journal_id as journal_id,
98
                    ai.fiscal_position as fiscal_position,
99
                    ai.user_id as user_id,
100
                    ai.company_id as company_id,
101
                    count(ail.*) as nbr,
102
                    ai.type as type,
103
                    ai.state,
104
                    pt.categ_id,
105
                    ai.date_due as date_due,
106
                    ai.address_contact_id as address_contact_id,
107
                    ai.address_invoice_id as address_invoice_id,
108
                    ai.account_id as account_id,
109
                    ail.account_id as account_line_id,
110
                    ai.partner_bank_id as partner_bank_id,
111
                    sum(case when ai.type in ('out_refund','in_invoice') then
112
                         -ail.quantity / u.factor
113
                        else
114
                         ail.quantity / u.factor
115
                        end) as product_qty,
116
117
                    sum(case when ai.type in ('out_refund','in_invoice') then
118
                         -ail.price_subtotal
119
                        else
120
                          ail.price_subtotal
121
                        end) / cr.rate as price_total,
122
123
                    (case when ai.type in ('out_refund','in_invoice') then
124
                      sum(-ail.price_subtotal)
125
                    else
126
                      sum(ail.price_subtotal)
127
                    end) / (CASE WHEN sum(ail.quantity/u.factor) <> 0
128
                       THEN
129
                         (case when ai.type in ('out_refund','in_invoice')
130
                          then sum(-ail.quantity/u.factor)
131
                          else sum(ail.quantity/u.factor) end)
132
                       ELSE 1
133
                       END)
134
                     / cr.rate as price_average,
135
136
                    cr.rate as currency_rate,
137
                    sum((select extract(epoch from avg(date_trunc('day',aml.date_created)-date_trunc('day',l.create_date)))/(24*60*60)::decimal(16,2)
138
                        from account_move_line as aml
139
                        left join account_invoice as a ON (a.move_id=aml.move_id)
140
                        left join account_invoice_line as l ON (a.id=l.invoice_id)
141
                        where a.id=ai.id)) as delay_to_pay,
142
                    sum((select extract(epoch from avg(date_trunc('day',a.date_due)-date_trunc('day',a.date_invoice)))/(24*60*60)::decimal(16,2)
143
                        from account_move_line as aml
144
                        left join account_invoice as a ON (a.move_id=aml.move_id)
145
                        left join account_invoice_line as l ON (a.id=l.invoice_id)
146
                        where a.id=ai.id)) as due_delay,
147
                    (case when ai.type in ('out_refund','in_invoice') then
148
                      -ai.residual
149
                    else
150
                      ai.residual
151
                    end)/ (CASE WHEN
152
                        (select count(l.id) from account_invoice_line as l
153
                         left join account_invoice as a ON (a.id=l.invoice_id)
154
                         where a.id=ai.id) <> 0
155
                       THEN
156
                        (select count(l.id) from account_invoice_line as l
157
                         left join account_invoice as a ON (a.id=l.invoice_id)
158
                         where a.id=ai.id)
159
                       ELSE 1
160
                       END) / cr.rate as residual
161
                from account_invoice_line as ail
162
                left join account_invoice as ai ON (ai.id=ail.invoice_id)
163
                left join product_product pr on (pr.id=ail.product_id)
164
                left join product_template pt on (pt.id=pr.product_tmpl_id)
165
                left join product_uom u on (u.id=ail.uos_id),
166
                res_currency_rate cr
167
                where cr.id in (select id from res_currency_rate cr2  where (cr2.currency_id = ai.currency_id)
168
                and ((ai.date_invoice is not null and cr.name <= ai.date_invoice) or (ai.date_invoice is null and cr.name <= NOW())) limit 1)
169
                group by ail.product_id,
170
                    ai.date_invoice,
171
                    ai.id,
172
                    cr.rate,
173
                    to_char(ai.date_invoice, 'YYYY'),
174
                    to_char(ai.date_invoice, 'MM'),
175
                    to_char(ai.date_invoice, 'YYYY-MM-DD'),
176
                    ai.partner_id,
177
                    ai.payment_term,
178
                    ai.period_id,
179
                    u.name,
180
                    ai.currency_id,
181
                    ai.journal_id,
182
                    ai.fiscal_position,
183
                    ai.user_id,
184
                    ai.company_id,
185
                    ai.type,
186
                    ai.state,
187
                    pt.categ_id,
188
                    ai.date_due,
189
                    ai.address_contact_id,
190
                    ai.address_invoice_id,
191
                    ai.account_id,
192
                    ail.account_id,
193
                    ai.partner_bank_id,
194
                    ai.residual,
195
                    ai.amount_total,
196
                    u.uom_type,
197
                    u.category_id
198
            )
199
        """)

My point of view about the OpenERP relicensing

Hello everybody,

I will now tell you about the subject of the last week: The addition of an exception in the OpenERP AGPL license, potentially allowing to avoid the redistribution of source code through the purchase of an OpenERP Enterprise version.

So like everyone else in the community, instantly I was shocked:

-We create some kind of a dual license, which is our worst fear: SugarCRM, Pentaho, Magento, etc … most of the popular business free software also have in parallel an enterprise version which means that not all efforts are made to improve the free version and often even limiting the efforts of the community. This is one of the main power of OpenERP now than not falling into this trap and it’s a very, very bad news to see that begin to rears its ugly head.
Ok so we are assured that the Enterprise version has nothing to do with the other double licenses, that all the modules continue to be dismissed AGPL, don’t act I return to it later in this post. Nevertheless, the name is very scary.

-We can also read the fact we can, against some good cash, purchase the right not to redistribute the source code. No really need to be a fan of conspiracy theories to immediately imagine arrangements between OpenERP SA and large companies to make some breaches against the GPL’s garantees and thus those protecting the community and users.

This is what comes to mind when OpenERP SA presented its new offer, and that is why the debates have been particularly virulent last week about this. I myself began to fear that a significant part of the community begins to turn to Tryton.
But when we analyze in detail the offer, we realize that it is not necessarily so bad thoughts, to understand where I’m going let me go into detail *GPL license.

The first license *GPL , I will move quickly on it because it was never used by OpenERP, and also the least restrictive is the LGPL. It is used primarily when the license of software needs to be compatible with proprietary code while being able to protect by the GPL guarantees the software itself.

The GPL is the basic license approved by FSF and one of the most restrictive. Sometimes excess according to some people because you can not use GPL software with other proprietary code. You have an obligation to redistribute the source code if you make a modification to the software, but however you can create an extension as an OpenERP module without having to publish as you use it privately. OpenERP remained long in GPL V2 and then in GPL V3 when this version was released.

Still, the GPL failed to give guarantees with the SaaS. You could take for example the OpenERP code, create useful modules, and on that basis make an SaaS offer without having to publish the source code of your modules. I call that an opportunistic SaaS offer obviously wrong in light of the spirit of free software.
This is to compensate for this scenario that the FSF has created the AGPL license. The principle is simple: You can request the source code of any software you use, even if it is used across the network. Note the size difference between the GPL and the AGPL: If we place ourselves in business context, this means that even employees or partners with limited access to the ERP can request the source code of the company’s OpenERP, including modules developed specifically for it and only used privately.

OpenERP is licensed under the AGPL since last year. It was obviously necessary to avoid opportunistic SaaS offers I mentioned and that could appear very quickly. Imagine you take the code OpenERP, develop a vertical integration, for example services companies and sell all without having to redistribute your work. I can imagine how these opportunists could appear in a few years on the back of OpenERP so it was obviously a necessity.

And so now OpenERP SA receives requests from companies wishing to protect their private modules (which can often reflect a unique way of working to the company and does not want to give to the competition). On which OpenERP SA meets today with the AGPL exception.
This exception says that if the client company pays the enterprise version, it may not give the source code of its modules to private users but must make if it distributes copies (especially if he tries to sell them) returning immediately under the terms of the classic AGPL. For me it is neither more nor less than selling the right to use the GPL instead of the AGPL.

And for once I will not plant a knife in the back OpenERP SA: I agree with them. For me, both GPL and AGPL protect the interests of the community, with the exception of opportunistic SaaS offers for GPL. I see no problem in allowing the companies to use private module, it’s fully in the spirit of free software, it has been like that throughout the GPL period of OpenERP and I would even say that simply forbid it as the AGPL actually unserve the interests of OpenERP and community.

But where I find really interesting the choice of OpenERP SA is that they have managed to find an economic model (the fact to charge companies that want to protect their internal working methods), equal (not all companies will need such protection, and those who need it can pay for it) and especially with the only difference between the paying and non-paying users is … just impose even more restrictive license about the free software guarantees, via the AGPL license for non-paying users. Users who pay will have a GPL equivalent already properly protecting the interests of the community and non-paying users whose the only restriction is to be forced to publish the source code for its employees and partners … It’s brilliant, just brilliant.

Since I started on OpenERP, I feared that OpenERP SA is finally forced to adopt a dual license in order to survive, I have seen throughout the period struggle to come to find a viable business model but respectful of the community. When this exception appeared, I thought, like many others, they had mainly started throwing in the towel and move to a dual license, however, finally … it seems on the contrary they have actually managed to find the economic model they were looking for. Personally I therefore support the idea, and I think it is incredibly original.

Now consider the various scenarios:

1) The case where an unscrupulous company is developing a module and then tries to sell it without redistribute the source code. This case should in my view not be possible without violating the spirit of free software.

2) The case where a client company wants to develop a module for internal use only. The company should have the opportunity, so free or paid, to retain full intellectual property of the module without publish it to its employees and partners. This does not violate the spirit of free software.

3) The case where a client company wants access to a module. It is my opinion that is respected the spirit of free software if he has free access to the source code for all modules developed by the publisher, by an integrator which bases its services above and those used in a SaaS offering. They did not necessarily have access to a module only used internally in another company.

4) The case where an unscrupulous company develops a module for an SaaS offer based on it without having to redistribute the source code. This case should in my view not be possible without violating the spirit of free software.

OpenERP under GPL licence:

1) Case impossible without violating the license

2) Possible case without license violation

3) The client company has no access to modules of an unscrupulous SaaS offer.

4) Possible case without license violation

OpenERP under AGPL licence:

1) Case impossible without violating the license

2) Case impossible without violating the license

3) The client company has successfully access to all modules.

4) Case impossible without violating the license

OpenERP under AGPL + exception. The company which is mentioned in the case purchased the enterprise version.

1) Case impossible without violating the license

2) Possible case without license violation

3) 4) I’m not sure … I’m looking at the text of the exception, what OpenERP SA offers to the users with the Enterprise version is the right not to redistribute the source code to users over network, without any other restriction. That’s too close to the GPL to prevent opportunistic SaaS offers to appear, they would then just buy the Enterprise version … OpenERP SA needs to be much more explicit on this point, and explicitly specify that the exemption is void if access to ERP is paid in any way (I think of SaaS opportunistic offer as well as to a company that would charge an option to its clients for accessing their invoices on the ERP of the company, in this case the code must also be redistributed).

Moreover, there are two problems with the implementation of this license, I’ll just mention them quickly:

-There are still many people in the community, holding some copyright on the code of OpenERP, who refuse to allow the transition to the new license. In response OpenERP SA wants to rewrite their contribution which is obviously an insult. I find this regrettable, even if ultimately the idea seems good OpenERP SA wanted to push through and the result is climbing. OpenERP SA MUST NOT rewrite these contributions, they have tended to be too closed in on themselves which is not healthy for a free software (I have already sufficiently expressed my opinion on the fact OpenERP SA should make a much better use of the community contributions). I encourage everyone to talk responsibly about the subject, if there is a reluctance on the side of the community, suggest and ask for guarantees.

-Some community members have highlighted the fact that the modules AGPL is not compatible with AGPL + Exception. It would be obviously a huge problem, but my limited legal skills do not allow me to make more comments on the subject.

In conclusion, my opinion is that I support the new license, provided that the opportunistic SaaS offer is explicitly banned from the exception, and congratulations to OpenERP SA for finding this business model.

PS: I invite you to read this excellent post on the same subject: http://www.qmuxs.com/version2beta/2011/a-new-openerp-product-and-license/.

Mon point de vue sur le changement de licence d’OpenERP

Bonjour à tous,

Je vais aujourd’hui vous parler du sujet qui a embrasé la communauté depuis la semaine dernière : L’ajout d’une exception dans la licence AGPL d’OpenERP, permettant potentiellement d’éviter la redistribution du code source via l’achat d’une version Entreprise auprès d’OpenERP SA.

Alors comme tout le monde dans la communauté, sur le coup j’ai été scandalisé :

-On a la création d’une part d’une double licence, ce qui est notre pire frayeur : SugarCRM, Pentaho, Magento, etc… énormément de logiciels libres populaires aujourd’hui et à destination des entreprises ont également en parallèle une version entreprise ce qui implique que tous les efforts ne sont pas fait pour améliorer la version libre et souvent limiter même les efforts de la communauté. C’est l’une des principales forces d’OpenERP à l’heure actuelle que de ne pas être tombé dans ce travers et c’est une très, TRES mauvaise nouvelle que de la voir commencer à pointer le bout de son nez.
Alors ok on nous assure que cette version Entreprise n’a rien à voir avec les autres doubles licences, que l’ensemble des modules continuera à être licencié en AGPL, don’t act j’y reviens plus tard dans ce billet. Il n’empêche que le nom fait très peur.

-On nous parle également d’acheter contre espèce sonnantes et trébuchantes le droit de ne pas redistribuer le code source. Pas vraiment besoin d’être un adepte des théories du complot pour imaginer immédiatement des arrangements entre OpenERP SA et de grosses sociétés afin de faire des entorses aux garanties de la GPL et donc les garanties protégeant la communauté et les utilisateurs.

C’est ce qui nous vient immédiatement à l’esprit lorsque OpenERP SA a présenté sa nouvelle offre, et c’est pour cela que les débats ont été particulièrement virulent la semaine dernière à ce sujet. J’ai moi-même commencé à craindre qu’une partie importante de la communauté ne commence à se tourner vers Tryton.
Mais quand on analyse dans le détail l’offre, on se rend compte qu’elle n’est pas forcément si mal pensée que cela, pour comprendre où je veux en venir laissez moi rentrer dans le détail des licences *GPL.

La première licence *GPL, que je vais passer rapidement car elle n’a jamais été utilisée par OpenERP, et également la moins restrictive est la licence LGPL. Elle sert principalement quand la licence d’un logiciel a besoin d’être compatible avec du code propriétaire tout en pouvant néanmoins protéger par les garanties GPL le logiciel lui-même.

La licence GPL est la licence de base approuvée par la FSF et l’une des plus restrictive. Parfois trop au regard de certaines personnes, car vous ne pouvez utiliser un logiciel sous GPL avec du code propriétaire. Vous avez l’obligation de redistribuer le code source si vous faites une modification sur le logiciel, mais vous pouvez néanmoins créer une extension comme un module OpenERP sans avoir à le publier tant que vous l’utilisez de manière privée. OpenERP est resté longtemps en GPL V2 puis en GPL V3 quand cette version est sortie.

La licence GPL n’apportait néanmoins aucune garantie par rapport au SaaS. Vous pouviez par exemple prendre le code d’OpenERP, créer des modules utiles dont vous gardiez le code et proposer sur cette base un service SaaS payant sans avoir à publier le code source de vos modules. C’est ce que j’appelle une offre SaaS opportuniste, evidemment condamnable en regard de l’esprit du logiciel libre.
C’est pour palier à ce cas de figure que la FSF a créée la licence AGPL. Le principe est simple : vous pouvez demander le code source de tout logiciel que vous utiliser, même si celui-ci est utilisé à travers le réseau. Notez la différence de taille entre la GPL et la AGPL : Si on se place en contexte d’entreprise, cela signifie que même les employés ou les partenaires ayant un accès restreint sur l’ERP peuvent demander le code source de l’OpenERP de l’entreprise, y compris des modules développés spécifiquement pour elle et qu’elle utilise uniquement à titre privé.

OpenERP est sous licence AGPL depuis l’année dernière. C’était de toute évidence nécessaire pour éviter les offres SaaS opportunistes que j’ai évoqué et qui auraient pu apparaitre très rapidement. Imaginez vous prenez le code d’OpenERP, développez une verticalisation par exemple à destination des sociétés de services et vendiez le tout sans avoir à redistribuer votre verticalisation. J’imagine aisément comment ces opportunistes aurait pu apparaitre en quelques années sur le dos d’OpenERP donc c’était de tout évidence une nécessité.

Et donc maintenant OpenERP SA reçoit des demandes de la part d’entreprises souhaitant protéger leurs modules privés (qui peuvent souvent refléter une manière de travailler unique à l’entreprise et dont elle ne veut pas voir profiter sa concurrence). Ce sur quoi OpenERP SA répond aujourd’hui par l’exception de l’offre AGPL.
Cette exception dit que si l’entreprise cliente paye la version entreprise, elle peut ne pas donner le code source de ses modules privés à ses utilisateurs mais doit le donner si elle en distribue des copies (notamment si elle essaye de les revendre) qui reviennent alors immédiatement sous les termes classiques de la AGPL. Pour moi il ne s’agit ni plus ni moins que de vendre le droit d’utiliser la licence GPL plutôt que l’AGPL.

Et pour une fois je ne vais pas planter de couteau dans le dos à OpenERP SA : Je suis d’accord avec eux. Pour moi, les deux licences GPL et l’AGPL protègent les intérêts de la communauté, à la seule exception des offres SaaS opportunistes pour la GPL. Je ne vois aucun problème à autoriser les modules à usage privés dans les entreprises utilisatrices, c’est parfaitement dans l’esprit du logiciel libre, cela a été comme ça pendant toute la période GPL d’OpenERP et je dirait même que l’interdire purement et simplement comme le fait l’AGPL déservirait vraiment les intérêts d’OpenERP et de sa communauté.

Mais là où je trouve vraiment intéressant le choix d’OpenERP SA, c’est qu’ils ont réussi à trouver un modèle économique (le fait de faire payer les entreprises qui veulent protéger leurs méthodes de travail interne), égalitaire (c’est pas toutes les entreprises qui auront besoin d’une telle protection, et celles qui en ont besoin peuvent en payer le prix) et surtout dont la seule différence entre les utilisateurs payants et non-payants est… juste d’imposer une licence plus restrictive encore sur les garanties du logiciel libre, via l’imposition pour les utilisateurs non-payants de la licence AGPL. Des utilisateurs payants ayant un équivalent GPL protégeant déjà correctement les intérêts de la communauté et des utilisateurs non-payants dont la seule restriction est uniquement d’être obligé de publier le code source à ses employés et partenaires… C’est brillant, juste brillant.

Depuis mes débuts sur OpenERP, je craignais que OpenERP SA ne soit obligé finalement d’adopter une double licence pour arriver à survivre, je les ai vu pendant toute la période lutter pour arriver à trouver un business model viable mais respectueux de la communauté. Quand cette exception est arrivée, j’ai cru, comme beaucoup d’autres, qu’ils avaient surtout commencé à jeter l’éponge et à se diriger vers une double licence néanmoins finalement… il semble qu’au contraire ils aient bel et bien réussi à trouver le modèle économique qu’ils cherchaient! Personnellement je soutiens donc cette idée qui est selon moi incroyablement originale.

Étudions maintenant les différents cas de figure :

1)Le cas où une société peu scrupuleuse développe un module et tente ensuite de le vendre sans redistribuer librement le code source. Ce cas ne doit selon moi pas être possible sans violer l’esprit du logiciel libre.

2)Le cas où une société cliente veut développer un module à usage interne exclusivement. La société doit avoir la possibilité, de manière gratuite ou payante, de garder la pleine propriété intellectuelle du module y compris vis à vis de ses employés et partenaires. Ceci ne viole pas selon l’esprit du logiciel libre.

3)Le cas où une société cliente veut avoir accès à un module. Elle doit selon moi pour que soit respecté l’esprit du logiciel libre pouvoir accéder librement au code source de tous les modules développés par l’éditeur, par un intégrateur qui base ses services dessus et ceux utilisés dans une offre SaaS. Ils n’a pas forcément à avoir accès à un module utilisé uniquement en interne dans une autre société.

4)Le cas où une société peu scrupuleuse développe un module pour baser une offre SaaS dessus sans avoir à redistribuer librement le code source. Ce cas ne doit selon moi pas être possible sans violer l’esprit du logiciel libre.

OpenERP sous GPL :

1) Cas impossible sans violer la licence

2) Cas possible sans violation de licence

3) La société cliente n’a pas accès aux modules d’une offre SaaS peu scrupuleuse.

4) Cas possible sans violation de licence

OpenERP  sous AGPL

1) Cas impossible sans violer la licence

2) Cas impossible sans violer la licence

3) La société cliente a correctement accès à tous les modules.

4) Cas impossible sans violer la licence

OpenERP sous AGPL + exception. La société dont il est fait mention dans le cas a acheté la version entreprise.

1) Cas impossible sans violer la licence

2) Cas possible sans violation de licence

3)4) Je ne suis pas sûr… J’ai beau regarder le texte de l’exception, ce qu’OpenERP SA offre aux utilisateurs de la version Entreprise est le droit de ne pas redistribuer le code source aux utilisateurs, sans autre restriction. C’est bien trop proche de la GPL pour empêcher les offres SaaS opportunistes d’apparaitre, il leur suffirait alors juste d’acheter la version Entreprise… OpenERP SA a besoin d’être beaucoup plus explicite sur ce point, et indiquer explicitement que l’exception n’est plus valable si l’accès à l’ERP est payant d’une quelconque manière (Je pense aux offres SaaS opportuniste mais aussi à une société qui ferait payer par exemple une option à ses clients pour qu’ils accèdent à leurs factures sur l’ERP de la société, dans ce cas le code doit être également redistribué).

Qui plus est, il reste deux problèmes à la mise en place de cette licence que je vais juste évoquer rapidement :

-Il y a encore beaucoup de personnes dans la communauté, détentrice de copyright sur le code d’OpenERP, qui refusent d’autoriser le passage à la nouvelle licence. En réaction OpenERP SA veut réécrire leur contribution ce qui est évidemment une sacrée insulte. Je trouve cela infiniment regrettable, même si au final l’idée semble bonne OpenERP SA a voulu passer en force et résultat c’est l’escalade. OpenERP SA ne DOIT PAS réécrire ces contributions, ils ont déjà beaucoup trop tendance à être renfermé sur eux même ce qui n’est pas sain pour un logiciel libre (J’ai déjà suffisamment fait part de mon opinion sur le fait qu’OpenERP SA devrait faire un bien meilleur usage des contributions de la communauté). J’invite tout un chacun à discuter de manière responsable sur le sujet, si il y a des réticences du coté de la communauté, proposez et demandez des garanties.

-Certains membres de la communauté ont mis en avant le fait que les modules AGPL ne serait pas compatible avec l’AGPL+Exception. Ce serait évidement un considérable problème, mais mes compétences juridiques limitées ne me permettent pas de faire plus de commentaires sur le sujet.

En conclusion, mon avis est que je soutient la nouvelle licence, à condition que les offres SaaS opportunistes soit explicitement bannies de l’exception, et j’adresse mes félicitations à OpenERP SA pour avoir trouver ce business model.

PS : Pour les anglophones, je vous invite à lire cet excellent billet sur le même sujet : http://www.qmuxs.com/version2beta/2011/a-new-openerp-product-and-license/.

Update : Depuis l’article et suite principalement à l’insistance de la société Akretion, il semblerait que l’on commence à ce diriger vers la possibilité pour les contributeurs de vendre leur “version entreprise” de leur module : http://www.openerp.com/irc/%23openobject.2011-06-30.log.html#t2011-06-30T23:22:31 . C’est en train de devenir très interessant car du coup non seulement le modèle économique de la licence est interessant mais en plus toute la communauté pourra profiter des retombées économiques! Ceci pourrait potentiellement convaincre la communauté de changer la licence de leurs modules et donc régler ce problème d’incompatiblité.

Bravo et merci Raphael ;).

Pourquoi OpenERP-Universe?

Bonjour à tous,

Les dernières finalisations du site internet de www.openerp-universe.org ont été réalisées cette semaine et le site est désormais prêt à accueillir les contributeurs.
Je vais donc m’employer dans les prochains jours à promouvoir le site pour son lancement officiel, toutefois avant je pense nécessaire d’expliquer ma vision de l’écosystème OpenERP, les raisons qui m’ont amené à créer le site et comment celui-ci répond aux problématiques actuelles de la communauté OpenERP.

Les choses que j’ai à dire en ce sens sont assez nombreuses aussi ce texte, qui s’apparente à une tribune, sera assez long. Tout ce qui sera dit ici ne reflète bien sûr que mon avis personnel.

Précisons dans un premier temps que l’objectif du site est avant tout de promouvoir et de créer une communauté OpenERP composée certes des personnes qui gagnent leurs vies avec mais aussi et avant tout de personnes intéressées par le logiciel et qui souhaitent, qu’ils l’utilisent ou non, améliorer toujours plus le logiciel afin de dépasser la concurrence propriétaire. En somme l’objectif n’est ni plus ni moins que participer à la création d’une communauté qui se rapprocherai le plus de la définition d’une “communauté du logiciel libre”, définition qui, selon moi, ne correspond pas encore totalement à la communauté OpenERP aujourd’hui.

Il faut dire que créer une communauté du libre vraiment forte et organisé (Je parle ici de communauté comparable aux communautés Mozilla, Debian ou du noyau Linux, pas moins car le défi organisationnel est bien réel) sur un logiciel ERP sera une tâche excessivement difficile, et je pèse mes mots.
Ainsi j’explique immédiatement pourquoi le site parlera uniquement d’OpenERP, et non d’OpenBravo, Ofbiz, ERP5 etc… Je ne doute pas de leurs propres qualités mais il sera impossible de construire une communauté satisfaisante sans se concentrer sur un seul logiciel.
Aussi je vous propose ma propre croyance, celle qu’OpenERP a le potentiel le plus important pour envahir le marché, et je vous invite ainsi à nous concentrer sur lui et à m’aider à créer cette communauté dont l’objectif sera bel et bien la promotion et l’amélioration du logiciel OpenERP. Si votre croyance est différente, libre à vous de copier cette initiative pour promouvoir un autre ERP, après tout la concurrence a toujours été une bonne chose pour le dynamisme et l’innovation.

Cette communauté, que je nommerai désormais la communauté OpenERP-Universe, aura clairement pour objectif de palier certains des manques de la communauté OpenERP actuelle, et je crains que l’éditeur n’ait une part de responsabilité dans ces manques.
Attention à ne pas me faire dire ce que je n’ai pas dit, l’éditeur d’OpenERP a fourni un travail considérable, en terme de développement du logiciel, de sa promotion mais aussi en terme de sacrifice car il faut le rappeler ils ne sont JAMAIS parti sur un système de double licence comme tant d’autres éditeurs open-sources, mais ont au contraire toujours libéré leur travail (à quelques exceptions largement excusables comme les shared founding). Pour cette raison, afin que l’éditeur reste récompensé pour son travail passé et pour ne pas diviser les efforts, je suis contre les forks d’OpenERP (y compris Tryton) dans l’état actuel des choses et je préfère agir pour faire évoluer le logiciel.

Il n’en reste pas moins, toujours selon moi bien sûr, que l’éditeur d’OpenERP fait des erreurs.
La plus importante, et de loin, c’est qu’ils ont une tendance a vouloir tout faire par eux-mêmes. Cela a toujours été comme ça, ils ont une armée de développeurs qui s’occupent d’améliorer le logiciel à chaque version, et ne récupèrent quasiment jamais le travail de la communauté préférant systématiquement réinventer la roue. Selon moi, l’éditeur a beaucoup trop de développeurs et pas assez de personnes qui passent en revue les quelques déjà 900 modules OpenERP de la communauté pour intégrer les meilleurs et les plus pertinent dans les fonctions de base du logiciel.
Je reconnais que l’approche était la bonne pour le lancement du logiciel. Les modèles libres basés sur un éditeur sont plus efficace pour le lancement d’un projet car cela va plus vite et facilite la constitution de la communauté, en revanche je pense fermement que les modèles basés sur une communauté sont largement plus efficace en terme de qualité une fois que le projet est déjà leader dans son domaine.
Il est clair que l’éditeur a déjà réussi son pari depuis la V5, c’est à ce moment là qu’ils devaient commencer à donner beaucoup plus d’importance à l’intégration du travail de la communauté, à la promotion de cette communauté pour la renforcer, tout en restant bien entendu au coeur de celle-ci afin de continuer à pouvoir proposer des services aux partenaires, aux clients etc… L’éditeur devrait consacrer des effectifs au passage en revue les modules les plus intéressants, de les intégrer, et de faire vivre la communauté.
En revanche tout développer eux-mêmes bloque l’avantage de qualité inhérente au logiciel libre, et surtout empêche la communauté de s’emparer de l’évolution du logiciel, l’empêchant par la même de grandir et de se renforcer. C’est totalement contre-productif et cela amène un risque réel.
En effet, certains projets libres basés sur un éditeur donnent naissance a des forks à ce stade si l’éditeur a ce comportement et deviennent des projets basés sur une communauté (gaffe à Tryton notamment…). Certes c’est mieux pour le logiciel en terme de qualité mais dans ce cas l’éditeur a tout perdu et encore une fois ce n’est pas ce que je veux pour l’éditeur d’OpenERP

Une autre erreur, bien moins importante car elle porte surtout sur la bonne utilisation des ressources de l’éditeur, consiste aujourd’hui à se concentrer sur le marketing alors que le produit pourrait encore devenir bien meilleur et que la communauté est insatisfaisante. OpenERP, et donc son éditeur, aurait gros à gagner à faire du lobbying, et notamment dans les écoles et les associations professionnelles qui sont stratégiques pour le bouche à oreille qui, rappelons-le, porte OpenERP depuis le tout début. Cela rapporterai à la fois des clients et des contributeurs.

La communauté qui s’est formée autour de ce contexte est une communauté intéressée, c’est à dire principalement constituée des employés de l’éditeur et les partenaires intégrateurs, soit uniquement des personnes qui gagnent leur vie avec OpenERP. La communauté manque donc cruellement de personnes qui développeraient des modules géniaux par goût du challenge, de contributeurs qui aideraient rien que pour que le libre envahisse également ce secteur de l’informatique (et avec lui probablement l’un des derniers bastions du propriétaire dans les entreprises), d’étudiants qui chercheraient à se spécialiser dans cette technologie et apporteront un regard neuf sur la manière dont un ERP doit fonctionner, et enfin et surtout les experts métiers qui savent ce dont ils ont besoin et pourront orienter les développeurs vers la bonne manière d’implémenter une fonctionnalité. Toutes ces personnes sont aujourd’hui absentes, ou trop peu représentées, dans la communauté OpenERP et c’est clairement l’un des plus importants rendez-vous manqués du logiciel libre en ce moment.

Sans cela, OpenERP reste d’une qualité équivalente au propriétaire, ce qui déjà bien il est vrai. Mais il est possible de faire infiniment plus grâce aux qualités que peut apporter le logiciel libre quand une communauté est suffisamment organisée. Ceci d’autant plus que le secteur des ERPs, qui est en évolution perpétuelle et réclame des avis nombreux pour implémenter une fonctionnalité de la meilleure façon, est probablement le secteur qui peut le plus profiter des avantages inhérents aux communautés libres.

Ceci étant dit, créer une communauté autour d’un logiciel ERP est quelque chose d’extrêmement difficile. En effet, il s’agit de logiciels complexes, dont ne serait-ce qu’une seule partie nécessite des mois de recherche pour se familiariser et des années d’expérience pour maîtriser totalement tous les enjeux. C’est probablement la raison principale qui limite actuellement la communauté à des personnes ayant un intérêt financier et limite le nombre de contributeurs désintéressés.

Rajoutons également le problème suivant : étant donné que les ERPs supportent les processus de l’entreprise, chaque personne a sa propre vision des choses sur le processus idéal et comment l’implanter dans l’ERP. Cela implique des débats intenses avant d’arriver à trouver le processus qui contentera la majorité. De plus l’élaboration ou l’amélioration d’une fonctionnalité doit impérativement être appuyé par des schémas, documentation technique, processus BPMN, etc… Actuellement soit l’éditeur décide soit dans le meilleur des cas les discussions prennent la forme d’un sujet sur Launchpad, mais sans l’appui de réelles spécifications il est difficile de comprendre pleinement les suggestions des précédents intervenants…
L’éditeur et la communauté actuelle (dont je ne m’exempte pas bien sûr) manquent clairement de rigueur sur les spécifications de développement alors que le moindre changement dans le mauvais sens peut provoquer des bugs ou des régressions en cascade dans tout le logiciel.

Pour qu’une communauté arrive à développer correctement une nouvelle fonctionnalité, il faut dans un premier temps que les experts métiers testent l’existant et émettent des critiques ou des suggestions. Le reste de la communauté peut alors s’employer à rédiger les spécifications de développement et une fois que tout le monde est d’accord on peut transmettre et faire pression sur l’éditeur pour que celles-ci soient suivi, ou laisser quelques développeurs développer un module à part et en faire la promotion. A ce moment là, les experts métiers peuvent à nouveau tester, proposer de nouvelles choses, expérimenter de nouveau processus, et c’est reparti pour un tour.
C’est uniquement de cette façon qu’il sera je pense possible de mettre en place une organisation suffisante pour faire atteindre au développement d’OpenERP sa vitesse et sa qualité optimale.

Bien sûr ce genre d’organisation va nécessiter un support adapté, et la problématique est tellement spécifique qu’il est illusoire de compter sur les forges habituelles comme Launchpad ou Sourceforge. Tout simplement car la communauté qu’on vise à créer n’est pas une communauté de développeurs mais une communauté hétérogène comprenant des personnes ayant des métiers extérieurs à l’informatique (les experts métiers notamment).

La partie la plus importante du processus de développement consiste en les débats qui permettent de définir la meilleure manière d’implémenter ou d’améliorer une fonctionnalité.
Mais avant de pouvoir améliorer, il faut déjà connaître l’existant. Comme je le disais l’un des principaux problèmes de la communauté est la barrière à l’entrée, qui rend difficile à une simple personne intéressée de se familiariser avec les fonctionnalités existantes.
Ainsi sur OpenERP-Universe la partie la plus importante est très probablement la partie “Fonctionnalités”. C’est ici que le nouveau venu pourra parcourir la liste des fonctionnalités classées par département de l’entreprise. Il pourra savoir si telle ou telle fonctionnalité est déjà implémenté, comment elle est implémentée, quel module l’implémente, etc…
C’est ici également que les experts métiers pourront emmètre des critiques sur une fonctionnalité déjà existante ou en suggérer une nouvelle, et que les autres contributeurs pourront joindre à la fonctionnalité en construction les spécifications techniques de celle-ci. J’ai mis sur le site les spécifications que nous-même utilisons dans ma société, à savoir des spécifications à base d’un document sous forme de tableur spécialement adapté pour les développements sous OpenERP et de schémas BPMN. Bien sûr ces modèles eux-mêmes attendent vos améliorations.

Il faudra notamment dans un premier temps répertorier les fonctionnalités implémentées par les modules certifiés et surtout les décrire.
La précision des mots dans la description des fonctionnalités est capitale pour les suggestions qui suivront. Par exemple une phrase “Renseignement automatique de l’adresse de facturation du partenaire quand le partenaire est renseigné dans la facture” pourrait avoir comme phrase de suggestion “Renseignement automatique de l’adresse de facturation du partenaire quand le partenaire est renseigné dans la facture. Si l’on veut tout de même changer cette adresse, seules les adresses appartenant au partenaire déjà sélectionné seront proposée.”

Je me suis d’ores et déjà occupé de lister les fonctionnalités des modules certifiés mais les descriptions sont vides, à l’exception de la fonctionnalité de facturation et de certaines fonctionnalité du framework OpenObject qui sont là pour montrer ce que je propose comme description.
Renseigner les descriptions sera un travail très long et qui va demander beaucoup de contributeurs, mais une fois ceci fait il sera d’autant plus facile de proposer les améliorations et je ne doute pas que la qualité d’OpenERP fera un bond en avant. Je suis convaincu qu’une communauté avec suffisamment d’experts métiers, soutenu par une description et donc une connaissance précise de l’existant, est exactement ce dont OpenERP a besoin.

Ceci est le point principal, mais c’est loin d’être la seule fonction du site. Chaque fonctionnalité est notamment liée au module qui l’implémente. Les modules peuvent être classés par critère d’intérêt, de fiabilité et de support ce qui permet de déterminer si un module doit être mis en avant ou au contraire oublié.
Précisons qu’à terme, j’aimerai mettre en place sur le site un OpenERP de démonstration qui téléchargerai les dernières versions stables des modules chaque nuit. Ceci permettrait ainsi de tester le logiciel en permanence pour chasser les bugs, et proposer aux visiteurs un OpenERP rempli avec des bases de démonstration pour chaque secteur d’activité et chaque type d’employé.

Le site aura bien sûr une partie documentation, sous forme de wiki. Toutefois, pour éviter de faire doublon avec la documentation officielle de l’éditeur ou même la partie Fonctionnalité du site, je propose de rédiger la documentation sous forme de cours. Par exemple un cours sur comment être un bon commercial, un autre pour être un bon responsable commercial, avec des cas concrets et pratiques sur OpenERP. De cette façon nous éviterons les doublons, cela fera une documentation avec des informations supplémentaires (Pas seulement le “Comment l’utiliser” mais aussi le “Pourquoi l’utiliser”) et ces cours pourrait certainement intéresser les écoles supérieures… Je crois dur comme fer que nous aurons gagné quand les étudiants utiliseront OpenERP dans leurs travaux pratiques.

Je désire éviter les forks d’OpenERP afin de récompenser l’éditeur pour ses efforts, mais dans ce cas il faut une communauté puissante pour le protéger de lui-même. Mon objectif n’est ni de rester sur un écosystème basé sur un éditeur ni de partir vers un écosystème basé sur une communauté qui évincerai l’éditeur, mais de partir sur un écosystème qui serait un mélange des deux, avec l’éditeur et la communauté ayant une puissance égale et travaillant ensemble pour améliorer toujours plus le logiciel.
De plus, une communauté totalement indépendante de l’éditeur, qui possédera ses propres outils (et donc qui ne repose pas sur le forum de l’éditeur ou Launchpad) pourra certainement apporter une autre vision des choses qui pourrait permettre de résister à l’éditeur quand celui-ci fait des mauvais choix.
Si des responsables de chez l’éditeur passent par ici, j’espère que vous comprendrez mon raisonnement.

Concernant les intégrateurs, certains outils sont quand même prévus pour eux sur le site.
Ils peuvent notamment inscrire librement leur société sur le site, qu’ils soient une grande société ou un simple auto-entrepreneur. C’est de la publicité gratuite et sans contrainte, l’objectif étant de dresse une liste exhaustive des intégrateurs en France, même les plus petits.
Vous pouvez également, et c’est très important, renseigner vos clients avec leur accord, ainsi que leur secteur d’activité et les fonctionnalités installées. Cela permettra ainsi de créer une liste de référence pour OpenERP dont le logiciel a bien besoin et qui n’existe nulle part ailleurs. Bien entendu c’est également un moyen pour vous de montrer l’étendu de vos compétences, et inversement cela permettra à vos prospects de consulter vos expériences précédentes.
De plus, les sociétés intéressées par OpenERP peuvent déposer une demande de devis sur le site. Pas d’inquiétude, je certifie que tous les intégrateurs enregistrés sur le site ont et auront un accès sans limite à ces demandes. L’objectif est que la société en question puisse recevoir plusieurs offres, notamment des intégrateurs de sa région et expérimentés dans son secteur d’activité.
Enfin, vous trouverez bien entendu un forum tout ce qu’il y a de plus classique.

Derniers points, qui ont toutefois leurs importances.
Dans un premier temps, je tiens à le dire haut et fort : D’ores et déjà, le site OpenERP-Universe appartient à sa communauté. Les directions que prendra le site seront décidés par les modérateurs qui eux-même écouteront les souhaits des contributeurs, je considère que le site ne m’appartient déjà plus. Je vous serait néanmoins reconnaissant de tolérer la petite phrase en bas du site qui indique la société à l’origine du projet.
Le deuxième point, l’ensemble des ressources publiées sur le site sera sous licence Creative Common by-sa, avec l’attribution à la “Communauté OpenERP-Universe”. Il n’y a pas de coup fourré, c’est uniquement pour protéger le travail de la communauté. En publiant sur le site, vous acceptez donc que votre travail soit publié sous ces termes.
Enfin dernier point, que j’ai déjà dit mais que je tiens à redire : Il y a aura déjà beaucoup trop de travail pour qu’on se disperse sur d’autres logiciels, aussi le site est dédié à OpenERP. Si vous souhaitez parler d’un autre logiciel, n’hésitez pas à copier cette initiative sur un autre site.

Dans l’immédiat je vais avoir besoin de trouver très rapidement des personnes souhaitant assurer la modération du site. En effet, même si j’ai trouvé le temps de mettre mes idées en ordre, de développer le site et de poster les premières contributions je doute fort, en tant que gérant de ma société, pouvoir trouver assez de temps dans les prochains mois pour assurer la modération d’un site aussi ambitieux que celui-ci.
Il est donc urgent de former aussi vite que possible un groupe de modérateurs qui s’emparera de ce projet et le fera vivre. Pour postuler je ne demanderai pas grand chose si ce n’est de s’investir véritablement dans ce projet dans les prochains mois.

J’aurai également besoin de quelques personnes ayant des compétences sous Drupal et souhaitant m’aider avec l’administration du site. J’ai eu la main assez lourde et je m’attend à ce que quelques problèmes apparaissent ici et là, de plus j’aurai besoin d’aide pour implémenter sur le sites quelques autres idées par la suite.

J’invite toutes les personnes intéressée à aller s’enregistrer sur le site et à contribuer. Les personnes souhaitant participer à la modération ou juste savoir comment elle peuvent aider peuvent me contacter via le formulaire de contact du site.

Je vous remercie de m’avoir lu, et je vous remercie d’avance pour l’aide que vous apporterez à ce projet. Espérons sincèrement que celui-ci marchera comme nous pouvons l’espérer.

Lancement de la béta du site OpenERP-Universe

Bonjour à tous,

Ceux qui me suivent sur twitter savent que je travaille depuis trois semaines sur un nouveau site en rapport avec OpenERP : http://www.openerp-universe.org , dont j’annonce le lancement de la beta par ce billet.

Celui-ci est un site communautaire sur OpenERP, c’est à dire qu’il contiendra un forum, une documentation en wiki et bien d’autres outils communautaires spécifiques au cas OpenERP, tels la liste des fonctionnalités, des modules, des références, des intégrateurs etc…

Certains me diront “Pourquoi faire un site communautaire alors qu’on a déjà le site d’openerp.com et launchpad, ca ne risque pas de diviser les efforts?”, ce à quoi je répondrais plusieurs choses :

  • Je crois fermement que dans le logiciel libre les supports de contributions (comme les sites internet) ne divisent pas les contributions mais au contraire les multiplient, en apportant une plus grande visibilité et également le fait qu’un contributeur peut plus facilement trouver une communauté qui lui corresponde. Le site peut donc apporter un dynamisme supplémentaire à la communauté OpenERP qui en a bien besoin.
  • Launchpad est une forge tout à fait correcte pour les experts OpenERP, mais est bien trop complexe d’utilisation pour les experts métiers. De manière générale, les modules issus de la communauté n’ont pas la visibilité qu’ils méritent et j’espère palier cela avec le site.
  • Il n’est pas très bon, selon moi, que la majorité des outils communautaires soient sous le contrôle direct de l’éditeur. Non pas qu’ils fassent preuve de censure bien sûr, loin de là, et j’ai le plus grand respect pour la société OpenERP SA, mais je crois que la communauté a vraiment besoin de s’approprier ses outils pour s’épanouir.
  • On a un gros, très gros problème au niveau de la représentation des experts métiers au sein de la communauté OpenERP. Pour l’instant la très grande majorité de la communauté OpenERP est constituée de ce que j’appelle les experts OpenERP (l’éditeur et les intégrateurs) et très peu d’experts métiers et d’utilisateurs. C’est le cas car pour le moment ils n’ont pas de moyen d’avoir une vue d’ensemble des fonctionnalités d’OpenERP et de la manière dont elles sont implémentées sans passer par une très longue phase d’apprentissage sur le logiciel.
    Le site vise d’abord et avant tout à répondre à ce problème, avec une visibilité sur les fonctionnalités implémentées, classées par domaine fonctionnel, ils ont la possibilité de consulter le processus BPMN décrivant comment la fonctionnalité est implémentée, peuvent émettre des critiques, peuvent consulter la liste des secteurs d’activités supportés et leurs références etc… Cela est très certainement la mission première du site OpenERP-Universe, intégrer les experts métiers, leur montrer comment OpenERP fonctionne, et faire en sorte de générer des débats entre experts métiers pour connaitre la meilleure manière dont telle fonctionnalité doit être implémentée, et faire en sorte qu’elle le soit.

Je vais pas m’étendre plus sur les objectifs du site, j’ai créé une page spéciale sur celui-ci afin de répondre à vos interrogations à ce niveau.

Le site sera francophone au moins au début car il y a beaucoup de travail à faire entre renseigner les modules, décrire les fonctionnalités qu’ils implémentent, créer une documentation etc… et la communauté francophone étant majoritaire au sein de la communauté cela ira bien plus vite. De plus et surtout, l’objectif est également de se servir du site pour promouvoir OpenERP, je ne vise pas moins que d’avoir un logiciel capable de renverser les acteurs majoritaires propriétaires, et pour cela je pense préférable de se concentrer d’abord à fond sur les localisations francophones qui pourront ensuite servir de pays références pour le reste du monde.
Ce n’est évidemment pas la stratégie de OpenERP SA et encore heureux, mais c’est celle que j’aimerai donner à OpenERP-Universe. Si on veut qu’OpenERP triomphe il doit battre les ERP propriétaires (au moins sur le marché des TPE-PME) sur tous les points, y compris l’implémentation fonctionnelle et l’implémentation de la localisation, pas seulement au niveau de la base technologique. Et pour cela il faut y aller selon moi localisation après localisation, et avec une communauté d’experts métiers organisés.

Comme je le disais il y a beaucoup de travail à faire, et j’invite déjà dans un premier temps les intégrateurs à se rajouter sur le site (ca fait de la pub gratuite pour eux), à renseigner leurs références d’entreprises et les fonctionnalités implémentées qu’ils ont implémentée. Une fois qu’il y aura suffisamment de contenu, les experts métiers ne devraient pas tarder à s’intéresser au site.
J’aurai également besoin de modérateurs, et les personnes souhaitant s’impliquer sur le site et souhaitant remplir ce rôle seront plus que les bienvenues. Pour ma part mon temps est limité mais je vais essayer de rajouter tous les contenus en ma possession durant le mois.

Merci pour votre attention, et j’espère vous voir bientôt au sein de la communauté OpenERP-Universe!

Nouvelle présentation de notre méthodologie d’intégration

Bonjour à tous,

En ce moment Tiny publie beaucoup de documents, ce qui est plutôt une bonne chose. En début de semaine, un document très intéressant et très bien fait a été publié : un memento sur la méthodologie d’intégration, à destination des partenaires intégrateurs comme nous.

Je dois avouer avoir été surpris par la précision et la qualité du document (la dernière fois que j’ai été surpris de la sorte, c’était le memento technique il y a plus de six mois). En tout cas pour nous à SYNERPGY, qui attachons une grande importance à avoir une méthodologie la plus parfaite possible, ce document a été une véritable mine d’or.

On a déjà récemment complètement refondu notre méthodologie, à coup de schémas BPMN, de maquettes OpenERP et de documents de spécifications techniques. Ce nouveau document a donc été l’occasion de mixer le meilleur de notre nouvelle méthodologie et de celle recommandée par Tiny (ainsi que de se forcer à trouver le temps de la présenter sur le site…).

Vous trouverez donc la présentation de notre nouvelle méthodologie sur le site. Si vous êtes un potentiel client cette présentation devrait vous rassurer, si vous êtes intégrateur n’hésitez pas à vous en inspirer et pourquoi pas nous aider à améliorer nos documents de travail.

Module Stock d’OpenERP : Quantité disponible et affichage des stocks

Bonjour à tous,

Aujourd’hui, la demande d’un client a été l’occasion pour nous d’explorer plus avant le fonctionnement de la gestion des stocks, notamment comment était calculé la quantité disponible et le stock virtuel d’un produit.

Pour ceux qui ne le savent pas, la quantité disponible représente la quantité de produit qui est actuellement physiquement présente dans un emplacement tandis que le stock virtuel représente la quantité qui sera disponible quand tous les fournisseurs auront livré les commandes et quand la société aura livré tous ses clients. Ce dernier est notamment très utile pour les commerciaux ce qui leur permet de déterminer la quantité de produits qu’ils peuvent promettre à leurs clients.

Ces champs sont mis à jour dynamiquement en fonction des mouvements de stocks, que ce soit des produits entrants, expéditions etc…

Le problème qui se posait, c’est que la structure des emplacements ayant été modifiée, les quantités disponibles et stocks virtuels de tous les produits restaient invariablement à 0. Cela nous a poussé à chercher comment étaient calculés ces champs, et notamment quels emplacements de stock étaient considérés par OpenERP comme faisant parti du stock de la société et donc comme produit disponible.

Nous avons d’abord pensé que tous les emplacements ayant le type “emplacement interne” étaient pris en compte, ce qui était faux. Nous avons également pensé qu’il fallait obligatoirement garder les emplacement “Emplacement physique” / “nom de la société” / “Stock” définis par défaut mais c’était faux également.

Ne trouvant pas l’information sur Internet, nous avons dû regarder directement dans le code. L’information se trouve dans le fichier product.py du module stock.

En vérité, ils sont basés non sur les emplacements mais sur les entrepots (stock.warehouse). Ceux-ci ont un emplacement stock et c’est celui-ci qui est utilisé pour le calcul des quantités disponibles du produit. Ainsi, les quantités disponibles d’un produit sont les quantités de ce produit dans tous les emplacement de stock de tous les entrepôt existants.
Si vous avez à modifier vos emplacement de stock, n’oubliez donc pas de renseigner l’emplacement de stock de vos entrepots.

Pour information supplémentaire, sachez que lorsque vous consulter la liste des produits en créant un devis, la liste des produits affiche uniquement les quantités disponibles dans l’entrepot du magasin de la commande, et donc uniquement l’emplacement de stock et ses emplacements fils de cet entrepot. Sur la fiche produit, en revanche tous les entrepots sont pris en compte.

Le client nous a également demandé que seul les produits ayant une quantité différente de zéro (dans le cas du client, seulement 40 produits au lieu de 2000…) soient affichés quand on consulte les produits d’un emplacement de stock. Pour les plus techniques d’entre vous, voici le code qu’on a implanté dans le module stock.

Il vous faut modifier le fichier stock/wizard/wizard_location_product.py et remplacer la fonction _action_open_windows par celle-ci :

def _action_open_window(self, cr, uid, data, context):

self.pool = pooler.get_pool(cr.dbname)
product_obj = self.pool.get(‘product.product’)

product_ids = product_obj.search(cr, uid, [(‘active’,’=’,True)])
prod_context = {‘location': data[‘ids’][0],’from_date':data[‘form’][‘from_date’],’to_date':data[‘form’][‘to_date’]}
products = product_obj.read(cr, uid, product_ids, [‘qty_available’,’virtual_available’], prod_context)

res = []

for product in products:
if (product[‘qty_available’] > 0) or (product[‘virtual_available’] > 0):
res = res + [product[‘id’]]

return {
‘name': False,
‘view_type': ‘form’,
“view_mode”: ‘tree,form’,
‘res_model': ‘product.product’,
‘type': ‘ir.actions.act_window’,
‘context':{‘location': data[‘ids’][0],’from_date':data[‘form’][‘from_date’],’to_date':data[‘form’][‘to_date’]},
‘domain':[(‘type’,'<>’,’service’),(‘id’,’in’,res)]
}

Il n’est pas certain que Tiny accepte ce code car il est très consommateur en ressource système (il doit passer les 2000 produits ayant la case “actif” cochée en revue et calculer leurs quantités disponibles avant de sélectionner ceux qui apparaitront), mais c’est il est vrai une amélioration ergonomique notable que de pouvoir afficher que les produits présents dans l’emplacement consulté.

New resources available for OpenERP: Process and Training Plans

Greetings,

There’s definitely a lot of things happening this month, and not just the V6 which begin to come. Here at Synerpgy, there is no less than three new important process that was modeled and two training plans now freely available on our website.

Thus, we can include :

About training plans, the entire accounting training plan is now available on the site. Moreover, the first part (development through graphical interface) of the technical training plan is also available. I hope these training plans can help people who can’t or don’t want to pay for training.

Unfortunately, and as usual, these resources are only in French, sorry for the english-speaking people. If someone want to translate, feel free.

All these documents are licensed as Creative Commons by-sa, do not hesitate to use it as long as you meet the conditions of the license. See you later!