# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and contributors
# License: MIT. See LICENSE

import frappe


def run_webhooks(doc, method):
	'''Run webhooks for this method'''
	if frappe.flags.in_import or frappe.flags.in_patch or frappe.flags.in_install:
		return

	if frappe.flags.webhooks_executed is None:
		frappe.flags.webhooks_executed = {}

	if frappe.flags.webhooks is None:
		# load webhooks from cache
		webhooks = frappe.cache().get_value('webhooks')
		if webhooks is None:
			# query webhooks
			webhooks_list = frappe.get_all('Webhook',
						fields=["name", "`condition`", "webhook_docevent", "webhook_doctype"],
						filters={"enabled": True}
					)

			# make webhooks map for cache
			webhooks = {}
			for w in webhooks_list:
				webhooks.setdefault(w.webhook_doctype, []).append(w)
			frappe.cache().set_value('webhooks', webhooks)

		frappe.flags.webhooks = webhooks

	# get webhooks for this doctype
	webhooks_for_doc = frappe.flags.webhooks.get(doc.doctype, None)

	if not webhooks_for_doc:
		# no webhooks, quit
		return

	def _webhook_request(webhook):
		if webhook.name not in frappe.flags.webhooks_executed.get(doc.name, []):
			frappe.enqueue("frappe.integrations.doctype.webhook.webhook.enqueue_webhook",
				enqueue_after_commit=True, doc=doc, webhook=webhook)

			# keep list of webhooks executed for this doc in this request
			# so that we don't run the same webhook for the same document multiple times
			# in one request
			frappe.flags.webhooks_executed.setdefault(doc.name, []).append(webhook.name)

	event_list = ["on_update", "after_insert", "on_submit", "on_cancel", "on_trash"]

	if not doc.flags.in_insert:
		# value change is not applicable in insert
		event_list.append('on_change')
		event_list.append('before_update_after_submit')

	from frappe.integrations.doctype.webhook.webhook import get_context

	for webhook in webhooks_for_doc:
		trigger_webhook = False
		event = method if method in event_list else None
		if not webhook.condition:
			trigger_webhook = True
		elif frappe.safe_eval(webhook.condition, eval_locals=get_context(doc)):
			trigger_webhook = True

		if trigger_webhook and event and webhook.webhook_docevent == event:
			_webhook_request(webhook)

frappe/integrations/doctype/webhook/__init__.py
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies and contributors
# License: MIT. See LICENSE

import frappe


def run_webhooks(doc, method):
	'''Run webhooks for this method'''
	if frappe.flags.in_import or frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_migrate:
		return

	if frappe.flags.webhooks_executed is None:
		frappe.flags.webhooks_executed = {}

	if frappe.flags.webhooks is None:
		# load webhooks from cache
		webhooks = frappe.cache().get_value('webhooks')
		if webhooks is None:
			# query webhooks
			webhooks_list = frappe.get_all('Webhook',
						fields=["name", "`condition`", "webhook_docevent", "webhook_doctype"],
						filters={"enabled": True}
					)

			# make webhooks map for cache
			webhooks = {}
			for w in webhooks_list:
				webhooks.setdefault(w.webhook_doctype, []).append(w)
			frappe.cache().set_value('webhooks', webhooks)

		frappe.flags.webhooks = webhooks

	# get webhooks for this doctype
	webhooks_for_doc = frappe.flags.webhooks.get(doc.doctype, None)

	if not webhooks_for_doc:
		# no webhooks, quit
		return

	def _webhook_request(webhook):
		if webhook.name not in frappe.flags.webhooks_executed.get(doc.name, []):
			frappe.enqueue("frappe.integrations.doctype.webhook.webhook.enqueue_webhook",
				enqueue_after_commit=True, doc=doc, webhook=webhook)

			# keep list of webhooks executed for this doc in this request
			# so that we don't run the same webhook for the same document multiple times
			# in one request
			frappe.flags.webhooks_executed.setdefault(doc.name, []).append(webhook.name)

	event_list = ["on_update", "after_insert", "on_submit", "on_cancel", "on_trash"]

	if not doc.flags.in_insert:
		# value change is not applicable in insert
		event_list.append('on_change')
		event_list.append('before_update_after_submit')

	from frappe.integrations.doctype.webhook.webhook import get_context

	for webhook in webhooks_for_doc:
		trigger_webhook = False
		event = method if method in event_list else None
		if not webhook.condition:
			trigger_webhook = True
		elif frappe.safe_eval(webhook.condition, eval_locals=get_context(doc)):
			trigger_webhook = True

		if trigger_webhook and event and webhook.webhook_docevent == event:
			_webhook_request(webhook)

frappe/integrations/doctype/webhook/__init__.py
diff --git a/frappe/integrations/doctype/webhook/__init__.py b/frappe/integrations/doctype/webhook/__init__.py
index 6dcc0218a333..cb7a9963b7aa 100644
--- a/frappe/integrations/doctype/webhook/__init__.py
+++ b/frappe/integrations/doctype/webhook/__init__.py
@@ -7,7 +7,7 @@
 
 def run_webhooks(doc, method):
 	'''Run webhooks for this method'''
-	if frappe.flags.in_import or frappe.flags.in_patch or frappe.flags.in_install:
+	if frappe.flags.in_import or frappe.flags.in_patch or frappe.flags.in_install or frappe.flags.in_migrate:
 		return
 
 	if frappe.flags.webhooks_executed is None:

pymysql.err.ProgrammingError: ('DocType', 'Webhook')
```
> bench --site all migrate --skip-failing 
...
Migrating my-site

Traceback (most recent call last):
  File "/usr/lib/python3.6/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 104, in <module>
    main()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/bench_helper.py", line 19, in main
    click.Group(commands=commands)(prog_name='bench')
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/frappe/frappe-bench/env/lib/python3.6/site-packages/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/__init__.py", line 27, in _func
    ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/commands/site.py", line 309, in migrate
    skip_search_index=skip_search_index
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 78, in migrate
    skip_search_index=skip_search_index
  File "/home/frappe/frappe-bench/apps/frappe/frappe/migrate.py", line 78, in migrate
    sync_languages()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/core/doctype/language/language.py", line 43, in sync_languages
    'language_name': l['name']
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 231, in insert
    self.run_method("before_insert")
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/document.py", line 870, in run_method
    run_webhooks(self, method)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/integrations/doctype/webhook/__init__.py", line 25, in run_webhooks
    filters={"enabled": True}
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 1469, in get_all
    return get_list(doctype, *args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/__init__.py", line 1442, in get_list
    return frappe.model.db_query.DatabaseQuery(doctype).execute(*args, **kwargs)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/db_query.py", line 102, in execute
    self.columns = self.get_table_columns()
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/db_query.py", line 339, in get_table_columns
    return get_table_columns(self.doctype)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/meta.py", line 49, in get_table_columns
    return frappe.db.get_table_columns(doctype)
  File "/home/frappe/frappe-bench/apps/frappe/frappe/database/database.py", line 902, in get_table_columns
    raise self.TableMissingError('DocType', doctype)
pymysql.err.ProgrammingError: ('DocType', 'Webhook')
```

Migrating from `version-13-beta` to `version-13` (13.17)

### Versions

```
> bench version
erpnext 13.17.0
frappe 13.17.1
```
