===== Module Manager Description ===== ===== Fonctionnement du module ===== Quand l’utilisateur clique sur le lien de téléchargement de l'attachement au niveau du portail Odoo : La fonction **download_attachement()** sera lancé ,elle vérifie si le client à acheté le produit associé def download_attachment(self, attachment_id): # Check if this is a valid attachment id log.warning("########### i''m in #######################") attachment = request.env['ir.attachment'].sudo().search_read( [('id', '=', int(attachment_id))], ["name", "datas", "mimetype", "res_model", "res_id", "type", "url"] ) if attachment: attachment = attachment[0] else: return redirect(self.orders_page) # Check if the user has bought the associated product res_model = attachment['res_model'] res_id = attachment['res_id'] purchased_products = request.env['account.move.line'].get_digital_purchases() if res_model == 'product.product': if res_id not in purchased_products: return redirect(self.orders_page) Aussi elle vérifie la pièce jointe (attachement) sur le module **product.template** # Also check for attachments in the product templates elif res_model == 'product.template': template_ids = request.env['product.product'].sudo().browse(purchased_products).mapped('product_tmpl_id').ids if res_id not in template_ids: return redirect(self.orders_page) else: return redirect(self.orders_page) Si le type de l’attachement == 'module' une requête sera envoyé pour vérifier si les modules avec ces versions existe sur le serveur (module-manager) a travers la route : http://m-m/api/update/modules/version data = [] # Get the list of product & append them in a list [name, version] for a in attachments: if a['version']: b = requests.get(f'{static_url}/api/update/modules/{a["version"]}') log.warning('======== B ============== {} '.format(b)) data.append( { "name": a['name'], "version": a['version'] }) Au niveau du serveur Module-manager: La fonction **update_module_list()** fait appel à la fonction **module_populator()**: def update_module_list(request, version): utils.modules_populator(Module, str(version)) return JsonResponse({'status': 200, 'date':" DATE "}) La fonction **module_populator()** récupère la version du module et le nom du modele: * La fonction récupère la liste des modules depuis gitlab a traves la fonction **get_module_liste()** et vérifie si la version du module existe sur la liste * Si la version n'existe pas elle va créer des modules sur la base de données locale du module manager pour les version qui n’existe pas def modules_populator(model, version): """ Create Modules in The Local Database """ for module in get_module_list(version=version): # Check if module exists in the local database if not model.objects.filter( name=module, version=version ).exists(): model.objects.create( name=module, version=version ) la fonction **get_module_liste()** : def get_module_list(version): """ Fetch all the modules by Name & Version then return the it as a list """ repo_modules = f'{settings.GITLAB_URL}/projects/{settings.PROJECT_ID}/repository/tree?ref={version}' get_modules_req = requests.get( repo_modules, headers=settings.HEADERS ).text # GET ALL MODULES OF ELOAPPS REPOSITORY modules_list = [] for module in json.loads(get_modules_req): modules_list.append(module['path']) print(f"==== modules_list = {modules_list} ====") return modules_list Après la mise à jour des modules sur le serveur module-manager et la vérification avec le dépôt Gitlab , on arrivera à l’étape de vérification du token de l'utilisateur , cette étape sera faite sur la même fonction **download_attachement()** : if user['access_token'] : log.warning('in if token') token_id = request.env['user.token'].sudo().search_read([('id','=', user['access_token'][0])],['access_token']) token = token_id[0]['access_token'] log.warning('token {}'.format(token)) # If the user doesn t have a token create a call to the url service to create # a access token () else : log.warning('in else token') token = request.env['res.users'].sudo().get_access(user['login'],user['access_token']).access_token log.warning("token{} ".format(token)) La fonction **get_acces()** vérifie si l’utilisateur existe au niveau du serveur module-manager: * Sur le service module-manager la vérification de l'utilisateur se fait à travers la route: http://m-m/user/exists/+mail * Si l'utilisateur existe sur le serveur module-manager et possède d'un token sur odoo , la fonction **get_acces()** reourne le token * Si l'utilisateur existe sur le serveur module-manager et ne possède pas un token sur odoo ; une requete sera enovoyé à la route : http://m-m/api-token-auth + data = {'username':mail, 'password':PILOT-ALGA-ANDY} , cette requette récupere le token depuis e servaur sans creer un nouveau utilisateur * Si l'utilisateur n'existe pas sur le serveur module-manager, une requette va creer un nouveauutilisateur su le serveur avec le mail du client de odoo , cela fait à travers la route suivante : http://m-m/user/api/register + data = {'username':mail, 'password':PILOT-ALGA-ANDY} et retourne le token * Si l'utilisateur possède un token sur odoo ,le token sera récupéré sans avoir passé par le service module-manager def get_access(self, mail,token): url_user = "http://m-m/api/user/exists/"+ mail url = "http://m-m/api/user/register" url_token = "http://m-m/api-token-auth" data = { 'username': mail, 'password': 'PILOT-ALGA-ANDY' } req_user =json.loads(requests.get(str(url_user)).text) #If the user exists in the server if req_user['exists']: #likely never happens if token : return token #fetch the token from the server and return it without creating a new user else : req_token = json.loads(requests.post(url_token, data=data).text) token = self.env['user.token'].create({ 'access_token': req_token['token'], 'user_id': self.env['res.users'].search([('login','=', mail)]).id, }) return token #create a user in the server with mail and fetch the token else : req = json.loads(requests.post(url, data=data).text) token = self.env['user.token'].create({ 'access_token': req['key'], 'user_id': self.env['res.users'].search([('login','=', mail)]).id, }) return token Après avoir terminer tous ces étapes avec succès, une requête sera envoyé à la route : http://m-m/connect/+ data + token , avec data = {la liste des attachements du client sur odoo } cette étape mettre a jour le compte du client au niveau du serveur module-manager avec la listes des pièces-jointes après il sera redirigé vers la listes du module sur le serveur module-manager à traves la route : http://m-m/modules?token pour qu'il puisse accéder à ces pièces-jointes et les télécharger . la suite de la fonction **download_attachement()** : url_connect = f"{static_url}/connect" url_mdl = f"{static_url}/modules?token={token}" # # url = "http://192.168.1.130/api/modules/create" req = requests.put(url_connect ,json=data, headers={"Authorization": f"Token {token}"}) log.warning("req 1::: {} ".format(req)) # req = requests.post(url_update, data=json.dumps(data), headers={'Content-Type': 'application/json'}).text # log.warning("req 2::: {} ".format(req)) # log.warning(req) return redirect(url_mdl) ===== Résumé ===== Un client a aquis un module et souhaite le télécharger. En appuyant sur le bouton télécharger sur Odoo - Odoo envoie une requête sur ''/api/update/modules/15.0'' (15.0 est un exemple de la version souhaitée par le client) - Odoo envoie une requête sur ''/api/user/exists/anwar.said@gmail.com'' (anwar.said@gmail.com est un exemple du mail client) - Odoo envoie une requête sur ''/api/user/register'' - Odoo reçoit un token - Odoo envoie une requête sur ''/connect'' - Odoo redirige le client vers ''/modules'' avec comme paramètre le token reçu en (4)