Odoo : show amount in letters in Invoices PDF reports

In some countries like Madagascar, invoices must states the total amount in letters additionally to the numbers. This basic need is unfortunately difficult to get with the current version of Odoo online (Odoo online v16-sass-1). I had to edit the Invoice report template manually to add the amount in letters.

This tutorial is is long and painful so hang tight!

There are 3 steps to do it in a (kind of) future proof way

  1. Duplicate the main invoice template and add the magic code
  2. Duplicate the specific report view and make it point to the new invoice template
  3. Duplicate the report entry and make it point to the specific report view

Step 1. Duplicate the invoice template in Odoo

  • Activate debug mode and goto General Setting > Menu Technical > User Interface > Views
    You can browse this url (change your-adress.com with yours) : https://your-adress.com/web?debug=1&reload=true#action=29&model=ir.ui.view&view_type=list&cids=1&menu_id=45
  • Search for the view named report_invoice_document, clic on it to edit, but do not change this view as it’s a default view and would not be updated automatically if changed. The Odoo update process do not overwrite your changes.
  • Instead clic on the button Action > Duplicate (on the top right) and name your new View a little bit differently for example : report_invoice_document_letters
  • Then add this code to add the amount in letter is this one :
    <span>
    Arrêtée la présente facture à la somme de <span t-out="o.currency_id.amount_to_text(o.amount_total)"/>.
    </span>

    This code use the Currency object of the current invoice to format the total amount using the partner language. If you want another language, you’ll be able to change it in the second part of this tutorial
    You can put the code where it makes sense to you. If you’re stranger to HTML then you’re in trouble 😅. I recommend that you put this code just after the </table> below the total_tax widget. Feel free to let me know in comments if the previous doesn’t make sentence to you.
  • Save your duplicated View and record its database id. The Id of your view is a number and visible in the current url of your browser just after the id=  
  • Add an external id to your new template. To do so, go to General Setting > Menu Technical > Sequence and Identifiers > External Identifiers
    Or go to : https://nivo.odoo.com/web?debug=1&reload=true#action=21&model=ir.model.data&view_type=list&cids=1&menu_id=37
  • Clic on the New button on the top left and fil the following information
    • Module : mycompany  (of course, put your company name or any module name you want)
    • External Id : report_invoice_document_letters (the name of the template you previously created)
    • Model : ir.ui.view  (this is to say that we’re pointing to a view)
    • Record Id : The id of the view you created previously (I asked you to note it somewhere, remember ? 😉 )

Step 2. Duplicate the report view in Odoo

  • Activate debug mode and goto General Setting > Menu Technical > User Interface > Views
    You can browse this url (change your-adress.com with yours) : https://your-adress.com/web?debug=1&reload=true#action=29&model=ir.ui.view&view_type=list&cids=1&menu_id=45
  • For tweaking the Invoices with payment report, search for the view named  report_invoice_with_payments, clic on it to edit, but do not change this view as it’s a default view and would not be updated automatically if changed
  • Instead clic on the button Action > Duplicate (on the top right) and name your new View a little bit differently for example : report_invoice_with_payments_letters
  • Then change the code t-call=”account.report_invoice_document” to t-call=”mycompany.report_invoice_document_letters”
    Note that mycompany should be the module name you chose in the previous step
  • Save your duplicated View and note its database id. The Id of your view is a number and visible in the current url of your browser just after the id=  
  • Add an external id to your new template. To do so, go to General Setting > Menu Technical > Sequence and Identifiers > External Identifiers
    Or go to : https://nivo.odoo.com/web?debug=1&reload=true#action=21&model=ir.model.data&view_type=list&cids=1&menu_id=37
  • Clic on the New button on the top left and fil the following information
    • Module : mycompany  (of course, put your company name or any module name you want)
    • External Id : report_invoice_with_payments_letters (the name of the template you previously created)
    • Model : ir.ui.view  (this is to say that we’re pointing to a view)
    • Record Id : The id of the view you created previously (I asked you to note it somewhere, remember ? 😉 You’re not crazy, it’s the second time you do this but with a slightly different id)

Don’t quit now. You’re only one step ahead of success 🙂

