-
Notifications
You must be signed in to change notification settings - Fork 1
2.4. Desenvolupar l'IMS
A continuació s'ofereix un compendi de tota la informació que ofereix aquesta wiki, estructurada i guiada per a facilitar la preparació d'un entorn de desenvolupament per a l'IMS:
-
Plataforma de desenvolupament: Cal configurar una plataforma de desenvolupament per a poder instal·lar Odoo.
-
Preparació de l'entorn: Cal seguir la guia de preparació de l'entorn per a deixar el sistema preparat i poder treballar amb Odoo.
-
Accés remot: Després cal configurar l'accés remot a la màquina per a poder treballar amb comoditat.
-
Directori de proves: Tot seguit, és necessari configurar un directori de proves on es desenvoluparà el mòdul.
-
Permisos: El següent pas consisteix en donar els permisos necessaris perquè Odoo pugui accedir al mòdul.
-
Prerequisits: Cal instal·lar alguns paquets per a que l'IMS funcioni correctament, cal executar les següents comandes: 6.1.
apt install git pip -y
6.2.pip3 install phonenumbers
-
Instal·lació del mòdul: Finalment, només cal situar-se dins el directori
myModules
i fer:
7.1. Clonar el repositori:git clone https://github.com/ElPuig/IMS.git ims
7.2. Accedir a la carpeta:cd ims
7.3. Escollir la base de dades (opcional): modificar el paràmetre-i
de l'scriptinstall.sh
per a escollir la base de dades.
7.4. Instal·lar el mòdul:./install.sh
-
Accedir a Odoo: Ja es pot accedir a Odoo fent servir un navegador web, la IP o el hostname i el port 8069 (http://ims-devel:8069). Les credencials predeterminades són:
Usuari: admin
Password: admin
Es pot instal·lar o actualitzar l'IMS afegint dades de demostració per a fer proves, amb la comanda:
./demo.sh
Es pot actualitzar l'IMS mentre es fan canvis al codi font, per a veure'ls reflectits en la instal·lació i fer-ne proves, amb la comanda:
./update.sh
Només cal fer servir el cercador i copiar l'exemple. Odoo fa servir els que acaben en "-o" quan n'hi ha alguna variant (per exemple: "fa fa-trash-o").
https://fontawesome.com/v4/icons/
Exemple: el següent bloc de codi permet afegir un botó per esborrar un ítem
<a title="Delete" type="delete" href="#" class="we-button.o_delete_btn" role="button">
<i class="fa fa-trash-o" aria-hidden="true" />
</a>
Cal cercar el menú dins de "Settings / Techincal / User Interface / Menu Items", es recomana cercar pel nom del menú. Per exemple: "Employees":
Una forma de saber si és el menú correcte, és revisar els seus submenús:
Un cop trobat el menú, cal accedir al seu ID consultant les metadades:
Es mostrarà l'ID:
Editant el camp "name" amb XML i aportant el ID correcte, es pot modificar el nom:
<record model="ir.ui.menu" id="hr.menu_hr_employee_user">
<field name="name">All</field>
</record>
Afegir el següent codi dins un XML de vista per a sobreescriure'l:
<record model="ir.ui.menu" id="hr.menu_view_employee_category_form">
<field name="active">false</field>
</record>
Consultar els detalls sobre com trobar els IDs a l'apartat "Canviar el nom d'un menú existent (nadiu d'Odoo)".
https://www.cybrosys.com/blog/add-colors-to-tree-view-odoo-13
Pot resultar útil per a debugar amb Python o simplement per a mostrar alertes als usuaris. https://www.cybrosys.com/blog/raising-exceptions-in-the-odoo-15
Si el desplegable depèn d'un camp Many2one, cal indicar l'ordre dins del propi model:
class ims_attendance_schedule(models.Model):
_name = "ims.attendance_schedule"
_description = "Attendance schedule: concretes the weekdays data."
_order = 'attendance_template_id asc, weekday asc, start_time asc'
A continuació es detallen els passos per a editar una vista existent, sense alterar el codi font original:
- Primer cal heretar la vista que es vol modificar:
<record model="ir.ui.view" id="view_contact_form">
<field name="name">ims.contact.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
- A continuació, es pot escollir un element fent servir XPath o directament pel nom d'un atribut del model: 2.1. Exemple a partir del nom d'un atribut del model:
<field name="vat" position="after">
<field name="contact_type"/>
<field name="company_type" attrs="{'invisible': [('contact_type', '!=', 'provider')]}"/>
</field>
2.2. Exemple a partir d'una consulta XPath:
<xpath expr="//page[@name='sales_purchases']" position="attributes">
<attribute name="attrs">{'invisible': [('contact_type', '!=', 'provider')]}</attribute>
</xpath>
2.3. Els detalls sobre els diferents valors de "position" o d'altres elements de modificació, es poden consultar a la documentació oficial: https://www.odoo.com/documentation/16.0/es/developer/reference/backend/views.html#inheritance-specs
Per a simular vistes cal crear un nou model de dades, que no estarà orientat a la lògica de negoci sinó a proveir d'una estructura per a recollir la informació que ha de mostrar una vista, normalment un llistat o "treeview". El primer que cal decidir és si el model de dades ha de ser persistent (llistat d'elements, com per exemple el de "subject") o si pot ser temporal o "transient" (com el llistat d'alumnes matriculat a assignatures concretes dins un grup, que es mostra dins el formulari de "group"):
- Model: funciona com un model de dades normal, amb persistència dins la base de dades, però cal determinar-ne el moment de creació d'aquest model en funció del model de dades original. Com a exemple es pot trobar el model "subject" ja que es permet assignar una assignatura a més d'un nivell d'estudis, però el llistat d'assignatures (que mostra les assignatures agrupades per nivell d'estudis) necessita d'un llistat amb relació 1-1 i no pas 1-N. És per aquest motiu que, quan es crea un nou "subject" o se'n modifiquen els seus estudis, es crea un nou model de vista. Per a fer-ho, s'ha fet de la següent manera:
1.1. Es crea el model de vista (models.Model
) dins el mateix fitxer que el model de dades original (ims_subject_view
iims_subject
es troben dins el fitxersubject.py
.
1.2. Es crea un nou atribut cap a la vista, de tipusOne2many
, amb un mètodecompute
istore=True
. Per exemple:subject_view_ids = fields.One2many(comodel_name="ims.subject_view", inverse_name="subject_id", compute="_compute_subject_views", store=True)
.
1.3. Es crea el mètodecompute
tenint en compte que necessita un@api.depends
que indicarà que, quan es modifiquin altres atributs, caldrà tornar a recalcular aquest mètode. Per exemple:
@api.depends("study_ids")
def _compute_subject_views(self):
for rec in self:
self.env['ims.subject_view'].search([('subject_id', '=', rec.id)]).unlink()
for study in rec.study_ids:
rec.subject_view_ids.create({
"level": rec.level,
"code": rec.code,
"acronym": rec.acronym,
"name": rec.name,
"study_id": study.id,
"subject_id": rec.id,
})
- TransientModel: funciona com un model de dades normal, amb persistència temporal dins la base de dades (s'esborra de tant en tant), però cal determinar-ne el moment de creació d'aquest model en funció del model de dades original. Com a exemple es pot trobar el model "group" perquè es volen mostrar quines matèries cursen els alumnes dins aquest grup (ignorant la resta de matèries que un alumne pugui cursar a altres grups), però el treeview no permet filtrar els resultats d'un camp que és una relació cap a N (existeix l'opció, amb l'atribut
domain
, però l'ignora). És per aquest motiu que, quan s'obre el formulari d'un "group", es crea un nou model de vista. Per a fer-ho, s'ha fet de la següent manera:
2.1. Es crea el model de vista (models.TransientModel
) dins el mateix fitxer que el model de dades original (ims_enrollment_view
iims_group
es troben dins el fitxergroup.py
.
2.2. Es crea un nou atribut cap a la vista, de tipusOne2many
, amb un mètodecompute
. Per exemple:enrollment_view_ids = fields.One2many(string="Enrollment", comodel_name="ims.enrollment_view", inverse_name="group_id", compute="_compute_enrollment_ids")
.
2.3. Es crea el mètodecompute
sense cap@api.depends
, de tal manera que s'activarà només en obrir el formulari. Per exemple:
def _compute_enrollment_ids(self):
for rec in self:
self.env['ims.enrollment_view'].search([('group_id', '=', rec.id)]).unlink()
for student in self.env['ims.enrollment'].read_group(domain=[('group_id', '=', rec.id)], fields=['student_id'], groupby=['student_id']):
sid = student['student_id'][0]
subs = self.env["ims.enrollment"].search([("group_id", "=", rec.id), ('student_id', '=', sid)]).mapped("subject_id")
rec.enrollment_view_ids.create({
"group_id": rec.id,
"student_id": sid,
"subject_ids": subs,
})
Mes informació sobre com obtenir dades agrupades o com crear-ne nous registres de forma manual:
- https://www.odoo.com/documentation/16.0/developer/reference/backend/orm.html?highlight=read_group#search-read
- https://www.cybrosys.com/odoo/odoo-books/odoo-15-development/ch15/grouped-data/
- https://www.odoo.com/fi_FI/forum/apua-1/how-to-insert-value-to-a-one2many-field-in-table-with-create-method-28714
TODO:
TODO:
TODO: