Diferencia entre revisiones de «Millores en la vista en Odoo»

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda
(Página creada con «=== Millores en les vistes tree === En les vistes tree es pot modificar el '''color''' en funció del contingut d'un field amb l'etiqueta '''decoration''', que utilitza col…»)
 
Línea 1: Línea 1:
=== Millores en les vistes tree ===
=== Millores en les vistes tree ===
==== Colors ====
En les vistes tree es pot modificar el '''color''' en funció del contingut d'un field amb l'etiqueta '''decoration''', que utilitza colors contextuals de '''Bootstrap''':
En les vistes tree es pot modificar el '''color''' en funció del contingut d'un field amb l'etiqueta '''decoration''', que utilitza colors contextuals de '''Bootstrap''':
     decoration-bf - Lineas en BOLD  
     decoration-bf - Lineas en BOLD  
Línea 22: Línea 25:
</syntaxhighlight>
</syntaxhighlight>


==== Editable ====


També es pot fer '''editable''' per no tindre que obrir un form: '''editable="[top | bottom]"'''. Els trees editables poden tindre un atribut més '''on_write''' que indica un mètode a executar quan s'edita o crea un element.
També es pot fer '''editable''' per no tindre que obrir un form: '''editable="[top | bottom]"'''. Top o Bottom indica on es crearan els nous registres. Els trees editables poden tindre un atribut més '''on_write''' que indica un mètode a executar quan s'edita o crea un element.
   
   
 