Step 3. Duplicate the report entry

  • Activate debug mode and goto General Setting > Menu Technical > Actions >
    Report 
    You can browse this url (change your-adress.com with yours) : https://nivo.odoo.com/web?debug=1&reload=true#action=6&model=ir.actions.report&view_type=list&menu_id=4&cids=1
  • Search for report_invoice_with_payments, you should get a row named Invoices using the model repot_invoice_with_payments. Clic on it to edit, but do not change this report as it’s a default item and would not be updated automatically if changed
  • Instead clic on the button Action > Duplicate (on the top right) and name your new Report a little bit differently for example : Invoices with letters
  • Then change the report this way :
    • Model : account.move  (do not change it)
    • Report name : mycompany.report_invoice_with_payments_letters (the module and the name you chose in the previous step)
  • Save your duplicated report
  • Clic on the smart button Add to “Print” menu on the top right of the screen

Done ! You have a new invoice report which shows the amounts in letters.
If you have more questions, feel free to contact at manitra [at] manitra [dot] net .

Tips

Do not even try to do this with Odoo Studio. I wasted 3 days of my life trying. Odoo Studio tries to use xpath with loosely identified elements to update the report. You will most likely fail to do what you want and will pollute your instance with lot of randomly named elements.

Tips2

Did you actually manage to follow this very long tutorial ? Or where did you get stuck 😉.
Let me know if I wrote some mistakes somewhere, I’ll gladly correct it.

Resolving version conflicts on MsBuild projects with dep.exe

I’ve recently came accross a surprisingly painful task which were about removing a warning.
One of them were the famous “MSB3247: Found conflicts between different version of same dependent assembly”.

After hours of manual troubleshooting I finally created a command line tool called dep.exe to dump the nested dependencies of every assemblies inside a directory to easily

  • Know which assemblies are referenced (directly or indirectly) with more than one version
  • Understand the dependency chain which pulled those assemblies in your bin folder

Everything is explained on the README of dep.exe.
dep.exe output sample
If you happen to have any question or suggestions, just post them in the comment section.

How to Create a Virtual Machine with Ubuntu 15.04 Vivid and VMBuilder?

The need of a Virtual Machine

I recently decided to migrate my dedicated server from Online to OVH and realized that installing a server is extremely painful.
Then I realized that one way to avoid this mess again could be to setup a Virtual Machine so that I could just move that VM to another host later.

How to do it with the command line?

There are plenty of tutorials which explain how to do so. But it looks like the options change every six months. So after hours of experimentation here is what worked for me:

mkdir /var/vms
vmbuilder kvm ubuntu \
	--cpus 2 --arch amd64 \
	--rootsize 65536 \
	--mem 4096 \
	--hostname vm01 \
	--ip 192.168.122.101 --net 192.168.122.0 --mask 255.255.255.0 --gw 192.168.122.1 --bcast 192.168.122.255 --dns 192.168.122.1 \
	--user [USER] --name [YOUR NAME] --pass [PASSWORD] \
	--suite trusty --flavour virtual \
	--addpkg acpid --addpkg linux-image-generic --addpkg vim \
	--mirror "ftp://ubuntu.mirrors.ovh.net/ftp.ubuntu.com/ubuntu" --components main,universe \
	--libvirt qemu:///system \
	--destdir /var/vms/vm01
virsh start vm01
virsh autostart vm01
  • a VM with Ubuntu Trusty as Guest OS run by KVM and controllable with virsh later
  • a NATed network with static IPs
    (the doc doesn’t mention that you need to specify –net and –mask for –ip to be taken into account)
    Note that 192.168.122.0/24 is the default IP range available so you kind of have to choose an IP in that range
  • An automatic startup

Brute force on a .p12 password with c#

It started with a VPN problem

The other day, I had an issue with my VPN and someone from the IT service remotely connected to my machine to put a certificate on it. While he manipulated the certificate manager, he exported a certificate and typed a password of 4 characters that I couldn’t see (characters were obfuscated). Just after that he requested me to use another wifi connection to test the VPN so we had to stop the chat and the remote session. Unfortunatly for me it didn’t work and the guy went to lunch.

So now, I was stuck with no VPN and a certificate which were not working! I decided to delete all the personal certificates having my name from my computer and to re-import the p12 file that the IT guy left on my desktop. I tried to do so but then I was requested to type the password – remember? it was only 4 chars. I tried all the stupid 4 letters password I got in mind (“test”, “1234”, “0000”, “aaaa”, “azer”, “qwert” …) but none of them worked.

Let’s brute force that weak p12 password

So here is the interesting part. I decided to try that very famous thing called “brute force” a password. I was saying in my mind “With my years of programming experience, it should take me 10 minutes to code it and few second to run”.
But actually it took me up to one hour to make the stuff to actually work without obvious bug in C#:

