Pesquisar neste blogue

Mostrar mensagens com a etiqueta odoo. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta odoo. Mostrar todas as mensagens

quarta-feira, 20 de dezembro de 2017

When we didn't call it a blockchain




Blockchain seems to be one of the buzz words in the tech world right now - at WebSummit 2017 for sure one of the 3 top words i retained - and some hope with a bright future ahead.
For the non tech it's the way bitcoin works.
Trying to learn more about the technology i came across Learn Blockchains by making one.
And a sentence resonated with something i had done in the past
At this point, the idea of a chain should be apparent—each new block contains within itself, the hash of the previous Block
SAFT-PT (Standard Audit File for Tax purposes Portuguese Version) uses this method to easily identify and verify the correctness of a series of invoices and other tax related documents.
Part of my first job was implementing this on what was then OpenERP (now Odoo) in order to get the program certified by the DGCI (Portugal's main Institute of tax related matters). If you wish to take a closer look at file's structure it is available at SAFT-PT XSD.

Each block is formed by
  • InvoiceDate
  • SystemEntryDate
  • InvoiceNo
  • GrossTotal
  • Hash (hash of the former document thus creating a chain)

DGCI supplies a validator for the file given the public key and the SAFT-PT file.
On any invoice you will find a sequence of 4 characters (corresponding to the 1º, o 11º, o 21º e o 31º digits of the store signature) followed by the name of the certified company.
If you use Odoo and wish to take a look at a base implementation it can be found here - Odoo SAFT-PT- it is not complete and but it should be nice as a basis for a complete implementation.


PS: This article is also available at my LinkedIn.

quarta-feira, 28 de outubro de 2015

New job new life new projects.

It seems i have left this place a bit scarse on news for a while now. Starting a new job and getting used to new routines made me neglect this place a bit.
That does not mean i have not been busy :) :

  • Working on Spring + JPA + AOP and learning how to deal with some strange errors (if you follow this blog and wish some tutorials and/or to get around common errors please let me know)
  • A project i have started in between jobs, leveraging odoo to implement tracking of e-procurement contracts (adapted to the Portuguese reality as that is the one i am more familiarized with) . Connecting those with Odoo projects allows for some really nice features ( https://www.odoo.com/page/project-management. ). 
  • Working with my good friends at https://www.linkedin.com/company/good-omens-webstudio (if you do work in Morocco do check them out, they are great at what they do).
  • Uploading "Templo dos Jogos" to the Youtube (https://www.youtube.com/channel/UC3QNejga3cw69-NvmFvjyWA/videos )

On a side topic, are there any UK citizens following this blog? I have received some jobs offers from the U.K and i do have a passion for that country, more than for my own country Portugal sometimes (and god knows how it is decreasing), so moving to the  U.K would be a long time project with hopefully citizenship involved. How is it like to be an UK citizen?


sexta-feira, 17 de julho de 2015

Playing with Odoo and Tesseract.

During these lasts days i have been reading things about Odoo and how it had improved since i last worked on it professionally and i came across  Basics-developing-simple-module-openerp a great resource for anyone wanting to start working on Odoo.
So work started on document_scanner, a plugin for Odoo, which uses Tesseract to import pictures and convert them to text .

 The entry point of a Odoo plugin is the __init__.py file and as my plugin is written on document_scanner.py my __init__.py file looks like


1
2
3
# -*- coding: utf-8 -*-

import document_scanner


Next lets take a look at the __openerp__.py file where you must include the dependencies, the description and your personal information which will be visible to the user when the plugin is installed. My file looks like:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    'name': 'Document Scanner',
    'version': '1.0',
    'category': 'Tools',
    'description': """
Module which uses OCR to treat image files in Odoo.
==============================================
    """,
    'author': 'Rui Caridade',
    'depends': ['base','document'],
    'data': ['document_scanner_view.xml'],
    'demo': [], 
    'installable': True,
    'auto_install': False
}


which visually translates to


On the __openerp__.py file if you notice there is a reference to a xml file "document_scanner_view.xml" which is where the look and feel of the plugin is defined.
On document_scanner the xml file looks like :


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data>

        <record id="document_scanner_wizard_view_form" model="ir.ui.view">
            <field name="name">document.scanner.wizard.form</field>
            <field name="model">document.scanner.wizard</field>
            <field name="arch" type="xml">
             <form string="Document Scanner">
                <group col="4">
                <field name="data"/>
                </group>
                <group col="4">
                    <field name="textoDaImagem"/>
                </group>
                    <button name="import_file" string="Import" type="object" />
                    <button icon="gtk-cancel" special="cancel" string="Cancel"/>
            </form>
            </field>
        </record>
        
     <record model="ir.actions.act_window" id="action_document_scanner_form">
        <field name="name">Document Scanner</field>
        <field name="type">ir.actions.act_window</field>
        <field name="res_model">document.scanner.wizard</field>
        <field name="view_type">form</field>
        <field name="view_mode">form</field>
        <field name="target">new</field>
    </record>
        
     <record id="action_dir_doc_scanner_view" model="ir.actions.act_window.view">
        <field name="view_mode">form</field>
        <field name="view_id" ref="document_scanner_wizard_view_form"/>
        <field name="act_window_id" ref="action_document_scanner_form"/>
    </record>

    <menuitem
        action="action_document_scanner_form"
        id="menu_document_scanner"
        parent="knowledge.menu_document_configuration"/>


    </data>
</openerp>


To better understand the file i recommend you read it from the menuitem till the top.

After that was done i needed to find a picture to test and i found Factura Vaca

The end result

 
The text is not quite right yet, still have to look into it. Still thinking on how i can improve this plugin. Any suggestions?



sexta-feira, 3 de julho de 2015

Starting with Odoo - Part 1

Some years ago i worked professionaly with OpenERP in its version 5 and 6 for a small portuguese company called OpenSecure . Life takes you in different routes sometimes and i lost track of its development, which made Odoo a really pleasant surprise.
So in order to refresh my own knowledge of OpenErp and Python i decided to do a series of tutorials, or if you prefer progress reports,where we'll be making a simple app for Odoo , a document scanner using tesseract ocr ( Tesseract-ocr ).

First we need to install Odoo.
The most complete tutorial, really a great job people , can be found here - how-to-install-openerp-odoo-8-on-ubuntu-server -

We'll also need a python binding for tesseract -  pytesseract  - which means in Ubuntu or in your OS choice you may need also to install pip.

In the Part 2 i'll describe the anotomy of an OpenERP app and how to use   pytesseract to extract information from an image file.
If you can identify which kind of document it is the really fun part can begin :).


