• Introduzione

  • Come funziona Odoo

  • Moduli aggiuntivi

  • Modifiche di base

  • Funzioni standard

  • Debug

  • Q-Web

  • Tecniche avanzate

  • Odoo History

    • ORM
    • I tipi di file:
      • *.py
      • *.xml
      • *.csv
      • altri file
    • Workflows
    • l10n-italy
    • server-tools
    • web
  • inherit, inherits

    • inheritance
    • prototype inheritance
    • delegation
  • Aggiungere un campo

    Due modalità di modificare Odoo:

    • Modifica da interfaccia (quando può essere utile, quando evitarla)
    • Modifica da codice

    Scrittura del modulo

    Modifiche di base riguardano i model e i view.

    • Creare cartella per gli Addon Custom
    • Modificare file di configurazione
    • Creare un modulo nuovo
      • Struttura modulo
        • __init__.py
        • __openerp__.py
        • models/
        • views/
        • README.rst
    • Estendere il Model
      • Nota: richiede riavvio
    • Estendere il View
      • Nota: richiede l’aggiornamento
  • Aggiungere e collegare una tabella

    Tabella Animals:

    • Name
    • Type
    • Sex
    • Age
    • owner_id
    • owner_phone
    • active

    L’esempio si può scaricare da:
    https://github.com/andreinl/vet_clinic

  • Funzioni standard di un Model

    • create(self, values)
    • write(self, values)
    • copy(self, defaults)
    • copy_data(self, default=None)
    • unlink(self)
    • onchange_field_name(self, variable)
    • search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)
      name_search(self, name, args=None, operator=’ilike’, context=None, limit=100)
    • name_get(self)
    • default_get(self, fields)
    • get_object_reference(self, cr, uid, module, xml_id)
    • browse(self, object_id)
  • Creare / aggiornare record con le connessioni One2many (Ex: Sale Order con Sale Order Lines):

    • (0, False, { values }) link to a new record that needs to be created with the given values dictionary
    • (1, ID, { values }) update the linked record with id = ID (write values on it)
    • (2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)
    • (3, ID) cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself)
    • (4, ID) link to existing record with id = ID (adds a relationship)
    • (5) unlink all (like using (3, ID) for all linked records)
    • (6, False, [IDs]) replace the list of linked IDs (like using (5) then (4, ID) for each ID in the list of IDs)
  • Wizard

    The most frequent reason for changing a view is the necessity to show newly created record. In this example we pass to a new view the invoice_id:

    view = self.env['ir.model.data'].get_object_reference('account', 'invoice_form')
    view_id = view and view[1] or False
    
    return {
        'type': 'ir.actions.act_window',
        'name': _('Customer Invoices'),
        'res_model': 'account.invoice',
        'view_type': 'form',
        'view_mode': 'form',
        'view_id': [view_id],
        'target': 'current',
        'res_id': invoice_id,
        'context': "{'type':'out_invoice'}",
    }
  • Debug con standard Python debugger

    import pdb
    pdb.set_trace()

    Debug dentro PyCharm

    • Setup PyCharm Editor per eseguire e debuggare Odoo
    • Modifica file openerp/__init__.py per essere eseguito dentro PyCharm. Commentare il codice (line: 30):

        if sys.modules.get("gevent") is not None:
            evented = True
  • Logging

    • debug
        --log-level debug
    • debug_sql
    • debug_rpc
    • debug_rpc_answer
    • info
    • warn
    • error
    • critical
  • Utilizzo del JSON-RPC per testare le funzioni

    • Passare una variabile dentro context
    • Impostare il valore di default
  • Tiny ERP

    • 1.0 February 2005 First release GNU GPL
    • 2.0 May 2005
    • 3.0 September 2005
    • 4.0 December 2006

    OpenERP

    • 5.0 April 2009
    • 6.0 January 2011 First web client GNU AGPL
    • 6.1 February 2012 First Ajax web client, discontinued GTK client
    • 7.0 December 22, 2012 Improved web client and usability

    Odoo

    • 8.0 September 18, 2014 Website builder, e-commerce, point of sale and business intelligence, New API syntax
    • 9.0 October 1, 2015 Odoo Community split from Odoo Enterprise, GNU LGPL v3
    • 10.0 October 5, 2016 Removed support for old API
    • La funzione “Old style”
    • Operatori del domain:
      • List of Domain operators: ! (Not), | (Or), & (And)
      • List of Term operators: ‘=’, ‘!=’, ‘<=’, ‘<’, ‘>’, ‘>=’, ‘=?’, ‘=like’, ‘=ilike’, ‘like’, ‘not like’, ‘ilike’, ‘not ilike’, ‘in’, ‘not in’, ‘child_of’
{"cards":[{"_id":"71356456478d015a19000013","treeId":"71356116478d015a19000010","seq":8802661,"position":1,"parentId":null,"content":"## Introduzione\n"},{"_id":"713578024086536b5d000007","treeId":"71356116478d015a19000010","seq":8802674,"position":1,"parentId":"71356456478d015a19000013","content":"### Odoo History\n"},{"_id":"71357a234086536b5d000008","treeId":"71356116478d015a19000010","seq":8802591,"position":1,"parentId":"713578024086536b5d000007","content":"**Tiny ERP**\n* 1.0\tFebruary 2005\tFirst release\tGNU GPL\n* 2.0\tMay 2005\n* 3.0\tSeptember 2005\t\n* 4.0\tDecember 2006\n\n**OpenERP**\n * 5.0\tApril 2009\n * 6.0\tJanuary 2011\tFirst web client\tGNU AGPL\n * 6.1\tFebruary 2012\tFirst Ajax web client, discontinued GTK client\n * 7.0\tDecember 22, 2012\tImproved web client and usability\n\n**Odoo**\n * 8.0\tSeptember 18, 2014\tWebsite builder, e-commerce, point of sale and business intelligence, New API syntax\n * 9.0\tOctober 1, 2015 Odoo Community split from Odoo Enterprise, GNU LGPL v3\n * 10.0\tOctober 5, 2016 Removed support for old API\n"},{"_id":"715257688fc23e985e000048","treeId":"71356116478d015a19000010","seq":8818342,"position":1,"parentId":"71357a234086536b5d000008","content":"Links\nhttp://blog.karmacomputing.co.uk/an-odoo-review-how-odoo-could-be-so-much-better-for-smes/"},{"_id":"71356fab478d015a19000014","treeId":"71356116478d015a19000010","seq":8802662,"position":2,"parentId":null,"content":"## Come funziona Odoo\n"},{"_id":"7135ab584086536b5d000009","treeId":"71356116478d015a19000010","seq":8802667,"position":1,"parentId":"71356fab478d015a19000014","content":"* **ORM**\n* I tipi di file:\n * *.py\n * *.xml\n * *.csv\n * altri file\n* **Workflows**\n"},{"_id":"7135ae894086536b5d00000a","treeId":"71356116478d015a19000010","seq":8802618,"position":1,"parentId":"7135ab584086536b5d000009","content":"**Links**\nhttp://bloopark.de/en_US/blog/the-bloopark-times-english-2/post/odoo-10-workflows-partial-removal-265"},{"_id":"7136ae5e8fc23e985e000017","treeId":"71356116478d015a19000010","seq":8802864,"position":2.5,"parentId":null,"content":"## Moduli aggiuntivi\n"},{"_id":"7136afc58fc23e985e000018","treeId":"71356116478d015a19000010","seq":8824786,"position":1,"parentId":"7136ae5e8fc23e985e000017","content":"* l10n-italy\n* server-tools\n* web\n"},{"_id":"714f2d188fc23e985e000046","treeId":"71356116478d015a19000010","seq":8816865,"position":2,"parentId":"7136ae5e8fc23e985e000017","content":"### inherit, inherits\n * inheritance\n * prototype inheritance\n * delegation\n"},{"_id":"714f2e818fc23e985e000047","treeId":"71356116478d015a19000010","seq":8816862,"position":1,"parentId":"714f2d188fc23e985e000046","content":"Links\nhttps://www.odoo.com/forum/how-to/developers-13/whats-the-difference-between-inherit-and-inherits-52205\n"},{"_id":"7135ba2e4086536b5d00000b","treeId":"71356116478d015a19000010","seq":8802671,"position":3,"parentId":null,"content":"## Modifiche di base\n"},{"_id":"7135c4534086536b5d00000e","treeId":"71356116478d015a19000010","seq":8815261,"position":1,"parentId":"7135ba2e4086536b5d00000b","content":"### Aggiungere un campo\nDue modalità di modificare Odoo:\n * Modifica da interfaccia (quando può essere utile, quando evitarla)\n * Modifica da codice\n\n\n#### Scrittura del modulo\nModifiche di base riguardano i model e i view.\n\n* Creare cartella per gli Addon Custom\n* Modificare file di configurazione\n* Creare un modulo nuovo\n * Struttura modulo\n * &#95;&#95;init&#95;&#95;.py\n * &#95;&#95;openerp&#95;&#95;.py\n * models/\n * views/\n * README.rst\n* Estendere il **Model**\n * Nota: richiede riavvio\n* Estendere il **View**\n * Nota: richiede l'aggiornamento\n"},{"_id":"714df8718fc23e985e000045","treeId":"71356116478d015a19000010","seq":8847382,"position":2,"parentId":"7135ba2e4086536b5d00000b","content":"### Aggiungere e collegare una tabella\n\nTabella **Animals**:\n * Name\n * Type\n * Sex\n * Age\n * owner_id\n * owner_phone\n * active\n\nL'esempio si può scaricare da:\nhttps://github.com/andreinl/vet_clinic"},{"_id":"713672a9304487beb8000012","treeId":"71356116478d015a19000010","seq":8847350,"position":3.5,"parentId":null,"content":"## Funzioni standard\n\n"},{"_id":"713673bf304487beb8000013","treeId":"71356116478d015a19000010","seq":8847371,"position":1,"parentId":"713672a9304487beb8000012","content":"### Funzioni standard di un Model\n\n* create(self, values)\n* write(self, values)\n* copy(self, defaults)\n* copy_data(self, default=None)\n* unlink(self)\n* onchange_field_name(self, variable)\n* search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)\nname_search(self, name, args=None, operator=’ilike’, context=None, limit=100)\n* name_get(self)\n* default_get(self, fields)\n* get_object_reference(self, cr, uid, module, xml_id)\n* browse(self, object_id)"},{"_id":"71406efc8fc23e985e000041","treeId":"71356116478d015a19000010","seq":8807838,"position":1,"parentId":"713673bf304487beb8000013","content":"#### Search\n* La funzione \"Old style\"\n* Operatori del domain:\n * List of Domain operators: ! (Not), | (Or), & (And)\n * List of Term operators: '=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of'"},{"_id":"71406f628fc23e985e000042","treeId":"71356116478d015a19000010","seq":8807839,"position":1,"parentId":"71406efc8fc23e985e000041","content":"http://stackoverflow.com/questions/29442993/available-domain-operator-in-openerp-odoo"},{"_id":"7183f1dd7f9078d595000029","treeId":"71356116478d015a19000010","seq":8847372,"position":2,"parentId":"713672a9304487beb8000012","content":"### Creare / aggiornare record con le connessioni One2many (Ex: Sale Order con Sale Order Lines):\n * **(0, False, { values })** link to a new record that needs to be created with the given values dictionary\n * **(1, ID, { values })** update the linked record with id = ID (write values on it)\n * **(2, ID)** remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)\n * **(3, ID)** cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself)\n * **(4, ID)** link to existing record with id = ID (adds a relationship)\n * **(5)** unlink all (like using (3, ID) for all linked records)\n * **(6, False, [IDs])** replace the list of linked IDs (like using * * (5) then (4, ID) for each ID in the list of IDs)"},{"_id":"7183f2d67f9078d59500002a","treeId":"71356116478d015a19000010","seq":8847380,"position":3,"parentId":"713672a9304487beb8000012","content":"### Wizard\n\nThe most frequent reason for changing a view is the necessity to show newly created record. In this example we pass to a new view the **invoice_id**:\n\n view = self.env['ir.model.data'].get_object_reference('account', 'invoice_form')\n view_id = view and view[1] or False\n\n return {\n 'type': 'ir.actions.act_window',\n 'name': _('Customer Invoices'),\n 'res_model': 'account.invoice',\n 'view_type': 'form',\n 'view_mode': 'form',\n 'view_id': [view_id],\n 'target': 'current',\n 'res_id': invoice_id,\n 'context': \"{'type':'out_invoice'}\",\n }"},{"_id":"71368e05304487beb8000014","treeId":"71356116478d015a19000010","seq":8802820,"position":3.75,"parentId":null,"content":"## Debug"},{"_id":"71369445304487beb8000015","treeId":"71356116478d015a19000010","seq":8837255,"position":3,"parentId":"71368e05304487beb8000014","content":"### Debug con standard Python debugger\n import pdb\n pdb.set_trace()\n\n### Debug dentro PyCharm \n* Setup PyCharm Editor per eseguire e debuggare Odoo\n* Modifica file openerp/&#95;&#95;init&#95;&#95;.py per essere eseguito dentro PyCharm. Commentare il codice (line: 30):\n\n if sys.modules.get(\"gevent\") is not None:\n evented = True\n"},{"_id":"714053488fc23e985e00003f","treeId":"71356116478d015a19000010","seq":8824926,"position":3.25,"parentId":"71368e05304487beb8000014","content":"### Logging\n* debug\n --log-level debug\n* debug_sql \n* debug_rpc\n* debug_rpc_answer\n* info\n* warn\n* error\n* critical\n"},{"_id":"714065c78fc23e985e000040","treeId":"71356116478d015a19000010","seq":8824892,"position":1,"parentId":"714053488fc23e985e00003f","content":"Links\nhttp://www.mindissoftware.com/Odoo-logging-configuration-usage-implementation/"},{"_id":"713b7c6f8fc23e985e00003d","treeId":"71356116478d015a19000010","seq":8824761,"position":3.5,"parentId":"71368e05304487beb8000014","content":"### Utilizzo del JSON-RPC per testare le funzioni"},{"_id":"716b636c1380c00297000026","treeId":"71356116478d015a19000010","seq":8831755,"position":1,"parentId":"713b7c6f8fc23e985e00003d","content":"Links\nhttps://www.odoo.com/documentation/8.0/howtos/backend.html"},{"_id":"7136a6cd8fc23e985e000015","treeId":"71356116478d015a19000010","seq":8802853,"position":3.875,"parentId":null,"content":"## Q-Web"},{"_id":"7136be2d8fc23e985e00003c","treeId":"71356116478d015a19000010","seq":8847349,"position":1,"parentId":"7136a6cd8fc23e985e000015","content":" * Layout (Formato carta, posizione header)\n * *.css\n * Translation\n * main template\n\naddons/sale/views/report_saleorder.xml\n\nApertura report da browser:\n * http://localhost:8069/report/html/sale.report_saleorder/1\n * http://localhost:8069/report/pdf/sale.report_saleorder/1\n"},{"_id":"7149690a8fc23e985e000044","treeId":"71356116478d015a19000010","seq":8814425,"position":1,"parentId":"7136be2d8fc23e985e00003c","content":"Links\nhttp://odoo.guide/report-design-workshop/\n"},{"_id":"713614354086536b5d00000f","treeId":"71356116478d015a19000010","seq":8802678,"position":5,"parentId":null,"content":"## Tecniche avanzate"},{"_id":"71361b524086536b5d000010","treeId":"71356116478d015a19000010","seq":8802860,"position":1,"parentId":"713614354086536b5d00000f","content":"* Passare una variabile dentro *context*\n* Impostare il valore di default\n\n"}],"tree":{"_id":"71356116478d015a19000010","name":"Programming Odoo 8.0","publicUrl":"programming-odoo-8-0"}}