private IEnumerable<string> EnumerateOptions(IList<char> options, int minLength, int maxLength)
{
    var number = new List<int>(maxLength);
    for (int i = 0; i < minLength; i++)
        number.Add(0);

    while (number.Count <= maxLength)
    {
        yield return Stringify(number, options);

        bool overflowed = true;
        for (int numberPart = number.Count - 1; numberPart >= 0 && overflowed; numberPart--)
        {
            number[numberPart]++;
            if (number[numberPart] >= options.Count)
            {
                number[numberPart] = number[numberPart] % options.Count;
            }
            else
            {
                overflowed = false;
            }
        }
        if (overflowed)
            number.Insert(0, 0);
    }
}

private string Stringify(IList<int> number, IList<char> options)
{
    return string.Join("", number.Select(n => options[n]));
}

The result

The app was testing 2k passwords per seconds and found the password in less than 3 minutes 🙂 !

p12-brute-force

The conclusions are

  • don’t use a 4 letters password, obviously, especially on your p12 files which can used to act on your behalf
  • coding simple things can take more time than we expect (think hiring interview questions)
  • The method I’m using to check the password (X509Certificate2Collection.Import) throws an exception when the password is wrong. This makes the process extremelly slow (15x). When you happen to completely ignore the exception (catch(Exception) with a variable), it becomes reasonably faster if you activate the code optimization (Release mode)

That’s it, the code is on Github.  If you happen to spot obvious bugs in the enumerator of passwords, don’t hesitate to let me know with a comment.

 

Criteo Code of Duty 2

Après une première session pleine de succès, Criteo remet ça.

Quoi

Criteo organise un concours de programmation ouvert à tous les passionnés de programmation. Il y a 20 000 € à partager entre les 10 premiers (le premier empochant 10 000 €).

Quand et Ou

La première phase se fait sur le site de programmation codility.com le 02 Juin 2012 à midi. Pour vous inscrire il faut aller :

Comment ça se passe ?

Les qualificatifs

