2021-08-26 02:35:59 +00:00
|
|
|
# Copyright (c) 2013, Havenir Solutions and contributors
|
|
|
|
# For license information, please see license.txt
|
|
|
|
|
2021-09-16 20:14:41 +00:00
|
|
|
|
|
|
|
import json
|
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
import frappe
|
|
|
|
from frappe import _
|
|
|
|
from frappe.utils import get_url_to_list
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
def execute(filters=None):
|
|
|
|
columns = columns = get_columns()
|
|
|
|
data = get_data(filters)
|
|
|
|
return columns, data
|
|
|
|
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
def get_columns():
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
"fieldname": "title",
|
|
|
|
"label": _("Title"),
|
|
|
|
"fieldtype": "Data",
|
2022-01-05 09:38:29 +00:00
|
|
|
"width": 300,
|
2021-08-26 02:35:59 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"fieldname": "amount",
|
|
|
|
"label": _("Amount (SAR)"),
|
|
|
|
"fieldtype": "Currency",
|
2022-01-05 09:38:29 +00:00
|
|
|
"options": "currency",
|
2021-08-26 02:35:59 +00:00
|
|
|
"width": 150,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"fieldname": "adjustment_amount",
|
|
|
|
"label": _("Adjustment (SAR)"),
|
|
|
|
"fieldtype": "Currency",
|
2022-01-05 09:38:29 +00:00
|
|
|
"options": "currency",
|
2021-08-26 02:35:59 +00:00
|
|
|
"width": 150,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"fieldname": "vat_amount",
|
|
|
|
"label": _("VAT Amount (SAR)"),
|
|
|
|
"fieldtype": "Currency",
|
2022-01-05 09:38:29 +00:00
|
|
|
"options": "currency",
|
2021-08-26 02:35:59 +00:00
|
|
|
"width": 150,
|
2022-01-05 09:38:29 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"fieldname": "currency",
|
|
|
|
"label": _("Currency"),
|
|
|
|
"fieldtype": "Currency",
|
|
|
|
"width": 150,
|
|
|
|
"hidden": 1,
|
2021-08-26 02:35:59 +00:00
|
|
|
},
|
|
|
|
]
|
|
|
|
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
def get_data(filters):
|
|
|
|
data = []
|
|
|
|
|
|
|
|
# Validate if vat settings exist
|
|
|
|
company = filters.get("company")
|
2022-01-05 09:38:29 +00:00
|
|
|
company_currency = frappe.get_cached_value("Company", company, "default_currency")
|
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
if frappe.db.exists("KSA VAT Setting", company) is None:
|
|
|
|
url = get_url_to_list("KSA VAT Setting")
|
2021-09-14 09:26:44 +00:00
|
|
|
frappe.msgprint(_('Create <a href="{}">KSA VAT Setting</a> for this company').format(url))
|
2021-08-26 02:35:59 +00:00
|
|
|
return data
|
|
|
|
|
|
|
|
ksa_vat_setting = frappe.get_doc("KSA VAT Setting", company)
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
# Sales Heading
|
2022-01-05 09:38:29 +00:00
|
|
|
append_data(data, "VAT on Sales", "", "", "", company_currency)
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
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:
|
2022-03-28 13:22:46 +00:00
|
|
|
(
|
2021-08-26 02:35:59 +00:00
|
|
|
total_taxable_amount,
|
|
|
|
total_taxable_adjustment_amount,
|
|
|
|
total_tax,
|
|
|
|
) = get_tax_data_for_each_vat_setting(vat_setting, filters, "Sales Invoice")
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
# Adding results to data
|
2021-09-16 20:14:41 +00:00
|
|
|
append_data(
|
|
|
|
data,
|
|
|
|
vat_setting.title,
|
|
|
|
total_taxable_amount,
|
2022-01-05 09:38:29 +00:00
|
|
|
total_taxable_adjustment_amount,
|
|
|
|
total_tax,
|
|
|
|
company_currency,
|
|
|
|
)
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
grand_total_taxable_amount += total_taxable_amount
|
|
|
|
grand_total_taxable_adjustment_amount += total_taxable_adjustment_amount
|
|
|
|
grand_total_tax += total_tax
|
|
|
|
|
|
|
|
# Sales Grand Total
|
2021-09-16 20:14:41 +00:00
|
|
|
append_data(
|
|
|
|
data,
|
|
|
|
"Grand Total",
|
|
|
|
grand_total_taxable_amount,
|
2022-01-05 09:38:29 +00:00
|
|
|
grand_total_taxable_adjustment_amount,
|
|
|
|
grand_total_tax,
|
|
|
|
company_currency,
|
|
|
|
)
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
# Blank Line
|
2022-01-05 09:38:29 +00:00
|
|
|
append_data(data, "", "", "", "", company_currency)
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
# Purchase Heading
|
2022-01-05 09:38:29 +00:00
|
|
|
append_data(data, "VAT on Purchases", "", "", "", company_currency)
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
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:
|
2022-03-28 13:22:46 +00:00
|
|
|
(
|
2021-08-26 02:35:59 +00:00
|
|
|
total_taxable_amount,
|
|
|
|
total_taxable_adjustment_amount,
|
|
|
|
total_tax,
|
|
|
|
) = get_tax_data_for_each_vat_setting(vat_setting, filters, "Purchase Invoice")
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
# Adding results to data
|
2021-09-16 20:14:41 +00:00
|
|
|
append_data(
|
|
|
|
data,
|
|
|
|
vat_setting.title,
|
|
|
|
total_taxable_amount,
|
2022-01-05 09:38:29 +00:00
|
|
|
total_taxable_adjustment_amount,
|
|
|
|
total_tax,
|
|
|
|
company_currency,
|
|
|
|
)
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
grand_total_taxable_amount += total_taxable_amount
|
|
|
|
grand_total_taxable_adjustment_amount += total_taxable_adjustment_amount
|
|
|
|
grand_total_tax += total_tax
|
|
|
|
|
|
|
|
# Purchase Grand Total
|
2021-09-16 20:14:41 +00:00
|
|
|
append_data(
|
|
|
|
data,
|
|
|
|
"Grand Total",
|
|
|
|
grand_total_taxable_amount,
|
2022-01-05 09:38:29 +00:00
|
|
|
grand_total_taxable_adjustment_amount,
|
|
|
|
grand_total_tax,
|
|
|
|
company_currency,
|
|
|
|
)
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
return data
|
|
|
|
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
def get_tax_data_for_each_vat_setting(vat_setting, filters, doctype):
|
2022-03-28 13:22:46 +00:00
|
|
|
"""
|
2021-08-26 02:35:59 +00:00
|
|
|
(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
|
2021-11-08 11:44:03 +00:00
|
|
|
invoices = frappe.get_all(
|
|
|
|
doctype,
|
2021-08-26 02:35:59 +00:00
|
|
|
filters={"docstatus": 1, "posting_date": ["between", [from_date, to_date]]},
|
2021-09-16 20:14:41 +00:00
|
|
|
fields=["name", "is_return"],
|
|
|
|
)
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
for invoice in invoices:
|
2021-11-08 11:44:03 +00:00
|
|
|
invoice_items = frappe.get_all(
|
|
|
|
f"{doctype} Item",
|
2021-08-26 02:35:59 +00:00
|
|
|
filters={
|
|
|
|
"docstatus": 1,
|
|
|
|
"parent": invoice.name,
|
|
|
|
"item_tax_template": vat_setting.item_tax_template,
|
2021-09-16 20:14:41 +00:00
|
|
|
},
|
|
|
|
fields=["item_code", "net_amount"],
|
|
|
|
)
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
for item in invoice_items:
|
|
|
|
# Summing up total taxable amount
|
|
|
|
if invoice.is_return == 0:
|
|
|
|
total_taxable_amount += item.net_amount
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
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)
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
return total_taxable_amount, total_taxable_adjustment_amount, total_tax
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
|
2022-01-05 09:38:29 +00:00
|
|
|
def append_data(data, title, amount, adjustment_amount, vat_amount, company_currency):
|
2021-08-26 02:35:59 +00:00
|
|
|
"""Returns data with appended value."""
|
2022-01-05 09:38:29 +00:00
|
|
|
data.append(
|
2022-03-28 13:22:46 +00:00
|
|
|
{
|
2022-01-05 09:38:29 +00:00
|
|
|
"title": _(title),
|
|
|
|
"amount": amount,
|
|
|
|
"adjustment_amount": adjustment_amount,
|
|
|
|
"vat_amount": vat_amount,
|
|
|
|
"currency": company_currency,
|
2022-03-28 13:22:46 +00:00
|
|
|
}
|
2022-01-05 09:38:29 +00:00
|
|
|
)
|
2022-03-28 13:22:46 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
|
|
|
|
def get_tax_amount(item_code, account_head, doctype, parent):
|
|
|
|
if doctype == "Sales Invoice":
|
|
|
|
tax_doctype = "Sales Taxes and Charges"
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
elif doctype == "Purchase Invoice":
|
|
|
|
tax_doctype = "Purchase Taxes and Charges"
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-08-26 02:35:59 +00:00
|
|
|
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
|
2021-09-16 20:14:41 +00:00
|
|
|
|
2021-10-10 19:17:59 +00:00
|
|
|
return tax_amount
|