Odoo incluye su propio mecanismo de importación de registros (aunque lo haya cambiado un poquito de lugar en la versión 14, ahí está disponible), pero en ocasiones necesitamos procesar o transformar un poquito la info antes de ingresarla a nuestro sistema.
En mi caso la necesidad más ‘recurrente’ de hacer esto, es la importación del registro de asistencia cuando por algún motivo, no puedes integrar tu sistema directamente a un dispositivo biométrico.
En ese caso puedes exportar un fichero (generalmente EXCEL o CSV) con los datos que te permita el dispositivo según marca y modelo, y luego convertirlo a 'formato Odoo' antes de registrarlo, tal vez filtrar de alguna manera la información, o aplicar ciertas validaciones, o concatenar fechas y horas... antes de decidir cuáles datos se importan y cuáles no.
En este post queremos poner un botón encima del Tree del registro de asistencia. Desde el punto de vista de la interfaz, es una forma muy práctica de permitirle al usuario hacer una importación personalizada (en este post nos centraremos solamente en mostrar el botón)
Paso 1: Dentro de la carpeta de tu módulo, en /static/src/xml/, crea un fichero qweb.xml. Ver Estructura de carpetas de un módulo Odoo
<?xml version="1.0" encoding="UTF-8"?>
<templates id="import_template" xml:space="preserve">
<t t-extend="ListView.buttons">
<t t-jquery="button.o_list_button_add" t-operation="after">
<t t-if="widget.modelName == 'hr.attendance'">
<button class="btn btn_sm btn-danger import_data_button" type="button">
Update Attendance Data
</button>
</t>
</t>
</t>
</templates>
Nota: En este caso, quiero poner el botón justo después del botón CREAR que se muestra sobre la vista Tree, del modelo 'hr.attendance' específicamente (no lo queremos sobre todos los Trees de nuestro sistema)
Paso 2: Incluye la dirección de este archivo en tu __manifest__.py:
'qweb': [
'static/src/xml/qweb.xml',
],
Paso 3: Crea un fichero import.js, y ponlo en '/static/src/js/’ dentro de tu módulo.
odoo.define(my_custom_module.import', function (require)
{
"use strict";
var core = require('web.core');
var ListController = require('web.ListController');
ListController.include({
renderButtons: function($node)
{
this._super.apply(this, arguments);
if (this.$buttons)
{
let import_button = this.$buttons.find('.import_data_button');
import_button && import_button.click(this.proxy('import_button')) ;
}
},
import_button: function ()
{
this.do_action({
type: "ir.actions.act_window",
name: "import",
res_model: "import.sheet",
views: [[false,'form']],
target: 'new',
view_mode : 'form',
flags: {'form': {'action_buttons': true, 'options': {'mode': 'edit'}}}
});
return { 'type': 'ir.actions.client','tag': 'reload', }
}
});
})
Nota: En este ejemplo ‘import.sheet’ es un TransientModel correspondiente a un pequeño wizard que me permitirá cargar un fichero con los registros a importar. Lo estamos llamando desde nuestro botón, asegúrate de usar el tuyo propio.
Paso 4: En alguno de nuestros archivos .xml, le diremos al sistema donde encontrar nuestro archivo .js. Recuerda que el fichero donde incluyas esto, también debes adicionarlo a tu __manifest__.py
<template id="assets_backend_attendance" name="Attendance assets" inherit_id= "web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/my_module/static/src/js/ import.js"/>
</xpath>
</template>
A partir de aquí, por supuesto dependerá de tu negocio... de lo que quieras hacer bajo este botón.
Esta vía la he usado con las versiones 12 y 14, pero tengo entendido que la forma de acceder al widget para mostrar el ListView (<t t-extend="ListView.buttons">) es ligeramente diferente por ejemplo en Odoo 10… Así que tenlo presente...
Ojalá te sirva el consejito ;)