Les qualificatifs se dérouleront sur codility.com et voici le principe de fonctionnement :

  • vous ecrivez votre code sur le site directement (les languages autorisés sont : Java, C++, C#, Javascript, Pascal, Perl, PHP, Python, Ruby, VB.NET, Objective-C et Lua)
  • vous choisissez vos données d’entrées (en général des tableaux d’entiers ou de chaines de caractères, vous pouvez créer plusieurs jeux de données)
  • vous cliquez sur un bouton pour compiler votre code et le tester avec les données d’entrées
  • le site vous informe si votre code a fonctionné avec les données saisies et si ce n’est pas le cas, vous avez du details sur les raisons de l’echec.

La finale

Quant à la finale, vous serez invité à venir au siège de Criteo (Paris) et cette étape se passera dans nos locaux directement.

Donc voila, il ne vous reste plus qu’à vous inscrire : labs.criteo.com/code-of-duty-2

Sweet DevTools

I just published few online tools for developers at devtools.manitra.net and I hope they will allow you to save time. The widgets currently available are :

Those tools already exist on the web but the key stuffs here is that they are :

  • tiny (minimalist web page without blabla about what a base64 encoding is etc ..)
  • embeddable as widget
  • free and ad-free

By the way, they are best used within a netvibes dashboard (Web Page Widget).

Enjoy 🙂

Code of duty : le concours de programmation de Criteo

Criteo, ma société, lance un concours de programmation avec 10 000€ ou 20 IPAD2 à gagner. Les short listés auront de grandes chances d’être embauchés.

Si vous en avez marre des SSII ou des sociétés qui ne jurent que par le prestige des diplômes et que, comme moi vous êtes passionnés par la programmation, c’est le moment de vous bouger et de rejoindre le petit Google français.

p.s : ce n’est pas un jeu vidéo 🙂

How to create deeply nested Asp.net Dynamic Controls ?

Creating controls at runtime (dynamic controls) in Asp.net is both tricky and unintuitive. This article will explain a pattern to make it easier.

The main advantages of this strategy are :
– ability to create deeply nested controls with unlimited depth
– each dynamicaly created controls have normal states (Viewstate is not broken)
– you can create those controls whenever you want (including OnClick events, PreRender and Render phases)
– no hacks with postback arguments are required

[UPDATE (2011/08/01)] : “M” found that the PersistentPanel doesn’t work well when it is instantiated in a markup file (aspx/ascx/master …) so I would advice you to instanciate it via code in the CreateChildControl method. The source code in the bottom of the page have been updated to reflect that.

The online demo

To help you understand what am I talking about here is an online example of deeply nested and dynamically created controls using Asp.Net.

You can create as much nested controls as you want and test that each controls persists its state upon postbacks.

The implementation

The PersistentPanel

The PersistentPanel is just a Panel wich persists its child controls collection using the viewstate automatically. This is a key control because it recreates the dynamically created controls on each post back during the right life-cycle phase : OnLoadViewstate. Thanks to this early recreation, those controls can persist their state in the ViewState like any controls declared in the markup page during the design time.

This kind of component is quite common now a days but the particularity here is that I do not try to persits all the nested controls but only the direct children. Indeed, if you try to persist and recreate the whole hierarchy, you’ll encounter problems and will have to handle a lot of special cases. More over since event handlers are not persisted, the restored components wont work.

The implementation process of the PersitentPanel :

  • during the save process of the viewstate we save the control hierarchy (type+Id only) using a serializable entity that store the control type, its Id and and a list of children
  • during the restore process of the viewstate we refill the Controls collection using the previously saved control hierarchy
    public class PersistentPanel : Panel
    {
        private static string ControlsViewStateKey = "Controls";
        public int MaxDepth
        {
            get
            {
                var value = ViewState["MaxDepth"];
                if (value != null) return (int)value;
                return 1;
            }
            set
            {
                ViewState["MaxDepth"] = value;
            }
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            var persisted = (ControlEntity)ViewState[ControlsViewStateKey];
            if (persisted != null)
                foreach (var child in persisted.Children)
                    Controls.Add(child.ToControl());
        }

        protected override object SaveViewState()
        {
            ViewState[ControlsViewStateKey] = new ControlEntity(this, MaxDepth);
            var result = base.SaveViewState();
            return result;
        }
    }

The parent of the dynamic controls

The component wich will dynamicaly create the controls will first embed a PersistentPanel. And each time it will want to add a control it will add that control in the PersistentPanel’s controls collection. Here is an example :

public class CustomerView : Page {
    private PersistentPanel ctlPanel;
    // ------ //
    protected void ctlAdd_click(object sender, EventArgs e){
        ctlPanel.Controls.Add(new Textbox{Text=Datetime.Now.ToString();});
    }

}

Combining both to build a hierarchical data editor

Now we have a persistant panel and know that dynamically created controls are persisted, we’ll create a control that would create other complexes controls wich will have the same type as their creator. This would give us a powerfull control that would be able to display or edit hierarchical data wich, in our case, is a filter expression. We’ll have
– a control to edit scalar filter
– a control to edit composite filter
The scalar filter will just contain 3 simple controls for the field name, the operator and the value. The composite filter editor will be the interesting one. Indeed, it’s gonna contains a variable number of scalar editor and other composite filter editor. So it will use a persistant panel to host those nested controls. And that’s it !

public class compositeView : WebControl, INamingContainer

Conclusion

The important things to remember are that :
– a control can be created at anytime, but it must be recreated on each postback during/before the LoadViewState of its container
– the ID of the dynamic control must be the same
– event handlers are not persisted, you have to rewire them up on each postback, the PersistantPanel has the ControlRestored event wich is the best place to do so.

Download the source code

The online demo application is available here :

Have fun !

Concise C# Part 3 : C# 3 shortcuts

The version 3 of C# brings us a lot of syntactic sugar to reduce the length of our code. Here are some of them.

This post is part of a serie about making C# code shorter.

Constructors with Property initializers

//Verbose and Ugly
Post value = new Post();
value.Title = "New Version For C#";
value.CreatedOn = DateTime.Now;
CreatePost(value);

//Concise and Sweet
CreatePost(new Post
{
    Title = "NewVersion For C#",
    CreatedOn = DateTime.Now
});

Collection initializers

//Verbose and Ugly
var names = new List();
names.Add("manitra");
names.Add("yeah");
SaveNames(names);

//Concise and Sweet
SaveNames(new List { "manitra", "yeah" });

Var keyword

//Verbose and Ugly
Dictionary> result = new Dictionary>();

//Concise and Sweet (But still strongly typed)
var result = new Dictionary>();

Automatic properties

//Verbose and Ugly
public class Post
{
    private string title;
    private string description;
    private DateTime createdOn;

    public string Title
    {
        get
        {
            return this.title;
        }
        set
        {
            this.title = value;
        }
    }

    public string Description
    {
        get
        {
            return this.description;
        }
        set
        {
            this.description = value;
        }
    }

    public System.DateTime CreatedOn
    {
        get
        {
            return this.createdOn;
        }
        set
        {
            this.createdOn = value;
        }
    }
}

//Concise and Sweet
public class Post
{
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTime CreatedOn { get; set; }
}