Merge pull request #22488 from rohitwaghchaure/fixed-letter-head-not-found
fix: letter head not found in opening invoice creation tool
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/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/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