==== Camps invisibles ====
De vegades, un camp pot servir per a alguna cosa, però no cal que l'usuari el veja. El que cal fer és ficar el field , però dir que es '''invisible="1"'''
De vegades, un camp pot servir per a alguna cosa, però no cal que l'usuari el veja. El que cal fer és ficar el field , però dir que es '''invisible="1"'''
<syntaxhighlight lang="xml" style="font-family:monospace">
<syntaxhighlight lang="xml" style="font-family:monospace">
Línea 35: Línea 39:
                 </tree>
                 </tree>
</syntaxhighlight>
</syntaxhighlight>
==== Botons ====


Els ''trees'' poden tindre '''buttons''' amb els mateixos atributs que els buttons dels forms.
Els ''trees'' poden tindre '''buttons''' amb els mateixos atributs que els buttons dels forms.
{{nota| Cal tindre cura en els trees dins de forms (X2many), ja que el botó s'executa en el model del tree i no del formulari que el conté. Si volem accedir al pare, cal utilitzar l'atribut parent. Mireu en [[Odoo#Context]] }}
==== Totals ====


En els trees es pot calcular totals amb aquesta etiqueta:
En els trees es pot calcular totals amb aquesta etiqueta:
Línea 43: Línea 53:
</syntaxhighlight>
</syntaxhighlight>
'''header'''
'''header'''
TODO


==== banner_route ====
==== banner_route ====

Revisión del 15:55 4 nov 2021

Millores en les vistes tree

Colors

En les vistes tree es pot modificar el color en funció del contingut d'un field amb l'etiqueta decoration, que utilitza colors contextuals de Bootstrap:

   decoration-bf - Lineas en BOLD 
   decoration-it - Lineas en ITALICS 
   decoration-danger - Color LIGHT RED 
   decoration-info - Color LIGHT BLUE 
   decoration-muted - Color LIGHT GRAY 
   decoration-primary - Color LIGHT PURPLE 
   decoration-success - Color LIGHT GREEN 
   decoration-warning - Color LIGHT BROWN
<tree  decoration-info="state=='draft'" decoration-danger="state=='trashed'">
    <field name="name"/>
    <field name="state"/>
</tree>

En el cas de que es vulga comparar un field Date o Datetime es pot fer amb la variable global de QWeb current_date. Per exemple:

<tree  decoration-info="start_date==current_date">
...

Editable

També es pot fer editable per no tindre que obrir un form: editable="[top | bottom]". Top o Bottom indica on es crearan els nous registres. Els trees editables poden tindre un atribut més on_write que indica un mètode a executar quan s'edita o crea un element.

Camps invisibles

De vegades, un camp pot servir per a alguna cosa, però no cal que l'usuari el veja. El que cal fer és ficar el field , però dir que es invisible="1"

<tree  decoration-info="duration==0">
                    <field name="name"/>
                    <field name="course_id"/>
                    <field name="duration" invisible="1"/>
                    <field name="taken_seats" widget="progressbar"/>
                </tree>

Botons

Els trees poden tindre buttons amb els mateixos atributs que els buttons dels forms.

Cal tindre cura en els trees dins de forms (X2many), ja que el botó s'executa en el model del tree i no del formulari que el conté. Si volem accedir al pare, cal utilitzar l'atribut parent. Mireu en Odoo#Context

Totals

En els trees es pot calcular totals amb aquesta etiqueta:

<field name="amount" sum="Total Amount"/>

header

A partir de la versió 12 d'Odoo, permet afegir als trees, forms, etc una capçalera obtinguda per una url. https://www.odoo.com/documentation/12.0/reference/views.html#common-structure

Aquesta capçalera serà un codi HTML que pot aprofitar les classes CSS d'Odoo, però no aprofita la generació de codi HTML que realitza el client web d'Odoo en la definició de les vistes. En cas d'utilitzar imatges, aquestes estaran en el directori static del mòdul.

Fer un banner route pas a pas:

El primer és ficar en el tree la referència al banner_route:

   <tree banner_route="/negocity/city_banner" >


Ara cal crear el web controller que implementa aquesta ruta (es recomana en controllers.py):

from odoo import http


class banner_city_controller(http.Controller):
    @http.route('/negocity/city_banner', auth='user', type='json')
    def banner(self):
        return {
            'html': """
                <div  class="negocity_banner" 
                style="height: 200px; background-size:100%; background-image: url(/negocity/static/src/img/negocity_city.jpg)">
                <div class="negocity_button" style="position: static; color:#fff;"><a>Generate Cities</a></div>
                </div> """
        }

En aquest cas, el CSS es podria fer un estil en CSS segons les instruccions de El client Web Odoo.

El resultat és un banner amb un <a> que, de moment, no fa res. Anem a donar-li funcionalitat a l'enllaç. El primer és assignar-li un action:

                 <a class="banner_button" type="action" data-reload-on-close="true" 
                role="button" data-method="action_generate_cities" data-model="negocity.city">Generate Cities</a>

Segons les instruccions de addons/web/static/src/js/views/abstract_controller.js, si fem un <a> amb un type="action", el JS d'Odoo interpretarà que ha de cridar al backend a una funció d'un model en concret. La resta de dades es fan com l'exemple. La funció que diu data-method és una funció que ha d'estar en el model que diu data-model.

Millores en les vistes form

Per a que un form quede bé, es pot inclure la etiqueta <sheet>, que fa que no ocupe tota la pantalla encara que siga panoràmica.

Tot sheet ha de tindre <group> i dins els fields. Es poden fer els group que vullgam i poden tindre string per mostrar un títol.

Si no utilitzem l'etiquet group, els fields no tindran label, no obstant, coses com el class="oe_edit_only" no funcionen en el group, per tant, cal utilitzar l'etiqueta <label for="name">

Per facilitar la gestió, un form pot tindre pestanyes temàtiques. Es fa en <notebook> <page string="titol">

Es pot separar els grups amb <separator string="Description for Quotations"/>

Alguns One2Many donen una vista tree que no es adequada, per això es pot modificar el tree per defecte:

<field name="subscriptions" colspan="4" mode=”tree”>
   <tree>...</tree>
</field>

En un One2many es pot especificar també el form que en donarà quan anem a crear un nou element.

Una altra opció és especificar la vista que insertarà en el field:

<field name="m2o_id" context="{'form_view_ref': 'module_name.form_id'}"/>

Valors per defecte en un one2many

Quant creem un One2many en el mode form (o tree editable) ens permet crear elements d'aquesta relació. Per a aconseguir que, al crear-los, el camp many2one corresponga al pare des del que es crida, es pot fer amb el context: Dins del field one2many que estem fent fiquem aquest codi:

context="{'default_<camp many2one>':active_id}"

O este exemple per a dins d'un action:

<field name="context">{"default_doctor": True}</field>
Aquesta sintaxi funciona per a passar per context valors per defecte a un form cridat amb un action. Pot ser en One2many, botons o menús
active_id és una variable que apunta al id del element que està en aquest moment actiu. Com que estem en un formulari, és el que se està creant o modificant amb en formulari. En el cas de la creació, active_id no està encara apuntant a un element de la base de dades, però funciona internament, encara que en el field no diga res o diga False.

Domains en Many2ones

Els camps Many2one es poden filtrar, per exemple:

<field name="hotel" domain="[('ishotel', '=', True)]"/>
Sembla que els domains sols funcionen en la vista en els Many2one, ja que en els One2many sols funcionen si estan en el codi python.

Widgets

Alguns camps, com ara les imatges, es poden mostrar utilitzant un widget distint que el per defecte:

<field name="image" widget="image" class="oe_left oe_avatar"/>
<field name="taken_seats" widget="progressbar"/>
<field name="country_id" widget="selection"/>
<field name="state" widget="statusbar"/>

Llista de widgets d'Odoo disponibles per a camps dins de forms:

instance.web.form.widgets = new instance.web.Registry({
    'char' : 'instance.web.form.FieldChar',
    'id' : 'instance.web.form.FieldID',
    'email' : 'instance.web.form.FieldEmail',
    'url' : 'instance.web.form.FieldUrl',
    'text' : 'instance.web.form.FieldText',
    'html' : 'instance.web.form.FieldTextHtml',
    'char_domain': 'instance.web.form.FieldCharDomain',
    'date' : 'instance.web.form.FieldDate',
    'datetime' : 'instance.web.form.FieldDatetime',
    'selection' : 'instance.web.form.FieldSelection',
    'radio' : 'instance.web.form.FieldRadio',
    'many2one' : 'instance.web.form.FieldMany2One',
    'many2onebutton' : 'instance.web.form.Many2OneButton',
    'many2many' : 'instance.web.form.FieldMany2Many',
    'many2many_tags' : 'instance.web.form.FieldMany2ManyTags',
    'many2many_kanban' : 'instance.web.form.FieldMany2ManyKanban',
    'one2many' : 'instance.web.form.FieldOne2Many',
    'one2many_list' : 'instance.web.form.FieldOne2Many',
    'reference' : 'instance.web.form.FieldReference',
    'boolean' : 'instance.web.form.FieldBoolean',
    'float' : 'instance.web.form.FieldFloat',
    'percentpie': 'instance.web.form.FieldPercentPie',
    'barchart': 'instance.web.form.FieldBarChart',
    'integer': 'instance.web.form.FieldFloat',
    'float_time': 'instance.web.form.FieldFloat',
    'progressbar': 'instance.web.form.FieldProgressBar',
    'image': 'instance.web.form.FieldBinaryImage',
    'binary': 'instance.web.form.FieldBinaryFile',
    'many2many_binary': 'instance.web.form.FieldMany2ManyBinaryMultiFiles',
    'statusbar': 'instance.web.form.FieldStatus',
    'monetary': 'instance.web.form.FieldMonetary',
    'many2many_checkboxes': 'instance.web.form.FieldMany2ManyCheckBoxes',
    'x2many_counter': 'instance.web.form.X2ManyCounter',
    'priority':'instance.web.form.Priority',
    'kanban_state_selection':'instance.web.form.KanbanSelection',
    'statinfo': 'instance.web.form.StatInfo',
});

Tret de: https://github.com/odoo/odoo/blob/8.0/addons/web/static/src/js/view_form.js#L6355

Reescalar les imatges

Molt a sovint, tenim la necessitat de reescalar les imatges que l'usuari penja. A partir d'Odoo 13 tenim el field Image que permet tindre diferents resolucions amb varis related

buttons

Podem introduir un botó en el form:

 <button name="update_progress" type="object" string="update" class="oe_highlight" /> <!-- El name ha de ser igual que la funció a la que crida. -->

La funció pot ser un workflow, una del model en el que està o un action. En el type cal indicar el tipus amb: workflow, object o action En l'exemple anterior, el button és de tipus object. Aixó vol dir que crida a una funció del model al que represente el formulari que el conté.

És important que el record sobre el que es pulsa un botó de tipus object estiga ja guardat, ja que si no existeix en la base de dades, el servidor no té la seua id i pot fer res. Per això, un botó polsat en fase de creació crida primer a la funció create().

Per a fer un butó que cride a un altre formulari, s'ha de fer en un tipus action. Amés, per ficar la id del action al que es vol cridar, cal ficar el prefixe i sufixe %(...)d, com en l'exemple:

 <button name="%(launch_mmog_fortress_wizard)d" type="action" string="Launch attack" class="oe_highlight" />

D'aquesta manera, un formulari, té un botó que, al ser polsat, envia el ID de l'action a executar als servidor, aquest li retorna un action per a que el client l'execute. L'action pot obrir una altra finestra o un pop-up. En qualsevol cas, aquest action executat en el client, demana la vista i les dades que vol mostrar i les mostra. Aquesta és la raó de la sintaxis %(...)d. Ja que es tracta d'un External Id a una action guardada en la base de dades.

Els buttons poden tindre una icona. Odoo proporciona algunes que es poden trobar a aquesta web: [1]

<button name="test" icon="fa-star-o" confirm="Are you sure?"/>
Esborrar: <button type="object" icon="fa-trash-o"  name="unlink"/>

En l'exemple anterior, també hem ficat l'atribut confirm per mostrar una pregunta a l'usuari. Els buttons es poden posar per el form, encara que es recomana en el header:

<header>
 <field name="state" widget="statusbar"/>
 <button name="accept" type="object" string="Accept" class="oe_highlight"/>
 <button special="cancel" string="Cancel"/>
</header>

Els botons sempre executen una funció de Javascript en la part del client web que demana alguna cosa al servidor. En el cas dels button action, demana el action, per després executar aquesta. En el cas dels buttons object demana que s'execute una funció del model i recordset actual en el servidor. El client web es queda a l'espera d'una resposta del servidor, que si és un diccionari buit, provoca un refresc de la pàgina, però pot retornar moltes coses: warnings, domains, actions... i el client ha d'actuar en conseqüència. Els buttons poden tindre també context per enviar alguna cosa extra al servidor.

Smart Buttons [2]

En el formulari dels client, podem veure aquests botons:

Smartbutton.png

Es tracta de botons que, amés d'executar-se, mostren una informació resumida i una icona. El text i la forma del botó es modifica dinàmicament en funció d'alguns criteris i això li dona més comoditat a l'usuari. Per exemple, si sols vol saber quantes factures té eixe client, el botó li ho diu. Si polsa el botó ja va a les factures en detall.

Per fer-los, el primer és modificar la seua forma, de botó automàticament creat per el navegador a un rectangle. Això odoo ho pot fer per CSS amb la classe class="oe_stat_button". A continuació, se li posa una icona icon="fa-star". [3]. A partir d'ahí, l'etiqueta <button> pot contindre el contingut que desitgem. Per exemple, camps computed que mostren el resum del formulari que va a obrir.

       <div class="oe_button_box">
             <button type="object" class="oe_stat_button" icon="fa-pencil-square-o" name="regenerate_password">
                        <div class="o_form_field o_stat_info">
                            <span class="o_stat_value">
                                <field name="password" string="Password"/>
                            </span>
                            <span class="o_stat_text">Password</span>
                        </div>
                    </button>
            </div>

Formularis dinàmics

Els fields dels formularis tenen un atribut anomenat attrs que permet modificar el seu comportament en funció de condicions. Per exemple, ocultar amb invisible, permetre ser editat o no amb readonly o required.

Ocultar condicionalment un field

Es pot ocultar un field si algunes condicions no es cumpleixen. Per exemple:

<field name="boyfriend_name" attrs="{'invisible':[('married', '!=', False)]}" />
<field name="boyfriend_name" attrs="{'invisible':[('married', '!=', 'selection_key')]}" />

Tambés es pot ocultar i mostrar sols en el mode edició o lectura:

<field name="partit" class="oe_edit_only"/>
<field name="equip" class="oe_read_only"/>

O mostrar si un camp anomenat state té un determinat valor:

 <group states="dia"><field name="dia"/></group>

En el següent exemple, introdueix dos conceptes nous: el column_invisible per ocultar una columna d'un tree i el parent per fer referència al valor d'un field de la vista pare:

<field name="lot_id" attrs="{'column_invisible': [('parent.state', 'not in', ['sale', 'done'])] }"/>


Editar condicionalment un field

En attrs també es pot afegir readonly

<field name="name2" attrs="{'readonly': [('condition', '=', False)]}"/>

Aquests exemples combinen tots els attrs:

<field name="name" attrs="{'invisible': [('condition1', '=', False)], 
                           'required': [('condition2', '=', True)], 
                           'readonly': [('condition3','=',True)]}" />

<field name="suma" attrs="{'readonly':[('valor','=','calculat')], 
                           'invisible': ['|',('servici','in',['Reparacions','Manteniment']),
                           ('client','=','Pepe')]}" />

readonly

En ocasions volem que un field siga readonly, al no poder editar, no pot ser required. En cas de ser modificar per un Onchage i es vulga guardar, cal afegir:

<field name="salary" readonly="1" force_save="1"/>

Workflows

Els Workflows es consideren obsolets en la versió 11 d'Odoo. Es pot aconseguir el mateix en les variables status , el widget statusbar i l'atribut XML states. Per simplificar la programació, han considerat que no és necessari fer difeencies entre Workflows i altres canvis d'estat.

Vistes Kanban

Les vistes kanban són per a mostrar el model en forma de 'cartes'. Les vistes kanban se declaren amb una mescla de xml, html i plantilles Qweb.

Un Kanban és una mescla entre tree i form. En Odoo, les vistes tenen una estructura jeràrquica. En el cas del Kanban, està la vista Kanban, que conté molts Kanban Box, un per a cada record mostrat. Cada kanban box té dins un div de class vignette o card i, dins, els Widgets per a cada field.

             Window
+---------------------------+
|     Kanban View           |
| +----------+ +----------+ |
| |Kanban Box| |Kanban Box| |
| +----------+ +----------+ |
| || Widget || || Widget || |
| |----------| |----------| |
| |----------| |----------| |
| || Widget || || Widget || |
| |----------| |----------| |
| +----------+ +----------+ |
|                           |
+---------------------------+

Per mostrar un Kanban, la vista de Odoo, obri un action Window, dins clava una caixa que ocupa tota la finestra i va recorreguent els records que es tenen que mostrant i dibuixant els widgets de cada record.

A diferència en els trees o forms, els kanbans poden ser molt variats i han de deixar llibertat per ser dissenyats. És per això, que els desenvolupadors d'Odoo no han proporcionat unes etiquetes i atributs XML d'alt nivell com passa en els forms o trees, en els que no hem de preocupar-nos de la manera en que serà renderitzar, el CSS o cóm obté els fields de la base de dades. Al fer un Kanban, entrem al nivel de QWeb, per el que controlem plantilles, CSS i indicacions i funcions per al Javascript. Tot això està ocult en la resta de vistes, però en Kanban és impossible ocultar-ho.

Exemple bàsic:

<record model="ir.ui.view" id="socio_kanban_view">
            <field name="name">cooperativa.socio</field>
            <field name="model">cooperativa.socio</field>
            <field name="arch" type="xml">
                <kanban>
                    <!--list of field to be loaded -->
                    <field name="name" />
                    <field name="id" /> <!-- És important afegir el id per al record.id.value -->
                    <field name="foto" />
                    <field name="arrobas"/>

                    <templates>
                    <t t-name="kanban-box">
                            <div class="oe_product_vignette">
                                <a type="open">
                                    <img class="oe_kanban_image"
                                        t-att-alt="record.name.value"
                                        t-att-src="kanban_image('cooperativa.socio', 'foto', record.id.value)" />
                                </a>
                                <div class="oe_product_desc">
                                    <h4>
                                        <a type="edit">
                                            <field name="name"></field>
                                        </a>
                                    </h4>
                                    <ul>

                                       <li>Arrobas: <field name="arrobas"></field></li>
                                    </ul>
                                </div>
                            </div>
                        </t>
                    </templates>
                </kanban>
            </field>
        </record>

En l'anterior vista kanban cal comentar les línies.

Al principi es declaren els fields que han de ser mostrats. Si no es necessiten per a la lògica del kanban i sols han de ser mostrats no cal que estiguen declarats al principi. No obstant, per que l'exemple estiga complet els hem deixat. Aquesta declaració, fa demanar els fields en la primera petició asíncrona de dades. Els no especificats ací, són demanats després, però no estan disponibles per a que el Javascript puga utilitzar-los.

A continuació ve un template Qweb en el que cal definir una etiqueta <t t-name="kanban-box"> que serà renderitzada una vegada per cada element del model.

Dins del template, es declaren divs o el que necessitem per donar-li el aspecte definitiu. Odoo ja té en el seu CSS unes classes per al productes o partners que podem aprofitar. El primer div defineix la forma i aspecte de cada caixa. Hi ha múltiples classes CSS que es poden utilitzar. Les que tenen vignette en principi no mostren vores ni colors de fons. Les que tenen card tenen el border prou marcat i un color de fons. Les bàsiques són oe_kanban_vignette i oe_kanban_card.

Hi ha molts altres CSS que podem estudiar i utilitzar. Per exemple, els oe_kanban_image per a fer la imatge d'una mida adequada o el oe_product_desc que ajuda a colocar el text al costat de la foto. En l'exemple, usem uns <a> amb dos tipus: open i edit. Segons el que posem, al fer click ens obri el form en mode vista o edició. Aquests botons o enllaços poden tindre aquestes funcions:

  • action, object: Com en els botons dels forms, criden a accions o a mètodes.
  • open, edit, delete: Efectua aquestes accions al record que representa el kanban box.

Si ja volem fer un kanban més avançat, tenim aquestes opcions:

  • En la etiqueta <kanban>:
    • default_group_by per agrupar segons algun criteri al agrupar apareixen opcions per crear nous elements sense necessitat d'entrar al formulari.
    • default_order per ordenar segons algun criteri si no s'ha ordenat en el tree.
    • quick_create a true o false segons vulguem que es puga crear elements sobre la marxa sense el form. Per defecte és false si no està agrupat i true si està agrupat.
  • En cada field:
    • sum, avg, min, max, count com a funcions d'agregació en els kanbans agrupats.
  • Dins del template:
    • Cada field pot tindre un type que pot ser open, edit, action, delete.
  • Una serie de funcions javascript:
    • kanban_image() que accepta com a argument: model, field, id, cache i retorna una url a una imatge. La raó és perquè la imatge està en base64 i dins de la base de dades i cal convertir-la per mostrar-la.
    • kanban_text_ellipsis(string[, size=160]) per acurtar textos llargs, ja que el kanban sols és una previsualització.
    • kanban_getcolor(raw_value) per a obtindre un color dels 0-9 que odoo te predefinits en el CSS a partir de qualsevol field bàsic.
    • kanban_color(raw_value) Si tenim un field color que pot definir de forma específica el color que necessitem. Aquest field tindrà un valor de 0-9.

Un exemple més complet i correcte:

      <record model="ir.ui.view" id="music_kanban_view">
            <field name="name">conservatori.music</field>
            <field name="model">conservatori.music</field>
            <field name="arch" type="xml">
            <kanban default_group_by="instrument" default_order="instrument" quick_create="true">
                    <field name="numero" sum="numero"/>
                    <templates>
                    <t t-name="kanban-box">
                            <div  t-attf-class="oe_kanban_color_{{kanban_getcolor(record.numero.raw_value)}}
                                                  oe_kanban_global_click_edit oe_semantic_html_override
                                                  oe_kanban_card {{record.group_fancy==1 ? 'oe_kanban_card_fancy' : ''}}">
                                <a type="open">
                                    <img class="oe_kanban_image"
                                        t-att-src="kanban_image('conservatori.music', 'foto', record.id.value)" />
                                </a>
                                <div t-attf-class="oe_kanban_content">
                                    <h4>
                                        <a type="edit">
                                            <field name="name"></field>
                                        </a>
                                    </h4>
                                    <ul>
 
                                       <li>Group: <field name="grup"></field></li>
                                    </ul>
                                </div>
                            </div>
                        </t>
                    </templates>
                </kanban>
             </field>
        </record>


Forms dins de kanbans:

A partir de la versió 12 es pot introduir un form dins d'un kanban, encara que es recomana que siga simple. Aquest funciona si tenim activat el quick_create i preferiblement quan el kanban està agrupat per Many2one o altres. Observem, per exemple el kanban de la secció de tasques del mòdul de proyecte:

<kanban default_group_by="stage_id" class="o_kanban_small_column o_kanban_project_tasks" on_create="quick_create"
 quick_create_view="project.quick_create_task_form" examples="project">
....
</kanban>

Com podem observar, té activat el quick_create i una referència al identificador extern d'una vista form en quick_create_view. Aquest és el contingut del form:

<?xml version="1.0"?>
<form>
  <group>
     <field name="name" string="Task Title"/>
     <field name="user_id" options="{'no_open': True,'no_create': True}"/>
  </group>
 </form>

Vistes search

Les vistes search tenen 3 tipus:

  • field que permeten buscar en un determinat camp.
  • filter amb domain per filtrar per un valor predeterminat.
  • filter amb group per agrupar per algun criteri.

Pel que fa a les search field, sols cal indicar quins fields seran buscats.

<search>
    <field name="name"/>
    <field name="inventor_id"/>
</search>
Els fields han de ser guardats en la base de dades, encara que siguen de tipus computed

Les field poden tindre un domain per especificar quin tipus de búsqueda volem. Per exemple:

<field name="description" string="Name and description"
    filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/>

Busca per ‘name’ i ‘description’ amb un domini que busca que es parega en “case-insensitive” (ilike) el que escriu l’usuari (self) amb el name o amb la descripció.

o:

<field name="cajones" string="Boxes or @" filter_domain="['|',('cajones','=',self),('arrobas','=',self)]"/>

Busca per cajones o arrobas sempre que l'usuari pose el mateix número.

Les filter amb domain són per a predefinir filtres o búsquedes. Per exemple:

<filter name="my_ideas" string="My Ideas" domain="[('inventor_id', '=', uid)]"/>
<filter name="more_100" string="More than 100 boxes" domain="[('cajones','>',100)]"/> 
<filter name="Today" string="Today" domain="[('date', '&gt;=', datetime.datetime.now().strftime('%Y-%m-%d 00:00:00')),
                                             ('date', '&lt;=',datetime.datetime.now().strftime('%Y-%m-%d 23:23:59'))]"/>
Els filtres sols poden comparar un field amb un valor específic. Així que si volem comparar dos fields cal fer una funció.

Operadors per als domains:

'like': [('input', 'like', 'open')] - Returns case sensitive (wildcards - '%open%') search.

O/p: open, opensource, openerp, Odooopenerp

'not like': [('input', 'not like', 'open')] - Returns results not matched with case sensitive (wildcards - '%open%') search.

O/p: Openerp, Opensource, Open, Odoo, odoo, OdooOpenerp

'=like': [('name', '=like', 'open')] - Returns exact (= 'open') case sensitive search.

O/p: open

'ilike': [('name', 'ilike', 'open')] - Returns exact case insensitive (wildcards - '%open%') search.

O/p: Openerp, openerp, Opensource, opensource, Open, open, Odooopenerp, OdooOpenerp

'not ilike': [('name', 'not ilike', 'open')] - Returns results not matched with exact case insensitive (wildcards - '%open%') search.

O/p: Odoo, odoo

'=ilike': [('name', '=ilike', 'open')] - Returns exact (= 'open' or 'Open') case insensitive search.

O/p: Open, open

'=?':

name = 'odoo' parent_id = False [('name', 'like', name), ('parent_id', '=?', parent_id)] - Returns name domain result & True

name = 'odoo' parent_id = 'openerp' [('name', 'like', name), ('parent_id', '=?', parent_id)] - Returns name domain result & parent_id domain result

'=?' is a short-circuit that makes the term TRUE if right is None or False, '=?' behaves like '=' in other cases

'in': [('value1', 'in', ['value1', 'value2'])] - in operator will check the value1 is present or not in list of right term

'not in': [('value1', 'not in', ['value2'])] - not in operator will check the value1 is not present in list of right term While these 'in' and 'not in' works with list/tuple of values, the latter '=' and '!=' works with string

'=': value = 10 [('value','=',value)] - term left side has 10 in db and term right our value 10 will match

'!=': value = 15 [('value','!=',value)] - term left side has 10 in db and term right our value 10 will not match

'child_of': parent_id = '1' #Agrolait 'child_of': [('partner_id', 'child_of', parent_id)] - return left and right list of partner_id for given parent_id

'<=', '<', '>', '>=': These operators are largely used in openerp for comparing dates - [('date', '>=', date_begin), ('date', '<=', date_end)]. You can use these operators to compare int or float also.

Els filter amb group agrupen per algun field:

<group string="Group By">
        <filter name="group_by_inventor" string="Inventor" context="{'group_by': 'inventor_id'}"/>
</group>
o:
  <filter name="group_by_matricula" string="Matricula" context="{'group_by': 'matricula'}"/>

Si agrupem per data, el grup és per defecte per cada mes, si volem agrupar per dia:

<filter name="group_by_exit_day" string="Exit" context="{'group_by': 'exit_day:day'}"/>

Si volem que un filtre estiga predefinit s'ha de posar en el context de l'action:

<field name="context">{'search_default_clients':1,"default_is_client": True}</field>

En aquest exemple, filtra amb en search_default_XXXX que activa el filtre XXXX i, amés, fa que en els formularis tiguen un camp boolean a true.

Vistes Calendar

Si el recurs té un camp date o datetime. Permet editar els recursos ordenats per temps. L’exemple són els esdeveniments del mòdul de ventes.

  • string, per al títol de la vista
  • date_start, que ha de contenir el nom d’un camp datetime o date del model.
  • date_delay, que ha de contenir la llargada en hores de l’interval.
  • date_stop, Aquest atribut és ignorat si existeix l’atribut date_delay.
  • day_length, per indicar la durada en hores d’un dia. OpenObject utilitza aquest valor per calcular la data final a partir del valor de date_delay. Per defecte, el seu valor és 8 hores.
  • color, per indicar el camp del model utilitzat per distingir, amb colors, els recursos mostrats a la vista.
  • mode, per mostrar l’enfoc (dia/setmana/mes) amb el què s’obre la vista. Valors possibles: day, week, month. Per defecte, month.
 <record model="ir.ui.view" id="session_calendar_view">
            <field name="name">session.calendar</field>
            <field name="model">openacademy.session</field>
            <field name="arch" type="xml">
                <calendar string="Session Calendar" date_start="start_date"
                          date_stop="end_date"
                          color="instructor_id">
                    <field name="name"/>
                </calendar>
            </field>
        </record>

Vistes Graph

En general s'utilitza per a veure agregacions sobre les dades a mostrar. Accepta els següents atributs:

  • string, per al títol de la vista
  • type, per al tipus de gràfic. (bar, pie, line)
  • stacked sols per a bar per mostrar les dades amuntonades en una única barra.

La definició dels elements fills de l’element arrel graph determina el contingut del gràfic:

  • Primer camp: eix X (horitzontal). Obligatori.
  • Segon camp: eix Y (vertical). Obligatori.

A cadascun dels camps que determinen els eixos, se’ls pot aplicar els atributs següents:

  • name: El nom del field
  • title: El nom que tindrà en el gràfic
  • invisible: No apareixerà
  • type: En aquest cas cal dir si és row per agrupar per aquest field, col per fer distintes línies o measure per a les dades en sí que es van a agregar.
 <record model="ir.ui.view" id="terraform.planet_changes_graph">
      <field name="name">Planet Changes graph</field>
      <field name="model">terraform.planetary_changes</field>
      <field name="arch" type="xml">
        <graph string="Changes History" type="line">
          <field name="time"  type="row"/>
          <field name="planet"  type="col"/>
          <field name="greenhouse" type="measure"/>
        </graph>
      </field>
    </record>


Les vistes graph en Odoo són molt limitades, sols accepten un element en les X i necessiten que els camps estiguen guardats en la base de dades