|
Started by Vincent DUBREIL, Feb., 17 2020 10:10 AM - 10 replies |
| |
| | | |
|
| |
Posted on February, 17 2020 - 10:10 AM |
Bonjour à tous,
j'essaye actuellement de connecter un projet windev (ou webdev) à une base postgresql Odoo hébergée sur Odoo.sh
Est-ce quelqu'un a déjà fait cela et si oui, par quel moyen ?
J'ai trouvé dans la LST 112, un code permettant d'exploiter via Windev, du code python qui va utiliser l'API odoo pour interroger la base. Après un test, cela marche, mais j'aurais préféré trouver un moyen plus direct afin de ne pas avoir à écrire du python.
Par moyen direct, j'entends soit de pouvoir envoyer des requêtes SQL par exemples et en récupérer le résultat ou à défaut, de générer moi-même le XML à utiliser avec du HTTPRequete mais pas moyen de trouver la syntaxe du XML attendu par Odoo.
Si vous avez des infos, d'autres idées qui pourraient m'aider, car voilà plus d'une semaine que je cherche et toujours rien.
Merci de m'avoir lu
Bonne journée et bonne semaine
Vincent |
| |
| |
| | | |
|
| | |
| |
Registered member 449 messages Popularité : +31 (43 votes) |
|
Posted on February, 17 2020 - 12:15 PM |
Bonjour
J'avais écrit une réponse à ce sujet voici le lien : https://forum.pcsoft.fr/fr-FR/pcsoft.fr.windevmobile/37831-connect-directement-erp-odoo-postgressql-avec-windev-mobile/read.awp…
vous y trouverez un exemple de connection de windev à odoo et ma procedure call qui permet d'interroger une API et de récupérer le résultat en json
Par contre il va vous falloir vous mettre à python pour pouvoir faire communiquer votre application windev avec la base de donnée postgres.
Je vous rajoute en code ci dessous un exemple d'appel dans windev et une api ecrit en python dans odoo
Dans la procédure ci dessous j'appelle odoo:call vous trouverez la procédure dans le lien au dessus
************************************************************************************************************************** code windev d'appel de l'api dans odoo
Procedure Recuperation_cadence(sPoste_Atelier est une chaîne) <métier> odoo:var = Null odoo:var.filtre = "('name','=','"+ SansEspace(sPoste_Atelier) +"')," SI odoo:call("wpa.posteateliers","api_v1_wpa_posteateliers_cadence_get") ALORS VarGlobal:__Cadence = odoo:res_data[1].cadence VarGlobal:__Nbr_Cadence_Default = odoo:res_data[1].nb_cadence_default VarGlobal:__Nbre_Cadence = odoo:res_data[1].nb_cadence RENVOYER Vrai SINON RENVOYER Faux FIN
***************************************************************************************************** code dans odoo en langage python # -*- coding: utf-8 -*-
import odoo from odoo import tools, models, fields, api, _ from datetime import date, time, datetime import base64 import json import encodings
class wpa_posteateliers(models.Model): _name = 'wpa.posteateliers' _inherit = 'wpa.posteateliers' _model = 'wpa.posteateliers' _description = 'Package header'
#API qui permet de renvoyer juste les informations de cadence en fonction d'un poste envoyer en valeur de filtre en amont @api.model def api_v1_wpa_posteateliers_cadence_get(self, company_id, var): data = [] filter = []
filter = [('company_id', '=', company_id)] if var != None: if 'filtre' in var: filter += eval(var['filtre']) posteateliers = self.env['wpa.posteateliers'].search(filter) for element in posteateliers: dict = {} dict['cadence'] = element.cadence dict['nb_cadence'] = element.nb_cadence dict['nb_cadence_default'] = element.nb_cadence_default
data.append(dict)
if data: return json.dumps(data)
return False
J'espère que cela vous aidera
Bon courage
Cordialement DG |
| |
| |
| | | |
|
| | |
| |
Registered member 67 messages Popularité : +1 (1 vote) |
|
Posted on February, 18 2020 - 3:33 PM |
Bonjour DG,
Merci pour ton retour, je vais regarde cela de plus près.
Par contre, de ce que j'ai pu lire à droite à gauche, le fait de ne pas utiliser l'API propriétaire d'Odoo, on risque quelques incohérences dans la base car , en passant par leur API, le fait d'écrire dans la table A, ne va pas forcément faire qu'écrire dans la table A Par exemple, si tu écris un enregistrement dans la table sale.order, cela va automatiquement écrire dans la table des messages pour tracer l'historique. Cet exemple n'est pas le plus embêtant mais, à moins de connaître toutes ces subtilités, ne risque-t'on pas au final de passer à côté de certaines choses ?
Vincent
-- ______________________________________ Vincent DUBREIL |
| |
| |
| | | |
|
| | |
| |
Registered member 67 messages Popularité : +1 (1 vote) |
|
Posted on February, 18 2020 - 3:40 PM |
DG,
J'en profite pour te demander si tu n'avais pas déjà essayé de te connecter à odoo.sh via un tunnel SSH afin de passer des requêtes directement sur la base (pour faire des select par exemple) ?
-- ______________________________________ Vincent DUBREIL |
| |
| |
| | | |
|
| | |
| |
Registered member 449 messages Popularité : +31 (43 votes) |
|
Posted on February, 18 2020 - 5:22 PM |
Vincent DUBREIL a écrit :
Bonjour DG,
Merci pour ton retour, je vais regarde cela de plus près.
Par contre, de ce que j'ai pu lire à droite à gauche, le fait de ne pas utiliser l'API propriétaire d'Odoo, on risque quelques incohérences dans la base car , en passant par leur API, le fait d'écrire dans la table A, ne va pas forcément faire qu'écrire dans la table A Par exemple, si tu écris un enregistrement dans la table sale.order, cela va automatiquement écrire dans la table des messages pour tracer l'historique. Cet exemple n'est pas le plus embêtant mais, à moins de connaître toutes ces subtilités, ne risque-t'on pas au final de passer à côté de certaines choses ?
Vincent
-- ______________________________________ Vincent DUBREIL
Franchement cela fait à peu près 2 ans que nous sommes passez sur odoo, on travail avec une société qui s'appelle "sudokeys", qui elle s'occupe de mettre à jour les module compta et nous à former au développement sur odoo. Par contre pour le reste on écrit nous même nos api pour faire communiquer notre logiciel de prod avec les bases de odoo et on a pas de souci d’incohérence.
Sinon, je n'ai pas tester le tunnel ssh, pour les requêtes, on écrit une api, notre logiciel de prod(en windev) appel l'api , l'api nous retourne un résultat en json que je traite.
Au cas ou voici un exemple d'api avec requête :
#=================================================================================================== #API requete pour compter.... @api.model def api_v1_wpa_tracking_distinct_counter(self, company_id, var):
if var is None: return False
data = [] sql = "SELECT DISTINCT wpa_tracking.post_workshop, wpa_posteateliers.description, wpa_tracking.user_login " sql = sql + "FROM wpa_tracking, wpa_posteateliers " sql = sql + "WHERE wpa_tracking.company_id = %i AND " %(company_id) sql = sql + "wpa_posteateliers.name = wpa_tracking.post_workshop AND " if 'production' in var: sql = sql + "wpa_posteateliers.production IN (%s) AND " %(var['production']) sql = sql + "wpa_posteateliers.company_id = wpa_tracking.company_id AND " sql = sql + "wpa_tracking.date_scan BETWEEN '%s' and '%s' AND " %(var['date_scan_begin'],var['date_scan_end']) sql = sql + "wpa_tracking.archive = False " sql = sql + "order by wpa_tracking.post_workshop,wpa_tracking.user_login"
self.env.cr.execute(sql) resultreq = self.env.cr.fetchall()
for post_workshop,description,user_login in resultreq: dict = {} dict['post_workshop'] = post_workshop dict['description'] = description dict['user_login'] = user_login
data.append(dict)
if data: return json.dumps(data)
return False
Cordialement
DImitriMessage modified, February, 18 2020 - 5:25 PM |
| |
| |
| | | |
|
| | |
| |
Registered member 67 messages Popularité : +1 (1 vote) |
|
Posted on February, 19 2020 - 8:42 AM |
Bonjour Dimitri,
ok bien noté cela me rassure pour les incohérences. Merci pour tous ces éléments qui devrait bien m'aider
Bonne journée
-- ______________________________________ Vincent DUBREIL |
| |
| |
| | | |
|
| | |
| |
Registered member 449 messages Popularité : +31 (43 votes) |
|
Posted on February, 19 2020 - 10:04 AM |
Bonjour Vincent
N’hésitez pas si vous avez d'autres questions je reste abonné à ce post au cas où.
Bonne journée également
cdlt
Dimitri |
| |
| |
| | | |
|
| | |
| |
Registered member 67 messages Popularité : +1 (1 vote) |
|
Posted on February, 19 2020 - 2:31 PM |
Justement j'allais te poser une autre question
J'essaye plusieurs solutions en parallèle avant de décider laquelle sera retenue. J'étais à essayer l'exemple WD Python de la LST 112
J'ai codé en python la fonction de lecture qui fait un read et doit renvoyer la liste des données (n champs de n enregistrements) Dans le code de l'exemple windev, on récupère la réponse en spécifiant le type en retour (entier, etc...) Pour ce cas, j'utilise un type dédié wlPythonObject qui est déclaré dans une classe rattachée au projet.
Sais-tu comment on peut ensuite lire ce genre de variable pour en récupérer les différents élements (par exemple client 1 (nom, prénom, tel), Client 2 (nom, prénom, tel),....) ?
Je te mets un bout de code si c'est plus parlant
-- ______________________________________ Vincent DUBREIL |
| |
| |
| | | |
|
| | |
| |
Registered member 67 messages Popularité : +1 (1 vote) |
|
Posted on February, 19 2020 - 2:58 PM |
Dimitri,
C'est bon j'ai trouvé, il y avait bien une procédure dans la classe pour faire cela, j'étais passé trop vite!!!
-- ______________________________________ Vincent DUBREIL |
| |
| |
| | | |
|
| | |
| |
Registered member 67 messages Popularité : +1 (1 vote) |
|
Posted on February, 20 2020 - 4:19 PM |
Bonjour Dimitri,
J'ai à nouveau besoin de tes lumières
J'ai une fonction python "read_data" (celle que tu peux voir dans mon post au-dessus) à laquelle je passe un filtre tel que [[('name','=','toto')]] Ça marche bien si je passe ce filtre en paramètre depuis une autre fonction python Par contre si je veux appeler directement cette fonction depuis Windev, je n'arrive pas à passer le paramètre car ce n'est pas juste une chaine ou un numérique. Sais-tu comment passer ce genre de paramètre ?
Cordialement
-- ______________________________________ Vincent DUBREIL |
| |
| |
| | | |
|
| | |
| |
Registered member 449 messages Popularité : +31 (43 votes) |
|
Posted on February, 20 2020 - 5:12 PM |
Bonjour vincent
mon passage de paramètre je le fais comme ceci lors de l'appel de ma procedure call le filtre est traité à la ligne => :demande_request.params.args[2] = :var
EXEMPLE de filtre odoo
Procedure Supprimer_tracking(nNum_Indice est un entier) <métier>
odoo:var = Null odoo:var.filtre = "('id','=','" + nNum_Indice + "'),"
SI odoo:call("wpa.tracking","api_v1_wpa_tracking_delete") ALORS RENVOYER Vrai SINON RENVOYER Faux FIN
Ma procedure call
Procedure call(p_model="",p_method="" )
SI :IDFichier<>-1 ALORS ChronoDébut() FIN
:MaRequeteRequest..ContentType = typeMimeJSON
:MaRequeteRequest..Entête["Cookie"] = :cReponseRequest.Entête["Set-Cookie"] :MaRequeteRequest..URL = "http://"+:p_ipserveur+"/web/dataset/call_kw" :MaRequeteRequest..DuréeNonRéponse = :p_timeout :demande_request.jsonrpc = "2.0" :demande_request.method = "call"
SI p_model<>"" ALORS :demande_request.params.model = p_model SI p_model<>"" ALORS :demande_request.params.method = p_method
:demande_request.params.context.lang = :result_connexion.user_context.lang :demande_request.params.context.tz = :result_connexion.user_context.tz :demande_request.params.context.uid = :result_connexion.user_context.uid
:demande_request.params.kwargs.tmp = "" SupprimeTout(:demande_request.params.kwargs..Membre)
:demande_request.params.args[1] = :result_connexion.Company_id :demande_request.params.args[2] = :var
:MaRequeteRequest.Contenu = :demande_request..FormatJSON cMaReponsedata est un restRéponse = RESTEnvoie(:MaRequeteRequest)
SI ErreurDétectée ALORS Erreur(ErreurInfo(errComplet)) SINON
SI cMaReponsedata..CodeEtat<>200 ALORS Erreur("Erreur HTTP "+cMaReponsedata.CodeEtat,AnsiVersUnicode(cMaReponsedata..Contenu)) RENVOYER Faux SINON :res_data = cMaReponsedata..Contenu SI :res_data.RESULT = Faux ALORS RENVOYER False :res_data = :res_data.RESULT SI :IDFichier<>-1 ALORS DureeMaFonction = ChronoFin() :log_write(DuréeVersChaîne(DureeMaFonction,"HH-MM-SS-LLL")+";"+p_model+";"+NetAdresseIP+";"+p_method) FIN RENVOYER Vrai FIN FIN
J'espère que cela t'aidera
Cordialement
Dimitri |
| |
| |
| | | |
|
| | | | |
| | |
|