Merge pull request #21047 from vishdha/feat_taxjar

feat(ERPNext Integrations): Taxjar Integration Added
diff --git a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py
index 54464e7..a53417e 100644
--- a/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py
+++ b/erpnext/accounts/doctype/opening_invoice_creation_tool/opening_invoice_creation_tool.py
@@ -68,6 +68,9 @@
 		if not self.company:
 			frappe.throw(_("Please select the Company"))
 
+		company_details = frappe.get_cached_value('Company', self.company,
+			["default_currency", "default_letter_head"], as_dict=1) or {}
+
 		for row in self.invoices:
 			if not row.qty:
 				row.qty = 1.0
@@ -99,6 +102,12 @@
 			if not args:
 				continue
 
+			if company_details:
+				args.update({
+					"currency": company_details.get("default_currency"),
+					"letter_head": company_details.get("default_letter_head")
+				})
+
 			doc = frappe.get_doc(args).insert()
 			doc.submit()
 			names.append(doc.name)
@@ -172,8 +181,7 @@
 			"due_date": row.due_date,
 			"posting_date": row.posting_date,
 			frappe.scrub(party_type): row.party,
-			"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice",
-			"currency": frappe.get_cached_value('Company',  self.company,  "default_currency")
+			"doctype": "Sales Invoice" if self.invoice_type == "Sales" else "Purchase Invoice"
 		})
 
 		accounting_dimension = get_accounting_dimensions()
diff --git a/erpnext/hr/doctype/job_applicant/job_applicant_list.js b/erpnext/hr/doctype/job_applicant/job_applicant_list.js
new file mode 100644
index 0000000..3b9141b
--- /dev/null
+++ b/erpnext/hr/doctype/job_applicant/job_applicant_list.js
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+// MIT License. See license.txt
+
+frappe.listview_settings['Job Applicant'] = {
+	add_fields: ["company", "designation", "job_applicant", "status"],
+	get_indicator: function (doc) {
+		if (doc.status == "Accepted") {
+			return [__(doc.status), "green", "status,=," + doc.status];
+		} else if (["Open", "Replied"].includes(doc.status)) {
+			return [__(doc.status), "orange", "status,=," + doc.status];
+		} else if (["Hold", "Rejected"].includes(doc.status)) {
+			return [__(doc.status), "red", "status,=," + doc.status];
+		}
+	}
+};
diff --git a/erpnext/hr/doctype/job_offer/job_offer.json b/erpnext/hr/doctype/job_offer/job_offer.json
index ccbfdc5..c0b7f69 100644
--- a/erpnext/hr/doctype/job_offer/job_offer.json
+++ b/erpnext/hr/doctype/job_offer/job_offer.json
@@ -30,7 +30,6 @@
   {
    "fieldname": "job_applicant",
    "fieldtype": "Link",
-   "in_list_view": 1,
    "label": "Job Applicant",
    "options": "Job Applicant",
    "print_hide": 1,
@@ -161,7 +160,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2019-12-31 02:40:33.650728",
+ "modified": "2020-06-25 00:56:24.756395",
  "modified_by": "Administrator",
  "module": "HR",
  "name": "Job Offer",
diff --git a/erpnext/hr/doctype/job_offer/job_offer_list.js b/erpnext/hr/doctype/job_offer/job_offer_list.js
new file mode 100644
index 0000000..4fa5be7
--- /dev/null
+++ b/erpnext/hr/doctype/job_offer/job_offer_list.js
@@ -0,0 +1,15 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+// MIT License. See license.txt
+
+frappe.listview_settings['Job Offer'] = {
+	add_fields: ["company", "designation", "job_applicant", "status"],
+	get_indicator: function (doc) {
+		if (doc.status == "Accepted") {
+			return [__(doc.status), "green", "status,=," + doc.status];
+		} else if (doc.status == "Awaiting Response") {
+			return [__(doc.status), "orange", "status,=," + doc.status];
+		} else if (doc.status == "Rejected") {
+			return [__(doc.status), "red", "status,=," + doc.status];
+		}
+	}
+};
diff --git a/erpnext/loan_management/doctype/loan/loan.py b/erpnext/loan_management/doctype/loan/loan.py
index 76e10e5..4e805d4 100644
--- a/erpnext/loan_management/doctype/loan/loan.py
+++ b/erpnext/loan_management/doctype/loan/loan.py
@@ -235,8 +235,10 @@
 @frappe.whitelist()
 def create_loan_security_unpledge(loan, applicant_type, applicant, company, as_dict=1):
 	loan_security_pledge_details = frappe.db.sql("""
-		SELECT p.parent, p.loan_security, p.qty as qty FROM `tabLoan Security Pledge` lsp , `tabPledge` p
+		SELECT p.loan_security, sum(p.qty) as qty
+		FROM `tabLoan Security Pledge` lsp , `tabPledge` p
 		WHERE p.parent = lsp.name AND lsp.loan = %s AND lsp.docstatus = 1
+		GROUP BY p.loan_security
 	""",(loan), as_dict=1)
 
 	unpledge_request = frappe.new_doc("Loan Security Unpledge")
diff --git a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
index c28994e..9605045 100644
--- a/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
+++ b/erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
@@ -116,7 +116,7 @@
 	def allocate_amounts(self, paid_entries):
 		self.set('repayment_details', [])
 		self.principal_amount_paid = 0
-		interest_paid = 0
+		interest_paid = self.amount_paid - self.penalty_amount
 
 		if self.amount_paid - self.penalty_amount > 0 and paid_entries:
 			interest_paid = self.amount_paid - self.penalty_amount
diff --git a/erpnext/loan_management/doctype/loan_security_price/loan_security_price.json b/erpnext/loan_management/doctype/loan_security_price/loan_security_price.json
index db260a4..a55b482 100644
--- a/erpnext/loan_management/doctype/loan_security_price/loan_security_price.json
+++ b/erpnext/loan_management/doctype/loan_security_price/loan_security_price.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "autoname": "LM-LSP-.####",
  "creation": "2019-09-03 18:20:31.382887",
  "doctype": "DocType",
@@ -46,6 +47,7 @@
    "fieldtype": "Currency",
    "in_list_view": 1,
    "label": "Loan Security Price",
+   "options": "Company:company:default_currency",
    "reqd": 1
   },
   {
@@ -79,7 +81,8 @@
    "read_only": 1
   }
  ],
