Files
odoo_source/addons/google_spreadsheet/models/google_drive.py
T
Nasreddin Boulif (bon) ad3cf187e2 [FIX] google_spreadsheet: migrate to new api (v3 -> v4)
Steps to Reproduce:

  - Install 'account' module
  - Go to Settings and set a token for Google Drive
  - Activate Google Spreadsheet
  - Go to Invoicing -> Invoices
  - Under Search bar, click on Favorites -> Add to Google Spreadsheet

Issue:

  A spreadsheet does open but with no data (no formula or config).

Cause:

  The V3 API we were using was turned down in August 2021 and therefore
  not able to use the api to write on the spreadsheet.
  https://cloud.google.com/blog/products/g-suite/migrate-your-apps-use-latest-sheets-api)

Note: In case that the system parameters `​google_drive_client_id` and
`google_drive_client_secret` has been changed (and therefore also the
default templates), it must be ensured that the `client` has the
Google Sheet API (v4) activated and the scope
`https://www.googleapis.com/auth/spreadsheets` set.

API activation and configuration available here :
https://console.developers.google.com/apis/dashboard?project=[PROJECT]
https://console.developers.google.com/apis/credentials/consent/edit?project=[PROJECT]
**[PROJECT]** : Google project that will be linked to `​google_drive_client_id`.

opw-2633951

closes odoo/odoo#84488

X-original-commit: 3268530a071d9351ca86776fe85289ee5feece3d
Signed-off-by: Nasreddin Boulif (bon) <bon@odoo.com>
2022-02-14 07:58:56 +00:00

89 lines
3.5 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
import logging
import requests
from lxml import etree
import re
import werkzeug.urls
from odoo import api, models
from odoo.tools import misc
from odoo.addons.google_account import TIMEOUT
_logger = logging.getLogger(__name__)
class GoogleDrive(models.Model):
_inherit = 'google.drive.config'
def get_google_scope(self):
scope = super(GoogleDrive, self).get_google_scope()
return '%s https://www.googleapis.com/auth/spreadsheets' % scope
@api.model
def write_config_formula(self, attachment_id, spreadsheet_key, model, domain, groupbys, view_id):
access_token = self.get_access_token(scope='https://www.googleapis.com/auth/spreadsheets')
fields = self.env[model].fields_view_get(view_id=view_id, view_type='tree')
doc = etree.XML(fields.get('arch'))
display_fields = []
for node in doc.xpath("//field"):
if node.get('modifiers'):
modifiers = json.loads(node.get('modifiers'))
if not modifiers.get('invisible') and not modifiers.get('column_invisible'):
display_fields.append(node.get('name'))
fields = " ".join(display_fields)
domain = domain.replace("'", r"\'").replace('"', "'").replace('True', 'true').replace('False', 'false')
if groupbys:
fields = "%s %s" % (groupbys, fields)
formula = '=oe_read_group("%s";"%s";"%s";"%s")' % (model, fields, groupbys, domain)
else:
formula = '=oe_browse("%s";"%s";"%s")' % (model, fields, domain)
url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
dbname = self._cr.dbname
user = self.env['res.users'].browse(self.env.user.id).read(['login', 'password'])[0]
username = user['login']
password = user['password']
if not password:
config_formula = '=oe_settings("%s";"%s")' % (url, dbname)
else:
config_formula = '=oe_settings("%s";"%s";"%s";"%s")' % (url, dbname, username, password)
request = {
"valueInputOption": "USER_ENTERED",
"data": [
{"range": "A1", "values": [[formula]]},
{"range": "O60", "values": [[config_formula]]},
]
}
try:
req = requests.post(
'https://sheets.googleapis.com/v4/spreadsheets/%s/values:batchUpdate?%s' % (spreadsheet_key, werkzeug.urls.url_encode({'access_token': access_token})),
data=json.dumps(request),
headers={'content-type': 'application/json', 'If-Match': '*'},
timeout=TIMEOUT,
)
except IOError:
_logger.warning("An error occurred while writing the formula on the Google Spreadsheet.")
description = '''
formula: %s
''' % formula
if attachment_id:
self.env['ir.attachment'].browse(attachment_id).write({'description': description})
return True
@api.model
def set_spreadsheet(self, model, domain, groupbys, view_id):
config = self.env.ref('google_spreadsheet.google_spreadsheet_template')
title = 'Spreadsheet %s' % model
res = self.copy_doc(False, config.google_drive_resource_id, title, model)
mo = re.search("(key=|/d/)([A-Za-z0-9-_]+)", res['url'])
if mo:
key = mo.group(2)
self.write_config_formula(res.get('id'), key, model, domain, groupbys, view_id)
return res