From ac9a4fe03c40409af44f2f101d75968991a5f579 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Tue, 11 Jun 2019 14:25:44 +0530
Subject: [PATCH 01/49] feat: add tax and charges in expense claim
---
.../hr/doctype/expense_claim/expense_claim.js | 62 +++++++++++
.../doctype/expense_claim/expense_claim.json | 22 +++-
.../hr/doctype/expense_claim/expense_claim.py | 33 +++++-
.../expense_taxes_and_charges/__init__.py | 0
.../expense_taxes_and_charges.json | 103 ++++++++++++++++++
.../expense_taxes_and_charges.py | 10 ++
6 files changed, 227 insertions(+), 3 deletions(-)
create mode 100644 erpnext/hr/doctype/expense_taxes_and_charges/__init__.py
create mode 100644 erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
create mode 100644 erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 7c6abc7f94..0ff70cb680 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -157,6 +157,14 @@ frappe.ui.form.on("Expense Claim", {
}
};
});
+ // frm.set_query("taxes", "account_head", function(doc) {
+ // return {
+ // filters: [
+ // ['docstatus', '=', 1],
+ // ['company', '=', doc.company]
+ // ]
+ // };
+ // });
},
onload: function(frm) {
@@ -259,6 +267,18 @@ frappe.ui.form.on("Expense Claim", {
frm.events.get_advances(frm);
},
+ get_taxes: function(frm) {
+ if(frm.doc.taxes) {
+ frappe.call({
+ method: "calculate_taxes",
+ doc: frm.doc,
+ callback: (r) => {
+ refresh_field("taxes");
+ }
+ });
+ }
+ },
+
get_advances: function(frm) {
frappe.model.clear_table(frm.doc, "advances");
if (frm.doc.employee) {
@@ -298,6 +318,7 @@ frappe.ui.form.on("Expense Claim Detail", {
sanctioned_amount: function(frm, cdt, cdn) {
var doc = frm.doc;
cur_frm.cscript.calculate_total(doc,cdt,cdn);
+ frm.trigger("get_taxes");
}
});
@@ -332,6 +353,47 @@ frappe.ui.form.on("Expense Claim Advance", {
}
});
+frappe.ui.form.on("Expense Taxes and Charges", {
+ account_head: function(frm, cdt, cdn) {
+ var child = locals[cdt][cdn];
+ if(child.account_head && !child.description && !child.rate) {
+ // set description from account head
+ child.description = child.account_head.split(' - ').slice(0, -1).join(' - ');
+
+ // set the tax rate from account head
+ frappe.db.get_value("Account", child.account_head, "tax_rate").then((r) => {
+ if(r.message) {
+ frappe.model.set_value(cdt, cdn, 'rate', r.message.tax_rate);
+ }
+ });
+ refresh_field("taxes");
+ }
+ },
+
+ calculate_total: function(frm, cdt, cdn) {
+ var child = locals[cdt][cdn];
+ child.total = flt(frm.doc.total_sanctioned_amount) + flt(child.tax_amount);
+
+ refresh_field("taxes");
+ },
+
+ rate: function(frm, cdt, cdn) {
+ var child = locals[cdt][cdn];
+ if(!child.amount) {
+ child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100);
+ refresh_field("taxes");
+ }
+ frm.trigger("calculate_total", cdt, cdn)
+ },
+
+ tax_amount: function(frm, cdt, cdn) {
+ var child = locals[cdt][cdn];
+ child.rate = flt(child.tax_amount/frm.doc.total_sanctioned_amount) * 100;
+ frm.trigger("calculate_total", cdt, cdn)
+ refresh_field("taxes");
+ }
+});
+
cur_frm.fields_dict['task'].get_query = function(doc) {
return {
filters:{
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index 6e04644036..007e646815 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -4,6 +4,7 @@
"creation": "2013-01-10 16:34:14",
"doctype": "DocType",
"document_type": "Setup",
+ "engine": "InnoDB",
"field_order": [
"naming_series",
"employee",
@@ -18,6 +19,9 @@
"expense_details",
"expenses",
"sb1",
+ "taxes",
+ "net_total",
+ "section_break_16",
"posting_date",
"vehicle_log",
"task",
@@ -315,12 +319,28 @@
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "taxes",
+ "fieldtype": "Table",
+ "label": "Expense Taxes and Charges",
+ "options": "Expense Taxes and Charges"
+ },
+ {
+ "fieldname": "section_break_16",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "net_total",
+ "fieldtype": "Currency",
+ "label": "Net Total",
+ "read_only": 1
}
],
"icon": "fa fa-money",
"idx": 1,
"is_submittable": 1,
- "modified": "2019-05-25 22:53:31.682151",
+ "modified": "2019-06-11 13:21:42.386420",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index d6b0eca70e..c5b6ebe56b 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -12,6 +12,7 @@ from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
from erpnext.controllers.accounts_controller import AccountsController
from frappe.utils.csvutils import getlink
+from erpnext.accounts.utils import get_account_currency
class InvalidExpenseApproverError(frappe.ValidationError): pass
class ExpenseApproverIdentityError(frappe.ValidationError): pass
@@ -29,6 +30,7 @@ class ExpenseClaim(AccountsController):
self.set_expense_account(validate=True)
self.set_payable_account()
self.set_cost_center()
+ self.calculate_taxes()
self.set_status()
if self.task and not self.project:
self.project = frappe.db.get_value("Task", self.task, "project")
@@ -93,7 +95,7 @@ class ExpenseClaim(AccountsController):
elif self.project:
frappe.get_doc("Project", self.project).update_project()
- def make_gl_entries(self, cancel = False):
+ def make_gl_entries(self, cancel=False):
if flt(self.total_sanctioned_amount) > 0:
gl_entries = self.get_gl_entries()
make_gl_entries(gl_entries, cancel)
@@ -102,7 +104,7 @@ class ExpenseClaim(AccountsController):
gl_entry = []
self.validate_account_details()
- payable_amount = flt(self.total_sanctioned_amount) - flt(self.total_advance_amount)
+ payable_amount = flt(self.net_total) - flt(self.total_advance_amount)
# payable entry
if payable_amount:
@@ -170,8 +172,26 @@ class ExpenseClaim(AccountsController):
})
)
+ gl_entry = self.make_tax_gl_entries(gl_entry)
+
return gl_entry
+ def make_tax_gl_entries(self, gl_entries):
+ # tax table gl entries
+ for tax in self.get("taxes"):
+ account_currency = get_account_currency(tax.account_head)
+ gl_entries.append(
+ self.get_gl_dict({
+ "account": tax.account_head,
+ "debit": tax.tax_amount,
+ "against": self.employee,
+ "cost_center": self.cost_center,
+ "against_voucher_type": self.doctype,
+ "against_voucher": self.name
+ }, account_currency)
+ )
+ return gl_entries
+
def validate_account_details(self):
if not self.cost_center:
frappe.throw(_("Cost center is required to book an expense claim"))
@@ -193,6 +213,15 @@ class ExpenseClaim(AccountsController):
self.total_claimed_amount += flt(d.claim_amount)
self.total_sanctioned_amount += flt(d.sanctioned_amount)
+ def calculate_taxes(self):
+ for tax in self.taxes:
+ if tax.rate:
+ tax.tax_amount = flt(self.total_sanctioned_amount) * flt(tax.rate/100)
+ if tax.tax_amount:
+ tax.rate = flt(tax.tax_amount)/flt(self.total_sanctioned_amount) * 100
+ tax.total = flt(tax.tax_amount) + flt(self.total_sanctioned_amount)
+ self.net_total += tax.total
+
def update_task(self):
task = frappe.get_doc("Task", self.task)
task.update_total_expense_claim()
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/__init__.py b/erpnext/hr/doctype/expense_taxes_and_charges/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
new file mode 100644
index 0000000000..8caf0a975a
--- /dev/null
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
@@ -0,0 +1,103 @@
+{
+ "autoname": "hash",
+ "creation": "2019-06-03 11:42:33.123976",
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "account_head",
+ "cost_center",
+ "col_break1",
+ "rate",
+ "description",
+ "section_break_6",
+ "tax_amount",
+ "column_break_8",
+ "total"
+ ],
+ "fields": [
+ {
+ "fieldname": "col_break1",
+ "fieldtype": "Column Break"
+ },
+ {
+ "columns": 2,
+ "fieldname": "account_head",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Account Head",
+ "oldfieldname": "account_head",
+ "oldfieldtype": "Link",
+ "options": "Account",
+ "reqd": 1
+ },
+ {
+ "default": ":Company",
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "label": "Cost Center",
+ "oldfieldname": "cost_center",
+ "oldfieldtype": "Link",
+ "options": "Cost Center"
+ },
+ {
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description",
+ "oldfieldname": "description",
+ "oldfieldtype": "Small Text",
+ "print_width": "300px",
+ "reqd": 1,
+ "width": "300px"
+ },
+ {
+ "columns": 2,
+ "fieldname": "rate",
+ "fieldtype": "Float",
+ "in_list_view": 1,
+ "label": "Rate",
+ "oldfieldname": "rate",
+ "oldfieldtype": "Currency"
+ },
+ {
+ "columns": 2,
+ "fieldname": "tax_amount",
+ "fieldtype": "Currency",
+ "in_list_view": 1,
+ "label": "Amount",
+ "oldfieldname": "tax_amount",
+ "oldfieldtype": "Currency",
+ "options": "currency"
+ },
+ {
+ "columns": 2,
+ "fieldname": "total",
+ "fieldtype": "Currency",
+ "in_list_view": 1,
+ "label": "Total",
+ "oldfieldname": "total",
+ "oldfieldtype": "Currency",
+ "options": "currency",
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_6",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "column_break_8",
+ "fieldtype": "Column Break"
+ }
+ ],
+ "istable": 1,
+ "modified": "2019-06-11 14:19:34.780611",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Expense Taxes and Charges",
+ "owner": "Administrator",
+ "permissions": [],
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py
new file mode 100644
index 0000000000..4103bef1ff
--- /dev/null
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExpenseTaxesandCharges(Document):
+ pass
From 444313bdfcd2b1b06e2590c8db9d9c5cf827cb0d Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Wed, 12 Jun 2019 12:52:02 +0530
Subject: [PATCH 02/49] feat: change the claim amount in expenses to amount
---
erpnext/demo/user/hr.py | 4 ++--
.../hr/doctype/expense_claim/expense_claim.js | 6 +++---
.../doctype/expense_claim/expense_claim.json | 21 ++++++++++++-------
.../hr/doctype/expense_claim/expense_claim.py | 9 ++++----
.../expense_claim/test_expense_claim.js | 2 +-
.../expense_claim/test_expense_claim.py | 6 +++---
.../expense_claim_detail.json | 6 +++---
erpnext/hr/doctype/vehicle_log/vehicle_log.py | 8 +++----
8 files changed, 34 insertions(+), 28 deletions(-)
diff --git a/erpnext/demo/user/hr.py b/erpnext/demo/user/hr.py
index 79f3c19287..0211bc8a90 100644
--- a/erpnext/demo/user/hr.py
+++ b/erpnext/demo/user/hr.py
@@ -97,7 +97,7 @@ def get_expenses():
"expense_date": frappe.flags.current_date,
"expense_type": expense_type.name,
"default_account": expense_type.default_account or "Miscellaneous Expenses - WPL",
- "claim_amount": claim_amount,
+ "amount": claim_amount,
"sanctioned_amount": claim_amount
})
@@ -107,7 +107,7 @@ def update_sanctioned_amount(expense_claim):
for expense in expense_claim.expenses:
sanctioned_amount = random.randint(1,20)*10
- if sanctioned_amount < expense.claim_amount:
+ if sanctioned_amount < expense.amount:
expense.sanctioned_amount = sanctioned_amount
def get_timesheet_based_salary_slip_employee():
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 0ff70cb680..6425b95d7e 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -109,7 +109,7 @@ cur_frm.cscript.calculate_total = function(doc){
doc.total_claimed_amount = 0;
doc.total_sanctioned_amount = 0;
$.each((doc.expenses || []), function(i, d) {
- doc.total_claimed_amount += d.claim_amount;
+ doc.total_claimed_amount += d.amount;
doc.total_sanctioned_amount += d.sanctioned_amount;
});
@@ -308,10 +308,10 @@ frappe.ui.form.on("Expense Claim", {
});
frappe.ui.form.on("Expense Claim Detail", {
- claim_amount: function(frm, cdt, cdn) {
+ amount: function(frm, cdt, cdn) {
var child = locals[cdt][cdn];
var doc = frm.doc;
- frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.claim_amount);
+ frappe.model.set_value(cdt, cdn, 'sanctioned_amount', child.amount);
cur_frm.cscript.calculate_total(doc,cdt,cdn);
},
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index 007e646815..409bdc8615 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -13,20 +13,21 @@
"column_break_5",
"expense_approver",
"approval_status",
- "total_claimed_amount",
- "total_sanctioned_amount",
"is_paid",
"expense_details",
"expenses",
"sb1",
"taxes",
- "net_total",
+ "transactions_section",
+ "total_tax_amount",
+ "total_amount_reimbursed",
+ "total_sanctioned_amount",
+ "total_claimed_amount",
"section_break_16",
"posting_date",
"vehicle_log",
"task",
"cb1",
- "total_amount_reimbursed",
"remark",
"title",
"email_id",
@@ -331,16 +332,22 @@
"fieldtype": "Section Break"
},
{
- "fieldname": "net_total",
+ "fieldname": "transactions_section",
+ "fieldtype": "Section Break",
+ "label": "Transactions"
+ },
+ {
+ "fieldname": "total_tax_amount",
"fieldtype": "Currency",
- "label": "Net Total",
+ "label": "Total Tax Amount",
+ "options": "Company:company:default_currency",
"read_only": 1
}
],
"icon": "fa fa-money",
"idx": 1,
"is_submittable": 1,
- "modified": "2019-06-11 13:21:42.386420",
+ "modified": "2019-06-12 12:32:13.775009",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index c5b6ebe56b..07e711939c 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -172,11 +172,11 @@ class ExpenseClaim(AccountsController):
})
)
- gl_entry = self.make_tax_gl_entries(gl_entry)
+ self.add_tax_gl_entries(gl_entry)
return gl_entry
- def make_tax_gl_entries(self, gl_entries):
+ def add_tax_gl_entries(self, gl_entries):
# tax table gl entries
for tax in self.get("taxes"):
account_currency = get_account_currency(tax.account_head)
@@ -190,7 +190,6 @@ class ExpenseClaim(AccountsController):
"against_voucher": self.name
}, account_currency)
)
- return gl_entries
def validate_account_details(self):
if not self.cost_center:
@@ -210,7 +209,7 @@ class ExpenseClaim(AccountsController):
if self.approval_status == 'Rejected':
d.sanctioned_amount = 0.0
- self.total_claimed_amount += flt(d.claim_amount)
+ self.total_claimed_amount += flt(d.amount)
self.total_sanctioned_amount += flt(d.sanctioned_amount)
def calculate_taxes(self):
@@ -253,7 +252,7 @@ class ExpenseClaim(AccountsController):
def validate_sanctioned_amount(self):
for d in self.get('expenses'):
- if flt(d.sanctioned_amount) > flt(d.claim_amount):
+ if flt(d.sanctioned_amount) > flt(d.amount):
frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx))
def set_expense_account(self, validate=False):
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.js b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
index 070474e10f..d0c43d3be4 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
@@ -17,7 +17,7 @@ QUnit.test("Test: Expense Claim [HR]", function (assert) {
d.expense_date = '2017-08-01',
d.expense_type = 'Test Expense Type 1',
d.description = 'This is just to test Expense Claim',
- d.claim_amount = 2000,
+ d.amount = 2000,
d.sanctioned_amount=2000,
refresh_field('expenses');
},
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index 075bc63345..6fc2a83ebd 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -89,7 +89,7 @@ class TestExpenseClaim(unittest.TestCase):
"payable_account": payable_account,
"approval_status": "Rejected",
"expenses":
- [{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 300, "sanctioned_amount": 200 }]
+ [{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "amount": 300, "sanctioned_amount": 200 }]
})
expense_claim.submit()
@@ -102,7 +102,7 @@ class TestExpenseClaim(unittest.TestCase):
def get_payable_account(company):
return frappe.get_cached_value('Company', company, 'default_payable_account')
-def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company, account, project=None, task_name=None):
+def make_expense_claim(payable_account,amount, sanctioned_amount, company, account, project=None, task_name=None):
expense_claim = frappe.get_doc({
"doctype": "Expense Claim",
"employee": "_T-Employee-00001",
@@ -110,7 +110,7 @@ def make_expense_claim(payable_account,claim_amount, sanctioned_amount, company,
"approval_status": "Approved",
"company": company,
"expenses":
- [{ "expense_type": "Travel", "default_account": account, "claim_amount": claim_amount, "sanctioned_amount": sanctioned_amount }]
+ [{ "expense_type": "Travel", "default_account": account, "amount": amount, "sanctioned_amount": sanctioned_amount }]
})
if project:
expense_claim.project = project
diff --git a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
index d4e70575e9..b23fb6af0f 100644
--- a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
+++ b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
@@ -253,7 +253,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "claim_amount",
+ "fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -262,7 +262,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Claim Amount",
+ "label": "Amount",
"length": 0,
"no_copy": 0,
"oldfieldname": "claim_amount",
@@ -360,7 +360,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2019-02-24 08:41:36.122565",
+ "modified": "2019-06-10 08:41:36.122565",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim Detail",
diff --git a/erpnext/hr/doctype/vehicle_log/vehicle_log.py b/erpnext/hr/doctype/vehicle_log/vehicle_log.py
index ceea4933f3..df633611be 100644
--- a/erpnext/hr/doctype/vehicle_log/vehicle_log.py
+++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.py
@@ -18,11 +18,11 @@ class VehicleLog(Document):
if (service_detail.service_item or service_detail.type or service_detail.frequency or service_detail.expense_amount):
if not (service_detail.service_item and service_detail.type and service_detail.frequency and service_detail.expense_amount):
frappe.throw(_("Service Item,Type,frequency and expense amount are required"))
-
+
def on_submit(self):
frappe.db.sql("update `tabVehicle` set last_odometer=%s where license_plate=%s",
(self.odometer, self.license_plate))
-
+
@frappe.whitelist()
def get_make_model(license_plate):
vehicle=frappe.get_doc("Vehicle",license_plate)
@@ -41,7 +41,7 @@ def make_expense_claim(docname):
for serdetail in vehicle_log.service_detail:
total_exp_amt = total_exp_amt + serdetail.expense_amount
return total_exp_amt
-
+
vehicle_log = frappe.get_doc("Vehicle Log", docname)
exp_claim = frappe.new_doc("Expense Claim")
exp_claim.employee=vehicle_log.employee
@@ -52,6 +52,6 @@ def make_expense_claim(docname):
exp_claim.append("expenses",{
"expense_date":vehicle_log.date,
"description":_("Vehicle Expenses"),
- "claim_amount":total_claim_amt
+ "amount":total_claim_amt
})
return exp_claim.as_dict()
From ddea50fa223ce8caf9407ee280251bd87f914012 Mon Sep 17 00:00:00 2001
From: Rohan Bansal
Date: Tue, 11 Jun 2019 14:44:45 +0530
Subject: [PATCH 03/49] fix(stock): Remove hardcoded validation for Item
---
erpnext/stock/doctype/item/item.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 48693359fe..1a88473b1b 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -67,8 +67,6 @@ class Item(WebsiteGenerator):
from frappe.model.naming import set_name_by_naming_series
set_name_by_naming_series(self)
self.item_code = self.name
- elif not self.item_code:
- msgprint(_("Item Code is mandatory because Item is not automatically numbered"), raise_exception=1)
self.item_code = strip(self.item_code)
self.name = self.item_code
From a1d354e14752ef1ee2faee52f9239fd7b9b3ef81 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Wed, 12 Jun 2019 18:18:38 +0530
Subject: [PATCH 04/49] feat: add grand total field
---
.../hr/doctype/expense_claim/expense_claim.js | 46 +++++++++++--------
.../doctype/expense_claim/expense_claim.json | 29 ++++++++----
.../hr/doctype/expense_claim/expense_claim.py | 32 ++++++-------
3 files changed, 64 insertions(+), 43 deletions(-)
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 6425b95d7e..4a61963d49 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -112,9 +112,6 @@ cur_frm.cscript.calculate_total = function(doc){
doc.total_claimed_amount += d.amount;
doc.total_sanctioned_amount += d.sanctioned_amount;
});
-
- refresh_field("total_claimed_amount");
- refresh_field('total_sanctioned_amount');
};
cur_frm.cscript.calculate_total_amount = function(doc,cdt,cdn){
@@ -157,14 +154,14 @@ frappe.ui.form.on("Expense Claim", {
}
};
});
- // frm.set_query("taxes", "account_head", function(doc) {
- // return {
- // filters: [
- // ['docstatus', '=', 1],
- // ['company', '=', doc.company]
- // ]
- // };
- // });
+ frm.set_query("account_head", "taxes", function(doc) {
+ return {
+ filters: [
+ ['company', '=', doc.company],
+ ['account_type', 'in', ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation"]]
+ ]
+ };
+ });
},
onload: function(frm) {
@@ -205,6 +202,12 @@ frappe.ui.form.on("Expense Claim", {
}
},
+ calculate_grand_total: function(frm) {
+ var grand_total = flt(frm.doc.total_sanctioned_amount) + flt(frm.doc.total_taxes_and_charges) - flt(frm.doc.total_advance_amount);
+ frm.set_value("grand_total", grand_total);
+ frm.refresh_fields();
+ },
+
make_payment_entry: function(frm) {
var method = "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry";
if(frm.doc.__onload && frm.doc.__onload.make_payment_via_journal_entry) {
@@ -319,6 +322,7 @@ frappe.ui.form.on("Expense Claim Detail", {
var doc = frm.doc;
cur_frm.cscript.calculate_total(doc,cdt,cdn);
frm.trigger("get_taxes");
+ frm.trigger("calculate_grand_total");
}
});
@@ -345,6 +349,7 @@ frappe.ui.form.on("Expense Claim Advance", {
child.advance_paid = r.message[0].paid_amount;
child.unclaimed_amount = flt(r.message[0].paid_amount) - flt(r.message[0].claimed_amount);
child.allocated_amount = flt(r.message[0].paid_amount) - flt(r.message[0].claimed_amount);
+ frm.trigger('calculate_grand_total');
refresh_field("advances");
}
}
@@ -370,27 +375,30 @@ frappe.ui.form.on("Expense Taxes and Charges", {
}
},
- calculate_total: function(frm, cdt, cdn) {
+ calculate_total_tax: function(frm, cdt, cdn) {
var child = locals[cdt][cdn];
child.total = flt(frm.doc.total_sanctioned_amount) + flt(child.tax_amount);
+ frm.trigger("calculate_tax_amount", cdt, cdn);
+ },
- refresh_field("taxes");
+ calculate_tax_amount: function(frm) {
+ frm.doc.total_taxes_and_charges = 0;
+ (frm.doc.taxes || []).forEach(function(d) {
+ frm.doc.total_taxes_and_charges += d.tax_amount;
+ });
+ frm.trigger("calculate_grand_total")
},
rate: function(frm, cdt, cdn) {
var child = locals[cdt][cdn];
if(!child.amount) {
child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100);
- refresh_field("taxes");
}
- frm.trigger("calculate_total", cdt, cdn)
+ frm.trigger("calculate_total_tax", cdt, cdn)
},
tax_amount: function(frm, cdt, cdn) {
- var child = locals[cdt][cdn];
- child.rate = flt(child.tax_amount/frm.doc.total_sanctioned_amount) * 100;
- frm.trigger("calculate_total", cdt, cdn)
- refresh_field("taxes");
+ frm.trigger("calculate_total_tax", cdt, cdn)
}
});
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index 409bdc8615..7b0d4943fc 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -19,10 +19,13 @@
"sb1",
"taxes",
"transactions_section",
- "total_tax_amount",
- "total_amount_reimbursed",
"total_sanctioned_amount",
"total_claimed_amount",
+ "total_advance_amount",
+ "column_break_17",
+ "total_amount_reimbursed",
+ "total_taxes_and_charges",
+ "grand_total",
"section_break_16",
"posting_date",
"vehicle_log",
@@ -44,8 +47,7 @@
"status",
"amended_from",
"advance_payments",
- "advances",
- "total_advance_amount"
+ "advances"
],
"fields": [
{
@@ -122,7 +124,6 @@
{
"fieldname": "total_sanctioned_amount",
"fieldtype": "Currency",
- "in_list_view": 1,
"label": "Total Sanctioned Amount",
"no_copy": 1,
"oldfieldname": "total_sanctioned_amount",
@@ -337,9 +338,21 @@
"label": "Transactions"
},
{
- "fieldname": "total_tax_amount",
+ "fieldname": "grand_total",
"fieldtype": "Currency",
- "label": "Total Tax Amount",
+ "in_list_view": 1,
+ "label": "Grand Total",
+ "options": "Company:company:default_currency",
+ "read_only": 1
+ },
+ {
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "total_taxes_and_charges",
+ "fieldtype": "Currency",
+ "label": "Total Taxes and Charges",
"options": "Company:company:default_currency",
"read_only": 1
}
@@ -347,7 +360,7 @@
"icon": "fa fa-money",
"idx": 1,
"is_submittable": 1,
- "modified": "2019-06-12 12:32:13.775009",
+ "modified": "2019-06-12 15:35:09.092603",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index 07e711939c..7f660a45b5 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -104,15 +104,13 @@ class ExpenseClaim(AccountsController):
gl_entry = []
self.validate_account_details()
- payable_amount = flt(self.net_total) - flt(self.total_advance_amount)
-
# payable entry
- if payable_amount:
+ if self.grand_total:
gl_entry.append(
self.get_gl_dict({
"account": self.payable_account,
- "credit": payable_amount,
- "credit_in_account_currency": payable_amount,
+ "credit": self.grand_total,
+ "credit_in_account_currency": self.grand_total,
"against": ",".join([d.default_account for d in self.expenses]),
"party_type": "Employee",
"party": self.employee,
@@ -146,15 +144,16 @@ class ExpenseClaim(AccountsController):
"against_voucher": self.name
})
)
+ self.add_tax_gl_entries(gl_entry)
- if self.is_paid and payable_amount:
+ if self.is_paid and self.grand_total:
# payment entry
payment_account = get_bank_cash_account(self.mode_of_payment, self.company).get("account")
gl_entry.append(
self.get_gl_dict({
"account": payment_account,
- "credit": payable_amount,
- "credit_in_account_currency": payable_amount,
+ "credit": self.grand_total,
+ "credit_in_account_currency": self.grand_total,
"against": self.employee
})
)
@@ -165,15 +164,13 @@ class ExpenseClaim(AccountsController):
"party_type": "Employee",
"party": self.employee,
"against": payment_account,
- "debit": payable_amount,
- "debit_in_account_currency": payable_amount,
+ "debit": self.grand_total,
+ "debit_in_account_currency": self.grand_total,
"against_voucher": self.name,
"against_voucher_type": self.doctype,
})
)
- self.add_tax_gl_entries(gl_entry)
-
return gl_entry
def add_tax_gl_entries(self, gl_entries):
@@ -184,11 +181,12 @@ class ExpenseClaim(AccountsController):
self.get_gl_dict({
"account": tax.account_head,
"debit": tax.tax_amount,
+ "debit_in_account_currency": tax.tax_amount,
"against": self.employee,
"cost_center": self.cost_center,
"against_voucher_type": self.doctype,
"against_voucher": self.name
- }, account_currency)
+ })
)
def validate_account_details(self):
@@ -213,13 +211,15 @@ class ExpenseClaim(AccountsController):
self.total_sanctioned_amount += flt(d.sanctioned_amount)
def calculate_taxes(self):
+ self.total_taxes_and_charges = 0
for tax in self.taxes:
if tax.rate:
tax.tax_amount = flt(self.total_sanctioned_amount) * flt(tax.rate/100)
- if tax.tax_amount:
- tax.rate = flt(tax.tax_amount)/flt(self.total_sanctioned_amount) * 100
+
tax.total = flt(tax.tax_amount) + flt(self.total_sanctioned_amount)
- self.net_total += tax.total
+ self.total_taxes_and_charges += flt(tax.tax_amount)
+
+ self.grand_total = flt(self.total_sanctioned_amount) + flt(self.total_taxes_and_charges) - flt(self.total_advance_amount)
def update_task(self):
task = frappe.get_doc("Task", self.task)
From 0a3ed374cddf38728ee5d4735d470041d707daaf Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Wed, 12 Jun 2019 20:03:22 +0530
Subject: [PATCH 05/49] test: validate tax based expense claim gl entries
---
.../doctype/expense_claim/expense_claim.json | 8 ++--
.../hr/doctype/expense_claim/expense_claim.py | 1 -
.../expense_claim/test_expense_claim.py | 41 +++++++++++++++----
3 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index 7b0d4943fc..db85037795 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -20,12 +20,12 @@
"taxes",
"transactions_section",
"total_sanctioned_amount",
- "total_claimed_amount",
+ "total_taxes_and_charges",
"total_advance_amount",
"column_break_17",
- "total_amount_reimbursed",
- "total_taxes_and_charges",
"grand_total",
+ "total_claimed_amount",
+ "total_amount_reimbursed",
"section_break_16",
"posting_date",
"vehicle_log",
@@ -360,7 +360,7 @@
"icon": "fa fa-money",
"idx": 1,
"is_submittable": 1,
- "modified": "2019-06-12 15:35:09.092603",
+ "modified": "2019-06-12 20:00:25.734108",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index 7f660a45b5..caeb2dd946 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -176,7 +176,6 @@ class ExpenseClaim(AccountsController):
def add_tax_gl_entries(self, gl_entries):
# tax table gl entries
for tax in self.get("taxes"):
- account_currency = get_account_currency(tax.account_head)
gl_entries.append(
self.get_gl_dict({
"account": tax.account_head,
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index 6fc2a83ebd..a42209f6ad 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -6,6 +6,7 @@ import frappe
import unittest
from frappe.utils import random_string, nowdate
from erpnext.hr.doctype.expense_claim.expense_claim import make_bank_entry
+from erpnext.accounts.doctype.account.test_account import create_account
test_records = frappe.get_test_records('Expense Claim')
test_dependencies = ['Employee']
@@ -26,7 +27,7 @@ class TestExpenseClaim(unittest.TestCase):
task_name = frappe.db.get_value("Task", {"project": "_Test Project 1"})
payable_account = get_payable_account("Wind Power LLC")
- make_expense_claim(payable_account, 300, 200, "Wind Power LLC","Travel Expenses - WP", "_Test Project 1", task_name)
+ make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP", "_Test Project 1", task_name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
@@ -62,7 +63,8 @@ class TestExpenseClaim(unittest.TestCase):
def test_expense_claim_gl_entry(self):
payable_account = get_payable_account("Wind Power LLC")
- expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP")
+ taxes = generate_taxes()
+ expense_claim = make_expense_claim(payable_account, 300, 200, "Wind Power LLC", "Travel Expenses - WP", do_not_submit=True, taxes=taxes)
expense_claim.submit()
gl_entries = frappe.db.sql("""select account, debit, credit
@@ -72,7 +74,8 @@ class TestExpenseClaim(unittest.TestCase):
self.assertTrue(gl_entries)
expected_values = dict((d[0], d) for d in [
- [payable_account, 0.0, 200.0],
+ ['CGST - WP',10.0, 0.0],
+ [payable_account, 0.0, 210.0],
["Travel Expenses - WP", 200.0, 0.0]
])
@@ -100,22 +103,44 @@ class TestExpenseClaim(unittest.TestCase):
self.assertEquals(len(gl_entry), 0)
def get_payable_account(company):
- return frappe.get_cached_value('Company', company, 'default_payable_account')
+ return frappe.get_cached_value('Company', company, 'default_payable_account')
-def make_expense_claim(payable_account,amount, sanctioned_amount, company, account, project=None, task_name=None):
- expense_claim = frappe.get_doc({
+def generate_taxes():
+ parent_account = frappe.db.get_value('Account',
+ {'company': "Wind Power LLC", 'is_group':1, 'account_type': 'Tax'},
+ 'name')
+ account = create_account(company="Wind Power LLC", account_name="CGST", account_type="Tax", parent_account=parent_account)
+ return {'taxes':[{
+ "account_head": account,
+ "rate": 0,
+ "description": "CGST",
+ "tax_amount": 10,
+ "total": 210
+ }]}
+
+def make_expense_claim(payable_account, amount, sanctioned_amount, company, account, project=None, task_name=None, do_not_submit=False, taxes=None):
+ expense_claim = {
"doctype": "Expense Claim",
"employee": "_T-Employee-00001",
"payable_account": payable_account,
"approval_status": "Approved",
"company": company,
"expenses":
- [{ "expense_type": "Travel", "default_account": account, "amount": amount, "sanctioned_amount": sanctioned_amount }]
- })
+ [{"expense_type": "Travel",
+ "default_account": account,
+ "amount": amount,
+ "sanctioned_amount": sanctioned_amount}]}
+ if taxes:
+ expense_claim.update(taxes)
+
+ expense_claim = frappe.get_doc(expense_claim)
+
if project:
expense_claim.project = project
if task_name:
expense_claim.task = task_name
+ if do_not_submit:
+ return expense_claim
expense_claim.submit()
return expense_claim
From f8bf57c95641034f6b91c7dff56fede81acb94d0 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Thu, 13 Jun 2019 18:09:23 +0530
Subject: [PATCH 06/49] fix: remove transaction section head
---
erpnext/hr/doctype/expense_claim/expense_claim.js | 6 +++---
erpnext/hr/doctype/expense_claim/expense_claim.json | 5 ++---
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 4a61963d49..9e78ca12c4 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -275,7 +275,7 @@ frappe.ui.form.on("Expense Claim", {
frappe.call({
method: "calculate_taxes",
doc: frm.doc,
- callback: (r) => {
+ callback: () => {
refresh_field("taxes");
}
});
@@ -386,7 +386,7 @@ frappe.ui.form.on("Expense Taxes and Charges", {
(frm.doc.taxes || []).forEach(function(d) {
frm.doc.total_taxes_and_charges += d.tax_amount;
});
- frm.trigger("calculate_grand_total")
+ frm.trigger("calculate_grand_total");
},
rate: function(frm, cdt, cdn) {
@@ -398,7 +398,7 @@ frappe.ui.form.on("Expense Taxes and Charges", {
},
tax_amount: function(frm, cdt, cdn) {
- frm.trigger("calculate_total_tax", cdt, cdn)
+ frm.trigger("calculate_total_tax", cdt, cdn);
}
});
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index db85037795..f0bc268e5d 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -334,8 +334,7 @@
},
{
"fieldname": "transactions_section",
- "fieldtype": "Section Break",
- "label": "Transactions"
+ "fieldtype": "Section Break"
},
{
"fieldname": "grand_total",
@@ -360,7 +359,7 @@
"icon": "fa fa-money",
"idx": 1,
"is_submittable": 1,
- "modified": "2019-06-12 20:00:25.734108",
+ "modified": "2019-06-13 18:05:52.530462",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",
From 6726dea88bdd59a17825d9947ec303de0a0a34a4 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Fri, 14 Jun 2019 11:17:17 +0530
Subject: [PATCH 07/49] style: change formatting
---
erpnext/hr/doctype/expense_claim/expense_claim.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 9e78ca12c4..deb6e1dc08 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -394,7 +394,7 @@ frappe.ui.form.on("Expense Taxes and Charges", {
if(!child.amount) {
child.tax_amount = flt(frm.doc.total_sanctioned_amount) * (flt(child.rate)/100);
}
- frm.trigger("calculate_total_tax", cdt, cdn)
+ frm.trigger("calculate_total_tax", cdt, cdn);
},
tax_amount: function(frm, cdt, cdn) {
From a5527225b694c6b95b5b4506df601b40388283e9 Mon Sep 17 00:00:00 2001
From: Anurag Mishra
Date: Fri, 14 Jun 2019 15:25:57 +0530
Subject: [PATCH 08/49] fix: requested changes
---
erpnext/patches.txt | 2 +-
erpnext/regional/india/setup.py | 2 +-
erpnext/setup/doctype/company/company.json | 7 +++++--
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 15fd82ea72..747177a3a7 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -602,6 +602,6 @@ erpnext.patches.v11_1.set_salary_details_submittable
erpnext.patches.v11_1.rename_depends_on_lwp
execute:frappe.delete_doc("Report", "Inactive Items")
erpnext.patches.v11_1.delete_scheduling_tool
-erpnext.patches.v12_0.make_custom_fields_for_bank_remittance
+erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019
execute:frappe.delete_doc_if_exists("Page", "support-analytics")
erpnext.patches.v12_0.make_item_manufacturer
\ No newline at end of file
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index f69c17e0c8..26fdb1a904 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -275,7 +275,7 @@ def make_custom_fields(update=True):
],
'Company': [
dict(fieldname='hra_section', label='HRA Settings',
- fieldtype='Section Break', insert_after='asset_received_but_not_billed'),
+ fieldtype='Section Break', insert_after='asset_received_but_not_billed', collapsible=1),
dict(fieldname='basic_component', label='Basic Component',
fieldtype='Link', options='Salary Component', insert_after='hra_section'),
dict(fieldname='hra_component', label='HRA Component',
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index fcccf5a973..d85fc45b46 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -170,9 +170,10 @@
"label": "Company Description"
},
{
+ "collapsible": 1,
"fieldname": "sales_settings",
"fieldtype": "Section Break",
- "label": "Sales"
+ "label": "Sales Settings"
},
{
"fieldname": "sales_monthly_history",
@@ -530,6 +531,7 @@
"options": "Account"
},
{
+ "collapsible": 1,
"fieldname": "fixed_asset_depreciation_settings",
"fieldtype": "Section Break",
"label": "Fixed Asset Depreciation Settings"
@@ -602,6 +604,7 @@
"options": "Role"
},
{
+ "collapsible": 1,
"description": "For reference only.",
"fieldname": "company_info",
"fieldtype": "Section Break",
@@ -708,7 +711,7 @@
"icon": "fa fa-building",
"idx": 1,
"image_field": "company_logo",
- "modified": "2019-06-13 18:03:14.764423",
+ "modified": "2019-06-14 14:36:11.363309",
"modified_by": "Administrator",
"module": "Setup",
"name": "Company",
From 8e99aaf6050afdf258343397c5e70109e89b56ea Mon Sep 17 00:00:00 2001
From: Faris Ansari
Date: Fri, 14 Jun 2019 20:06:54 +0530
Subject: [PATCH 09/49] fix: Add erpnext website theme import
---
erpnext/public/js/website_theme.js | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/erpnext/public/js/website_theme.js b/erpnext/public/js/website_theme.js
index 6c7edfa655..84de2f5b51 100644
--- a/erpnext/public/js/website_theme.js
+++ b/erpnext/public/js/website_theme.js
@@ -2,16 +2,13 @@
// MIT License. See license.txt
frappe.ui.form.on('Website Theme', {
- apply_custom_theme(frm) {
- let custom_theme = frm.doc.custom_theme;
- custom_theme = custom_theme.split('\n');
- if (
- frm.doc.apply_custom_theme
- && custom_theme.length === 2
- && custom_theme[1].includes('frappe/public/scss/website')
+ validate(frm) {
+ let theme_scss = frm.doc.theme_scss;
+ if (theme_scss.includes('frappe/public/scss/website')
+ && !theme_scss.includes('erpnext/public/scss/website')
) {
- frm.set_value('custom_theme',
- `$primary: #7575ff;\n@import "frappe/public/scss/website";\n@import "erpnext/public/scss/website";`);
+ frm.set_value('theme_scss',
+ `${frm.doc.theme_scss}\n@import "erpnext/public/scss/website";`);
}
}
});
From 7e3a98ba334b0f5c965459848d6b79892ddec970 Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Mon, 17 Jun 2019 12:44:49 +0530
Subject: [PATCH 10/49] fix: Is group filter fixes in dimensions
---
erpnext/public/js/utils/dimension_tree_filter.js | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js
index 16c1d4d248..f31b578b0b 100644
--- a/erpnext/public/js/utils/dimension_tree_filter.js
+++ b/erpnext/public/js/utils/dimension_tree_filter.js
@@ -14,9 +14,13 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => {
onload: function(frm) {
dimension_filters.then((dimensions) => {
dimensions.forEach((dimension) => {
- frm.set_query(dimension['fieldname'],{
- "is_group": 0
- });
+ frappe.model.with_doctype(dimension['document_type'], () => {
+ if (frappe.meta.has_field(dimension['document_type'], 'is_group')) {
+ frm.set_query(dimension['fieldname'],{
+ "is_group": 0
+ });
+ }
+ })
});
});
}
From d1e0f42fea2937d95e595534d023b9cc4a4914cd Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Mon, 17 Jun 2019 12:47:39 +0530
Subject: [PATCH 11/49] fix: Styling fix
---
erpnext/public/js/utils/dimension_tree_filter.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js
index f31b578b0b..ccca04df26 100644
--- a/erpnext/public/js/utils/dimension_tree_filter.js
+++ b/erpnext/public/js/utils/dimension_tree_filter.js
@@ -16,7 +16,7 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => {
dimensions.forEach((dimension) => {
frappe.model.with_doctype(dimension['document_type'], () => {
if (frappe.meta.has_field(dimension['document_type'], 'is_group')) {
- frm.set_query(dimension['fieldname'],{
+ frm.set_query(dimension['fieldname'], {
"is_group": 0
});
}
From 725f56faca7795fb74451cb8495a14b6cc7ec648 Mon Sep 17 00:00:00 2001
From: Rohit Waghchaure
Date: Mon, 17 Jun 2019 12:50:44 +0530
Subject: [PATCH 12/49] feat: delayed order reports
---
.../report/delayed_item_report/__init__.py | 0
.../delayed_item_report.js | 62 +++++++
.../delayed_item_report.json | 37 ++++
.../delayed_item_report.py | 168 ++++++++++++++++++
.../report/delayed_order_report/__init__.py | 0
.../delayed_order_report.js | 62 +++++++
.../delayed_order_report.json | 37 ++++
.../delayed_order_report.py | 83 +++++++++
8 files changed, 449 insertions(+)
create mode 100644 erpnext/stock/report/delayed_item_report/__init__.py
create mode 100644 erpnext/stock/report/delayed_item_report/delayed_item_report.js
create mode 100644 erpnext/stock/report/delayed_item_report/delayed_item_report.json
create mode 100644 erpnext/stock/report/delayed_item_report/delayed_item_report.py
create mode 100644 erpnext/stock/report/delayed_order_report/__init__.py
create mode 100644 erpnext/stock/report/delayed_order_report/delayed_order_report.js
create mode 100644 erpnext/stock/report/delayed_order_report/delayed_order_report.json
create mode 100644 erpnext/stock/report/delayed_order_report/delayed_order_report.py
diff --git a/erpnext/stock/report/delayed_item_report/__init__.py b/erpnext/stock/report/delayed_item_report/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.js b/erpnext/stock/report/delayed_item_report/delayed_item_report.js
new file mode 100644
index 0000000000..5d160b1519
--- /dev/null
+++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.js
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Delayed Item Report"] = {
+ "filters": [
+ {
+ fieldname: "company",
+ label: __("Company"),
+ fieldtype: "Link",
+ options: "Company",
+ default: frappe.defaults.get_default("company"),
+ reqd: 1
+ },
+ {
+ fieldname:"from_date",
+ label: __("From Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.month_start(),
+ reqd: 1
+ },
+ {
+ fieldname:"to_date",
+ label: __("To Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.now_date(),
+ reqd: 1
+ },
+ {
+ fieldname:"sales_order",
+ label: __("Sales Order"),
+ fieldtype: "Link",
+ options: "Sales Order",
+ },
+ {
+ fieldname:"customer",
+ label: __("Customer"),
+ fieldtype: "Link",
+ options: "Customer",
+ },
+ {
+ fieldname:"customer_group",
+ label: __("Customer Group"),
+ fieldtype: "Link",
+ options: "Customer Group",
+ },
+ {
+ fieldname:"item_group",
+ label: __("Item Group"),
+ fieldtype: "Link",
+ options: "Item Group",
+ },
+ {
+ fieldname:"based_on",
+ label: __("Based On"),
+ fieldtype: "Select",
+ options: ["Delivery Note", "Sales Invoice"],
+ default: "Delivery Note",
+ reqd: 1
+ },
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.json b/erpnext/stock/report/delayed_item_report/delayed_item_report.json
new file mode 100644
index 0000000000..f336cecf20
--- /dev/null
+++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.json
@@ -0,0 +1,37 @@
+{
+ "add_total_row": 0,
+ "creation": "2019-06-17 12:45:07.324014",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Gadgets International",
+ "modified": "2019-06-17 12:45:07.324014",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Delayed Item Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Delivery Note",
+ "report_name": "Delayed Item Report",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Sales User"
+ },
+ {
+ "role": "Stock Manager"
+ },
+ {
+ "role": "Stock User"
+ },
+ {
+ "role": "Maintenance User"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_item_report/delayed_item_report.py b/erpnext/stock/report/delayed_item_report/delayed_item_report.py
new file mode 100644
index 0000000000..7b968b89a7
--- /dev/null
+++ b/erpnext/stock/report/delayed_item_report/delayed_item_report.py
@@ -0,0 +1,168 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import date_diff
+
+def execute(filters=None, consolidated = False):
+ data, columns = DelayedItemReport(filters).run()
+
+ return data, columns
+
+class DelayedItemReport(object):
+ def __init__(self, filters=None):
+ self.filters = frappe._dict(filters or {})
+
+ def run(self):
+ return self.get_columns(), self.get_data() or []
+
+ def get_data(self, consolidated=False):
+ conditions = ""
+
+ doctype = self.filters.get("based_on")
+ child_doc= "%s Item" % doctype
+
+ if doctype == "Sales Invoice":
+ conditions = " and `tabSales Invoice`.update_stock = 1 and `tabSales Invoice`.is_pos = 0"
+
+ if self.filters.get("item_group"):
+ conditions += " and `tab%s`.item_group = %s" % (child_doc,
+ frappe.db.escape(self.filters.get("item_group")))
+
+ for field in ["customer", "customer_group", "company"]:
+ if self.filters.get(field):
+ conditions += " and `tab%s`.%s = %s" % (doctype,
+ field, frappe.db.escape(self.filters.get(field)))
+
+ sales_order_field = "against_sales_order"
+ if doctype == "Sales Invoice":
+ sales_order_field = "sales_order"
+
+ if self.filters.get("sales_order"):
+ conditions = " and `tab%s`.%s = '%s'" %(child_doc, sales_order_field, self.filters.get("sales_order"))
+
+ self.transactions = frappe.db.sql(""" SELECT `tab{child_doc}`.item_code, `tab{child_doc}`.item_name,
+ `tab{child_doc}`.item_group, `tab{child_doc}`.qty, `tab{child_doc}`.rate, `tab{child_doc}`.amount,
+ `tab{child_doc}`.so_detail, `tab{child_doc}`.{so_field} as sales_order,
+ `tab{doctype}`.customer, `tab{doctype}`.posting_date, `tab{doctype}`.name, `tab{doctype}`.grand_total
+ FROM `tab{child_doc}`, `tab{doctype}`
+ WHERE
+ `tab{child_doc}`.parent = `tab{doctype}`.name and `tab{doctype}`.docstatus = 1 and
+ `tab{doctype}`.posting_date between %(from_date)s and %(to_date)s and
+ `tab{child_doc}`.{so_field} is not null and `tab{child_doc}`.{so_field} != '' {cond}
+ """.format(cond=conditions, doctype=doctype, child_doc=child_doc, so_field=sales_order_field), {
+ 'from_date': self.filters.get('from_date'),
+ 'to_date': self.filters.get('to_date')
+ }, as_dict=1)
+
+ if self.transactions:
+ self.filter_transactions_data(consolidated)
+
+ return self.transactions
+
+ def filter_transactions_data(self, consolidated=False):
+ sales_orders = [d.sales_order for d in self.transactions]
+ doctype = "Sales Order"
+ filters = {'name': ('in', sales_orders)}
+
+ if not consolidated:
+ sales_order_items = [d.so_detail for d in self.transactions]
+ doctype = "Sales Order Item"
+ filters = {'parent': ('in', sales_orders), 'name': ('in', sales_order_items)}
+
+ so_data = {}
+ for d in frappe.get_all(doctype, filters = filters,
+ fields = ["delivery_date", "parent", "name"]):
+ key = d.name if consolidated else (d.parent, d.name)
+ if key not in so_data:
+ so_data.setdefault(key, d.delivery_date)
+
+ for row in self.transactions:
+ key = row.sales_order if consolidated else (row.sales_order, row.so_detail)
+ row.update({
+ 'delivery_date': so_data.get(key),
+ 'delayed_days': date_diff(row.posting_date, so_data.get(key))
+ })
+
+ return self.transactions
+
+ def get_columns(self):
+ based_on = self.filters.get("based_on")
+
+ return [{
+ "label": _(based_on),
+ "fieldname": "name",
+ "fieldtype": "Link",
+ "options": based_on,
+ "width": 100
+ },{
+ "label": _("Customer"),
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "options": "Customer",
+ "width": 100
+ },
+ {
+ "label": _("Expected Delivery Date"),
+ "fieldname": "delivery_date",
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "label": _("Actual Delivery Date"),
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "label": _("Item Code"),
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "options": "Item",
+ "width": 100
+ },
+ {
+ "label": _("Item Name"),
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "width": 100
+ },
+ {
+ "label": _("Quantity"),
+ "fieldname": "qty",
+ "fieldtype": "Float",
+ "width": 100
+ },
+ {
+ "label": _("Rate"),
+ "fieldname": "rate",
+ "fieldtype": "Currency",
+ "width": 100
+ },
+ {
+ "label": _("Amount"),
+ "fieldname": "amount",
+ "fieldtype": "Currency",
+ "width": 100
+ },
+ {
+ "label": _("Delayed Days"),
+ "fieldname": "delayed_days",
+ "fieldtype": "Int",
+ "width": 100
+ },
+ {
+ "label": _("Sales Order"),
+ "fieldname": "sales_order",
+ "fieldtype": "Link",
+ "options": "Sales Order",
+ "width": 100
+ },
+ {
+ "label": _("Customer PO"),
+ "fieldname": "po_no",
+ "fieldtype": "Data",
+ "width": 100
+ }]
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_order_report/__init__.py b/erpnext/stock/report/delayed_order_report/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.js b/erpnext/stock/report/delayed_order_report/delayed_order_report.js
new file mode 100644
index 0000000000..11752ae9fb
--- /dev/null
+++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.js
@@ -0,0 +1,62 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Delayed Order Report"] = {
+ "filters": [
+ {
+ fieldname: "company",
+ label: __("Company"),
+ fieldtype: "Link",
+ options: "Company",
+ default: frappe.defaults.get_default("company"),
+ reqd: 1
+ },
+ {
+ fieldname:"from_date",
+ label: __("From Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.month_start(),
+ reqd: 1
+ },
+ {
+ fieldname:"to_date",
+ label: __("To Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.now_date(),
+ reqd: 1
+ },
+ {
+ fieldname:"sales_order",
+ label: __("Sales Order"),
+ fieldtype: "Link",
+ options: "Sales Order",
+ },
+ {
+ fieldname:"customer",
+ label: __("Customer"),
+ fieldtype: "Link",
+ options: "Customer",
+ },
+ {
+ fieldname:"customer_group",
+ label: __("Customer Group"),
+ fieldtype: "Link",
+ options: "Customer Group",
+ },
+ {
+ fieldname:"item_group",
+ label: __("Item Group"),
+ fieldtype: "Link",
+ options: "Item Group",
+ },
+ {
+ fieldname:"based_on",
+ label: __("Based On"),
+ fieldtype: "Select",
+ options: ["Delivery Note", "Sales Invoice"],
+ default: "Delivery Note",
+ reqd: 1
+ },
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.json b/erpnext/stock/report/delayed_order_report/delayed_order_report.json
new file mode 100644
index 0000000000..29c27cb1a6
--- /dev/null
+++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.json
@@ -0,0 +1,37 @@
+{
+ "add_total_row": 0,
+ "creation": "2019-06-17 12:45:56.359322",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "letter_head": "Gadgets International",
+ "modified": "2019-06-17 12:45:56.359322",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Delayed Order Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Delivery Note",
+ "report_name": "Delayed Order Report",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Sales User"
+ },
+ {
+ "role": "Stock Manager"
+ },
+ {
+ "role": "Stock User"
+ },
+ {
+ "role": "Maintenance User"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/stock/report/delayed_order_report/delayed_order_report.py b/erpnext/stock/report/delayed_order_report/delayed_order_report.py
new file mode 100644
index 0000000000..d2a1a30d9e
--- /dev/null
+++ b/erpnext/stock/report/delayed_order_report/delayed_order_report.py
@@ -0,0 +1,83 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe import _
+from erpnext.stock.report.delayed_item_report.delayed_item_report import DelayedItemReport
+
+def execute(filters=None):
+ columns, data = [], []
+
+ columns, data = DelayedOrderReport(filters).run()
+
+ return columns, data
+
+class DelayedOrderReport(DelayedItemReport):
+ def run(self):
+ return self.get_columns(), self.get_data(consolidated=True) or []
+
+ def get_data(self, consolidated=False):
+ data = super(DelayedOrderReport, self).get_data(consolidated) or []
+
+ so_list = []
+ result = []
+ for d in data:
+ if d.sales_order not in so_list:
+ so_list.append(d.sales_order)
+ result.append(d)
+
+ return result
+
+ def get_columns(self):
+ based_on = self.filters.get("based_on")
+
+ return [{
+ "label": _(based_on),
+ "fieldname": "name",
+ "fieldtype": "Link",
+ "options": based_on,
+ "width": 100
+ },{
+ "label": _("Customer"),
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "options": "Customer",
+ "width": 100
+ },
+ {
+ "label": _("Expected Delivery Date"),
+ "fieldname": "delivery_date",
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "label": _("Actual Delivery Date"),
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "width": 100
+ },
+ {
+ "label": _("Amount"),
+ "fieldname": "grand_total",
+ "fieldtype": "Currency",
+ "width": 100
+ },
+ {
+ "label": _("Delayed Days"),
+ "fieldname": "delayed_days",
+ "fieldtype": "Int",
+ "width": 100
+ },
+ {
+ "label": _("Sales Order"),
+ "fieldname": "sales_order",
+ "fieldtype": "Link",
+ "options": "Sales Order",
+ "width": 100
+ },
+ {
+ "label": _("Customer PO"),
+ "fieldname": "po_no",
+ "fieldtype": "Data",
+ "width": 100
+ }]
\ No newline at end of file
From 4babfdb987bcba43f7d0ea9bf8820497b2a7414c Mon Sep 17 00:00:00 2001
From: Rohan Bansal
Date: Mon, 15 Apr 2019 15:34:38 +0530
Subject: [PATCH 13/49] fix(delivery): Add more context for dispatch
notification email + formatting fixes
---
.../doctype/delivery_trip/delivery_trip.py | 25 ++++++++++---------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index 01b4734bf5..bc8c7493d5 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -20,8 +20,7 @@ class DeliveryTrip(Document):
# Google Maps returns distances in meters by default
self.default_distance_uom = frappe.db.get_single_value("Global Defaults", "default_distance_unit") or "Meter"
self.uom_conversion_factor = frappe.db.get_value("UOM Conversion Factor",
- {"from_uom": "Meter", "to_uom": self.default_distance_uom},
- "value")
+ {"from_uom": "Meter", "to_uom": self.default_distance_uom}, "value")
def validate(self):
self.validate_stop_addresses()
@@ -139,7 +138,7 @@ class DeliveryTrip(Document):
# Include last leg in the final distance calculation
self.uom = self.default_distance_uom
total_distance = sum([leg.get("distance", {}).get("value", 0.0)
- for leg in directions.get("legs")]) # in meters
+ for leg in directions.get("legs")]) # in meters
self.total_distance = total_distance * self.uom_conversion_factor
else:
idx += len(route) - 1
@@ -358,8 +357,12 @@ def notify_customers(delivery_trip):
email_recipients = []
for stop in delivery_trip.delivery_stops:
- contact_info = frappe.db.get_value("Contact", stop.contact,
- ["first_name", "last_name", "email_id", "gender"], as_dict=1)
+ contact_info = frappe.db.get_value("Contact", stop.contact, ["first_name", "last_name", "email_id"], as_dict=1)
+
+ context.update({"items": []})
+ if stop.delivery_note:
+ items = frappe.get_all("Delivery Note Item", filters={"parent": stop.delivery_note, "docstatus": 1}, fields=["*"])
+ context.update({"items": items})
if contact_info and contact_info.email_id:
context.update(stop.as_dict())
@@ -369,9 +372,9 @@ def notify_customers(delivery_trip):
dispatch_template = frappe.get_doc("Email Template", dispatch_template_name)
frappe.sendmail(recipients=contact_info.email_id,
- subject=dispatch_template.subject,
- message=frappe.render_template(dispatch_template.response, context),
- attachments=get_attachments(stop))
+ subject=dispatch_template.subject,
+ message=frappe.render_template(dispatch_template.response, context),
+ attachments=get_attachments(stop))
stop.db_set("email_sent_to", contact_info.email_id)
email_recipients.append(contact_info.email_id)
@@ -388,9 +391,7 @@ def get_attachments(delivery_stop):
return []
dispatch_attachment = frappe.db.get_single_value("Delivery Settings", "dispatch_attachment")
- attachments = frappe.attach_print("Delivery Note",
- delivery_stop.delivery_note,
- file_name="Delivery Note",
- print_format=dispatch_attachment)
+ attachments = frappe.attach_print("Delivery Note", delivery_stop.delivery_note,
+ file_name="Delivery Note", print_format=dispatch_attachment)
return [attachments]
From 7efeffa66a391d70f871c5267dcc4ae310c34e1e Mon Sep 17 00:00:00 2001
From: Rohit Waghchaure
Date: Mon, 17 Jun 2019 16:19:23 +0530
Subject: [PATCH 14/49] fix: allow edit is enabled in the pos profile still
user not able to edit the rates
---
.../page/point_of_sale/point_of_sale.js | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index 1218dd3bb4..d233b41787 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -779,6 +779,17 @@ class POSCart {
const customer = this.frm.doc.customer;
this.customer_field.set_value(customer);
+
+ if (this.numpad) {
+ const disable_btns = this.disable_numpad_control()
+ const enable_btns = [__('Rate'), __('Disc')]
+
+ if (disable_btns) {
+ enable_btns.filter(btn => !disable_btns.includes(btn))
+ }
+
+ this.numpad.enable_buttons(enable_btns);
+ }
}
get_grand_total() {
@@ -1551,6 +1562,16 @@ class NumberPad {
}
}
+ enable_buttons(btns) {
+ btns.forEach((btn) => {
+ const $btn = this.get_btn(btn);
+ $btn.prop("disabled", false)
+ $btn.hover(() => {
+ $btn.css('cursor','pointer');
+ })
+ })
+ }
+
set_class() {
for (const btn in this.add_class) {
const class_name = this.add_class[btn];
From 803f78435102745c71ff88a81937d06c9b66329b Mon Sep 17 00:00:00 2001
From: Rushabh Mehta
Date: Mon, 17 Jun 2019 17:33:04 +0530
Subject: [PATCH 15/49] fix(minor): format date in user format for accounting
dashboard
---
.../account_balance_timeline/account_balance_timeline.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
index f2abb81dbb..648cc68dac 100644
--- a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
+++ b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe, json
-from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day
+from frappe.utils import add_to_date, date_diff, getdate, nowdate, get_last_day, formatdate
from erpnext.accounts.report.general_ledger.general_ledger import execute
from frappe.core.page.dashboard.dashboard import cache_source, get_from_date_from_timespan
from frappe.desk.doctype.dashboard_chart.dashboard_chart import get_period_ending
@@ -37,7 +37,7 @@ def get(chart_name=None, from_date = None, to_date = None):
result = build_result(account, dates, gl_entries)
return {
- "labels": [r[0].strftime('%Y-%m-%d') for r in result],
+ "labels": [formatdate(r[0].strftime('%Y-%m-%d')) for r in result],
"datasets": [{
"name": account,
"values": [r[1] for r in result]
From 4803e817e9efbcaf910e60b37ff38d43a3ad48a3 Mon Sep 17 00:00:00 2001
From: Rohit Waghchaure
Date: Mon, 17 Jun 2019 14:57:05 +0530
Subject: [PATCH 16/49] fix: bank guarantee, not able to select the purchase
order
---
erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js
index 2a44cb3b52..0acbe2009f 100644
--- a/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js
+++ b/erpnext/accounts/doctype/bank_guarantee/bank_guarantee.js
@@ -43,8 +43,13 @@ frappe.ui.form.on('Bank Guarantee', {
reference_docname: function(frm) {
if (frm.doc.reference_docname && frm.doc.reference_doctype) {
- let fields_to_fetch = ["project", "grand_total"];
+ let fields_to_fetch = ["grand_total"];
let party_field = frm.doc.reference_doctype == "Sales Order" ? "customer" : "supplier";
+
+ if (frm.doc.reference_doctype == "Sales Order") {
+ fields_to_fetch.push("project");
+ }
+
fields_to_fetch.push(party_field);
frappe.call({
method: "erpnext.accounts.doctype.bank_guarantee.bank_guarantee.get_vouchar_detials",
From 3d47a6dbb5a7d36559edcff41529934f851fbe6b Mon Sep 17 00:00:00 2001
From: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
Date: Mon, 17 Jun 2019 17:49:04 +0530
Subject: [PATCH 17/49] fix: Company filters in Total Stock Summary Report
(#17965)
---
.../total_stock_summary.js | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/erpnext/stock/report/total_stock_summary/total_stock_summary.js b/erpnext/stock/report/total_stock_summary/total_stock_summary.js
index b7461c485f..90648f1b24 100644
--- a/erpnext/stock/report/total_stock_summary/total_stock_summary.js
+++ b/erpnext/stock/report/total_stock_summary/total_stock_summary.js
@@ -10,8 +10,23 @@ frappe.query_reports["Total Stock Summary"] = {
"fieldtype": "Select",
"width": "80",
"reqd": 1,
- "options": ["","Warehouse", "Company"],
- "default": "Warehouse"
+ "options": ["", "Warehouse", "Company"],
+ "change": function() {
+ let group_by = frappe.query_report.get_filter_value("group_by")
+ let company_filter = frappe.query_report.get_filter("company")
+ if (group_by == "Company") {
+ company_filter.df.reqd = 0;
+ company_filter.df.hidden = 1;
+ frappe.query_report.set_filter_value("company", "");
+ company_filter.refresh();
+ }
+ else {
+ company_filter.df.reqd = 1;
+ company_filter.df.hidden = 0;
+ company_filter.refresh();
+ frappe.query_report.refresh();
+ }
+ }
},
{
"fieldname": "company",
From 9ee5c8a4c68817622eabd7fb4b57f66a8c8070f6 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Mon, 17 Jun 2019 18:05:41 +0530
Subject: [PATCH 18/49] fix(employee-benefit-application): remove query from
setup
---
.../employee_benefit_application.js | 29 ++++++++++---------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
index e71ce1276b..c55c46db99 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
@@ -2,20 +2,8 @@
// For license information, please see license.txt
frappe.ui.form.on('Employee Benefit Application', {
- setup: function(frm) {
- if(!frm.doc.employee || !frm.doc.date) {
- frappe.throw(__("Please select Employee and Date first"));
- } else {
- frm.set_query("earning_component", "employee_benefits", function() {
- return {
- query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
- filters: {date: frm.doc.date, employee: frm.doc.employee}
- };
- });
- }
- },
-
employee: function(frm) {
+ frm.trigger('set_earning_component');
var method, args;
if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
method = "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_max_benefits_remaining";
@@ -35,6 +23,21 @@ frappe.ui.form.on('Employee Benefit Application', {
get_max_benefits(frm, method, args);
}
},
+
+ date: function(frm) {
+ frm.trigger('set_earning_component');
+ },
+
+ set_earning_component: function(frm) {
+ if(!frm.doc.employee && !frm.doc.date) return;
+ frm.set_query("earning_component", "employee_benefits", function() {
+ return {
+ query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
+ filters: {date: frm.doc.date, employee: frm.doc.employee}
+ }
+ });
+ },
+
payroll_period: function(frm) {
var method, args;
if(frm.doc.employee && frm.doc.date && frm.doc.payroll_period){
From 7293a98a10b0a7fedf09f519af740fa98061b3d8 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Mon, 17 Jun 2019 19:03:46 +0530
Subject: [PATCH 19/49] fix: change formatting
---
.../employee_benefit_application.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
index c55c46db99..b73dcf8ac3 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.js
@@ -34,7 +34,7 @@ frappe.ui.form.on('Employee Benefit Application', {
return {
query : "erpnext.hr.doctype.employee_benefit_application.employee_benefit_application.get_earning_components",
filters: {date: frm.doc.date, employee: frm.doc.employee}
- }
+ };
});
},
From 946eefe039c46f0add94f6d88178e6cba0c2e892 Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Mon, 17 Jun 2019 23:10:36 +0530
Subject: [PATCH 20/49] fix: Codacy fixes
---
erpnext/public/js/utils/dimension_tree_filter.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/public/js/utils/dimension_tree_filter.js b/erpnext/public/js/utils/dimension_tree_filter.js
index ccca04df26..fef450795b 100644
--- a/erpnext/public/js/utils/dimension_tree_filter.js
+++ b/erpnext/public/js/utils/dimension_tree_filter.js
@@ -20,7 +20,7 @@ erpnext.doctypes_with_dimensions.forEach((doctype) => {
"is_group": 0
});
}
- })
+ });
});
});
}
From 48585c94ffc99dd5e1daceca98e78eae63a81ec8 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Tue, 18 Jun 2019 19:11:17 +0530
Subject: [PATCH 21/49] fix: Consider discount_amount only when provided to
calculate rate
After selecting item_code in items table and not entering rate,
Clicking elsewhere will set rate to NaN.
All DocTypes on buying side have this bug.
---
erpnext/public/js/controllers/buying.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 7e61f03af9..97c823d053 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -144,7 +144,9 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
item.discount_amount = flt(item_rate) * flt(item.discount_percentage) / 100;
}
- item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item));
+ if (item.discount_amount) {
+ item.rate = flt((item.price_list_rate) - (item.discount_amount), precision('rate', item));
+ }
this.calculate_taxes_and_totals();
},
From be8a46a92a3cb79861720e0f084f6c4a12b6e78e Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Tue, 18 Jun 2019 21:50:05 +0530
Subject: [PATCH 22/49] fix(tests): Timesheet tests
---
erpnext/projects/doctype/timesheet/test_timesheet.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/erpnext/projects/doctype/timesheet/test_timesheet.py b/erpnext/projects/doctype/timesheet/test_timesheet.py
index f1179033be..32f0428fcd 100644
--- a/erpnext/projects/doctype/timesheet/test_timesheet.py
+++ b/erpnext/projects/doctype/timesheet/test_timesheet.py
@@ -103,8 +103,8 @@ class TestTimesheet(unittest.TestCase):
{
"billable": 1,
"activity_type": "_Test Activity Type",
- "from_type": now_datetime(),
- "hours": 3,
+ "from_time": now_datetime(),
+ "to_time": now_datetime() + datetime.timedelta(hours=3),
"company": "_Test Company"
}
)
@@ -113,8 +113,8 @@ class TestTimesheet(unittest.TestCase):
{
"billable": 1,
"activity_type": "_Test Activity Type",
- "from_type": now_datetime(),
- "hours": 3,
+ "from_time": now_datetime(),
+ "to_time": now_datetime() + datetime.timedelta(hours=3),
"company": "_Test Company"
}
)
From 645afe16c3aaf7d45b1254d6d80682655bc49a52 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Tue, 18 Jun 2019 23:01:20 +0530
Subject: [PATCH 23/49] fix(tests): Do not test order of features in Location
---
erpnext/assets/doctype/location/test_location.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py
index 22d25b5e11..c98b0b0936 100644
--- a/erpnext/assets/doctype/location/test_location.py
+++ b/erpnext/assets/doctype/location/test_location.py
@@ -25,9 +25,12 @@ class TestLocation(unittest.TestCase):
temp['features'][0]['properties']['feature_of'] = location
formatted_locations.extend(temp['features'])
- formatted_location_string = str(formatted_locations)
test_location = frappe.get_doc('Location', 'Test Location Area')
test_location.save()
- self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
+ test_location_features = json.loads(test_location.get('location'))['features']
+ ordered_test_location_features = sorted(test_location_features, key=lambda x: x['properties']['feature_of'])
+ ordered_formatted_locations = sorted(formatted_locations, key=lambda x: x['properties']['feature_of'])
+
+ self.assertEqual(ordered_formatted_locations, ordered_test_location_features)
self.assertEqual(area, test_location.get('area'))
From 2632107129bc8726a7dcd6d70c1d6df7d4bd8eab Mon Sep 17 00:00:00 2001
From: Faris Ansari
Date: Wed, 19 Jun 2019 12:15:37 +0530
Subject: [PATCH 24/49] fix: User MultiSelectList control for Party filter
(#17943)
* fix: User MultiSelectList control for Party filter
The comma based filter wouldn't work for values that had comma in them
* fix: Replace with MultiSelectList in reports
* fix: Parse json instead of string split
---
.../accounts/report/financial_statements.py | 4 +-
.../report/general_ledger/general_ledger.js | 92 +++----------------
.../report/general_ledger/general_ledger.py | 9 +-
.../gross_and_net_profit_report.js | 30 +-----
.../profit_and_loss_statement.js | 30 +-----
erpnext/public/js/financial_statements.js | 31 +------
6 files changed, 31 insertions(+), 165 deletions(-)
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 41205ae2b0..c06856aa75 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -390,8 +390,8 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
if filters:
if filters.get("project"):
if not isinstance(filters.get("project"), list):
- projects = frappe.safe_encode(filters.get("project"))
- filters.project = [d.strip() for d in projects.strip().split(',') if d]
+ filters.project = frappe.parse_json(filters.get("project"))
+
additional_conditions.append("project in %(project)s")
if filters.get("cost_center"):
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js
index 4235b7f60d..5c98b249db 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.js
+++ b/erpnext/accounts/report/general_ledger/general_ledger.js
@@ -72,46 +72,25 @@ frappe.query_reports["General Ledger"] = {
{
"fieldname":"party",
"label": __("Party"),
- "fieldtype": "MultiSelect",
- get_data: function() {
+ "fieldtype": "MultiSelectList",
+ get_data: function(txt) {
if (!frappe.query_report.filters) return;
- var party_type = frappe.query_report.get_filter_value('party_type');
- var parties = frappe.query_report.get_filter_value('party');
- if(!party_type) return;
- const values = parties.split(/\s*,\s*/).filter(d => d);
- const txt = parties.match(/[^,\s*]*$/)[0] || '';
- let data = [];
+ let party_type = frappe.query_report.get_filter_value('party_type');
+ if (!party_type) return;
- frappe.call({
- type: "GET",
- method:'frappe.desk.search.search_link',
- async: false,
- no_spinner: true,
- args: {
- doctype: frappe.query_report.get_filter_value('party_type'),
- txt: txt,
- filters: {
- "name": ["not in", values]
- }
- },
- callback: function(r) {
- data = r.results;
- }
- });
- return data;
+ return frappe.db.get_link_options(party_type, txt);
},
on_change: function() {
var party_type = frappe.query_report.get_filter_value('party_type');
var parties = frappe.query_report.get_filter_value('party');
- const values = parties.split(/\s*,\s*/).filter(d => d);
- if(!party_type || !parties || values.length>1) {
+ if(!party_type || parties.length === 0 || parties.length > 1) {
frappe.query_report.set_filter_value('party_name', "");
frappe.query_report.set_filter_value('tax_id', "");
return;
} else {
- var party = values[0];
+ var party = parties[0];
var fieldname = erpnext.utils.get_party_name(party_type) || "name";
frappe.db.get_value(party_type, party, fieldname, function(value) {
frappe.query_report.set_filter_value('party_name', value[fieldname]);
@@ -154,62 +133,17 @@ frappe.query_reports["General Ledger"] = {
{
"fieldname":"cost_center",
"label": __("Cost Center"),
- "fieldtype": "MultiSelect",
- get_data: function() {
- var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
-
- const values = cost_centers.split(/\s*,\s*/).filter(d => d);
- const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
- let data = [];
-
- frappe.call({
- type: "GET",
- method:'frappe.desk.search.search_link',
- async: false,
- no_spinner: true,
- args: {
- doctype: "Cost Center",
- txt: txt,
- filters: {
- "company": frappe.query_report.get_filter_value("company"),
- "name": ["not in", values]
- }
- },
- callback: function(r) {
- data = r.results;
- }
- });
- return data;
+ "fieldtype": "MultiSelectList",
+ get_data: function(txt) {
+ return frappe.db.get_link_options('Cost Center', txt);
}
},
{
"fieldname":"project",
"label": __("Project"),
- "fieldtype": "MultiSelect",
- get_data: function() {
- var projects = frappe.query_report.get_filter_value("project") || "";
-
- const values = projects.split(/\s*,\s*/).filter(d => d);
- const txt = projects.match(/[^,\s*]*$/)[0] || '';
- let data = [];
-
- frappe.call({
- type: "GET",
- method:'frappe.desk.search.search_link',
- async: false,
- no_spinner: true,
- args: {
- doctype: "Project",
- txt: txt,
- filters: {
- "name": ["not in", values]
- }
- },
- callback: function(r) {
- data = r.results;
- }
- });
- return data;
+ "fieldtype": "MultiSelectList",
+ get_data: function(txt) {
+ return frappe.db.get_link_options('Project', txt);
}
},
{
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index d9f395b895..1c5e089534 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -26,8 +26,7 @@ def execute(filters=None):
account_details.setdefault(acc.name, acc)
if filters.get('party'):
- parties = cstr(filters.get("party")).strip()
- filters.party = [d.strip() for d in parties.split(',') if d]
+ filters.party = frappe.parse_json(filters.get("party"))
validate_filters(filters, account_details)
@@ -61,12 +60,10 @@ def validate_filters(filters, account_details):
frappe.throw(_("From Date must be before To Date"))
if filters.get('project'):
- projects = cstr(filters.get("project")).strip()
- filters.project = [d.strip() for d in projects.split(',') if d]
+ filters.project = frappe.parse_json(filters.get('project'))
if filters.get('cost_center'):
- cost_centers = cstr(filters.get("cost_center")).strip()
- filters.cost_center = [d.strip() for d in cost_centers.split(',') if d]
+ filters.cost_center = frappe.parse_json(filters.get('cost_center'))
def validate_party(filters):
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
index 63ac281cdb..8dc5ab36dd 100644
--- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
@@ -13,33 +13,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Gross and Net Profit Report"]["filters"].push(
{
- "fieldname":"project",
+ "fieldname": "project",
"label": __("Project"),
- "fieldtype": "MultiSelect",
- get_data: function() {
- var projects = frappe.query_report.get_filter_value("project") || "";
-
- const values = projects.split(/\s*,\s*/).filter(d => d);
- const txt = projects.match(/[^,\s*]*$/)[0] || '';
- let data = [];
-
- frappe.call({
- type: "GET",
- method:'frappe.desk.search.search_link',
- async: false,
- no_spinner: true,
- args: {
- doctype: "Project",
- txt: txt,
- filters: {
- "name": ["not in", values]
- }
- },
- callback: function(r) {
- data = r.results;
- }
- });
- return data;
+ "fieldtype": "MultiSelectList",
+ get_data: function(txt) {
+ return frappe.db.get_link_options('Project', txt);
}
},
{
diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
index 250e516d7d..df5c982258 100644
--- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
+++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
@@ -8,33 +8,11 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Profit and Loss Statement"]["filters"].push(
{
- "fieldname":"project",
+ "fieldname": "project",
"label": __("Project"),
- "fieldtype": "MultiSelect",
- get_data: function() {
- var projects = frappe.query_report.get_filter_value("project") || "";
-
- const values = projects.split(/\s*,\s*/).filter(d => d);
- const txt = projects.match(/[^,\s*]*$/)[0] || '';
- let data = [];
-
- frappe.call({
- type: "GET",
- method:'frappe.desk.search.search_link',
- async: false,
- no_spinner: true,
- args: {
- doctype: "Project",
- txt: txt,
- filters: {
- "name": ["not in", values]
- }
- },
- callback: function(r) {
- data = r.results;
- }
- });
- return data;
+ "fieldtype": "MultiSelectList",
+ get_data: function(txt) {
+ return frappe.db.get_link_options('Project', txt);
}
},
{
diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js
index 73e04c0ff0..d1113a4ca4 100644
--- a/erpnext/public/js/financial_statements.js
+++ b/erpnext/public/js/financial_statements.js
@@ -118,34 +118,13 @@ function get_filters(){
"options": erpnext.get_presentation_currency_list()
},
{
- "fieldname":"cost_center",
+ "fieldname": "cost_center",
"label": __("Cost Center"),
- "fieldtype": "MultiSelect",
- get_data: function() {
- var cost_centers = frappe.query_report.get_filter_value("cost_center") || "";
-
- const values = cost_centers.split(/\s*,\s*/).filter(d => d);
- const txt = cost_centers.match(/[^,\s*]*$/)[0] || '';
- let data = [];
-
- frappe.call({
- type: "GET",
- method:'frappe.desk.search.search_link',
- async: false,
- no_spinner: true,
- args: {
- doctype: "Cost Center",
- txt: txt,
- filters: {
- "company": frappe.query_report.get_filter_value("company"),
- "name": ["not in", values]
- }
- },
- callback: function(r) {
- data = r.results;
- }
+ "fieldtype": "MultiSelectList",
+ get_data: function(txt) {
+ return frappe.db.get_link_options('Cost Center', txt, {
+ company: frappe.query_report.get_filter_value("company")
});
- return data;
}
}
]
From 0ef1df72adb463de7ca40c00612cde6ef938d446 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Wed, 19 Jun 2019 17:50:33 +0530
Subject: [PATCH 25/49] refactor: fetch rate directly from the account head
---
erpnext/hr/doctype/expense_claim/expense_claim.js | 9 +--------
.../expense_taxes_and_charges.json | 3 ++-
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index deb6e1dc08..40bec6d4d7 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -361,16 +361,9 @@ frappe.ui.form.on("Expense Claim Advance", {
frappe.ui.form.on("Expense Taxes and Charges", {
account_head: function(frm, cdt, cdn) {
var child = locals[cdt][cdn];
- if(child.account_head && !child.description && !child.rate) {
+ if(child.account_head && !child.description) {
// set description from account head
child.description = child.account_head.split(' - ').slice(0, -1).join(' - ');
-
- // set the tax rate from account head
- frappe.db.get_value("Account", child.account_head, "tax_rate").then((r) => {
- if(r.message) {
- frappe.model.set_value(cdt, cdn, 'rate', r.message.tax_rate);
- }
- });
refresh_field("taxes");
}
},
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
index 8caf0a975a..be51c43920 100644
--- a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
@@ -53,6 +53,7 @@
},
{
"columns": 2,
+ "fetch_from": "account_head.tax_rate",
"fieldname": "rate",
"fieldtype": "Float",
"in_list_view": 1,
@@ -91,7 +92,7 @@
}
],
"istable": 1,
- "modified": "2019-06-11 14:19:34.780611",
+ "modified": "2019-06-19 17:47:40.236436",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Taxes and Charges",
From ecc670047e025becd81275c77b304faa176c967f Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Wed, 19 Jun 2019 18:25:38 +0530
Subject: [PATCH 26/49] fix: From date and to date filters in HSN wise summary
of out ward supplies
---
.../hsn_wise_summary_of_outward_supplies.js | 15 ++++++++++++++-
.../hsn_wise_summary_of_outward_supplies.py | 4 +++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
index dcb81cb087..dfdf9dc095 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js
@@ -29,7 +29,20 @@ frappe.query_reports["HSN-wise-summary of outward supplies"] = {
"placeholder":"Company GSTIN",
"options": [""],
"width": "80"
- }
+ },
+ {
+ "fieldname":"from_date",
+ "label": __("From Date"),
+ "fieldtype": "Date",
+ "width": "80"
+ },
+ {
+ "fieldname":"to_date",
+ "label": __("To Date"),
+ "fieldtype": "Date",
+ "width": "80"
+ },
+
],
onload: (report) => {
fetch_gstins(report);
diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
index e938e29c44..222dfa1eb7 100644
--- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
+++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py
@@ -88,7 +88,9 @@ def get_conditions(filters):
for opts in (("company", " and company=%(company)s"),
("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"),
- ("company_gstin", " and company_gstin=%(company_gstin)s")):
+ ("company_gstin", " and company_gstin=%(company_gstin)s"),
+ ("from_date", " and posting_date >= %(from_date)s"),
+ ("to_date", "and posting_date <= %(to_date)s")):
if filters.get(opts[0]):
conditions += opts[1]
From 4a1c7ddb094549517dee41a403072b0a869525fd Mon Sep 17 00:00:00 2001
From: Faris Ansari
Date: Wed, 19 Jun 2019 19:15:37 +0530
Subject: [PATCH 27/49] fix: App logo URL
---
erpnext/hooks.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index da0972bf5c..9502006265 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -10,6 +10,7 @@ app_color = "#e74c3c"
app_email = "info@erpnext.com"
app_license = "GNU General Public License (v3)"
source_link = "https://github.com/frappe/erpnext"
+app_logo_url = '/assets/erpnext/images/erp-icon.svg'
develop_version = '12.x.x-develop'
From 357592f55efb920b7ffbca0b8ea39a3b17e0366b Mon Sep 17 00:00:00 2001
From: Faris Ansari
Date: Wed, 19 Jun 2019 19:17:50 +0530
Subject: [PATCH 28/49] fix: Remove logo replace logic
---
erpnext/public/js/conf.js | 3 ---
1 file changed, 3 deletions(-)
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 477781bc80..047922f366 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -11,9 +11,6 @@ $(document).bind('toolbar_setup', function() {
href="https://discuss.erpnext.com">Feedback
'
- $('.navbar-home').html('
');
-
$('[data-link="docs"]').attr("href", "https://erpnext.com/docs")
$('[data-link="issues"]').attr("href", "https://github.com/frappe/erpnext/issues")
From 23f9b6156fd16996768f531490c25824ec262514 Mon Sep 17 00:00:00 2001
From: Faris Ansari
Date: Thu, 20 Jun 2019 11:34:14 +0530
Subject: [PATCH 29/49] fix(Opportunity): Don't assign to Guest (#17996)
If Opportunity is created from Website, it breaks because
the assign_to user is Guest
---
erpnext/crm/doctype/opportunity/opportunity.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index 4d4593641a..adac8f5922 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -342,7 +342,7 @@ def assign_to_user(doc, subject_field):
elif doc.lead:
assign_user = frappe.db.get_value('Lead', doc.lead, 'lead_owner')
- if assign_user and assign_user != 'Administrator':
+ if assign_user and assign_user not in ['Administrator', 'Guest']:
if not assign_to.get(dict(doctype = doc.doctype, name = doc.name)):
assign_to.add({
"assign_to": assign_user,
From 8619fc7413e2cc98d7e9b768f671e54f7fcc9625 Mon Sep 17 00:00:00 2001
From: Mangesh-Khairnar
Date: Thu, 20 Jun 2019 12:02:47 +0530
Subject: [PATCH 30/49] fix: fetch rate only if field is empty
---
.../expense_taxes_and_charges/expense_taxes_and_charges.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
index be51c43920..9bf69daf65 100644
--- a/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
+++ b/erpnext/hr/doctype/expense_taxes_and_charges/expense_taxes_and_charges.json
@@ -54,6 +54,7 @@
{
"columns": 2,
"fetch_from": "account_head.tax_rate",
+ "fetch_if_empty": 1,
"fieldname": "rate",
"fieldtype": "Float",
"in_list_view": 1,
@@ -92,7 +93,7 @@
}
],
"istable": 1,
- "modified": "2019-06-19 17:47:40.236436",
+ "modified": "2019-06-20 12:01:33.919555",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Taxes and Charges",
From 7483cb49fe939636882e608ec53db9b2a341ef7b Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Thu, 20 Jun 2019 15:25:06 +0530
Subject: [PATCH 31/49] Revert "fix: GSTR-1 Report fixes"
This reverts commit 7592e0b588ad72d3e79cd101e94102ab1c1829f0.
---
erpnext/regional/report/gstr_1/gstr_1.py | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 9d8fa2ae53..7f323a2ab0 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -60,11 +60,8 @@ class Gstr1Report(object):
else:
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
invoice_details = self.invoices.get(inv)
- for key, items in items_based_on_rate.items():
- rate = key[0]
- account = key[1]
-
- row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items)
+ for rate, items in items_based_on_rate.items():
+ row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
if self.filters.get("type_of_business") == "CDNR":
row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")
@@ -103,7 +100,7 @@ class Gstr1Report(object):
for key, value in iteritems(b2cs_output):
self.data.append(value)
- def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, account, items):
+ def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items):
row = []
for fieldname in self.invoice_fields:
if self.filters.get("type_of_business") == "CDNR" and fieldname == "invoice_value":
@@ -120,10 +117,8 @@ class Gstr1Report(object):
taxable_value = 0
for item_code, net_amount in self.invoice_items.get(invoice).items():
if item_code in items:
- if self.item_tax_rate.get(invoice) and self.item_tax_rate.get(invoice, {}).get(item_code):
- item_tax_rate = self.item_tax_rate.get(invoice, {}).get(item_code)
- if account in item_tax_rate and tax_rate == item_tax_rate.get(account):
- taxable_value += abs(net_amount)
+ if self.item_tax_rate.get(invoice) and tax_rate == self.item_tax_rate.get(invoice, {}).get(item_code):
+ taxable_value += abs(net_amount)
elif not self.item_tax_rate.get(invoice):
taxable_value += abs(net_amount)
@@ -215,7 +210,8 @@ class Gstr1Report(object):
item_tax_rate = json.loads(d.item_tax_rate)
if item_tax_rate:
- self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, item_tax_rate)
+ for account, rate in item_tax_rate.items():
+ self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, rate)
def get_items_based_on_tax_rate(self):
self.tax_details = frappe.db.sql("""
@@ -255,7 +251,7 @@ class Gstr1Report(object):
tax_rate *= 2
rate_based_dict = self.items_based_on_tax_rate\
- .setdefault(parent, {}).setdefault((tax_rate, account), [])
+ .setdefault(parent, {}).setdefault(tax_rate, [])
if item_code not in rate_based_dict:
rate_based_dict.append(item_code)
except ValueError:
From a8e49b8afdb1bce536e926165b4b3dc1ec345ae5 Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Thu, 20 Jun 2019 15:26:04 +0530
Subject: [PATCH 32/49] Revert "fix: GSTR-2 Report fixes"
This reverts commit a55413cb0d3828c20ad53e54ad7abe3ca2492668.
---
erpnext/regional/report/gstr_1/gstr_1.py | 5 +----
erpnext/regional/report/gstr_2/gstr_2.py | 7 ++-----
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 7f323a2ab0..5aa2441ee6 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -204,10 +204,7 @@ class Gstr1Report(object):
sum(i.get('base_net_amount', 0) for i in items
if i.item_code == d.item_code and i.parent == d.parent))
- item_tax_rate = {}
-
- if d.item_tax_rate:
- item_tax_rate = json.loads(d.item_tax_rate)
+ item_tax_rate = json.loads(d.item_tax_rate)
if item_tax_rate:
for account, rate in item_tax_rate.items():
diff --git a/erpnext/regional/report/gstr_2/gstr_2.py b/erpnext/regional/report/gstr_2/gstr_2.py
index d9cab63fef..a362269007 100644
--- a/erpnext/regional/report/gstr_2/gstr_2.py
+++ b/erpnext/regional/report/gstr_2/gstr_2.py
@@ -43,11 +43,8 @@ class Gstr2Report(Gstr1Report):
self.get_igst_invoices()
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
invoice_details = self.invoices.get(inv)
- for key, items in items_based_on_rate.items():
- rate = key[0]
- account = key[1]
-
- row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, account, items)
+ for rate, items in items_based_on_rate.items():
+ row, taxable_value = self.get_row_data_for_invoice(inv, invoice_details, rate, items)
tax_amount = taxable_value * rate / 100
if inv in self.igst_invoices:
row += [tax_amount, 0, 0]
From 5ff830b6f43b238453bc91f5a29216c277fc007e Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Thu, 20 Jun 2019 15:50:02 +0530
Subject: [PATCH 33/49] fix: GSTR report fixes
---
erpnext/regional/report/gstr_1/gstr_1.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 5aa2441ee6..accbff760a 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -117,7 +117,7 @@ class Gstr1Report(object):
taxable_value = 0
for item_code, net_amount in self.invoice_items.get(invoice).items():
if item_code in items:
- if self.item_tax_rate.get(invoice) and tax_rate == self.item_tax_rate.get(invoice, {}).get(item_code):
+ if self.item_tax_rate.get(invoice) and tax_rate in self.item_tax_rate.get(invoice, {}).get(item_code):
taxable_value += abs(net_amount)
elif not self.item_tax_rate.get(invoice):
taxable_value += abs(net_amount)
@@ -208,7 +208,8 @@ class Gstr1Report(object):
if item_tax_rate:
for account, rate in item_tax_rate.items():
- self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, rate)
+ tax_rate_dict = self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, [])
+ tax_rate_dict.append(rate)
def get_items_based_on_tax_rate(self):
self.tax_details = frappe.db.sql("""
From 50f4fc48a583851bd1e8314246258f8ba5173098 Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Thu, 20 Jun 2019 15:53:14 +0530
Subject: [PATCH 34/49] fix: GSTR report fixes
---
erpnext/regional/report/gstr_1/gstr_1.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index accbff760a..815a4e4b82 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -204,7 +204,10 @@ class Gstr1Report(object):
sum(i.get('base_net_amount', 0) for i in items
if i.item_code == d.item_code and i.parent == d.parent))
- item_tax_rate = json.loads(d.item_tax_rate)
+ item_tax_rate = {}
+
+ if d.item_tax_rate:
+ item_tax_rate = json.loads(d.item_tax_rate)
if item_tax_rate:
for account, rate in item_tax_rate.items():
From 6ef38ebf34434c1748b0d6182ed9fe88f8b436bb Mon Sep 17 00:00:00 2001
From: deepeshgarg007
Date: Thu, 20 Jun 2019 15:55:09 +0530
Subject: [PATCH 35/49] fix: GSTR report fixes
---
erpnext/regional/report/gstr_1/gstr_1.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 815a4e4b82..3a8149d1cf 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -209,7 +209,6 @@ class Gstr1Report(object):
if d.item_tax_rate:
item_tax_rate = json.loads(d.item_tax_rate)
- if item_tax_rate:
for account, rate in item_tax_rate.items():
tax_rate_dict = self.item_tax_rate.setdefault(d.parent, {}).setdefault(d.item_code, [])
tax_rate_dict.append(rate)
From da629810ad129fbde879de8190b6bdb3511ec20e Mon Sep 17 00:00:00 2001
From: Suraj Shetty
Date: Thu, 20 Jun 2019 17:20:19 +0530
Subject: [PATCH 36/49] fix: Get accounting dimensions only if user has access
---
erpnext/public/js/utils.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index f44fb0c1a6..86fa70d8ad 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -65,6 +65,9 @@ $.extend(erpnext, {
},
get_dimension_filters: async function() {
+ if (!frappe.boot.user.can_read.includes('Accounting Dimension')) {
+ return
+ }
let dimensions = await frappe.db.get_list('Accounting Dimension', {
fields: ['label', 'fieldname', 'document_type'],
filters: {
From b663966c6821beafa2c77db24c245538f814aed7 Mon Sep 17 00:00:00 2001
From: Suraj Shetty
Date: Thu, 20 Jun 2019 18:00:19 +0530
Subject: [PATCH 37/49] fix: Use can_read API
---
erpnext/public/js/utils.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 86fa70d8ad..dcc15fb5b3 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -65,7 +65,7 @@ $.extend(erpnext, {
},
get_dimension_filters: async function() {
- if (!frappe.boot.user.can_read.includes('Accounting Dimension')) {
+ if (!frappe.model.can_read('Accounting Dimension')) {
return
}
let dimensions = await frappe.db.get_list('Accounting Dimension', {
From 01f56b867e13c837347fe26b3d2056a235e34d23 Mon Sep 17 00:00:00 2001
From: Suraj Shetty
Date: Thu, 20 Jun 2019 18:07:58 +0530
Subject: [PATCH 38/49] fix: Return empty array to avoid failure
---
erpnext/public/js/utils.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index dcc15fb5b3..f4bb64a64d 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -66,7 +66,7 @@ $.extend(erpnext, {
get_dimension_filters: async function() {
if (!frappe.model.can_read('Accounting Dimension')) {
- return
+ return [];
}
let dimensions = await frappe.db.get_list('Accounting Dimension', {
fields: ['label', 'fieldname', 'document_type'],
From 23deb6f79be27430a964a52eb203bb8892129225 Mon Sep 17 00:00:00 2001
From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com>
Date: Thu, 20 Jun 2019 19:11:58 +0530
Subject: [PATCH 39/49] fix: Default cost center fix for delivery note item
(#17990)
---
erpnext/selling/doctype/sales_order/sales_order.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index fb7a335302..b87ad031f5 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -581,8 +581,8 @@ def make_delivery_note(source_name, target_doc=None):
if item:
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center") \
- or item.get("selling_cost_center") \
- or item_group.get("selling_cost_center")
+ or item.get("buying_cost_center") \
+ or item_group.get("buying_cost_center")
target_doc = get_mapped_doc("Sales Order", source_name, {
"Sales Order": {
From d2061b44dde0b451700892cf3b9efa89537bcfc5 Mon Sep 17 00:00:00 2001
From: rohitwaghchaure
Date: Thu, 20 Jun 2019 19:13:54 +0530
Subject: [PATCH 40/49] fix: could not find company all (#17978)
---
.../employee_attendance_tool.js | 5 ++---
.../employee_attendance_tool.py | 11 +++++------
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
index 376d0c0a5a..22ba5ad473 100644
--- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.js
@@ -2,9 +2,8 @@ frappe.ui.form.on("Employee Attendance Tool", {
refresh: function(frm) {
frm.disable_save();
},
-
+
onload: function(frm) {
- frm.doc.department = frm.doc.branch = frm.doc.company = "All";
frm.set_value("date", frappe.datetime.get_today());
erpnext.employee_attendance_tool.load_employees(frm);
},
@@ -24,7 +23,7 @@ frappe.ui.form.on("Employee Attendance Tool", {
company: function(frm) {
erpnext.employee_attendance_tool.load_employees(frm);
}
-
+
});
diff --git a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
index ea5f4bdeca..32fcee1abe 100644
--- a/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
+++ b/erpnext/hr/doctype/employee_attendance_tool/employee_attendance_tool.py
@@ -17,12 +17,11 @@ def get_employees(date, department = None, branch = None, company = None):
attendance_not_marked = []
attendance_marked = []
filters = {"status": "Active", "date_of_joining": ["<=", date]}
- if department != "All":
- filters["department"] = department
- if branch != "All":
- filters["branch"] = branch
- if company != "All":
- filters["company"] = company
+
+ for field, value in {'department': department,
+ 'branch': branch, 'company': company}.items():
+ if value:
+ filters[field] = value
employee_list = frappe.get_list("Employee", fields=["employee", "employee_name"], filters=filters, order_by="employee_name")
marked_employee = {}
From 3fa112d8a7338d30112be476ea18b6734bc4c0eb Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Wed, 1 May 2019 11:16:25 +0530
Subject: [PATCH 41/49] feat(travis): Python 3.6 tests
---
.travis.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.travis.yml b/.travis.yml
index 869fe959c0..f2ba2c4326 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,6 +3,7 @@ dist: trusty
python:
- "2.7"
+ - "3.6"
services:
- mysql
From f397acc9362d7820798dae4286c8e839fa16f0f8 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Wed, 1 May 2019 11:31:08 +0530
Subject: [PATCH 42/49] fix(travis): Refactor .travis.yml
---
.travis.yml | 24 +++++++++---------------
travis/run-tests.sh | 12 ++++++++++++
2 files changed, 21 insertions(+), 15 deletions(-)
create mode 100644 travis/run-tests.sh
diff --git a/.travis.yml b/.travis.yml
index f2ba2c4326..26a4caa0fb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,10 @@ python:
- "2.7"
- "3.6"
+env:
+ - TEST_TYPE=Server Side Test
+ - TEST_TYPE=Patch Test
+
services:
- mysql
@@ -40,18 +44,8 @@ before_script:
- bench start &
- sleep 10
-jobs:
- include:
- - stage: test
- script:
- - set -e
- - bench run-tests --app erpnext --coverage
- after_script:
- - coveralls -b apps/erpnext -d ../../sites/.coverage
- env: Server Side Test
- - # stage
- script:
- - wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- - bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
- - bench migrate
- env: Patch Testing
+script:
+ - $TRAVIS_BUILD_DIR/travis/run-tests.sh
+
+after_script:
+ - coveralls -b apps/erpnext -d ../../sites/.coverage
diff --git a/travis/run-tests.sh b/travis/run-tests.sh
new file mode 100644
index 0000000000..7cfd64833b
--- /dev/null
+++ b/travis/run-tests.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -e
+
+if [[ $TEST_TYPE == 'Server Side Test' ]]; then
+ bench run-tests --app erpnext --coverage
+
+elif [[ $TEST_TYPE == 'Patch Test' ]]; then
+ wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
+ bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
+ bench migrate
+fi
From 63ddff867a0ad62648488ea99f7f1027abb965ec Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Wed, 1 May 2019 12:06:24 +0530
Subject: [PATCH 43/49] chore: Temporarily disable flake rule F821
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 26a4caa0fb..2e3a1e7782 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,7 @@ install:
# fix mongodb travis error
- sudo rm /etc/apt/sources.list.d/mongodb*.list
- pip install flake8==3.3.0
- - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
+ - flake8 . --count --select=E901,E999,F822,F823 --show-source --statistics
- sudo rm /etc/apt/sources.list.d/docker.list
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
- sudo apt-get purge -y mysql-common mysql-server mysql-client
From bb5ca5a01fe89fcb36a73306c2dedabcee2bf334 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Wed, 1 May 2019 17:35:37 +0530
Subject: [PATCH 44/49] fix(py3): Convert filter to list
---
erpnext/accounts/doctype/pricing_rule/utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 8a8e3291aa..5795b8f808 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -232,7 +232,7 @@ def filter_pricing_rules(args, pricing_rules, doc=None):
if len(pricing_rules) > 1:
rate_or_discount = list(set([d.rate_or_discount for d in pricing_rules]))
if len(rate_or_discount) == 1 and rate_or_discount[0] == "Discount Percentage":
- pricing_rules = filter(lambda x: x.for_price_list==args.price_list, pricing_rules) \
+ pricing_rules = list(filter(lambda x: x.for_price_list==args.price_list, pricing_rules)) \
or pricing_rules
if len(pricing_rules) > 1 and not args.for_shopping_cart:
From c052ce61f77a1660bc9322877f05ecdfd3632841 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Wed, 1 May 2019 17:41:36 +0530
Subject: [PATCH 45/49] fix: Set file permissions 755 on travis/run-tests.sh
---
travis/run-tests.sh | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 travis/run-tests.sh
diff --git a/travis/run-tests.sh b/travis/run-tests.sh
old mode 100644
new mode 100755
From 44da737c1bdc50ecf623957bae2c2dda7185052a Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Wed, 1 May 2019 18:08:44 +0530
Subject: [PATCH 46/49] fix: Minor
---
.travis.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 2e3a1e7782..612a9e416c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,8 +6,8 @@ python:
- "3.6"
env:
- - TEST_TYPE=Server Side Test
- - TEST_TYPE=Patch Test
+ - TEST_TYPE="Server Side Test"
+ - TEST_TYPE="Patch Test"
services:
- mysql
From 700711c28d2206efc939d6172c939b864cd81841 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Wed, 1 May 2019 18:25:53 +0530
Subject: [PATCH 47/49] fix: Run script with bash
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 612a9e416c..3ce1439d95 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -45,7 +45,7 @@ before_script:
- sleep 10
script:
- - $TRAVIS_BUILD_DIR/travis/run-tests.sh
+ - bash $TRAVIS_BUILD_DIR/travis/run-tests.sh
after_script:
- coveralls -b apps/erpnext -d ../../sites/.coverage
From 51eecd0c4276631ca267223c3fb84ef4b5a253b1 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Thu, 20 Jun 2019 14:07:32 +0530
Subject: [PATCH 48/49] chore: Enable Flake 821 rule
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 3ce1439d95..a8a0d82614 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,7 @@ install:
# fix mongodb travis error
- sudo rm /etc/apt/sources.list.d/mongodb*.list
- pip install flake8==3.3.0
- - flake8 . --count --select=E901,E999,F822,F823 --show-source --statistics
+ - flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
- sudo rm /etc/apt/sources.list.d/docker.list
- sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
- sudo apt-get purge -y mysql-common mysql-server mysql-client
From c980143764cac7bf1ffb809c6491a396d1e91615 Mon Sep 17 00:00:00 2001
From: Aditya Hase
Date: Thu, 2 May 2019 21:10:13 +0530
Subject: [PATCH 49/49] fix(test): Explicitly search for Material Request Item
with Item Code
---
.../doctype/production_plan/test_production_plan.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index 42fce5ad49..e9ef70c49b 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -152,7 +152,7 @@ class TestProductionPlan(unittest.TestCase):
make_bom(item = item, raw_materials = raw_materials)
production_plan = create_production_plan(item_code = 'Production Item CUST')
production_plan.make_material_request()
- material_request = frappe.get_value('Material Request Item', {'production_plan': production_plan.name}, 'parent')
+ material_request = frappe.db.get_value('Material Request Item', {'production_plan': production_plan.name, 'item_code': 'CUST-0987'}, 'parent')
mr = frappe.get_doc('Material Request', material_request)
self.assertTrue(mr.material_request_type, 'Customer Provided')
self.assertTrue(mr.customer, '_Test Customer')