terça-feira, 30 de junho de 2015

Javascript idiosyncrasies

To start this blog nothing better than a Javascript behaviour i noticed while working on a given project.
Let's say you submit a date like '2015-06-31' which is invalid. Javascript will do the smart thing, really people
, and consider that date as '2015-07-01' if you create a Date object out of it.
Searching for a solution i came across the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function isDate(txtDate)
{
    var currVal = txtDate;
    if(currVal == '')
        return false;

    var rxDatePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/; //Declare Regex
    var dtArray = currVal.match(rxDatePattern); // is format OK?

    if (dtArray == null) 
        return false;

    dtMonth = dtArray[3];
    dtDay= dtArray[5];
    dtYear = dtArray[1];        

    if (dtMonth < 1 || dtMonth > 12) 
        return false;
    else if (dtDay < 1 || dtDay> 31) 
        return false;
    else if ((dtMonth==4 || dtMonth==6 || dtMonth==9 || dtMonth==11) && dtDay ==31) 
        return false;
    else if (dtMonth == 2) 
    {
        var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
        if (dtDay> 29 || (dtDay ==29 && !isleap)) 
                return false;
    }
    return true;
}

From : http://stackoverflow.com/questions/18758772/how-do-i-validate-a-date-in-this-format-yyyy-mm-dd-using-jquery


It seems pretty complete and it has a special case to workaround the behavior at the start of this post.
As an alternative you could create a new Date object and compare dtMonth and dtDay and dtYear to be the same as before.
 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
function isDate(txtDate)
{
    var currVal = txtDate;
    if(currVal == '')
        return false;
    
    var rxDatePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/; //Declare Regex
    var dtArray = currVal.match(rxDatePattern); // is format OK?
    
    if (dtArray == null) 
        return false;
    
    dtMonth = dtArray[3];
    dtDay=  dtArray[5];
    dtYear = dtArray[1];
    
  
    var date = new Date(txtDate);

    return (date.getMonth()==(dtMonth-1) && date.getDate()==dtDay && date.getFullYear()==dtYear);
}
 
You can test it here - http://jsfiddle.net/EywSP/2282/ 
 
The month count being from 0 to 11 also makes perfect sense.

My next post will focus on odoo and how to implement a simple questionnaire framework for your clients.