Try ERPNext Buy Support Partners Foundation

Override method from Google Calendar or orther module not working

Continuing the discussion from How to override method in frappe?:

Hello everyone,

I’m trying to modify the method “insert_event_in_google_calendar” and “update_event_in_google_calendar” from google_calendar in frappe/integrations/doctype/google_calendar/google_calendar.py

I tried to follow the method on the above topic but I can’t get it to work.

I’ll give you an example:

In custom_app/doctype/google_calendar/google_calendar.py, i have :

from __future__ import unicode_literals
import frappe
import requests
import googleapiclient.discovery
import google.oauth2.credentials

from frappe import _
from frappe.model.document import Document
from frappe.utils import get_request_site_address
from googleapiclient.errors import HttpError
from frappe.utils import add_days, get_datetime, get_weekdays, now_datetime, add_to_date, get_time_zone
from dateutil import parser
from datetime import datetime, timedelta
from six.moves.urllib.parse import quote
from frappe.integrations.doctype.google_settings.google_settings import get_auth_url    
import frappe
    from frappe.integrations.doctype.google_calendar.google_calendar import GoogleCalendar

    def update_event_in_google_calendar(doc, method=None):
	"""
		Updates Events in Google Calendar if any existing event is modified in Frappe Calendar
	"""
	# Workaround to avoid triggering updation when Event is being inserted since
	# creation and modified are same when inserting doc
	if not frappe.db.exists("Google Calendar", {"name": doc.google_calendar}) or doc.modified == doc.creation \
		or not doc.sync_with_google_calendar:
		return

	if doc.sync_with_google_calendar and not doc.google_calendar_event_id:
		# If sync_with_google_calendar is checked later, then insert the event rather than updating it.
		insert_event_in_google_calendar(doc)
		return

	google_calendar, account = get_google_calendar_object(doc.google_calendar)

	if not account.push_to_google_calendar:
		return

	if doc.description is None:
		doc.description = ''

	try:
		event = google_calendar.events().get(calendarId=doc.google_calendar_id, eventId=doc.google_calendar_event_id).execute()
		event["summary"] = doc.subject
		event["description"] = doc.description + '\n' + 'Custom field 1 : ' + doc.custom_field_1
		event["recurrence"] = repeat_on_to_google_calendar_recurrence_rule(doc)
		event["status"] = "cancelled" if doc.event_type == "Cancelled" or doc.status == "Closed" else event.get("status")
		event.update(format_date_according_to_google_calendar(doc.all_day, get_datetime(doc.starts_on), get_datetime(doc.ends_on)))

		google_calendar.events().update(calendarId=doc.google_calendar_id, eventId=doc.google_calendar_event_id, body=event).execute()
		frappe.msgprint(_("Event Synced with Google Calendar - UPDATE"))
	except HttpError as err:
		frappe.throw(_("Google Calendar - Could not update Event {0} in Google Calendar, error code     {1}.").format(doc.name, err.resp.status))

GoogleCalendar.update_event_in_google_calendar = update_event_in_google_calendar

In this example I have modified event["description"] to take into consideration the fields created and add the word UPDATE in frappe.msgprint add also a if doc.description above…

For information, I did the same for the insert.

To take the updates into consideration, I execute this command :
bench --site SiteName migrate

When I update/create a Google Calendar event my python method doesn’t work.
So I thought I should add it in the hooks.py of my application :

doc_events = {
	"Event": {
  		"after_insert": "custom_app.custom_app.doctype.google_calendar.google_calendar.insert_event_in_google_calendar",
       	"on_update": "custom_app.custom_app.doctype.google_calendar.google_calendar.update_event_in_google_calendar"
    }
}

I look in the console bench and observe the events are present:

'Event': {
'after_insert': ['frappe.integrations.doctype.google_calendar.google_calendar.insert_event_in_google_calendar', 'custom_app.custom_app.doctype.google_calendar.google_calendar.insert_event_in_google_calendar'],
 'on_update': ['frappe.integrations.doctype.google_calendar.google_calendar.update_event_in_google_calendar', 'custom_app.custom_app.doctype.google_calendar.google_calendar.update_event_in_google_calendar'],

Except that there he added this method to me in addition and not replaced by this one. Which means that when I insert or modify an event he does it twice.

How to make frappe.integrations.doctype.google_calendar.google_calendar.insert_event_in_google_calendar be replaced by custom_app.custom_app.doctype.google_calendar.google_calendar.insert_event_in_google_calendar without touching core files ?

I can do it in the core files and it works except that when I have frappe/erpnext update, I have conflicts and I don’t think it’s the right method.

Can you help me because I’m a little lost for that and I’ve been looking through your forum and documentation, if someone can explain it to me?

Hi @revant_one, can you help me please ?

I use solution by youssef and it’s working.