Merge branch 'develop' into UAE-VAT-Format
diff --git a/erpnext/accounts/desk_page/accounting/accounting.json b/erpnext/accounts/desk_page/accounting/accounting.json
index 3f23ba9..29d1331 100644
--- a/erpnext/accounts/desk_page/accounting/accounting.json
+++ b/erpnext/accounts/desk_page/accounting/accounting.json
@@ -79,6 +79,11 @@
    "hidden": 0,
    "label": "Profitability",
    "links": "[\n    {\n        \"dependencies\": [\n            \"Sales Invoice\"\n        ],\n        \"doctype\": \"Sales Invoice\",\n        \"is_query_report\": true,\n        \"label\": \"Gross Profit\",\n        \"name\": \"Gross Profit\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"GL Entry\"\n        ],\n        \"doctype\": \"GL Entry\",\n        \"is_query_report\": true,\n        \"label\": \"Profitability Analysis\",\n        \"name\": \"Profitability Analysis\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Sales Invoice\"\n        ],\n        \"doctype\": \"Sales Invoice\",\n        \"is_query_report\": true,\n        \"label\": \"Sales Invoice Trends\",\n        \"name\": \"Sales Invoice Trends\",\n        \"type\": \"report\"\n    },\n    {\n        \"dependencies\": [\n            \"Purchase Invoice\"\n        ],\n        \"doctype\": \"Purchase Invoice\",\n        \"is_query_report\": true,\n        \"label\": \"Purchase Invoice Trends\",\n        \"name\": \"Purchase Invoice Trends\",\n        \"type\": \"report\"\n    }\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Value-Added Tax (VAT UAE)",
+   "links": "[\n    {\n        \"label\": \"UAE VAT Setting\",\n        \"name\": \"UAE VAT Setting\",\n        \"type\": \"doctype\"\n    },\n    {\n        \"is_query_report\": true,\n        \"label\": \"UAE VAT 21\",\n        \"name\": \"UAE VAT 21\",\n        \"type\": \"report\"\n    }\n]"
   }
  ],
  "category": "Modules",
@@ -98,7 +103,11 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Accounting",
+<<<<<<< HEAD
+ "modified": "2020-09-28 13:19:27.703992",
+=======
  "modified": "2020-09-09 11:45:33.766400",
+>>>>>>> develop
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Accounting",
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index f8b6be7..2d97d53 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -243,10 +243,16 @@
 			"erpnext.regional.italy.utils.sales_invoice_on_cancel",
 			"erpnext.erpnext_integrations.taxjar_integration.delete_transaction"
 		],
