diff --git a/README.rst b/README.rst index 379c5ba6fd65ef8e0d60d5e4c987cc24489f7317..0d5472934cc7370d12d7cd1f90cc20ba7fb72fd9 100644 --- a/README.rst +++ b/README.rst @@ -10,13 +10,17 @@ CG SCOP - Connecteur Alfresco Description =========== -Ce module permet utilise l'API Alfresco développée spécifiquement pour le projet de la CG Scop qui impémente les fonctions suivantes : +Ce module hérite des modules **cmis** et **cmis_web** pour permettre d'ajouter des champs et les fonctions mises à disposition par l'API Alfresco CG Scop. -* Création d'un dossier : lors de la création d'un organisme -* Mise à jour d'un dossier : lors des la mise à jour d'un organisme sur les champs nom, SIRET et n° adhérent +On crée un modèle abstrait rattachable au différents modèles et implémente les fonctions suivantes : + +* Création d'un dossier +* Mise à jour d'un dossier * Liste des fichiers pour un organisme * Ajout d'un fichier -* Suppression d'un dossier : lors de la suppression d'un organisme +* Suppression d'un dossier + +Il implémente également la fonction de connexion à Alfresco pour le module CMIS en utilisant le webservice mis à disposition. Usage diff --git a/__init__.py b/__init__.py index d997a09cbd2254168ef48fc13bf9789e2d3242ac..b9f967ea92a89276401151d71f466ffe3e0a4f33 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,5 @@ # © 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import controllers from . import models diff --git a/__manifest__.py b/__manifest__.py index deb7a48ee6cbbc7b198a2a0d5be18adb24fb134d..254cb43d457a601586fde207b8a57d64037c76ea 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -9,12 +9,11 @@ "depends": [ 'base', 'web', - 'cgscop_partner', - 'web_ir_actions_close_wizard_refresh_view', + 'cmis', ], "data": [ - "security/ir.model.access.csv", - "views/alfresco_connection.xml", + "views/assets.xml", + "views/cmis_backend.xml", ], 'qweb': [ 'static/src/xml/*.xml', diff --git a/controllers/__init__.py b/controllers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a676f817085c409e6659d0aef11f06ae9c2ff2f5 --- /dev/null +++ b/controllers/__init__.py @@ -0,0 +1,4 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import main diff --git a/controllers/main.py b/controllers/main.py new file mode 100644 index 0000000000000000000000000000000000000000..74c9bd908ced0851d4cf67596116c68ee68f29a9 --- /dev/null +++ b/controllers/main.py @@ -0,0 +1,12 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import http + + +class AlfrescoController(http.Controller): + + @http.route(['/web/alfresco/session'], type="json", auth="user", method=['POST']) + def get_alf_ticket(self, username): + data = http.request.env['cgscop.alfresco'].alfresco_get_ticket(username) + return data diff --git a/models/__init__.py b/models/__init__.py index 108ebf47f6cf44fe22cdcc5aa30e930427f5c9e2..9962060e4fc58898803c5ce02190d423ca10c475 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -2,4 +2,4 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import api_alfresco -from . import alfresco_connection +from . import cmis_backend diff --git a/models/alfresco_connection.py b/models/alfresco_connection.py deleted file mode 100644 index 818f03a47c767fb18e93a7a7132efeb6485d8995..0000000000000000000000000000000000000000 --- a/models/alfresco_connection.py +++ /dev/null @@ -1,24 +0,0 @@ -# © 2019 Le Filament (<http://www.le-filament.com>) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import models, fields - - -class CgscopAlfrescoConnection(models.Model): - _name = 'alfresco.connection' - _description = 'Infos API de connexion pour Alfresco' - - name = fields.Char(string='Nom') - login = fields.Char('Login') - password = fields.Char('Password') - url = fields.Char('URL') - ssl = fields.Boolean('Connexion SSL', default=False) - active = fields.Boolean('Actif', default=False) - - def toogle_active_config(self): - """ Active la connexion sélectionnée et désactive - toutes les autres connexions - """ - for item in self.env['alfresco.connection'].search([]): - item.active = False - self.active = True diff --git a/models/api_alfresco.py b/models/api_alfresco.py index a149df3939d42ac414084d7ed5703a7496ec0b95..25e0082a68137d08f9cbfe32c28a10057e6de4be 100644 --- a/models/api_alfresco.py +++ b/models/api_alfresco.py @@ -3,6 +3,7 @@ import requests import logging +import xml.etree.ElementTree as et from odoo import models, exceptions, tools @@ -27,7 +28,7 @@ class CgscopAlfresco(models.AbstractModel): @return response au format JSON """ _logger.info("Calling %s" % url) - param = self.env['alfresco.connection'].sudo().search([ + param = self.env['cmis.backend'].sudo().search([ ['active', '=', True]]) if not param: raise exceptions.Warning( @@ -36,7 +37,7 @@ class CgscopAlfresco(models.AbstractModel): alfresco_url = param.url alfresco_ssl = param.ssl basicAuthCredentials = ( - param.login, + param.username, param.password) try: if call_type == 'get': @@ -62,25 +63,26 @@ class CgscopAlfresco(models.AbstractModel): err.__str__(), ) response = False - # if not response: - # raise exceptions.Warning( - # "Oops... il y a un problème de connexion avec l'espace documentaire") + # Gestion erreur API if response.status_code not in [200, 201]: + try: + message = response.json().get('message') + except: + message = response.text raise exceptions.Warning( "L'appel url '%s' a échoué\n" "- Code erreur : %d\n" "- Message : %s" % ( response.url, response.status_code, - response.json().get('message'))) + message)) # Si dossier déjà créé elif (response.text.find("NUMADHERENT d") > 0 or response.text.find("SIRET d") > 0 or response.text.find("RAISONSOCIALE d") > 0): return response.json().get('dossiersExistants')[0] - - return response.json() + return response # Get Methods def alfresco_list_docs(self, node_id): @@ -88,7 +90,7 @@ class CgscopAlfresco(models.AbstractModel): :param name: raison sociale de la structure """ url = '/alfresco/s/erp/listedocuments?nodeId=' + node_id - return self.alfresco_get_by_url(url=url, call_type='get') + return self.alfresco_get_by_url(url=url, call_type='get').json() def alfresco_list_type(self): """ Liste le valeurs du formulaire de dépôt d'un nouveau document @@ -96,14 +98,11 @@ class CgscopAlfresco(models.AbstractModel): @return: dict des valeurs possibles pour période, validité, type """ url = '/alfresco/s/api/properties?nsp=crm&n=document' - list_type = self.alfresco_get_by_url(url=url, call_type='get') + list_type = self.alfresco_get_by_url(url=url, call_type='get').json() return { 'periode': self.get_allowed_values( list_type=list_type, value='crm:periode'), - 'validite': self.get_allowed_values( - list_type=list_type, - value='crm:validite'), 'type': self.get_allowed_values( list_type=list_type, value='crm:type'), @@ -114,7 +113,17 @@ class CgscopAlfresco(models.AbstractModel): :param nodeRef: id Alfresco """ url = '/alfresco/s/document/' + nodeRef - return self.alfresco_get_by_url(url=url, call_type='get') + return self.alfresco_get_by_url(url=url, call_type='get').json() + + def alfresco_get_ticket(self, username): + """ Liste les documents pour un organisme (raison sociale) + :param username: username de l'utilisateur + """ + url = '/alfresco/s/authentifier-entantque?compte=' + username + result = self.alfresco_get_by_url(url=url, call_type='get') + tree = et.ElementTree(et.fromstring(result.content)) + root = tree.getroot() + return root[0].text # Post Methods def alfresco_create_organism(self, partner): @@ -132,7 +141,7 @@ class CgscopAlfresco(models.AbstractModel): "numAdherent": partner.member_number } return self.get_nodeRef( - self.alfresco_get_by_url(url=url, call_type='post', json=json)) + self.alfresco_get_by_url(url=url, call_type='post', json=json).json()) def alfresco_update_organism(self, partner): """ Mise à jour d'un dossier Organisme @@ -149,7 +158,7 @@ class CgscopAlfresco(models.AbstractModel): "numAdherent": partner.member_number } return self.get_nodeRef( - self.alfresco_get_by_url(url=url, call_type='post', json=json)) + self.alfresco_get_by_url(url=url, call_type='post', json=json).json()) def alfresco_upload(self, partner, type, periode, validite, filename, mimetype, doc): """ Upload d'un document sur Alfresco @@ -165,11 +174,10 @@ class CgscopAlfresco(models.AbstractModel): 'type': type, 'nomOrigine': filename, 'mimeType': mimetype, - 'validite': validite, 'contentBase64': doc, } return self.get_nodeRef( - self.alfresco_get_by_url(url=url, call_type='post', json=json)) + self.alfresco_get_by_url(url=url, call_type='post', json=json).json()) # Delete Methods def alfresco_remove(self, nodeRef): @@ -177,7 +185,7 @@ class CgscopAlfresco(models.AbstractModel): :param id_doc: id du document Alfresco """ url = '/alfresco/s/document/' + nodeRef - return self.alfresco_get_by_url(url=url, call_type='delete') + return self.alfresco_get_by_url(url=url, call_type='delete').json() # Others def get_allowed_values(self, list_type, value): diff --git a/models/cmis_backend.py b/models/cmis_backend.py new file mode 100644 index 0000000000000000000000000000000000000000..1e67b5d246711be0cafa9ea1d09266819c088ac3 --- /dev/null +++ b/models/cmis_backend.py @@ -0,0 +1,12 @@ +# © 2019 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models, fields + + +class CgscopAlfrescoConnection(models.Model): + _inherit = 'cmis.backend' + + url = fields.Char('URL') + ssl = fields.Boolean('Connexion SSL', default=False) + active = fields.Boolean('Actif', default=False) diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index c3e7f01ed6761412a38008a3462d0b17b02c66a8..58262d4440d02ecccad693faa23505f01ced8a9f 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,2 +1 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_alfresco_connection,access_alfresco_connection,model_alfresco_connection,cgscop_partner.group_cg_administrator,1,1,1,1 \ No newline at end of file +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink \ No newline at end of file diff --git a/static/src/js/form_widgets.js b/static/src/js/form_widgets.js new file mode 100644 index 0000000000000000000000000000000000000000..12a82be2f0670c378d87cd99d3d02803064254e6 --- /dev/null +++ b/static/src/js/form_widgets.js @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------- + Copyright 2020 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +------------------------------------------------------------------*/ + +odoo.define('cgscop_alfresco.form_widgets', function(require) { + "use strict"; + + var core = require('web.core'); + var form_widgets = require('cmis_web.form_widgets'); + var session = require('web.session'); + + form_widgets.FieldCmisFolder.include({ + /** + * Surcharge la fonction d'initialisation de la session CMIS pour + * passer le token de l'utilisateur + */ + init_cmis_session: function () { + var self = this; + $.when(this.cmis_config_loaded).done(function () { + self.cmis_session = cmis.createSession(self.cmis_location); + self.cmis_session.setGlobalHandlers(self.on_cmis_error, self.on_cmis_error); + + // CGSCOP : appel vers la fonction custom + self._rpc({route:'/web/alfresco/session', params:{ + 'username': session.username + }}).done(function (result) { + self.cmis_session.setToken(result); + }); + + self.cmis_session_initialized.resolve(); + self.cmis_session.setCharacterSet(document.characterSet); + }); + }, + }); + +}); diff --git a/views/alfresco_connection.xml b/views/alfresco_connection.xml deleted file mode 100644 index 5fa567413e82c344da9e9daf707b138c997b39dd..0000000000000000000000000000000000000000 --- a/views/alfresco_connection.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0"?> -<!-- Copyright 2019 Le Filament - License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> - -<odoo> - <data> - - <record id="view_alfresco_connection_tree" model="ir.ui.view"> - <field name="name">alfresco.connection.tree</field> - <field name="model">alfresco.connection</field> - <field name="arch" type="xml"> - <tree string="Synchronisation Odoo"> - <field name="name"/> - <field name="login"/> - <field name="url"/> - <field name="active"/> - </tree> - </field> - </record> - - <record id="view_alfresco_connection_form" model="ir.ui.view"> - <field name="name">alfresco.connection.form</field> - <field name="model">alfresco.connection</field> - <field name="arch" type="xml"> - <form> - <header> - <button name="toogle_active_config" type="object" string="Activer" /> - </header> - <sheet> - <group> - <group> - <field name="name" /> - <field name="url"/> - <field name="ssl"/> - </group> - <group> - <field name="active" readonly="1" /> - <field name="login"/> - <field name="password" password="True" /> - </group> - </group> - </sheet> - </form> - </field> - </record> - - <record id="view_alfresco_connection_search" model="ir.ui.view"> - <field name="name">alfresco.connection.search</field> - <field name="model">alfresco.connection</field> - <field name="arch" type="xml"> - <search string="Synchronisation Odoo"> - <!-- Champs de recherche --> - <field name="name"/> - <!-- Filtres --> - <filter name="active_filter" string="Actifs" domain="[('active','=',True)]"/> - <filter name="inctive_filter" string="Inactifs" domain="[('active','=',False)]" /> - <filter name="all_filter" string="Tous" domain="['|', ('active','=',True), ('active','=',False)]" /> - </search> - </field> - </record> - - <record id="action_view_alfresco_connection" model="ir.actions.act_window"> - <field name="name">Configuration Connexion Alfresco</field> - <field name="res_model">alfresco.connection</field> - <field name="view_mode">tree,form</field> - <field name="search_view_id" ref="view_alfresco_connection_search"/> - </record> - - <menuitem id="menu_cgscop_alfresco" - parent="cgscop_partner.menu_cgscop_api_config" - sequence="10" - name="Alfresco"/> - - <menuitem id="menu_cgscop_alfresco_connection" - parent="menu_cgscop_alfresco" - action="action_view_alfresco_connection" - name="Configuration connexion" - sequence="90"/> - </data> -</odoo> diff --git a/views/assets.xml b/views/assets.xml new file mode 100644 index 0000000000000000000000000000000000000000..dd5c433db3bd1f5c3d7c654ece1a57db667dfb27 --- /dev/null +++ b/views/assets.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<!-- Copyright 2020 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> + +<odoo> + <template id="assets_backend" name="cgscop_alfodoo_assets" inherit_id="cmis_web.assets_backend"> + <xpath expr="." position="inside"> + <script type="text/javascript" src="/cgscop_alfresco/static/src/js/form_widgets.js"/> + </xpath> + </template> +</odoo> diff --git a/views/cmis_backend.xml b/views/cmis_backend.xml new file mode 100644 index 0000000000000000000000000000000000000000..89f7da529a579fa62af3a08ff8c47309b14671ed --- /dev/null +++ b/views/cmis_backend.xml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<!-- Copyright 2019 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> + +<odoo> + <data> + + <record id="view_cmis_backend_cgscop_form_inherited" model="ir.ui.view"> + <field name="name">cmis.backend.cgscop.form</field> + <field name="model">cmis.backend</field> + <field name="inherit_id" ref="cmis.cmis_backend_form_view"/> + <field name="arch" type="xml"> + <sheet position="inside"> + <group name="cgscop" string="API Alfresco CG Scop"> + <field name="url"/> + <field name="ssl"/> + <field name="active"/> + </group> + </sheet> + </field> + </record> + + </data> +</odoo>