- "modified": "2019-10-26 09:46:46.069667",
+ "links": [],
+ "modified": "2020-06-11 03:41:33.900340",
  "modified_by": "Administrator",
  "module": "Loan Management",
  "name": "Loan Security Price",
diff --git a/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py b/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py
index 308c438..ffd9673 100644
--- a/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py
+++ b/erpnext/loan_management/doctype/loan_security_shortfall/loan_security_shortfall.py
@@ -19,7 +19,9 @@
 		return
 
 	if security_value >= loan_security_shortfall.shortfall_amount:
-		frappe.db.set_value("Loan Security Shortfall", loan_security_shortfall.name, "status", "Completed")
+		frappe.db.set_value("Loan Security Shortfall", loan_security_shortfall.name, {
+			"status": "Completed",
+			"shortfall_value": loan_security_shortfall.shortfall_amount})
 	else:
 		frappe.db.set_value("Loan Security Shortfall", loan_security_shortfall.name,
 			"shortfall_amount", loan_security_shortfall.shortfall_amount - security_value)
diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
index f42b9ad..be9a2d3 100644
--- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
@@ -271,6 +271,7 @@
 		# as per assigned salary structure 40500 in monthly salary so 236000*5/100/12
 		frappe.db.sql("""delete from `tabPayroll Period`""")
 		frappe.db.sql("""delete from `tabSalary Component`""")
+		frappe.db.sql("""delete from `tabAdditional Salary`""")
 
 		payroll_period = create_payroll_period()
 
diff --git a/erpnext/payroll/doctype/salary_structure/salary_structure.js b/erpnext/payroll/doctype/salary_structure/salary_structure.js
index ca458f9..ad93a2f 100755
--- a/erpnext/payroll/doctype/salary_structure/salary_structure.js
+++ b/erpnext/payroll/doctype/salary_structure/salary_structure.js
@@ -35,7 +35,9 @@
 
 			d.show()
 		});