+		"validate": [
+			"erpnext.regional.united_arab_emirates.utils.validate_returns",
+		],
 		"on_trash": "erpnext.regional.check_deletion_permission"
 	},
 	"Purchase Invoice": {
-		"validate": "erpnext.regional.india.utils.update_grand_total_for_rcm"
+		"validate": [
+			"erpnext.regional.india.utils.update_grand_total_for_rcm",
+			"erpnext.regional.united_arab_emirates.utils.update_grand_total_for_rcm",
+			]
 	},
 	"Payment Entry": {
 		"on_submit": ["erpnext.regional.create_transaction_log", "erpnext.accounts.doctype.payment_request.payment_request.update_payment_req_status", "erpnext.accounts.doctype.dunning.dunning.resolve_dunning"],
@@ -384,7 +390,8 @@
 		'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_regional_gl_entries': 'erpnext.regional.india.utils.make_regional_gl_entries'
 	},
 	'United Arab Emirates': {
-		'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data'
+		'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data',
+		'erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_regional_gl_entries': 'erpnext.regional.united_arab_emirates.utils.make_regional_gl_entries',
 	},
 	'Saudi Arabia': {
 		'erpnext.controllers.taxes_and_totals.update_itemised_tax_data': 'erpnext.regional.united_arab_emirates.utils.update_itemised_tax_data'
diff --git a/erpnext/regional/doctype/uae_vat_account/__init__.py b/erpnext/regional/doctype/uae_vat_account/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_account/__init__.py
diff --git a/erpnext/regional/doctype/uae_vat_account/uae_vat_account.json b/erpnext/regional/doctype/uae_vat_account/uae_vat_account.json
new file mode 100644
index 0000000..73a8169
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_account/uae_vat_account.json
@@ -0,0 +1,35 @@
+{
+ "actions": [],
+ "autoname": "account",
+ "creation": "2020-09-28 11:30:45.472053",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "account"
+ ],
+ "fields": [
+  {
+   "allow_in_quick_entry": 1,
+   "fieldname": "account",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "in_preview": 1,
+   "label": "Account",
+   "options": "Account"
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "istable": 1,
+ "links": [],
+ "modified": "2020-09-28 12:02:56.444007",
+ "modified_by": "Administrator",
+ "module": "Regional",
+ "name": "UAE VAT Account",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/regional/doctype/uae_vat_account/uae_vat_account.py b/erpnext/regional/doctype/uae_vat_account/uae_vat_account.py
new file mode 100644
index 0000000..80d6b3a
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_account/uae_vat_account.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class UAEVATAccount(Document):
+	pass
diff --git a/erpnext/regional/doctype/uae_vat_setting/__init__.py b/erpnext/regional/doctype/uae_vat_setting/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_setting/__init__.py
diff --git a/erpnext/regional/doctype/uae_vat_setting/test_uae_vat_setting.py b/erpnext/regional/doctype/uae_vat_setting/test_uae_vat_setting.py
new file mode 100644
index 0000000..a5f151d
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_setting/test_uae_vat_setting.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestUAEVATSetting(unittest.TestCase):
+	pass
diff --git a/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.js b/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.js
new file mode 100644
index 0000000..f910e1f
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('UAE VAT Setting', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.json b/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.json
new file mode 100644
index 0000000..e2e2ab8
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.json
@@ -0,0 +1,55 @@
+{
+ "actions": [],
+ "autoname": "field:company",
+ "creation": "2020-09-25 12:48:51.463265",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "company",
+  "uae_vat_account"
+ ],
+ "fields": [
+  {
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Company",
+   "options": "Company",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "uae_vat_account",
+   "fieldtype": "Table",
+   "label": "UAE VAT Account",
+   "options": "UAE VAT Account",
+   "reqd": 1
+  }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [],
+ "modified": "2020-09-28 12:19:11.493138",
+ "modified_by": "Administrator",
+ "module": "Regional",
+ "name": "UAE VAT Setting",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.py b/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.py
new file mode 100644
index 0000000..9549de9
--- /dev/null
+++ b/erpnext/regional/doctype/uae_vat_setting/uae_vat_setting.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class UAEVATSetting(Document):
+	pass
diff --git a/erpnext/regional/report/uae_vat_21/__init__.py b/erpnext/regional/report/uae_vat_21/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/regional/report/uae_vat_21/__init__.py
diff --git a/erpnext/regional/report/uae_vat_21/uae_vat_21.html b/erpnext/regional/report/uae_vat_21/uae_vat_21.html
new file mode 100644
index 0000000..aa6a255
--- /dev/null
+++ b/erpnext/regional/report/uae_vat_21/uae_vat_21.html
@@ -0,0 +1,68 @@
+{%
+	var report_columns = report.get_columns_for_print();
+	report_columns = report_columns.filter(col => !col.hidden);
+
+	if (report_columns.length > 8) {
+		frappe.throw(__("Too many columns. Export the report and print it using a spreadsheet application."));
+	}
+%}
+
+<h1  style="margin-top:0; text-align: center;">{%= __(report.report_name) %}</h1>
+
+<h3  style="margin-top:0">{%= __("VAT on Sales and All Other Outputs") %}</h2>
+
+<table class="table table-bordered">
+
+    <thead>
+        {% for (let i=0; i<report_columns.length; i++) { %}
+            <th >{%= report_columns[i].label %}</th>
+        {% } %}
+    </thead>
+
+    <tbody>
+        {% for (let j=1; j<12; j++)  { %}
+        {%
+            var row = data[j];
+        %}
+        <tr >
+            {% for (let i=0; i<report_columns.length; i++) { %}
+                <td >
+                    {% const fieldname = report_columns[i].fieldname; %}
+                    {% if (!is_null(row[fieldname])) { %}
+                        {%= frappe.format(row[fieldname], report_columns[i], {}, row) %}
+                    {% } %}
+                </td>
+            {% } %}
+        </tr>
+        {% } %}
+    </tbody>
+</table>
+
+<h3  style="margin-top:0">{%= __("VAT on Expenses and All Other Inputs") %}</h2>
+
+<table  class="table table-bordered">
+    <thead>
+        {% for (let i=0; i<report_columns.length; i++) { %}
+            <th >{%= report_columns[i].label %}</th>
+        {% } %}
+    </thead>
+
+    <tbody>
+        {% for (let j=13; j<data.length; j++)  { %}
+        {%
+            var row = data[j];
+        %}
+        <tr >
+            {% for (let i=0; i<report_columns.length; i++) { %}
+                <td >
+                    {% const fieldname = report_columns[i].fieldname; %}
+                    {% if (!is_null(row[fieldname])) { %}
+                        {%= frappe.format(row[fieldname], report_columns[i], {}, row) %}
+                    {% } %}
+                </td>
+            {% } %}
+        </tr>
+        {% } %}
+    </tbody>
+
+</table>
\ No newline at end of file
diff --git a/erpnext/regional/report/uae_vat_21/uae_vat_21.js b/erpnext/regional/report/uae_vat_21/uae_vat_21.js
new file mode 100644
index 0000000..3e6cdd8
--- /dev/null
+++ b/erpnext/regional/report/uae_vat_21/uae_vat_21.js
@@ -0,0 +1,41 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["UAE VAT 21"] = {
+	"filters": [
+		{
+			"fieldname": "company",
+			"label": __("Company"),
+			"fieldtype": "Link",
+			"options": "Company",
+			"reqd": 1,
+			"default": frappe.defaults.get_user_default("Company")
+		},
+		{
+			"fieldname": "from_date",
+			"label": __("From Date"),
+			"fieldtype": "Date",
+			"reqd": 1,
+			"default": frappe.datetime.add_months(frappe.datetime.get_today(), -3),
+			"width": "80"
+		},
+		{
+			"fieldname": "to_date",
+			"label": __("To Date"),
+			"fieldtype": "Date",
+			"reqd": 1,
+			"default": frappe.datetime.get_today()
+		},
+	],
+	"formatter": function(value, row, column, data, default_formatter) {
+		if (data
+			&& (data.legend=='VAT on Sales and All Other Outputs' || data.legend=='VAT on Expenses and All Other Inputs')
+			&& data.legend==value) {
+			value = $(`<span>${value}</span>`);
+			var $value = $(value).css("font-weight", "bold");
+			value = $value.wrap("<p></p>").parent().html();
+		}
+		return value;
+	},
+};
diff --git a/erpnext/regional/report/uae_vat_21/uae_vat_21.json b/erpnext/regional/report/uae_vat_21/uae_vat_21.json
new file mode 100644
index 0000000..421990c
--- /dev/null
+++ b/erpnext/regional/report/uae_vat_21/uae_vat_21.json
@@ -0,0 +1,22 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2020-09-10 08:51:02.298482",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2020-09-10 08:51:02.298482",
+ "modified_by": "Administrator",
+ "module": "Regional",
+ "name": "UAE VAT 21",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "GL Entry",
+ "report_name": "UAE VAT 21",
+ "report_type": "Script Report",
+ "roles": []
+}
\ No newline at end of file
diff --git a/erpnext/regional/report/uae_vat_21/uae_vat_21.py b/erpnext/regional/report/uae_vat_21/uae_vat_21.py
new file mode 100644
index 0000000..6cb39e0
--- /dev/null
+++ b/erpnext/regional/report/uae_vat_21/uae_vat_21.py
@@ -0,0 +1,438 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from erpnext.regional.united_arab_emirates.utils import get_tax_accounts
+from frappe import _
+
+def execute(filters=None):
+	columns = get_columns()
+	data, emirates, amounts_by_emirate = get_data(filters)
+	chart = get_chart(emirates, amounts_by_emirate)
+
+	return columns, data, None, chart
+
+def get_columns():
+	"""Creates a list of dictionaries that are used to generate column headers of the data table
+
+	Returns:
+		List(Dict): list of dictionaries that are used to generate column headers of the data table
+	"""
+	return [
+		{
+			"fieldname": "no",
+			"label": "No",
+			"fieldtype": "Data",
+			"width": 50
+		},
+		{
+			"fieldname": "legend",
+			"label": "Legend",
+			"fieldtype": "Data",
+			"width": 300
+		},
+		{
+			"fieldname": "amount",
+			"label": "Amount (AED)",
+			"fieldtype": "Currency",
+			"width": 100
+		},
+		{
+			"fieldname": "vat_amount",
+			"label": "VAT Amount (AED)",
+			"fieldtype": "Currency",
+			"width": 100
+		}
+	]
+
+def get_data(filters = None):
+	"""Returns the list of dictionaries. Each dictionary is a row in the datatable and chart data
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		List(Dict): Each dictionary is a row in the datatable
+		Dict: Dictionary containing chart data
+	"""
+	data = []
+	data.append({
+		"no": '',
+		"legend": f'VAT on Sales and All Other Outputs',
+		"amount": '',
+		"vat_amount": ''
+		})
+	total_emiratewise = get_total_emiratewise(filters)
+	emirates = get_emirates()
+	amounts_by_emirate = {}
+	for d in total_emiratewise:
+		emirate, amount, vat= d
+		amounts_by_emirate[emirate] = {
+				"legend": emirate,
+				"amount": amount,
+				"vat_amount": vat
+			}
+
+	for d, emirate in enumerate(emirates, 97):
+		if emirate in amounts_by_emirate:
+			amounts_by_emirate[emirate]["no"] = f'1{chr(d)}'
+			amounts_by_emirate[emirate]["legend"] = f'Standard rated supplies in {emirate}'
+			data.append(amounts_by_emirate[emirate])
+		else:
+			data.append(
+				{
+					"no": f'1{chr(d)}',
+					"legend": f'Standard rated supplies in {emirate}',
+					"amount": 0,
+					"vat_amount": 0
+				}
+			)
+
+	data.append(
+		{
+			"no": '2',
+			"legend": f'Tax Refunds provided to Tourists under the Tax Refunds for Tourists Scheme',
+			"amount": (-1) * get_tourist_tax_return_total(filters),
+			"vat_amount": (-1) * get_tourist_tax_return_tax(filters)
+		}
+	)
+
+	data.append(
+		{
+			"no": '3',
+			"legend": f'Supplies subject to the reverse charge provision',
+			"amount": get_reverse_charge_total(filters),
+			"vat_amount": get_reverse_charge_tax(filters)
+		}
+	)
+
+	data.append(
+		{
+			"no": '4',
+			"legend": f'Zero Rated',
+			"amount": get_zero_rated_total(filters),
+			"vat_amount": "-"
+		}
+	)
+
+	data.append(
+		{
+			"no": '5',
+			"legend": f'Exempt Supplies',
+			"amount": get_exempt_total(filters),
+			"vat_amount": "-"
+		}
+	)
+
+	data.append({
+		"no": '',
+		"legend": f'VAT on Expenses and All Other Inputs',
+		"amount": '',
+		"vat_amount": ''
+		})
+	data.append(
+		{
+			"no": '9',
+			"legend": f'Standard Rated Expenses',
+			"amount": get_standard_rated_expenses_total(filters),
+			"vat_amount": get_standard_rated_expenses_tax(filters)
+		}
+	)
+	data.append(
+		{
+			"no": '10',
+			"legend": f'Supplies subject to the reverse charge provision',
+			"amount": get_reverse_charge_recoverable_total(filters),
+			"vat_amount": get_reverse_charge_recoverable_tax(filters)
+		}
+	)
+
+	return data, emirates, amounts_by_emirate
+
+
+def get_chart(emirates, amounts_by_emirate):
+	"""Returns chart data
+
+	Args:
+		emirates (List): List of Emirates
+		amounts_by_emirate (Dict): Vat and Tax amount by emirates with emirates as key
+
+	Returns:
+		[Dict]: Chart Data
+	"""
+	labels = []
+	amount = []
+	vat_amount = []
+	for d in emirates:
+		if d in amounts_by_emirate:
+			amount.append(amounts_by_emirate[d]["amount"])
+			vat_amount.append(amounts_by_emirate[d]["vat_amount"])
+			labels.append(d)
+
+	datasets = []
+	datasets.append({'name': _('Amount (AED)'), 'values':  amount})
+	datasets.append({'name': _('Vat Amount (AED)'), 'values': vat_amount})
+
+	chart = {
+			"data": {
+				'labels': labels,
+				'datasets': datasets
+			}
+		}
+
+	chart["type"] = "bar"
+	chart["fieldtype"] = "Currency"
+	return chart
+
+def get_total_emiratewise(filters):
+	return frappe.db.sql(f"""
+		select emirate, sum(total), sum(total_taxes_and_charges) from `tabSales Invoice`
+		where docstatus = 1 {get_conditions(filters)}
+		group by `tabSales Invoice`.emirate;
+		""", filters)
+
+def get_emirates():
+	"""Returns a List of emirates in the order that they are to be displayed
+
+	Returns:
+		List(String): List of emirates in the order that they are to be displayed
+	"""
+	return [
+		'Abu Dhabi',
+		'Dubai',
+		'Sharjah',
+		'Ajman',
+		'Umm Al Quwain',
+		'Ras Al Khaimah',
+		'Fujairah'
+	]
+
+def get_conditions(filters):
+	"""The conditions to be used to filter data to calculate the total sale
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		String: Concatenated list of conditions to be applied to calculate the total sale
+	"""
+	conditions = ""
+	for opts in (("company", " and company=%(company)s"),
+		("from_date", " and posting_date>=%(from_date)s"),
+		("to_date", " and posting_date<=%(to_date)s")):
+			if filters.get(opts[0]):
+				conditions += opts[1]
+	return conditions
+
+def get_reverse_charge_total(filters):
+	"""Returns the sum of the total of each Purchase invoice made
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the total of each Purchase invoice made
+	"""
+	conditions = get_conditions(filters)
+	print("""
+		select sum(total)  from
+		`tabPurchase Invoice`
+		where
+		reverse_charge = "Y"
+		and docstatus = 1 {where_conditions} ;
+		""".format(where_conditions=conditions))
+	return frappe.db.sql("""
+		select sum(total)  from
+		`tabPurchase Invoice`
+		where
+		reverse_charge = "Y"
+		and docstatus = 1 {where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_reverse_charge_tax(filters):
+	"""Returns the sum of the tax of each Purchase invoice made
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the tax of each Purchase invoice made
+	"""
+	conditions = get_conditions_join(filters)
+	return frappe.db.sql("""
+		select sum(debit)  from
+		`tabPurchase Invoice`  inner join `tabGL Entry`
+		on `tabGL Entry`.voucher_no = `tabPurchase Invoice`.name
+		where
+		`tabPurchase Invoice`.reverse_charge = "Y"
+		and `tabPurchase Invoice`.docstatus = 1
+		and `tabGL Entry`.docstatus = 1
+		and account in (select account from `tabUAE VAT Account` where  parent=%(company)s)
+		{where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_conditions_join(filters):
+	"""The conditions to be used to filter data to calculate the total vat
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		String: Concatenated list of conditions to be applied to calculate the total vat
+	"""
+	conditions = ""
+	for opts in (("company", " and `tabPurchase Invoice`.company=%(company)s"),
+		("from_date", " and `tabPurchase Invoice`.posting_date>=%(from_date)s"),
+		("to_date", " and `tabPurchase Invoice`.posting_date<=%(to_date)s")):
+			if filters.get(opts[0]):
+				conditions += opts[1]
+	return conditions
+
+def get_reverse_charge_recoverable_total(filters):
+	"""Returns the sum of the total of each Purchase invoice made with claimable reverse charge
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the total of each Purchase invoice made with claimable reverse charge
+	"""
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""
+		select sum(total)  from
+		`tabPurchase Invoice`
+		where
+		reverse_charge = "Y"
+		and claimable_reverse_charge > 0
+		and docstatus = 1 {where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_reverse_charge_recoverable_tax(filters):
+	"""Returns the sum of the tax of each Purchase invoice made
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the tax of each Purchase invoice made
+	"""
+	conditions = get_conditions_join(filters)
+	return frappe.db.sql("""
+		select sum(debit * `tabPurchase Invoice`.claimable_reverse_charge / 100)  from
+		`tabPurchase Invoice`  inner join `tabGL Entry`
+		on `tabGL Entry`.voucher_no = `tabPurchase Invoice`.name
+		where
+		`tabPurchase Invoice`.reverse_charge = "Y"
+		and `tabPurchase Invoice`.docstatus = 1
+		and `tabPurchase Invoice`.claimable_reverse_charge > 0
+		and `tabGL Entry`.docstatus = 1
+		and account in (select account from `tabUAE VAT Account` where  parent=%(company)s)
+		{where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_standard_rated_expenses_total(filters):
+	"""Returns the sum of the total of each Purchase invoice made with claimable reverse charge
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the total of each Purchase invoice made with claimable reverse charge
+	"""
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""
+		select sum(total)  from
+		`tabSales Invoice`
+		where
+		standard_rated_expenses > 0
+		and docstatus = 1 {where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_standard_rated_expenses_tax(filters):
+	"""Returns the sum of the tax of each Purchase invoice made
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the tax of each Purchase invoice made
+	"""
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""
+		select sum(standard_rated_expenses)  from
+		`tabSales Invoice`
+		where
+		standard_rated_expenses > 0
+		and docstatus = 1 {where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_tourist_tax_return_total(filters):
+	"""Returns the sum of the total of each Sales invoice with non zero tourist_tax_return
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the total of each Sales invoice with non zero tourist_tax_return
+	"""
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""
+		select sum(total)  from
+		`tabSales Invoice`
+		where
+		tourist_tax_return > 0
+		and docstatus = 1 {where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_tourist_tax_return_tax(filters):
+	"""Returns the sum of the tax of each Sales invoice with non zero tourist_tax_return
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of the tax of each Sales invoice with non zero tourist_tax_return
+	"""
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""
+		select sum(tourist_tax_return)  from
+		`tabSales Invoice`
+		where
+		tourist_tax_return > 0
+		and docstatus = 1 {where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_zero_rated_total(filters):
+	"""Returns the sum of each Sales Invoice Item Amount which is zero rated
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of each Sales Invoice Item Amount which is zero rated
+	"""
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""
+		select sum(i.base_amount) as total from
+		`tabSales Invoice Item` i, `tabSales Invoice` s
+		where s.docstatus = 1 and i.parent = s.name and i.is_zero_rated = 1
+		{where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
+
+def get_exempt_total(filters):
+	"""Returns the sum of each Sales Invoice Item Amount which is Vat Exempt
+
+	Args:
+		filters (Dict, optional): Dictionary consisting of the filters selected by the user. Defaults to None.
+
+	Returns:
+		Float: sum of each Sales Invoice Item Amount which is Vat Exempt
+	"""
+	conditions = get_conditions(filters)
+	return frappe.db.sql("""
+		select sum(i.base_amount) as total from
+		`tabSales Invoice Item` i, `tabSales Invoice` s
+		where s.docstatus = 1 and i.parent = s.name and i.is_exempt = 1
+		{where_conditions} ;
+		""".format(where_conditions=conditions), filters)[0][0] or 0
\ No newline at end of file
diff --git a/erpnext/regional/united_arab_emirates/setup.py b/erpnext/regional/united_arab_emirates/setup.py
index a2938bb..1c947d2 100644
--- a/erpnext/regional/united_arab_emirates/setup.py
+++ b/erpnext/regional/united_arab_emirates/setup.py
@@ -5,24 +5,30 @@
 
 import frappe, os, json
 from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
+from frappe.permissions import add_permission, update_permission_property
 from erpnext.setup.setup_wizard.operations.taxes_setup import create_sales_tax
 
 def setup(company=None, patch=True):
 	make_custom_fields()
 	add_print_formats()
-
+	add_custom_roles_for_reports()
+	add_permissions()
 	if company:
 		create_sales_tax(company)
 
 def make_custom_fields():
+	is_zero_rated = dict(fieldname='is_zero_rated', label='Is Zero Rated',
+		fieldtype='Check', fetch_from='item_code.is_zero_rated', insert_after='description',
+		print_hide=1)
+	is_exempt = dict(fieldname='is_exempt', label='Is Exempt',
+		fieldtype='Check', fetch_from='item_code.is_exempt', insert_after='is_zero_rated',
+		print_hide=1)
+
 	invoice_fields = [
 		dict(fieldname='vat_section', label='VAT Details', fieldtype='Section Break',
 			insert_after='group_same_items', print_hide=1, collapsible=1),
 		dict(fieldname='permit_no', label='Permit Number',
 			fieldtype='Data', insert_after='vat_section', print_hide=1),
-		dict(fieldname='reverse_charge_applicable', label='Reverse Charge Applicable',
-			fieldtype='Select', insert_after='permit_no', print_hide=1,
-			options='Y\nN', default='N')
 	]
 
 	purchase_invoice_fields = [
@@ -31,7 +37,13 @@
 				fetch_from='company.tax_id', print_hide=1),
 			dict(fieldname='supplier_name_in_arabic', label='Supplier Name in Arabic',
 				fieldtype='Read Only', insert_after='supplier_name',
-				fetch_from='supplier.supplier_name_in_arabic', print_hide=1)
+				fetch_from='supplier.supplier_name_in_arabic', print_hide=1),
+			dict(fieldname='reverse_charge', label='Reverse Charge Applicable',
+				fieldtype='Select', insert_after='permit_no', print_hide=1,
+				options='Y\nN', default='N'),
+			dict(fieldname='claimable_reverse_charge', label='Claimable Reverse Charge (Percentage)',
+				insert_after='reverse_charge', fieldtype='Percent', print_hide=1,
+				depends_on="eval:doc.reverse_charge=='Y'", default='100.000'),
 		]
 
 	sales_invoice_fields = [
@@ -42,7 +54,11 @@
 				fieldtype='Read Only', insert_after='customer_name',
 				fetch_from='customer.customer_name_in_arabic', print_hide=1),
 			dict(fieldname='emirate', label='Emirate', insert_after='customer_address',
-				fetch_from='customer_address.emirates'),
+				fieldtype='Read Only', fetch_from='customer_address.emirates'),
+			dict(fieldname='tourist_tax_return', label='Tax Refund provided to Tourists (AED)',
+				insert_after='permit_no', fieldtype='Currency', print_hide=1, default='0'),
+			dict(fieldname='standard_rated_expenses', label='Standard Rated Expenses (AED)',
+				insert_after='tourist_tax_return', fieldtype='Currency', print_hide=1, default='0'),
 		]
 
 	invoice_item_fields = [
@@ -69,6 +85,12 @@
 		'Item': [
 			dict(fieldname='tax_code', label='Tax Code',
 				fieldtype='Data', insert_after='item_group'),
+			dict(fieldname='is_zero_rated', label='Is Zero Rated',
+				fieldtype='Check', insert_after='tax_code',
+				print_hide=1),
+			dict(fieldname='is_exempt', label='Is Exempt ',
+				fieldtype='Check', insert_after='is_zero_rated',
+				print_hide=1)
 		],
 		'Customer': [
 			dict(fieldname='customer_name_in_arabic', label='Customer Name in Arabic',
@@ -79,8 +101,8 @@
 				fieldtype='Data', insert_after='supplier_name'),
 		],
 		'Address': [
-			dict(fieldname='emirates', label='Emirates',
-				fieldtype='Data', insert_after='state'),
+			dict(fieldname='emirates', label='Emirates', fieldtype='Select', insert_after='state',
+			options='Abu Dhabi\nAjman\nDubai\nFujairah\nRas Al Khaimah\nSharjah\nUmm Al Quwain')
 		],
 		'Purchase Invoice': purchase_invoice_fields + invoice_fields,
 		'Purchase Order': purchase_invoice_fields + invoice_fields,
@@ -88,7 +110,7 @@
 		'Sales Invoice': sales_invoice_fields + invoice_fields,
 		'Sales Order': sales_invoice_fields + invoice_fields,
 		'Delivery Note': sales_invoice_fields + invoice_fields,
-		'Sales Invoice Item': invoice_item_fields + delivery_date_field,
+		'Sales Invoice Item': invoice_item_fields + delivery_date_field + [is_zero_rated, is_exempt],
 		'Purchase Invoice Item': invoice_item_fields,
 		'Sales Order Item': invoice_item_fields,
 		'Delivery Note Item': invoice_item_fields,
@@ -107,3 +129,27 @@
 
 	frappe.db.sql(""" update `tabPrint Format` set disabled = 0 where
 		name in('Simplified Tax Invoice', 'Detailed Tax Invoice', 'Tax Invoice') """)
+
+def add_custom_roles_for_reports():
+	"""Add Access Control to UAE VAT 21
+	"""
+	if not frappe.db.get_value('Custom Role', dict(report='UAE VAT 21')):
+		frappe.get_doc(dict(
+			doctype='Custom Role',
+			report='UAE VAT 21',
+			roles= [
+				dict(role='Accounts User'),
+				dict(role='Accounts Manager'),
+				dict(role='Auditor')
+			]
+		)).insert()
+
+def add_permissions():
+	"""Add Permissions for UAE VAT Settings and UAE VAT Account
+	"""
+	for doctype in ('UAE VAT Setting', 'UAE VAT Account'):
+		add_permission(doctype, 'All', 0)
+		for role in ('Accounts Manager', 'Accounts User', 'System Manager'):
+			add_permission(doctype, role, 0)
+			update_permission_property(doctype, role, 0, 'write', 1)
+			update_permission_property(doctype, role, 0, 'create', 1)
diff --git a/erpnext/regional/united_arab_emirates/utils.py b/erpnext/regional/united_arab_emirates/utils.py
index a0425f6..4424d2e 100644
--- a/erpnext/regional/united_arab_emirates/utils.py
+++ b/erpnext/regional/united_arab_emirates/utils.py
@@ -1,6 +1,8 @@
 from __future__ import unicode_literals
 import frappe
-from frappe.utils import flt
+from frappe import _
+import erpnext
+from frappe.utils import flt, round_based_on_smallest_currency_fraction, money_in_words
 from erpnext.controllers.taxes_and_totals import get_itemised_tax
 from six import iteritems
 
@@ -26,4 +28,153 @@
 
 		row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
 		row.tax_amount = flt((row.net_amount * tax_rate) / 100, row.precision("net_amount"))
-		row.total_amount = flt((row.net_amount + row.tax_amount), row.precision("total_amount"))
\ No newline at end of file
+		row.total_amount = flt((row.net_amount + row.tax_amount), row.precision("total_amount"))
+
+def get_account_currency(account):
+	"""Helper function to get account currency"""
+	if not account:
+		return
+	def generator():
+		account_currency, company = frappe.get_cached_value("Account", account, ["account_currency", "company"])
+		if not account_currency:
+			account_currency = frappe.get_cached_value('Company',  company,  "default_currency")
+
+		return account_currency
+
+	return frappe.local_cache("account_currency", account, generator)
+
+def get_tax_accounts(company):
+	"""Get the list of tax accounts for a specific company
+
+	Args:
+		company (String): Current Company set as default
+
+	Returns:
+		tax_accounts: List of Tax Accounts for the company
+	"""
+	tax_accounts_dict = frappe._dict()
+	tax_accounts_list = frappe.get_all("UAE VAT Account",
+		filters={"parent": company},
+		fields=["Account"]
+		)
+
+	if not tax_accounts_list and not frappe.flags.in_test:
+		frappe.throw(_(f'Please set Vat Accounts for Company: "{company}" in UAE VAT Setting'))
+	for d in tax_accounts_list:
+		for key, name in d.items():
+			tax_accounts_dict[name] = name
+
+	return tax_accounts_dict
+
+def update_grand_total_for_rcm(doc, method):
+	"""If the Reverse Charge is Applicable subtract the tax amount from the grand total and update in the form
+
+	Args:
+		doc (Document): The document for the current Purchase Invoice
+	"""
+	country = frappe.get_cached_value('Company', doc.company, 'country')
+
+	if country != 'United Arab Emirates':
+		return
+
+	if not doc.total_taxes_and_charges:
+		return
+
+	if doc.reverse_charge == 'Y':
+		tax_accounts = get_tax_accounts(doc.company)
+
+		base_vat_tax = 0
+		vat_tax = 0
+
+		for tax in doc.get('taxes'):
+			if tax.category not in ("Total", "Valuation and Total"):
+				continue
+
+			if flt(tax.base_tax_amount_after_discount_amount) and tax.account_head in tax_accounts:
+				base_vat_tax += tax.base_tax_amount_after_discount_amount
+				vat_tax += tax.tax_amount_after_discount_amount
+
+		doc.taxes_and_charges_added -= vat_tax
+		doc.total_taxes_and_charges -= vat_tax
+		doc.base_taxes_and_charges_added -= base_vat_tax
+		doc.base_total_taxes_and_charges -= base_vat_tax
+
+		update_totals(vat_tax, base_vat_tax, doc)
+
+def update_totals(vat_tax, base_vat_tax, doc):
+	"""Update the grand total values in the form
+
+	Args:
+		vat_tax (float): Vat Tax to be subtracted
+		base_vat_tax (float): Base Vat Tax to be subtracted
+		doc (Document):  The document for the current Purchase Invoice
+	"""
+
+	doc.base_grand_total -= base_vat_tax
+	doc.grand_total -= vat_tax
+
+	if doc.meta.get_field("rounded_total"):
+
+		if doc.is_rounded_total_disabled():
+			doc.outstanding_amount = doc.grand_total
+
+		else:
+			doc.rounded_total = round_based_on_smallest_currency_fraction(doc.grand_total,
+				doc.currency, doc.precision("rounded_total"))
+			doc.rounding_adjustment = flt(doc.rounded_total - doc.grand_total,
+				doc.precision("rounding_adjustment"))
+			doc.outstanding_amount = doc.rounded_total or doc.grand_total
+
+	doc.in_words = money_in_words(doc.grand_total, doc.currency)
+	doc.base_in_words = money_in_words(doc.base_grand_total, erpnext.get_company_currency(doc.company))
+	doc.set_payment_schedule()
+
+def make_regional_gl_entries(gl_entries, doc):
+	"""This method is hooked to the make_regional_gl_entries in Purchase Invoice.
+	It appends the region specific general ledger entries to the list of GL Entries.
+
+	Args:
+		gl_entries (List): List of GL entries to be made
+		doc (Document): The document for the current Purchase Invoice
+
+	Returns:
+		List: Updates list of GL Entries
+	"""
+	country = frappe.get_cached_value('Company', doc.company, 'country')
+
+	if country != 'United Arab Emirates':
+		return gl_entries
+
+	if doc.reverse_charge == 'Y':
+		tax_accounts = get_tax_accounts(doc.company)
+		for tax in doc.get('taxes'):
+			if tax.category not in ("Total", "Valuation and Total"):
+				continue
+
+			dr_or_cr = "credit" if tax.add_deduct_tax == "Add" else "debit"
+			if flt(tax.base_tax_amount_after_discount_amount)  and tax.account_head in tax_accounts:
+				account_currency = get_account_currency(tax.account_head)
+
+				gl_entries.append(doc.get_gl_dict(
+					{
+						"account": tax.account_head,
+						"cost_center": tax.cost_center,
+						"posting_date": doc.posting_date,
+						"against": doc.supplier,
+						dr_or_cr: tax.base_tax_amount_after_discount_amount,
+						dr_or_cr + "_in_account_currency": tax.base_tax_amount_after_discount_amount \
+							if account_currency==doc.company_currency \
+							else tax.tax_amount_after_discount_amount
+					}, account_currency, item=tax)
+				)
+	return gl_entries
+
+def validate_returns(doc, method):
+	print("validate_returns")
+	country = frappe.get_cached_value('Company', doc.company, 'country')
+
+	if country != 'United Arab Emirates':
+		return
+
+	if flt(doc.tourist_tax_return) + flt(doc.standard_rated_expenses) > flt(doc.total_taxes_and_charges):
+		frappe.throw(_("The Total Returns(Tax Refund provided to Tourists (AED) + Standard Rated Expenses (AED)) should be less than the Total Taxes and Charges (Company Currency)"))
\ No newline at end of file