From e03965afa512a4cd88dd4b98314e4d4d0b7782dc Mon Sep 17 00:00:00 2001 From: Ahmad Date: Thu, 26 Aug 2021 07:35:59 +0500 Subject: [PATCH 01/13] feat(Regional): KSA VAT Report --- .../workspace/accounting/accounting.json | 23 ++- .../ksa_vat_purchase_account/__init__.py | 0 .../ksa_vat_purchase_account.json | 49 +++++ .../ksa_vat_purchase_account.py | 9 + .../doctype/ksa_vat_sales_account/__init__.py | 0 .../ksa_vat_sales_account.js | 8 + .../ksa_vat_sales_account.json | 49 +++++ .../ksa_vat_sales_account.py | 9 + .../test_ksa_vat_sales_account.py | 9 + .../doctype/ksa_vat_setting/__init__.py | 0 .../ksa_vat_setting/ksa_vat_setting.js | 8 + .../ksa_vat_setting/ksa_vat_setting.json | 49 +++++ .../ksa_vat_setting/ksa_vat_setting.py | 9 + .../ksa_vat_setting/ksa_vat_setting_list.js | 5 + .../ksa_vat_setting/test_ksa_vat_setting.py | 9 + erpnext/regional/report/ksa_vat/__init__.py | 0 erpnext/regional/report/ksa_vat/ksa_vat.js | 60 ++++++ erpnext/regional/report/ksa_vat/ksa_vat.json | 32 ++++ erpnext/regional/report/ksa_vat/ksa_vat.py | 179 ++++++++++++++++++ erpnext/regional/saudi_arabia/setup.py | 19 +- .../regional/saudi_arabia/wizard/__init__.py | 0 .../saudi_arabia/wizard/data/__init__.py | 0 .../wizard/data/ksa_vat_settings.json | 47 +++++ .../wizard/operations/__init__.py | 0 .../operations/setup_ksa_vat_setting.py | 48 +++++ 25 files changed, 619 insertions(+), 2 deletions(-) create mode 100644 erpnext/regional/doctype/ksa_vat_purchase_account/__init__.py create mode 100644 erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.json create mode 100644 erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.py create mode 100644 erpnext/regional/doctype/ksa_vat_sales_account/__init__.py create mode 100644 erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.js create mode 100644 erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.json create mode 100644 erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.py create mode 100644 erpnext/regional/doctype/ksa_vat_sales_account/test_ksa_vat_sales_account.py create mode 100644 erpnext/regional/doctype/ksa_vat_setting/__init__.py create mode 100644 erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js create mode 100644 erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.json create mode 100644 erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.py create mode 100644 erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js create mode 100644 erpnext/regional/doctype/ksa_vat_setting/test_ksa_vat_setting.py create mode 100644 erpnext/regional/report/ksa_vat/__init__.py create mode 100644 erpnext/regional/report/ksa_vat/ksa_vat.js create mode 100644 erpnext/regional/report/ksa_vat/ksa_vat.json create mode 100644 erpnext/regional/report/ksa_vat/ksa_vat.py create mode 100644 erpnext/regional/saudi_arabia/wizard/__init__.py create mode 100644 erpnext/regional/saudi_arabia/wizard/data/__init__.py create mode 100644 erpnext/regional/saudi_arabia/wizard/data/ksa_vat_settings.json create mode 100644 erpnext/regional/saudi_arabia/wizard/operations/__init__.py create mode 100644 erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py diff --git a/erpnext/accounts/workspace/accounting/accounting.json b/erpnext/accounts/workspace/accounting/accounting.json index 7e3ecaf3ab6a..236e47594d17 100644 --- a/erpnext/accounts/workspace/accounting/accounting.json +++ b/erpnext/accounts/workspace/accounting/accounting.json @@ -454,6 +454,17 @@ "onboard": 0, "type": "Link" }, + { + "dependencies": "GL Entry", + "hidden": 0, + "is_query_report": 1, + "label": "KSA VAT Report", + "link_to": "KSA VAT", + "link_type": "Report", + "onboard": 0, + "only_for": "Saudi Arabia", + "type": "Link" + }, { "hidden": 0, "is_query_report": 0, @@ -1034,6 +1045,16 @@ "onboard": 0, "type": "Link" }, + { + "hidden": 0, + "is_query_report": 0, + "label": "KSA VAT Setting", + "link_to": "KSA VAT Setting", + "link_type": "DocType", + "onboard": 0, + "only_for": "Saudi Arabia", + "type": "Link" + }, { "hidden": 0, "is_query_report": 0, @@ -1082,7 +1103,7 @@ "type": "Link" } ], - "modified": "2021-08-23 16:06:34.167267", + "modified": "2021-08-26 13:15:52.872470", "modified_by": "Administrator", "module": "Accounts", "name": "Accounting", diff --git a/erpnext/regional/doctype/ksa_vat_purchase_account/__init__.py b/erpnext/regional/doctype/ksa_vat_purchase_account/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.json b/erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.json new file mode 100644 index 000000000000..89ba3e977afd --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.json @@ -0,0 +1,49 @@ +{ + "actions": [], + "creation": "2021-07-13 09:17:09.862163", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "title", + "item_tax_template", + "account" + ], + "fields": [ + { + "fieldname": "account", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Account", + "options": "Account", + "reqd": 1 + }, + { + "fieldname": "title", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Title", + "reqd": 1 + }, + { + "fieldname": "item_tax_template", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item Tax Template", + "options": "Item Tax Template", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-08-04 06:42:38.205597", + "modified_by": "Administrator", + "module": "Regional", + "name": "KSA VAT Purchase Account", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.py b/erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.py new file mode 100644 index 000000000000..3920bc546c1a --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_purchase_account/ksa_vat_purchase_account.py @@ -0,0 +1,9 @@ +# Copyright (c) 2021, Havenir Solutions and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class KSAVATPurchaseAccount(Document): + pass diff --git a/erpnext/regional/doctype/ksa_vat_sales_account/__init__.py b/erpnext/regional/doctype/ksa_vat_sales_account/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.js b/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.js new file mode 100644 index 000000000000..72613f4064ff --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, Havenir Solutions and contributors +// For license information, please see license.txt + +frappe.ui.form.on('KSA VAT Sales Account', { + // refresh: function(frm) { + + // } +}); diff --git a/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.json b/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.json new file mode 100644 index 000000000000..df2747891dcd --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.json @@ -0,0 +1,49 @@ +{ + "actions": [], + "creation": "2021-07-13 08:46:33.820968", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "title", + "item_tax_template", + "account" + ], + "fields": [ + { + "fieldname": "account", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Account", + "options": "Account", + "reqd": 1 + }, + { + "fieldname": "title", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Title", + "reqd": 1 + }, + { + "fieldname": "item_tax_template", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Item Tax Template", + "options": "Item Tax Template", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-08-04 06:42:00.081407", + "modified_by": "Administrator", + "module": "Regional", + "name": "KSA VAT Sales Account", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.py b/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.py new file mode 100644 index 000000000000..7c2689f530e8 --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_sales_account/ksa_vat_sales_account.py @@ -0,0 +1,9 @@ +# Copyright (c) 2021, Havenir Solutions and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class KSAVATSalesAccount(Document): + pass diff --git a/erpnext/regional/doctype/ksa_vat_sales_account/test_ksa_vat_sales_account.py b/erpnext/regional/doctype/ksa_vat_sales_account/test_ksa_vat_sales_account.py new file mode 100644 index 000000000000..1d6a6a793dc8 --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_sales_account/test_ksa_vat_sales_account.py @@ -0,0 +1,9 @@ +# Copyright (c) 2021, Havenir Solutions and Contributors +# See license.txt + +# import frappe +import unittest + + +class TestKSAVATSalesAccount(unittest.TestCase): + pass diff --git a/erpnext/regional/doctype/ksa_vat_setting/__init__.py b/erpnext/regional/doctype/ksa_vat_setting/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js new file mode 100644 index 000000000000..0238c7b30685 --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, Havenir Solutions and contributors +// For license information, please see license.txt + +frappe.ui.form.on('KSA VAT Setting', { + onload: function(frm) { + frappe.breadcrumbs.add('Accounts', 'KSA VAT Setting'); + } +}); diff --git a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.json b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.json new file mode 100644 index 000000000000..33619467ed0d --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.json @@ -0,0 +1,49 @@ +{ + "actions": [], + "autoname": "field:company", + "creation": "2021-07-13 08:49:01.100356", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "company", + "ksa_vat_sales_accounts", + "ksa_vat_purchase_accounts" + ], + "fields": [ + { + "fieldname": "company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company", + "reqd": 1, + "unique": 1 + }, + { + "fieldname": "ksa_vat_sales_accounts", + "fieldtype": "Table", + "label": "KSA VAT Sales Accounts", + "options": "KSA VAT Sales Account", + "reqd": 1 + }, + { + "fieldname": "ksa_vat_purchase_accounts", + "fieldtype": "Table", + "label": "KSA VAT Purchase Accounts", + "options": "KSA VAT Purchase Account", + "reqd": 1 + } + ], + "links": [], + "modified": "2021-08-26 04:29:06.499378", + "modified_by": "Administrator", + "module": "Regional", + "name": "KSA VAT Setting", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "company", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.py b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.py new file mode 100644 index 000000000000..bdae1161fd7c --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.py @@ -0,0 +1,9 @@ +# Copyright (c) 2021, Havenir Solutions and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class KSAVATSetting(Document): + pass diff --git a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js new file mode 100644 index 000000000000..23d28b9e68b1 --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js @@ -0,0 +1,5 @@ +frappe.listview_settings['KSA VAT Setting'] = { + onload(list) { + frappe.breadcrumbs.add('Accounts'); + } +} \ No newline at end of file diff --git a/erpnext/regional/doctype/ksa_vat_setting/test_ksa_vat_setting.py b/erpnext/regional/doctype/ksa_vat_setting/test_ksa_vat_setting.py new file mode 100644 index 000000000000..7207901fd438 --- /dev/null +++ b/erpnext/regional/doctype/ksa_vat_setting/test_ksa_vat_setting.py @@ -0,0 +1,9 @@ +# Copyright (c) 2021, Havenir Solutions and Contributors +# See license.txt + +# import frappe +import unittest + + +class TestKSAVATSetting(unittest.TestCase): + pass diff --git a/erpnext/regional/report/ksa_vat/__init__.py b/erpnext/regional/report/ksa_vat/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/regional/report/ksa_vat/ksa_vat.js b/erpnext/regional/report/ksa_vat/ksa_vat.js new file mode 100644 index 000000000000..d46d260ac1e2 --- /dev/null +++ b/erpnext/regional/report/ksa_vat/ksa_vat.js @@ -0,0 +1,60 @@ +// Copyright (c) 2016, Havenir Solutions and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["KSA VAT"] = { + onload() { + frappe.breadcrumbs.add('Accounts'); + }, + "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(), -1), + }, + { + "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.title=='VAT on Sales' || data.title=='VAT on Purchases') + && data.title==value) { + value = $(`${value}`); + var $value = $(value).css("font-weight", "bold"); + value = $value.wrap("

").parent().html(); + return value + }else if (data.title=='Grand Total'){ + if (data.title==value) { + value = $(`${value}`); + var $value = $(value).css("font-weight", "bold"); + value = $value.wrap("

").parent().html(); + return value + }else{ + value = default_formatter(value, row, column, data); + value = $(`${value}`); + var $value = $(value).css("font-weight", "bold"); + value = $value.wrap("

").parent().html(); + console.log($value) + return value + } + }else{ + value = default_formatter(value, row, column, data); + return value; + } + }, +}; diff --git a/erpnext/regional/report/ksa_vat/ksa_vat.json b/erpnext/regional/report/ksa_vat/ksa_vat.json new file mode 100644 index 000000000000..036e26031032 --- /dev/null +++ b/erpnext/regional/report/ksa_vat/ksa_vat.json @@ -0,0 +1,32 @@ +{ + "add_total_row": 0, + "columns": [], + "creation": "2021-07-13 08:54:38.000949", + "disable_prepared_report": 1, + "disabled": 1, + "docstatus": 0, + "doctype": "Report", + "filters": [], + "idx": 0, + "is_standard": "Yes", + "modified": "2021-08-26 04:14:37.202594", + "modified_by": "Administrator", + "module": "Regional", + "name": "KSA VAT", + "owner": "Administrator", + "prepared_report": 1, + "ref_doctype": "GL Entry", + "report_name": "KSA VAT", + "report_type": "Script Report", + "roles": [ + { + "role": "System Manager" + }, + { + "role": "Accounts Manager" + }, + { + "role": "Accounts User" + } + ] +} \ No newline at end of file diff --git a/erpnext/regional/report/ksa_vat/ksa_vat.py b/erpnext/regional/report/ksa_vat/ksa_vat.py new file mode 100644 index 000000000000..b32dfc198113 --- /dev/null +++ b/erpnext/regional/report/ksa_vat/ksa_vat.py @@ -0,0 +1,179 @@ +# Copyright (c) 2013, Havenir Solutions and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals + +import json + +import frappe +from frappe import _ +from frappe.utils import get_url_to_list + + +def execute(filters=None): + columns = columns = get_columns() + data = get_data(filters) + return columns, data + +def get_columns(): + return [ + { + "fieldname": "title", + "label": _("Title"), + "fieldtype": "Data", + "width": 300 + }, + { + "fieldname": "amount", + "label": _("Amount (SAR)"), + "fieldtype": "Currency", + "width": 150, + }, + { + "fieldname": "adjustment_amount", + "label": _("Adjustment (SAR)"), + "fieldtype": "Currency", + "width": 150, + }, + { + "fieldname": "vat_amount", + "label": _("VAT Amount (SAR)"), + "fieldtype": "Currency", + "width": 150, + } + ] + +def get_data(filters): + data = [] + + # Validate if vat settings exist + company = filters.get('company') + if frappe.db.exists('KSA VAT Setting', company) is None: + url = get_url_to_list('KSA VAT Setting') + frappe.msgprint(f'Create KSA VAT Setting for this company') + return data + + ksa_vat_setting = frappe.get_doc('KSA VAT Setting', company) + + # Sales Heading + append_data(data, 'VAT on Sales', '', '', '') + + grand_total_taxable_amount = 0 + grand_total_taxable_adjustment_amount = 0 + grand_total_tax = 0 + + for vat_setting in ksa_vat_setting.ksa_vat_sales_accounts: + total_taxable_amount, total_taxable_adjustment_amount, \ + total_tax = get_tax_data_for_each_vat_setting(vat_setting, filters, 'Sales Invoice') + + # Adding results to data + append_data(data, vat_setting.title, total_taxable_amount, + total_taxable_adjustment_amount, total_tax) + + grand_total_taxable_amount += total_taxable_amount + grand_total_taxable_adjustment_amount += total_taxable_adjustment_amount + grand_total_tax += total_tax + + # Sales Grand Total + append_data(data, 'Grand Total', grand_total_taxable_amount, + grand_total_taxable_adjustment_amount, grand_total_tax ) + + # Blank Line + append_data(data, '', '', '', '') + + # Purchase Heading + append_data(data, 'VAT on Purchases', '', '', '') + + grand_total_taxable_amount = 0 + grand_total_taxable_adjustment_amount = 0 + grand_total_tax = 0 + + for vat_setting in ksa_vat_setting.ksa_vat_purchase_accounts: + total_taxable_amount, total_taxable_adjustment_amount, \ + total_tax = get_tax_data_for_each_vat_setting(vat_setting, filters, 'Purchase Invoice') + + # Adding results to data + append_data(data, vat_setting.title, total_taxable_amount, + total_taxable_adjustment_amount, total_tax) + + grand_total_taxable_amount += total_taxable_amount + grand_total_taxable_adjustment_amount += total_taxable_adjustment_amount + grand_total_tax += total_tax + + # Purchase Grand Total + append_data(data, 'Grand Total', grand_total_taxable_amount, + grand_total_taxable_adjustment_amount, grand_total_tax ) + + return data + +def get_tax_data_for_each_vat_setting(vat_setting, filters, doctype): + ''' + (KSA, {filters}, 'Sales Invoice') => 500, 153, 10 \n + calculates and returns \n + total_taxable_amount, total_taxable_adjustment_amount, total_tax''' + from_date = filters.get('from_date') + to_date = filters.get('to_date') + + # Initiate variables + total_taxable_amount = 0 + total_taxable_adjustment_amount = 0 + total_tax = 0 + # Fetch All Invoices + invoices = frappe.get_list(doctype, + filters ={ + 'docstatus': 1, + 'posting_date': ['between', [from_date, to_date]] + }, + fields =['name', 'is_return']) + + for invoice in invoices: + invoice_items = frappe.get_list(f'{doctype} Item', + filters ={ + 'docstatus': 1, + 'parent': invoice.name, + 'item_tax_template': vat_setting.item_tax_template + }, + fields =['item_code', 'net_amount']) + + + for item in invoice_items: + # Summing up total taxable amount + if invoice.is_return == 0: + total_taxable_amount += item.net_amount + + if invoice.is_return == 1: + total_taxable_adjustment_amount += item.net_amount + + # Summing up total tax + total_tax += get_tax_amount(item.item_code, vat_setting.account, doctype, invoice.name) + + return total_taxable_amount, total_taxable_adjustment_amount, total_tax + + + +def append_data(data, title, amount, adjustment_amount, vat_amount): + """Returns data with appended value.""" + data.append({"title":title, "amount": amount, "adjustment_amount": adjustment_amount, "vat_amount": vat_amount}) + +def get_tax_amount(item_code, account_head, doctype, parent): + if doctype == 'Sales Invoice': + tax_doctype = 'Sales Taxes and Charges' + + elif doctype == 'Purchase Invoice': + tax_doctype = 'Purchase Taxes and Charges' + + item_wise_tax_detail = frappe.get_value(tax_doctype, { + 'docstatus': 1, + 'parent': parent, + 'account_head': account_head + }, 'item_wise_tax_detail') + + tax_amount = 0 + if item_wise_tax_detail and len(item_wise_tax_detail) > 0: + item_wise_tax_detail = json.loads(item_wise_tax_detail) + for key, value in item_wise_tax_detail.items(): + if key == item_code: + tax_amount = value[1] + break + + return tax_amount \ No newline at end of file diff --git a/erpnext/regional/saudi_arabia/setup.py b/erpnext/regional/saudi_arabia/setup.py index 3ccaae9e6a53..3fc658b6eab6 100644 --- a/erpnext/regional/saudi_arabia/setup.py +++ b/erpnext/regional/saudi_arabia/setup.py @@ -3,9 +3,26 @@ from __future__ import unicode_literals -from erpnext.regional.united_arab_emirates.setup import add_print_formats, make_custom_fields +import frappe +from frappe.permissions import add_permission, update_permission_property +from erpnext.regional.united_arab_emirates.setup import make_custom_fields, add_print_formats +from erpnext.regional.saudi_arabia.wizard.operations.setup_ksa_vat_setting import create_ksa_vat_setting def setup(company=None, patch=True): make_custom_fields() add_print_formats() + add_permissions() + create_ksa_vat_setting(company) + + +def add_permissions(): + """Add Permissions for KSA VAT Setting.""" + add_permission('KSA VAT Setting', 'All', 0) + for role in ('Accounts Manager', 'Accounts User', 'System Manager'): + add_permission('KSA VAT Setting', role, 0) + update_permission_property('KSA VAT Setting', role, 0, 'write', 1) + update_permission_property('KSA VAT Setting', role, 0, 'create', 1) + + """Enable KSA VAT Report""" + frappe.db.set_value('Report', 'KSA VAT', 'disabled', 0) diff --git a/erpnext/regional/saudi_arabia/wizard/__init__.py b/erpnext/regional/saudi_arabia/wizard/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/regional/saudi_arabia/wizard/data/__init__.py b/erpnext/regional/saudi_arabia/wizard/data/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/regional/saudi_arabia/wizard/data/ksa_vat_settings.json b/erpnext/regional/saudi_arabia/wizard/data/ksa_vat_settings.json new file mode 100644 index 000000000000..709d65be0413 --- /dev/null +++ b/erpnext/regional/saudi_arabia/wizard/data/ksa_vat_settings.json @@ -0,0 +1,47 @@ +[ + { + "type": "Sales Account", + "accounts": [ + { + "title": "Standard rated Sales", + "item_tax_template": "KSA VAT 5%", + "account": "VAT 5%" + }, + { + "title": "Zero rated domestic sales", + "item_tax_template": "KSA VAT Zero", + "account": "VAT Zero" + }, + { + "title": "Exempted sales", + "item_tax_template": "KSA VAT Exempted", + "account": "VAT Zero" + } + ] + }, + { + "type": "Purchase Account", + "accounts": [ + { + "title": "Standard rated domestic purchases", + "item_tax_template": "KSA VAT 5%", + "account": "VAT 5%" + }, + { + "title": "Imports subject to VAT paid at customs", + "item_tax_template": "KSA Excise 50%", + "account": "Excise 50%" + }, + { + "title": "Zero rated purchases", + "item_tax_template": "KSA VAT Zero", + "account": "VAT Zero" + }, + { + "title": "Exempted purchases", + "item_tax_template": "KSA VAT Exempted", + "account": "VAT Zero" + } + ] + } +] \ No newline at end of file diff --git a/erpnext/regional/saudi_arabia/wizard/operations/__init__.py b/erpnext/regional/saudi_arabia/wizard/operations/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py b/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py new file mode 100644 index 000000000000..ba137dada6a0 --- /dev/null +++ b/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py @@ -0,0 +1,48 @@ +import json +import os + +import frappe + +from erpnext.setup.setup_wizard.operations.taxes_setup import setup_taxes_and_charges + + +def create_ksa_vat_setting(company): + """ + On creation of first company. Creates KSA VAT Setting""" + + company = frappe.get_doc('Company', company) + setup_taxes_and_charges(company.name, company.country) + + file_path = os.path.join(os.path.dirname(__file__), '..', 'data', 'ksa_vat_settings.json') + with open(file_path, 'r') as json_file: + account_data = json.load(json_file) + + + # Creating KSA VAT Setting + ksa_vat_setting = frappe.get_doc({ + 'doctype': 'KSA VAT Setting', + 'company': company.name + }) + + for data in account_data: + if data['type'] == 'Sales Account': + for row in data['accounts']: + item_tax_template = row['item_tax_template'] + account = row['account'] + ksa_vat_setting.append('ksa_vat_sales_accounts', { + 'title': row['title'], + 'item_tax_template': f'{item_tax_template} - {company.abbr}', + 'account': f'{account} - {company.abbr}' + }) + + elif data['type'] == 'Purchase Account': + for row in data['accounts']: + item_tax_template = row['item_tax_template'] + account = row['account'] + ksa_vat_setting.append('ksa_vat_purchase_accounts', { + 'title': row['title'], + 'item_tax_template': f'{item_tax_template} - {company.abbr}', + 'account': f'{account} - {company.abbr}' + }) + + ksa_vat_setting.save() \ No newline at end of file From 60fd96085c01f7f598814f4a85bfb6c99d47ea0f Mon Sep 17 00:00:00 2001 From: Ahmad Date: Mon, 6 Sep 2021 23:36:55 +0500 Subject: [PATCH 02/13] feat(regional): QR Code generation for Saudi Arabia Sales Invoices --- erpnext/hooks.py | 6 ++- erpnext/regional/__init__.py | 73 ++++++++++++++++++++++++++ erpnext/regional/saudi_arabia/setup.py | 17 ++++-- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 3094deaafa7f..894770c58a8e 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -257,6 +257,7 @@ "validate": "erpnext.regional.india.utils.validate_tax_category" }, "Sales Invoice": { + "after_insert": "erpnext.regional.create_qr_code", "on_submit": [ "erpnext.regional.create_transaction_log", "erpnext.regional.italy.utils.sales_invoice_on_submit", @@ -266,7 +267,10 @@ "erpnext.regional.italy.utils.sales_invoice_on_cancel", "erpnext.erpnext_integrations.taxjar_integration.delete_transaction" ], - "on_trash": "erpnext.regional.check_deletion_permission", + "on_trash": [ + "erpnext.regional.check_deletion_permission", + "erpnext.regional.delete_qr_code_file" + ], "validate": [ "erpnext.regional.india.utils.validate_document_name", "erpnext.regional.india.utils.update_taxable_values" diff --git a/erpnext/regional/__init__.py b/erpnext/regional/__init__.py index 45a689efa8ba..2fb68a6f5298 100644 --- a/erpnext/regional/__init__.py +++ b/erpnext/regional/__init__.py @@ -3,8 +3,12 @@ from __future__ import unicode_literals +import io +import os + import frappe from frappe import _ +from pyqrcode import create as qr_create from erpnext import get_region @@ -31,3 +35,72 @@ def create_transaction_log(doc, method): "document_name": doc.name, "data": data }).insert(ignore_permissions=True) + + +def create_qr_code(doc, method): + """Create QR Code after inserting Sales Inv + """ + + region = get_region(doc.company) + if region not in ['Saudi Arabia']: + return + + # if QR Code field not present, do nothing + if not hasattr(doc, 'qr_code'): + return + + # Don't create QR Code if it already exists + qr_code = doc.get("qr_code") + if qr_code and frappe.db.exists({"doctype": "File", "file_url": qr_code}): + return + + fields = frappe.get_meta('Sales Invoice').fields + + for field in fields: + if field.fieldname == 'qr_code' and field.fieldtype == 'Attach Image': + # Creating public url to print format + default_print_format = frappe.db.get_value('Property Setter', dict(property='default_print_format', doc_type=doc.doctype), "value") + + # System Language + language = frappe.get_system_settings('language') + + # creating qr code for the url + url = f"{ frappe.utils.get_url() }/{ doc.doctype }/{ doc.name }?format={ default_print_format or 'Standard' }&_lang={ language }&key={ doc.get_signature() }" + qr_image = io.BytesIO() + url = qr_create(url, error='L') + url.png(qr_image, scale=2, quiet_zone=1) + + # making file + filename = f"QR-CODE-{doc.name}.png".replace(os.path.sep, "__") + _file = frappe.get_doc({ + "doctype": "File", + "file_name": filename, + "is_private": 0, + "content": qr_image.getvalue() + }) + + _file.save() + + # assigning to document + doc.db_set('qr_code', _file.file_url) + doc.notify_update() + + break + + else: + pass + +def delete_qr_code_file(doc, method): + """Delete QR Code on deleted sales invoice""" + + region = get_region(doc.company) + if region not in ['Saudi Arabia']: + return + + if hasattr(doc, 'qr_code'): + if doc.get('qr_code'): + file_doc = frappe.get_list('File', { + 'file_url': doc.qr_code + }) + if len(file_doc): + frappe.delete_doc('File', file_doc[0].name) \ No newline at end of file diff --git a/erpnext/regional/saudi_arabia/setup.py b/erpnext/regional/saudi_arabia/setup.py index 3fc658b6eab6..fb0e3679f63c 100644 --- a/erpnext/regional/saudi_arabia/setup.py +++ b/erpnext/regional/saudi_arabia/setup.py @@ -2,18 +2,18 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals - import frappe from frappe.permissions import add_permission, update_permission_property -from erpnext.regional.united_arab_emirates.setup import make_custom_fields, add_print_formats +from erpnext.regional.united_arab_emirates.setup import make_custom_fields as uae_custom_fields, add_print_formats from erpnext.regional.saudi_arabia.wizard.operations.setup_ksa_vat_setting import create_ksa_vat_setting - +from frappe.custom.doctype.custom_field.custom_field import create_custom_field def setup(company=None, patch=True): - make_custom_fields() + uae_custom_fields() add_print_formats() add_permissions() create_ksa_vat_setting(company) + make_custom_fields() def add_permissions(): @@ -26,3 +26,12 @@ def add_permissions(): """Enable KSA VAT Report""" frappe.db.set_value('Report', 'KSA VAT', 'disabled', 0) + +def make_custom_fields(): + qr_code_field = dict( + fieldname='qr_code', + label='QR Code', + fieldtype='Attach Image', + read_only=1, no_copy=1, hidden=1) + + create_custom_field('Sales Invoice', qr_code_field) From a8ba52e8a5838362e6b5ba1663855570ea5a56ca Mon Sep 17 00:00:00 2001 From: Ahmad <7881486+ahmadpak@users.noreply.github.com> Date: Tue, 14 Sep 2021 14:26:44 +0500 Subject: [PATCH 03/13] Update erpnext/regional/report/ksa_vat/ksa_vat.py String made translatable Co-authored-by: Saqib --- erpnext/regional/report/ksa_vat/ksa_vat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/report/ksa_vat/ksa_vat.py b/erpnext/regional/report/ksa_vat/ksa_vat.py index b32dfc198113..3396d598e907 100644 --- a/erpnext/regional/report/ksa_vat/ksa_vat.py +++ b/erpnext/regional/report/ksa_vat/ksa_vat.py @@ -50,7 +50,7 @@ def get_data(filters): company = filters.get('company') if frappe.db.exists('KSA VAT Setting', company) is None: url = get_url_to_list('KSA VAT Setting') - frappe.msgprint(f'Create KSA VAT Setting for this company') + frappe.msgprint(_('Create KSA VAT Setting for this company').format(url)) return data ksa_vat_setting = frappe.get_doc('KSA VAT Setting', company) From 220ab16698050f9af82f795cf892f18dbc37a369 Mon Sep 17 00:00:00 2001 From: Ahmad <7881486+ahmadpak@users.noreply.github.com> Date: Tue, 14 Sep 2021 14:28:57 +0500 Subject: [PATCH 04/13] Refactor erpnext/regional/__init__.py Co-authored-by: Saqib --- erpnext/regional/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/erpnext/regional/__init__.py b/erpnext/regional/__init__.py index 2fb68a6f5298..49fd80e28da9 100644 --- a/erpnext/regional/__init__.py +++ b/erpnext/regional/__init__.py @@ -87,8 +87,6 @@ def create_qr_code(doc, method): break - else: - pass def delete_qr_code_file(doc, method): """Delete QR Code on deleted sales invoice""" From 3fca08e3e845eae61942056d7ecc9b30b7150054 Mon Sep 17 00:00:00 2001 From: Ahmad <7881486+ahmadpak@users.noreply.github.com> Date: Tue, 14 Sep 2021 14:29:33 +0500 Subject: [PATCH 05/13] Update erpnext/regional/saudi_arabia/setup.py Method name updated Co-authored-by: Saqib --- erpnext/regional/saudi_arabia/setup.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/erpnext/regional/saudi_arabia/setup.py b/erpnext/regional/saudi_arabia/setup.py index fb0e3679f63c..a49490b6c42c 100644 --- a/erpnext/regional/saudi_arabia/setup.py +++ b/erpnext/regional/saudi_arabia/setup.py @@ -13,8 +13,7 @@ def setup(company=None, patch=True): add_print_formats() add_permissions() create_ksa_vat_setting(company) - make_custom_fields() - + make_qrcode_field() def add_permissions(): """Add Permissions for KSA VAT Setting.""" @@ -27,7 +26,7 @@ def add_permissions(): """Enable KSA VAT Report""" frappe.db.set_value('Report', 'KSA VAT', 'disabled', 0) -def make_custom_fields(): +def make_qrcode_field(): qr_code_field = dict( fieldname='qr_code', label='QR Code', From 873ed1ae4f1ab75b29901927f8674be2d8a0e4e6 Mon Sep 17 00:00:00 2001 From: Ahmad Date: Tue, 14 Sep 2021 14:45:23 +0500 Subject: [PATCH 06/13] refactor(regional): moved methos to region specific utils for KSA --- erpnext/hooks.py | 4 +- erpnext/regional/__init__.py | 70 ------------------------ erpnext/regional/saudi_arabia/utils.py | 74 ++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 72 deletions(-) create mode 100644 erpnext/regional/saudi_arabia/utils.py diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 894770c58a8e..3d29de8728b9 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -257,7 +257,7 @@ "validate": "erpnext.regional.india.utils.validate_tax_category" }, "Sales Invoice": { - "after_insert": "erpnext.regional.create_qr_code", + "after_insert": "erpnext.regional.saudi_arabia.utils.create_qr_code", "on_submit": [ "erpnext.regional.create_transaction_log", "erpnext.regional.italy.utils.sales_invoice_on_submit", @@ -269,7 +269,7 @@ ], "on_trash": [ "erpnext.regional.check_deletion_permission", - "erpnext.regional.delete_qr_code_file" + "erpnext.regional.saudi_arabia.utils.delete_qr_code_file" ], "validate": [ "erpnext.regional.india.utils.validate_document_name", diff --git a/erpnext/regional/__init__.py b/erpnext/regional/__init__.py index 49fd80e28da9..d7dcbf4fe184 100644 --- a/erpnext/regional/__init__.py +++ b/erpnext/regional/__init__.py @@ -3,12 +3,8 @@ from __future__ import unicode_literals -import io -import os - import frappe from frappe import _ -from pyqrcode import create as qr_create from erpnext import get_region @@ -36,69 +32,3 @@ def create_transaction_log(doc, method): "data": data }).insert(ignore_permissions=True) - -def create_qr_code(doc, method): - """Create QR Code after inserting Sales Inv - """ - - region = get_region(doc.company) - if region not in ['Saudi Arabia']: - return - - # if QR Code field not present, do nothing - if not hasattr(doc, 'qr_code'): - return - - # Don't create QR Code if it already exists - qr_code = doc.get("qr_code") - if qr_code and frappe.db.exists({"doctype": "File", "file_url": qr_code}): - return - - fields = frappe.get_meta('Sales Invoice').fields - - for field in fields: - if field.fieldname == 'qr_code' and field.fieldtype == 'Attach Image': - # Creating public url to print format - default_print_format = frappe.db.get_value('Property Setter', dict(property='default_print_format', doc_type=doc.doctype), "value") - - # System Language - language = frappe.get_system_settings('language') - - # creating qr code for the url - url = f"{ frappe.utils.get_url() }/{ doc.doctype }/{ doc.name }?format={ default_print_format or 'Standard' }&_lang={ language }&key={ doc.get_signature() }" - qr_image = io.BytesIO() - url = qr_create(url, error='L') - url.png(qr_image, scale=2, quiet_zone=1) - - # making file - filename = f"QR-CODE-{doc.name}.png".replace(os.path.sep, "__") - _file = frappe.get_doc({ - "doctype": "File", - "file_name": filename, - "is_private": 0, - "content": qr_image.getvalue() - }) - - _file.save() - - # assigning to document - doc.db_set('qr_code', _file.file_url) - doc.notify_update() - - break - - -def delete_qr_code_file(doc, method): - """Delete QR Code on deleted sales invoice""" - - region = get_region(doc.company) - if region not in ['Saudi Arabia']: - return - - if hasattr(doc, 'qr_code'): - if doc.get('qr_code'): - file_doc = frappe.get_list('File', { - 'file_url': doc.qr_code - }) - if len(file_doc): - frappe.delete_doc('File', file_doc[0].name) \ No newline at end of file diff --git a/erpnext/regional/saudi_arabia/utils.py b/erpnext/regional/saudi_arabia/utils.py new file mode 100644 index 000000000000..e83d8c72ad61 --- /dev/null +++ b/erpnext/regional/saudi_arabia/utils.py @@ -0,0 +1,74 @@ +import io +import os + +import frappe +from pyqrcode import create as qr_create + +from erpnext import get_region + + +def create_qr_code(doc, method): + """Create QR Code after inserting Sales Inv + """ + + region = get_region(doc.company) + if region not in ['Saudi Arabia']: + return + + # if QR Code field not present, do nothing + if not hasattr(doc, 'qr_code'): + return + + # Don't create QR Code if it already exists + qr_code = doc.get("qr_code") + if qr_code and frappe.db.exists({"doctype": "File", "file_url": qr_code}): + return + + fields = frappe.get_meta('Sales Invoice').fields + + for field in fields: + if field.fieldname == 'qr_code' and field.fieldtype == 'Attach Image': + # Creating public url to print format + default_print_format = frappe.db.get_value('Property Setter', dict(property='default_print_format', doc_type=doc.doctype), "value") + + # System Language + language = frappe.get_system_settings('language') + + # creating qr code for the url + url = f"{ frappe.utils.get_url() }/{ doc.doctype }/{ doc.name }?format={ default_print_format or 'Standard' }&_lang={ language }&key={ doc.get_signature() }" + qr_image = io.BytesIO() + url = qr_create(url, error='L') + url.png(qr_image, scale=2, quiet_zone=1) + + # making file + filename = f"QR-CODE-{doc.name}.png".replace(os.path.sep, "__") + _file = frappe.get_doc({ + "doctype": "File", + "file_name": filename, + "is_private": 0, + "content": qr_image.getvalue() + }) + + _file.save() + + # assigning to document + doc.db_set('qr_code', _file.file_url) + doc.notify_update() + + break + + +def delete_qr_code_file(doc, method): + """Delete QR Code on deleted sales invoice""" + + region = get_region(doc.company) + if region not in ['Saudi Arabia']: + return + + if hasattr(doc, 'qr_code'): + if doc.get('qr_code'): + file_doc = frappe.get_list('File', { + 'file_url': doc.qr_code + }) + if len(file_doc): + frappe.delete_doc('File', file_doc[0].name) \ No newline at end of file From 5f7c5bcac8d544f24816ffec96e621f4aa3eaa4d Mon Sep 17 00:00:00 2001 From: Ahmad Date: Fri, 17 Sep 2021 01:14:41 +0500 Subject: [PATCH 07/13] fix: indentations --- erpnext/hooks.py | 2 +- .../doctype/ksa_vat_setting/ksa_vat_setting.js | 2 +- .../doctype/ksa_vat_setting/ksa_vat_setting_list.js | 6 +++--- erpnext/regional/report/ksa_vat/ksa_vat.py | 11 ++++------- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 3d29de8728b9..6be3e25440a6 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -270,7 +270,7 @@ "on_trash": [ "erpnext.regional.check_deletion_permission", "erpnext.regional.saudi_arabia.utils.delete_qr_code_file" - ], + ], "validate": [ "erpnext.regional.india.utils.validate_document_name", "erpnext.regional.india.utils.update_taxable_values" diff --git a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js index 0238c7b30685..00b62b9adfb9 100644 --- a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js +++ b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting.js @@ -2,7 +2,7 @@ // For license information, please see license.txt frappe.ui.form.on('KSA VAT Setting', { - onload: function(frm) { + onload: function () { frappe.breadcrumbs.add('Accounts', 'KSA VAT Setting'); } }); diff --git a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js index 23d28b9e68b1..269cbec5fb4c 100644 --- a/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js +++ b/erpnext/regional/doctype/ksa_vat_setting/ksa_vat_setting_list.js @@ -1,5 +1,5 @@ frappe.listview_settings['KSA VAT Setting'] = { - onload(list) { - frappe.breadcrumbs.add('Accounts'); - } + onload () { + frappe.breadcrumbs.add('Accounts'); + } } \ No newline at end of file diff --git a/erpnext/regional/report/ksa_vat/ksa_vat.py b/erpnext/regional/report/ksa_vat/ksa_vat.py index 3396d598e907..1697bbbd4d65 100644 --- a/erpnext/regional/report/ksa_vat/ksa_vat.py +++ b/erpnext/regional/report/ksa_vat/ksa_vat.py @@ -76,7 +76,7 @@ def get_data(filters): # Sales Grand Total append_data(data, 'Grand Total', grand_total_taxable_amount, - grand_total_taxable_adjustment_amount, grand_total_tax ) + grand_total_taxable_adjustment_amount, grand_total_tax) # Blank Line append_data(data, '', '', '', '') @@ -102,7 +102,7 @@ def get_data(filters): # Purchase Grand Total append_data(data, 'Grand Total', grand_total_taxable_amount, - grand_total_taxable_adjustment_amount, grand_total_tax ) + grand_total_taxable_adjustment_amount, grand_total_tax) return data @@ -123,8 +123,7 @@ def get_tax_data_for_each_vat_setting(vat_setting, filters, doctype): filters ={ 'docstatus': 1, 'posting_date': ['between', [from_date, to_date]] - }, - fields =['name', 'is_return']) + }, fields =['name', 'is_return']) for invoice in invoices: invoice_items = frappe.get_list(f'{doctype} Item', @@ -132,9 +131,7 @@ def get_tax_data_for_each_vat_setting(vat_setting, filters, doctype): 'docstatus': 1, 'parent': invoice.name, 'item_tax_template': vat_setting.item_tax_template - }, - fields =['item_code', 'net_amount']) - + }, fields =['item_code', 'net_amount']) for item in invoice_items: # Summing up total taxable amount From f9770b69b26e4ae77ec17cfcd441f06f3b3d3889 Mon Sep 17 00:00:00 2001 From: Ahmad <7881486+ahmadpak@users.noreply.github.com> Date: Fri, 17 Sep 2021 01:27:37 +0500 Subject: [PATCH 08/13] Update erpnext/regional/saudi_arabia/utils.py Co-authored-by: Saqib --- erpnext/regional/saudi_arabia/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/regional/saudi_arabia/utils.py b/erpnext/regional/saudi_arabia/utils.py index e83d8c72ad61..5b8b7c13836f 100644 --- a/erpnext/regional/saudi_arabia/utils.py +++ b/erpnext/regional/saudi_arabia/utils.py @@ -68,7 +68,7 @@ def delete_qr_code_file(doc, method): if hasattr(doc, 'qr_code'): if doc.get('qr_code'): file_doc = frappe.get_list('File', { - 'file_url': doc.qr_code + 'file_url': doc.get('qr_code') }) if len(file_doc): frappe.delete_doc('File', file_doc[0].name) \ No newline at end of file From 0313b44f1fac67df5521cba2647190882dae18c5 Mon Sep 17 00:00:00 2001 From: Ahmad <7881486+ahmadpak@users.noreply.github.com> Date: Fri, 17 Sep 2021 01:28:52 +0500 Subject: [PATCH 09/13] Update erpnext/regional/saudi_arabia/utils.py Co-authored-by: Saqib --- erpnext/regional/saudi_arabia/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/saudi_arabia/utils.py b/erpnext/regional/saudi_arabia/utils.py index 5b8b7c13836f..79a29de9ac7e 100644 --- a/erpnext/regional/saudi_arabia/utils.py +++ b/erpnext/regional/saudi_arabia/utils.py @@ -46,7 +46,10 @@ def create_qr_code(doc, method): "doctype": "File", "file_name": filename, "is_private": 0, - "content": qr_image.getvalue() + "content": qr_image.getvalue(), + "attached_to_doctype": doc.get("doctype"), + "attached_to_name": doc.get("name"), + "attached_to_field": "qr_code" }) _file.save() From 30f3b4804d7693c1eb9f1363c267eb9a45993680 Mon Sep 17 00:00:00 2001 From: Ahmad Date: Fri, 17 Sep 2021 01:33:32 +0500 Subject: [PATCH 10/13] refactor (regional): KSA utils --- erpnext/regional/saudi_arabia/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/regional/saudi_arabia/utils.py b/erpnext/regional/saudi_arabia/utils.py index 79a29de9ac7e..cc6c0af7a56e 100644 --- a/erpnext/regional/saudi_arabia/utils.py +++ b/erpnext/regional/saudi_arabia/utils.py @@ -24,10 +24,10 @@ def create_qr_code(doc, method): if qr_code and frappe.db.exists({"doctype": "File", "file_url": qr_code}): return - fields = frappe.get_meta('Sales Invoice').fields + meta = frappe.get_meta('Sales Invoice') - for field in fields: - if field.fieldname == 'qr_code' and field.fieldtype == 'Attach Image': + for field in meta.get_image_fields(): + if field.fieldname == 'qr_code': # Creating public url to print format default_print_format = frappe.db.get_value('Property Setter', dict(property='default_print_format', doc_type=doc.doctype), "value") From 301b94e06acad96881c6e7d7c8a9501718a7c697 Mon Sep 17 00:00:00 2001 From: Ahmad Date: Fri, 17 Sep 2021 01:46:45 +0500 Subject: [PATCH 11/13] fix: pre-commit hooks --- .../saudi_arabia/wizard/operations/setup_ksa_vat_setting.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py b/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py index ba137dada6a0..c30fcffc37c1 100644 --- a/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py +++ b/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py @@ -7,8 +7,7 @@ def create_ksa_vat_setting(company): - """ - On creation of first company. Creates KSA VAT Setting""" + """On creation of first company. Creates KSA VAT Setting""" company = frappe.get_doc('Company', company) setup_taxes_and_charges(company.name, company.country) From b69381117fe8536d72f121e247224c49ab554264 Mon Sep 17 00:00:00 2001 From: Ahmad Date: Fri, 17 Sep 2021 01:51:32 +0500 Subject: [PATCH 12/13] fix: pre-commit hooks --- erpnext/regional/saudi_arabia/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/regional/saudi_arabia/setup.py b/erpnext/regional/saudi_arabia/setup.py index a49490b6c42c..6113f48d3f15 100644 --- a/erpnext/regional/saudi_arabia/setup.py +++ b/erpnext/regional/saudi_arabia/setup.py @@ -27,6 +27,7 @@ def add_permissions(): frappe.db.set_value('Report', 'KSA VAT', 'disabled', 0) def make_qrcode_field(): + """Created QR code Image file""" qr_code_field = dict( fieldname='qr_code', label='QR Code', From 6d39b90b8ed2413e3b96c02f0ae96a88ae73e3a4 Mon Sep 17 00:00:00 2001 From: Ahmad Date: Sun, 10 Oct 2021 21:17:59 +0200 Subject: [PATCH 13/13] refactor: make strings translate --- erpnext/regional/report/ksa_vat/ksa_vat.py | 4 ++-- .../saudi_arabia/wizard/operations/setup_ksa_vat_setting.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/erpnext/regional/report/ksa_vat/ksa_vat.py b/erpnext/regional/report/ksa_vat/ksa_vat.py index 1697bbbd4d65..a42ebc9f7e51 100644 --- a/erpnext/regional/report/ksa_vat/ksa_vat.py +++ b/erpnext/regional/report/ksa_vat/ksa_vat.py @@ -150,7 +150,7 @@ def get_tax_data_for_each_vat_setting(vat_setting, filters, doctype): def append_data(data, title, amount, adjustment_amount, vat_amount): """Returns data with appended value.""" - data.append({"title":title, "amount": amount, "adjustment_amount": adjustment_amount, "vat_amount": vat_amount}) + data.append({"title": _(title), "amount": amount, "adjustment_amount": adjustment_amount, "vat_amount": vat_amount}) def get_tax_amount(item_code, account_head, doctype, parent): if doctype == 'Sales Invoice': @@ -173,4 +173,4 @@ def get_tax_amount(item_code, account_head, doctype, parent): tax_amount = value[1] break - return tax_amount \ No newline at end of file + return tax_amount diff --git a/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py b/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py index c30fcffc37c1..3c89edd37edc 100644 --- a/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py +++ b/erpnext/regional/saudi_arabia/wizard/operations/setup_ksa_vat_setting.py @@ -16,7 +16,6 @@ def create_ksa_vat_setting(company): with open(file_path, 'r') as json_file: account_data = json.load(json_file) - # Creating KSA VAT Setting ksa_vat_setting = frappe.get_doc({ 'doctype': 'KSA VAT Setting', @@ -44,4 +43,4 @@ def create_ksa_vat_setting(company): 'account': f'{account} - {company.abbr}' }) - ksa_vat_setting.save() \ No newline at end of file + ksa_vat_setting.save()