-		frm.get_field("conditions_and_formula_variable_and_example").$wrapper.append(frm.doc.filters_html).append(help_button)
+		let help_button_wrapper = frm.get_field("conditions_and_formula_variable_and_example").$wrapper;
+		help_button_wrapper.empty();
+		help_button_wrapper.append(frm.doc.filters_html).append(help_button)
 
 		frm.toggle_reqd(['payroll_frequency'], !frm.doc.salary_slip_based_on_timesheet)
 
diff --git a/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.py b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.py
index 3bad587..8a79416 100644
--- a/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.py
+++ b/erpnext/payroll/report/income_tax_deductions/income_tax_deductions.py
@@ -6,8 +6,8 @@
 from frappe import _
 
 def execute(filters=None):
-	columns = get_columns(filters)
 	data = get_data(filters)
+	columns = get_columns(filters) if len(data) else []
 
 	return columns, data
 
@@ -78,8 +78,11 @@
 	if filters.get("company"):
 		conditions.append("sal.company = '%s' " % (filters["company"]) )
 
-	if filters.get("period"):
-		conditions.append("month(sal.start_date) = '%s' " % (filters["period"]))
+	if filters.get("month"):
+		conditions.append("month(sal.start_date) = '%s' " % (filters["month"]))
+
+	if filters.get("year"):
+		conditions.append("year(start_date) = '%s' " % (filters["year"]))
 
 	return " and ".join(conditions)
 
@@ -96,6 +99,9 @@
 
 	component_types = [comp_type[0] for comp_type in component_types]
 
+	if not len(component_types):
+		return []
+
 	conditions = get_conditions(filters)
 
 	entry = frappe.db.sql(""" select sal.employee, sal.employee_name, sal.posting_date, ded.salary_component, ded.amount,sal.gross_pay
diff --git a/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py
index 073bd91..d09745c 100644
--- a/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py
+++ b/erpnext/payroll/report/salary_payments_via_ecs/salary_payments_via_ecs.py
@@ -84,9 +84,11 @@
 	if filters.get("company"):
 		conditions.append("company = '%s' " % (filters["company"]) )
 
-	if filters.get("period"):
-		conditions.append("month(start_date) = '%s' " % (filters["period"]))
-		conditions.append("year(start_date) = '%s' " % (frappe.utils.getdate().year))
+	if filters.get("month"):
+		conditions.append("month(start_date) = '%s' " % (filters["month"]))
+
+	if filters.get("year"):
+		conditions.append("year(start_date) = '%s' " % (filters["year"]))
 
 	return " and ".join(conditions)
 
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index ca897dd..905f6fb 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -159,6 +159,26 @@
 				};
 			});
 		}
+		if (this.frm.fields_dict["items"].grid.get_field("cost_center")) {
+			this.frm.set_query("cost_center", "items", function(doc) {
+				return {
+					filters: {
+						"company": doc.company,
+						"is_group": 0
+					}
+				};
+			});
+		}
+
+		if (this.frm.fields_dict["items"].grid.get_field("expense_account")) {
+			this.frm.set_query("expense_account", "items", function(doc) {
+				return {
+					filters: {
+						"company": doc.company
+					}
+				};
+			});
+		}
 
 		if(frappe.meta.get_docfield(this.frm.doc.doctype, "pricing_rules")) {
 			this.frm.set_indicator_formatter('pricing_rule', function(doc) {
diff --git a/erpnext/public/js/salary_slip_deductions_report_filters.js b/erpnext/public/js/salary_slip_deductions_report_filters.js
index 2420379..2b30e65 100644
--- a/erpnext/public/js/salary_slip_deductions_report_filters.js
+++ b/erpnext/public/js/salary_slip_deductions_report_filters.js
@@ -11,8 +11,8 @@
 			default: frappe.defaults.get_user_default("Company"),
 		},
 		{
-			fieldname: "period",
-			label: __("Period"),
+			fieldname: "month",
+			label: __("Month"),
 			fieldtype: "Select",
 			reqd: 1 ,
 			options: [
@@ -32,6 +32,12 @@
 			default: frappe.datetime.str_to_obj(frappe.datetime.get_today()).getMonth() + 1
 		},
 		{
+			fieldname:"year",
+			label: __("Year"),
+			fieldtype: "Select",
+			reqd: 1
+		},
+		{
 			fieldname: "department",
 			label: __("Department"),
 			fieldtype: "Link",
@@ -43,5 +49,18 @@
 			fieldtype: "Link",
 			options: "Branch",
 		}
-	]
+	],
+
+	"onload": function() {
+		return  frappe.call({
+			method: "erpnext.regional.report.provident_fund_deductions.provident_fund_deductions.get_years",
+			callback: function(r) {
+				var year_filter = frappe.query_report.get_filter('year');
+				year_filter.df.options = r.message;
+				year_filter.df.default = r.message.split("\n")[0];
+				year_filter.refresh();
+				year_filter.set_input(year_filter.df.default);
+			}
+		});
+	}
 }
\ No newline at end of file
diff --git a/erpnext/regional/report/datev/datev.py b/erpnext/regional/report/datev/datev.py
index a8e40cc..7fec94e 100644
--- a/erpnext/regional/report/datev/datev.py
+++ b/erpnext/regional/report/datev/datev.py
@@ -8,17 +8,18 @@
   all required columns. Used to import the data into the DATEV Software.
 """
 from __future__ import unicode_literals
+
 import datetime
 import json
-import zlib
 import zipfile
 import six
+import frappe
+import pandas as pd
+
+from frappe import _
 from csv import QUOTE_NONNUMERIC
 from six import BytesIO
 from six import string_types
-import frappe
-from frappe import _
-import pandas as pd
 from .datev_constants import DataCategory
 from .datev_constants import Transactions
 from .datev_constants import DebtorsCreditors
@@ -130,8 +131,10 @@
 		SELECT
 
 			acc.account_number as 'Konto',
-			cus.customer_name as 'Name (Adressatentyp Unternehmen)',
-			case cus.customer_type when 'Individual' then 1 when 'Company' then 2 else 0 end as 'Adressatentyp',
+			CASE cus.customer_type WHEN 'Company' THEN cus.customer_name ELSE null END as 'Name (Adressatentyp Unternehmen)',
+			CASE cus.customer_type WHEN 'Individual' THEN con.last_name ELSE null END as 'Name (Adressatentyp natürl. Person)',
+			CASE cus.customer_type WHEN 'Individual' THEN con.first_name ELSE null END as 'Vorname (Adressatentyp natürl. Person)',
+			CASE cus.customer_type WHEN 'Individual' THEN '1' WHEN 'Company' THEN '2' ELSE '0' end as 'Adressatentyp',
 			adr.address_line1 as 'Straße',
 			adr.pincode as 'Postleitzahl',
 			adr.city as 'Ort',
@@ -140,8 +143,7 @@
 			con.email_id as 'E-Mail',
 			coalesce(con.mobile_no, con.phone) as 'Telefon',
 			cus.website as 'Internet',
-			cus.tax_id as 'Steuernummer',
-			ccl.credit_limit as 'Kreditlimit (Debitor)'
+			cus.tax_id as 'Steuernummer'
 
 		FROM `tabParty Account` par
 
@@ -160,10 +162,6 @@
 			left join `tabContact` con
 			on con.name = cus.customer_primary_contact
 
-			left join `tabCustomer Credit Limit` ccl
-			on ccl.parent = cus.name
-			and ccl.company = par.company
-
 		WHERE par.company = %(company)s
 		AND par.parenttype = 'Customer'""", filters, as_dict=1)
 
@@ -179,8 +177,10 @@
 		SELECT
 
 			acc.account_number as 'Konto',
-			sup.supplier_name as 'Name (Adressatentyp Unternehmen)',
-			case sup.supplier_type when 'Individual' then '1' when 'Company' then '2' else '0' end as 'Adressatentyp',
+			CASE sup.supplier_type WHEN 'Company' THEN sup.supplier_name ELSE null END as 'Name (Adressatentyp Unternehmen)',
+			CASE sup.supplier_type WHEN 'Individual' THEN con.last_name ELSE null END as 'Name (Adressatentyp natürl. Person)',
+			CASE sup.supplier_type WHEN 'Individual' THEN con.first_name ELSE null END as 'Vorname (Adressatentyp natürl. Person)',
+			CASE sup.supplier_type WHEN 'Individual' THEN '1' WHEN 'Company' THEN '2' ELSE '0' end as 'Adressatentyp',
 			adr.address_line1 as 'Straße',
 			adr.pincode as 'Postleitzahl',
 			adr.city as 'Ort',
@@ -226,9 +226,18 @@
 
 
 def get_account_names(filters):
-	return frappe.get_list("Account", 
-		fields=["account_number as Konto", "name as Kontenbeschriftung"], 
-		filters={"company": filters.get("company"), "is_group": "0"})
+	return frappe.db.sql("""
+		SELECT
+
+			account_number as 'Konto',
+			LEFT(account_name, 40) as 'Kontenbeschriftung',
+			'de-DE' as 'Sprach-ID'
+
+		FROM `tabAccount`
+		WHERE company = %(company)s
+		AND is_group = 0
+		AND account_number != ''
+	""", filters, as_dict=1)
 
 
 def get_datev_csv(data, filters, csv_class):
@@ -287,9 +296,7 @@
 
 
 def get_header(filters, csv_class):
-	coa = frappe.get_value("Company", filters.get("company"), "chart_of_accounts")
-	description = filters.get("voucher_type", csv_class.FORMAT_NAME)
-	coa_used = "04" if "SKR04" in coa else ("03" if "SKR03" in coa else "")
+	description = filters.get('voucher_type', csv_class.FORMAT_NAME)
 
 	header = [
 		# DATEV format
@@ -316,19 +323,19 @@
 		# J = Imported by -- stays empty
 		'',
 		# K = Tax consultant number (Beraternummer)
-		frappe.get_value("DATEV Settings", filters.get("company"), "consultant_number"),
+		filters.get('consultant_number', '0000000'),
 		# L = Tax client number (Mandantennummer)
-		frappe.get_value("DATEV Settings", filters.get("company"), "client_number"),
+		filters.get('client_number', '00000'),
 		# M = Start of the fiscal year (Wirtschaftsjahresbeginn)
 		frappe.utils.formatdate(frappe.defaults.get_user_default("year_start_date"), "yyyyMMdd"),
 		# N = Length of account numbers (Sachkontenlänge)
-		'4',
+		'%d' % filters.get('acc_len', 4),
 		# O = Transaction batch start date (YYYYMMDD)
-		frappe.utils.formatdate(filters.get('from_date'), "yyyyMMdd"),
+		frappe.utils.formatdate(filters.get('from_date'), "yyyyMMdd") if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
 		# P = Transaction batch end date (YYYYMMDD)
-		frappe.utils.formatdate(filters.get('to_date'), "yyyyMMdd"),
+		frappe.utils.formatdate(filters.get('to_date'), "yyyyMMdd") if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
 		# Q = Description (for example, "Sales Invoice") Max. 30 chars
-		'"{}"'.format(_(description)),
+		'"{}"'.format(_(description)) if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
 		# R = Diktatkürzel
 		'',
 		# S = Buchungstyp
@@ -343,12 +350,12 @@
 		#	40 = Kalkulatorik
 		#	11 = Reserviert
 		#	12 = Reserviert
-		'0',
+		'0' if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
 		# U = Festschreibung
 		# TODO: Filter by Accounting Period. In export for closed Accounting Period, this will be "1"
 		'0',
 		# V = Default currency, for example, "EUR"
-		'"%s"' % frappe.get_value("Company", filters.get("company"), "default_currency"),
+		'"%s"' % filters.get('default_currency', 'EUR') if csv_class.DATA_CATEGORY == DataCategory.TRANSACTIONS else '',
 		# reserviert
 		'',
 		# Derivatskennzeichen
@@ -358,7 +365,7 @@
 		# reserviert
 		'',
 		# SKR
-		'"%s"' % coa_used,
+		'"%s"' % filters.get('skr', '04'),
 		# Branchen-Lösungs-ID
 		'',
 		# reserviert
@@ -389,6 +396,18 @@
 
 	validate(filters)
 
+	# set chart of accounts used
+	coa = frappe.get_value('Company', filters.get('company'), 'chart_of_accounts')
+	filters['skr'] = '04' if 'SKR04' in coa else ('03' if 'SKR03' in coa else '')
+
+	# set account number length
+	account_numbers = frappe.get_list('Account', fields=['account_number'], filters={'is_group': 0, 'account_number': ('!=', '')})
+	filters['acc_len'] = max([len(a.account_number) for a in account_numbers])
+
+	filters['consultant_number'] = frappe.get_value('DATEV Settings', filters.get('company'), 'consultant_number')
+	filters['client_number'] = frappe.get_value('DATEV Settings', filters.get('company'), 'client_number')
+	filters['default_currency'] = frappe.get_value('Company', filters.get('company'), 'default_currency')
+
 	# This is where my zip will be written
 	zip_buffer = BytesIO()
 	# This is my zip file
diff --git a/erpnext/regional/report/datev/datev_constants.py b/erpnext/regional/report/datev/datev_constants.py
index a059ed3..e063703 100644
--- a/erpnext/regional/report/datev/datev_constants.py
+++ b/erpnext/regional/report/datev/datev_constants.py
@@ -465,60 +465,71 @@
 		"label": "Umsatz (ohne Soll/Haben-Kz)",
 		"fieldname": "Umsatz (ohne Soll/Haben-Kz)",
 		"fieldtype": "Currency",
+		"width": 100
 	},
 	{
 		"label": "Soll/Haben-Kennzeichen",
 		"fieldname": "Soll/Haben-Kennzeichen",
 		"fieldtype": "Data",
+		"width": 100
 	},
 	{
 		"label": "Konto",
 		"fieldname": "Konto",
 		"fieldtype": "Data",
+		"width": 100
 	},
 	{
 		"label": "Gegenkonto (ohne BU-Schlüssel)",
 		"fieldname": "Gegenkonto (ohne BU-Schlüssel)",
 		"fieldtype": "Data",
+		"width": 100
 	},
 	{
 		"label": "Belegdatum",
 		"fieldname": "Belegdatum",
 		"fieldtype": "Date",
+		"width": 100
 	},
 	{
 		"label": "Belegfeld 1",
 		"fieldname": "Belegfeld 1",
 		"fieldtype": "Data",
+		"width": 150
 	},
 	{
 		"label": "Buchungstext",
 		"fieldname": "Buchungstext",
 		"fieldtype": "Text",
+		"width": 300
 	},
 	{
 		"label": "Beleginfo - Art 1",
 		"fieldname": "Beleginfo - Art 1",
 		"fieldtype": "Link",
-		"options": "DocType"
+		"options": "DocType",
+		"width": 100
 	},
 	{
 		"label": "Beleginfo - Inhalt 1",
 		"fieldname": "Beleginfo - Inhalt 1",
 		"fieldtype": "Dynamic Link",
-		"options": "Beleginfo - Art 1"
+		"options": "Beleginfo - Art 1",
+		"width": 150
 	},
 	{
 		"label": "Beleginfo - Art 2",
 		"fieldname": "Beleginfo - Art 2",
 		"fieldtype": "Link",
-		"options": "DocType"
+		"options": "DocType",
+		"width": 100
 	},
 	{
 		"label": "Beleginfo - Inhalt 2",
 		"fieldname": "Beleginfo - Inhalt 2",
 		"fieldtype": "Dynamic Link",
-		"options": "Beleginfo - Art 2"
+		"options": "Beleginfo - Art 2",
+		"width": 150
 	}
 ]
 
diff --git a/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.py b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.py
index 900fe96..acde68a 100644
--- a/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.py
+++ b/erpnext/regional/report/professional_tax_deductions/professional_tax_deductions.py
@@ -7,8 +7,8 @@
 from erpnext.regional.report.provident_fund_deductions.provident_fund_deductions import get_conditions
 
 def execute(filters=None):
-	columns = get_columns(filters)
 	data = get_data(filters)
+	columns = get_columns(filters) if len(data) else []
 
 	return columns, data
 
@@ -45,6 +45,9 @@
 	component_type_dict = frappe._dict(frappe.db.sql(""" select name, component_type from `tabSalary Component`
 		where component_type = 'Professional Tax' """))
 
+	if not len(component_type_dict):
+		return []
+
 	conditions = get_conditions(filters)
 
 	entry = frappe.db.sql(""" select sal.employee, sal.employee_name, ded.salary_component, ded.amount
diff --git a/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.py b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.py
index 9f58957..084890e 100644
--- a/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.py
+++ b/erpnext/regional/report/provident_fund_deductions/provident_fund_deductions.py
@@ -3,11 +3,12 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe.utils import getdate
 from frappe import _
 
 def execute(filters=None):
-	columns = get_columns(filters)
 	data = get_data(filters)
+	columns = get_columns(filters) if len(data) else []
 
 	return columns, data
 
@@ -71,10 +72,13 @@
 		conditions.append("sal.branch = '%s' " % (filters["branch"]) )
 
 	if filters.get("company"):
-		conditions.append("sal.company = '%s' " % (filters["company"]) )
+		conditions.append("sal.company = '%s' " % (filters["company"]))
 
-	if filters.get("period"):
-		conditions.append("month(sal.start_date) = '%s' " % (filters["period"]))
+	if filters.get("month"):
+		conditions.append("month(sal.start_date) = '%s' " % (filters["month"]))
+
+	if filters.get("year"):
+		conditions.append("year(start_date) = '%s' " % (filters["year"]))
 
 	if filters.get("mode_of_payment"):
 		conditions.append("sal.mode_of_payment = '%s' " % (filters["mode_of_payment"]))
@@ -114,6 +118,9 @@
 	component_type_dict = frappe._dict(frappe.db.sql(""" select name, component_type from `tabSalary Component`
 		where component_type in ('Provident Fund', 'Additional Provident Fund', 'Provident Fund Loan')"""))
 
+	if not len(component_type_dict):
+		return []
+
 	entry = frappe.db.sql(""" select sal.name, sal.employee, sal.employee_name, ded.salary_component, ded.amount
 		from `tabSalary Slip` sal, `tabSalary Detail` ded
 		where sal.name = ded.parent
@@ -150,4 +157,12 @@
 
 			data.append(employee)
 
-	return data
\ No newline at end of file
+	return data
+
+@frappe.whitelist()
+def get_years():
+	year_list = frappe.db.sql_list("""select distinct YEAR(end_date) from `tabSalary Slip` ORDER BY YEAR(end_date) DESC""")
+	if not year_list:
+		year_list = [getdate().year]
+
+	return "\n".join(str(year) for year in year_list)
\ No newline at end of file
diff --git a/erpnext/shopping_cart/product_info.py b/erpnext/shopping_cart/product_info.py
index 7c08f5b..29617a8 100644
--- a/erpnext/shopping_cart/product_info.py
+++ b/erpnext/shopping_cart/product_info.py
@@ -55,7 +55,7 @@
 
 def set_product_info_for_website(item):
 	"""set product price uom for website"""
-	product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True)
+	product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get("product_info")
 
 	if product_info:
 		item.update(product_info)
diff --git a/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.json b/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.json
index 07992b8..7eeb147 100644
--- a/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.json
+++ b/erpnext/stock/doctype/customs_tariff_number/customs_tariff_number.json
@@ -71,7 +71,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
    "translatable": 0, 
@@ -88,7 +88,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2018-09-12 09:30:03.951743", 
+ "modified": "2020-06-26 09:30:03.951743", 
  "modified_by": "Administrator", 
  "module": "Stock", 
  "name": "Customs Tariff Number", 
@@ -143,4 +143,4 @@
  "track_changes": 1, 
  "track_seen": 0, 
  "track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json
index d9f8b62..2be14c8 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.json
+++ b/erpnext/stock/doctype/serial_no/serial_no.json
@@ -1,7 +1,6 @@
 {
  "actions": [],
  "allow_import": 1,
- "allow_rename": 1,
  "autoname": "field:serial_no",
  "creation": "2013-05-16 10:59:15",
  "description": "Distinct unit of an Item",
@@ -427,7 +426,7 @@
  "icon": "fa fa-barcode",
  "idx": 1,
  "links": [],
- "modified": "2020-05-21 19:29:58.517772",
+ "modified": "2020-06-25 15:53:50.900855",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Serial No",