{%= frappe.boot.letter_heads[letterhead].header %}
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index 2c7bd7252ff..d26aeb11b9e 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -126,7 +126,7 @@ def get_label(periodicity, from_date, to_date):
def get_data(
company, root_type, balance_must_be, period_list, filters=None,
accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False,
- ignore_accumulated_values_for_fy=False):
+ ignore_accumulated_values_for_fy=False , total = True):
accounts = get_accounts(company, root_type)
if not accounts:
@@ -154,7 +154,7 @@ def get_data(
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
out = filter_out_zero_value_rows(out, parent_children_map)
- if out:
+ if out and total:
add_total_row(out, root_type, balance_must_be, period_list, company_currency)
return out
@@ -218,6 +218,9 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
"year_start_date": year_start_date,
"year_end_date": year_end_date,
"currency": company_currency,
+ "include_in_gross": d.include_in_gross,
+ "account_type": d.account_type,
+ "is_group": d.is_group,
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1),
"account_name": ('%s - %s' %(_(d.account_number), _(d.account_name))
if d.account_number else _(d.account_name))
@@ -285,7 +288,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
def get_accounts(company, root_type):
return frappe.db.sql("""
- select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name
+ select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name, include_in_gross, account_type, is_group, lft, rgt
from `tabAccount`
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
@@ -356,7 +359,8 @@ def set_gl_entries_by_account(
"from_date": from_date,
"to_date": to_date,
"cost_center": filters.cost_center,
- "project": filters.project
+ "project": filters.project,
+ "finance_book": filters.get("finance_book")
},
as_dict=True)
@@ -389,14 +393,8 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
filters.cost_center = get_cost_centers_with_children(filters.cost_center)
additional_conditions.append("cost_center in %(cost_center)s")
- company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
-
- if not filters.get('finance_book') or (filters.get('finance_book') == company_finance_book):
- additional_conditions.append("ifnull(finance_book, '') in ('%s', '')" %
- frappe.db.escape(company_finance_book))
- elif filters.get("finance_book"):
- additional_conditions.append("ifnull(finance_book, '') = '%s' " %
- frappe.db.escape(filters.get("finance_book")))
+ if filters.get("finance_book"):
+ additional_conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py
index be6633282ac..44ca8d3549a 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.py
+++ b/erpnext/accounts/report/general_ledger/general_ledger.py
@@ -53,7 +53,7 @@ def validate_filters(filters, account_details):
frappe.throw(_("Can not filter based on Account, if grouped by Account"))
if (filters.get("voucher_no")
- and filters.get("group_by") in [_('Group by Voucher'), _('Group by Voucher (Consolidated)')]):
+ and filters.get("group_by") in [_('Group by Voucher')]):
frappe.throw(_("Can not filter based on Voucher No, if grouped by Voucher"))
if filters.from_date > filters.to_date:
@@ -186,12 +186,8 @@ def get_conditions(filters):
if filters.get("project"):
conditions.append("project in %(project)s")
- company_finance_book = erpnext.get_default_finance_book(filters.get("company"))
- if not filters.get("finance_book") or (filters.get("finance_book") == company_finance_book):
- filters['finance_book'] = company_finance_book
+ if filters.get("finance_book"):
conditions.append("ifnull(finance_book, '') in (%(finance_book)s, '')")
- elif filters.get("finance_book"):
- conditions.append("ifnull(finance_book, '') = %(finance_book)s")
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("GL Entry")
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/__init__.py b/erpnext/accounts/report/gross_and_net_profit_report/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.html b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.html
new file mode 100644
index 00000000000..40ba20c4ac6
--- /dev/null
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.html
@@ -0,0 +1 @@
+{% include "accounts/report/financial_statements.html" %}
\ No newline at end of file
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
new file mode 100644
index 00000000000..63ac281cdb5
--- /dev/null
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.js
@@ -0,0 +1,51 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Gross and Net Profit Report"] = {
+ "filters": [
+
+ ]
+}
+frappe.require("assets/erpnext/js/financial_statements.js", function() {
+ frappe.query_reports["Gross and Net Profit Report"] = $.extend({},
+ erpnext.financial_statements);
+
+ frappe.query_reports["Gross and Net Profit Report"]["filters"].push(
+ {
+ "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;
+ }
+ },
+ {
+ "fieldname": "accumulated_values",
+ "label": __("Accumulated Values"),
+ "fieldtype": "Check"
+ }
+ );
+});
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.json b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.json
new file mode 100644
index 00000000000..994b47faef2
--- /dev/null
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.json
@@ -0,0 +1,30 @@
+{
+ "add_total_row": 0,
+ "creation": "2019-02-08 10:58:55.763090",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2019-02-08 10:58:55.763090",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Gross and Net Profit Report",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "GL Entry",
+ "report_name": "Gross and Net Profit Report",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Accounts Manager"
+ },
+ {
+ "role": "Auditor"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
new file mode 100644
index 00000000000..6550981a146
--- /dev/null
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
@@ -0,0 +1,154 @@
+# 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 flt
+from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
+import copy
+
+
+def execute(filters=None):
+ period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
+ filters.periodicity, filters.accumulated_values, filters.company)
+
+ columns, data = [], []
+
+ income = get_data(filters.company, "Income", "Credit", period_list, filters = filters,
+ accumulated_values=filters.accumulated_values,
+ ignore_closing_entries=True, ignore_accumulated_values_for_fy= True, total= False)
+
+ expense = get_data(filters.company, "Expense", "Debit", period_list, filters=filters,
+ accumulated_values=filters.accumulated_values,
+ ignore_closing_entries=True, ignore_accumulated_values_for_fy= True, total= False)
+
+ columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
+
+
+ gross_income = get_revenue(income, period_list)
+
+ gross_expense = get_revenue(expense, period_list)
+
+ if(len(gross_income)==0 and len(gross_expense)== 0):
+ data.append({"account_name": "'" + _("Nothing is included in gross") + "'",
+ "account": "'" + _("Nothing is included in gross") + "'"})
+
+ return columns, data
+
+ data.append({"account_name": "'" + _("Included in Gross Profit") + "'",
+ "account": "'" + _("Included in Gross Profit") + "'"})
+
+ data.append({})
+ data.extend(gross_income or [])
+
+ data.append({})
+ data.extend(gross_expense or [])
+
+ data.append({})
+ gross_profit = get_profit(gross_income, gross_expense, period_list, filters.company, 'Gross Profit',filters.presentation_currency)
+ data.append(gross_profit)
+
+ non_gross_income = get_revenue(income, period_list, 0)
+ data.append({})
+ data.extend(non_gross_income or [])
+
+ non_gross_expense = get_revenue(expense, period_list, 0)
+ data.append({})
+ data.extend(non_gross_expense or [])
+
+ net_profit = get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expense, period_list, filters.company,filters.presentation_currency)
+ data.append({})
+ data.append(net_profit)
+
+ return columns, data
+
+def get_revenue(data, period_list, include_in_gross=1):
+ revenue = [item for item in data if item['include_in_gross']==include_in_gross or item['is_group']==1]
+
+ data_to_be_removed =True
+ while data_to_be_removed:
+ revenue, data_to_be_removed = remove_parent_with_no_child(revenue, period_list)
+ revenue = adjust_account(revenue, period_list)
+ return copy.deepcopy(revenue)
+
+def remove_parent_with_no_child(data, period_list):
+ data_to_be_removed = False
+ for parent in data:
+ if 'is_group' in parent and parent.get("is_group") == 1:
+ have_child = False
+ for child in data:
+ if 'parent_account' in child and child.get("parent_account") == parent.get("account"):
+ have_child = True
+ break
+
+ if not have_child:
+ data_to_be_removed = True
+ data.remove(parent)
+
+ return data, data_to_be_removed
+
+def adjust_account(data, period_list, consolidated= False):
+ leaf_nodes = [item for item in data if item['is_group'] == 0]
+ totals = {}
+ for node in leaf_nodes:
+ set_total(node, node["total"], data, totals)
+ for d in data:
+ for period in period_list:
+ key = period if consolidated else period.key
+ d[key] = totals[d["account"]]
+ d['total'] = totals[d["account"]]
+ return data
+
+def set_total(node, value, complete_list, totals):
+ if not totals.get(node['account']):
+ totals[node["account"]] = 0
+ totals[node["account"]] += value
+
+ parent = node['parent_account']
+ if not parent == '':
+ return set_total(next(item for item in complete_list if item['account'] == parent), value, complete_list, totals)
+
+
+def get_profit(gross_income, gross_expense, period_list, company, profit_type, currency=None, consolidated=False):
+
+ profit_loss = {
+ "account_name": "'" + _(profit_type) + "'",
+ "account": "'" + _(profit_type) + "'",
+ "warn_if_negative": True,
+ "currency": currency or frappe.get_cached_value('Company', company, "default_currency")
+ }
+
+ has_value = False
+
+ for period in period_list:
+ key = period if consolidated else period.key
+ profit_loss[key] = flt(gross_income[0].get(key, 0)) - flt(gross_expense[0].get(key, 0))
+
+ if profit_loss[key]:
+ has_value=True
+
+ if has_value:
+ return profit_loss
+
+def get_net_profit(non_gross_income, gross_income, gross_expense, non_gross_expense, period_list, company, currency=None, consolidated=False):
+ profit_loss = {
+ "account_name": "'" + _("Net Profit") + "'",
+ "account": "'" + _("Net Profit") + "'",
+ "warn_if_negative": True,
+ "currency": currency or frappe.get_cached_value('Company', company, "default_currency")
+ }
+
+ has_value = False
+
+ for period in period_list:
+ key = period if consolidated else period.key
+ total_income = flt(gross_income[0].get(key, 0)) + flt(non_gross_income[0].get(key, 0))
+ total_expense = flt(gross_expense[0].get(key, 0)) + flt(non_gross_expense[0].get(key, 0))
+ profit_loss[key] = flt(total_income) - flt(total_expense)
+
+ if profit_loss[key]:
+ has_value=True
+
+ if has_value:
+ return profit_loss
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.js b/erpnext/accounts/report/gross_profit/gross_profit.js
index 1f7d24db1e4..ba17a94e8d3 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.js
+++ b/erpnext/accounts/report/gross_profit/gross_profit.js
@@ -23,6 +23,12 @@ frappe.query_reports["Gross Profit"] = {
"fieldtype": "Date",
"default": frappe.defaults.get_user_default("year_end_date")
},
+ {
+ "fieldname":"sales_invoice",
+ "label": __("Sales Invoice"),
+ "fieldtype": "Link",
+ "options": "Sales Invoice"
+ },
{
"fieldname":"group_by",
"label": __("Group By"),
diff --git a/erpnext/accounts/report/gross_profit/gross_profit.py b/erpnext/accounts/report/gross_profit/gross_profit.py
index 67105e58dea..ee5a4d28e37 100644
--- a/erpnext/accounts/report/gross_profit/gross_profit.py
+++ b/erpnext/accounts/report/gross_profit/gross_profit.py
@@ -6,7 +6,7 @@ import frappe
from frappe import _, scrub
from erpnext.stock.utils import get_incoming_rate
from erpnext.controllers.queries import get_match_cond
-from frappe.utils import flt
+from frappe.utils import flt, cint
def execute(filters=None):
@@ -106,11 +106,14 @@ class GrossProfitGenerator(object):
self.grouped = {}
self.grouped_data = []
+ self.currency_precision = cint(frappe.db.get_default("currency_precision")) or 3
+ self.float_precision = cint(frappe.db.get_default("float_precision")) or 2
+
for row in self.si_list:
if self.skip_row(row, self.product_bundles):
continue
- row.base_amount = flt(row.base_net_amount)
+ row.base_amount = flt(row.base_net_amount, self.currency_precision)
product_bundles = []
if row.update_stock:
@@ -122,22 +125,23 @@ class GrossProfitGenerator(object):
# get buying amount
if row.item_code in product_bundles:
- row.buying_amount = self.get_buying_amount_from_product_bundle(row,
- product_bundles[row.item_code])
+ row.buying_amount = flt(self.get_buying_amount_from_product_bundle(row,
+ product_bundles[row.item_code]), self.currency_precision)
else:
- row.buying_amount = self.get_buying_amount(row, row.item_code)
+ row.buying_amount = flt(self.get_buying_amount(row, row.item_code),
+ self.currency_precision)
# get buying rate
if row.qty:
- row.buying_rate = row.buying_amount / row.qty
- row.base_rate = row.base_amount / row.qty
+ row.buying_rate = flt(row.buying_amount / row.qty, self.float_precision)
+ row.base_rate = flt(row.base_amount / row.qty, self.float_precision)
else:
row.buying_rate, row.base_rate = 0.0, 0.0
# calculate gross profit
- row.gross_profit = flt(row.base_amount - row.buying_amount, 3)
+ row.gross_profit = flt(row.base_amount - row.buying_amount, self.currency_precision)
if row.base_amount:
- row.gross_profit_percent = flt((row.gross_profit / row.base_amount) * 100.0, 3)
+ row.gross_profit_percent = flt((row.gross_profit / row.base_amount) * 100.0, self.currency_precision)
else:
row.gross_profit_percent = 0.0
@@ -156,8 +160,8 @@ class GrossProfitGenerator(object):
new_row = row
else:
new_row.qty += row.qty
- new_row.buying_amount += row.buying_amount
- new_row.base_amount += row.base_amount
+ new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
+ new_row.base_amount += flt(row.base_amount, self.currency_precision)
new_row = self.set_average_rate(new_row)
self.grouped_data.append(new_row)
else:
@@ -167,18 +171,19 @@ class GrossProfitGenerator(object):
returned_item_rows = self.returned_invoices[row.parent][row.item_code]
for returned_item_row in returned_item_rows:
row.qty += returned_item_row.qty
- row.base_amount += returned_item_row.base_amount
- row.buying_amount = row.qty * row.buying_rate
+ row.base_amount += flt(returned_item_row.base_amount, self.currency_precision)
+ row.buying_amount = flt(row.qty * row.buying_rate, self.currency_precision)
if row.qty or row.base_amount:
row = self.set_average_rate(row)
self.grouped_data.append(row)
def set_average_rate(self, new_row):
- new_row.gross_profit = flt(new_row.base_amount - new_row.buying_amount,3)
- new_row.gross_profit_percent = flt(((new_row.gross_profit / new_row.base_amount) * 100.0),3) \
+ new_row.gross_profit = flt(new_row.base_amount - new_row.buying_amount, self.currency_precision)
+ new_row.gross_profit_percent = flt(((new_row.gross_profit / new_row.base_amount) * 100.0), self.currency_precision) \
if new_row.base_amount else 0
- new_row.buying_rate = (new_row.buying_amount / new_row.qty) if new_row.qty else 0
- new_row.base_rate = (new_row.base_amount / new_row.qty) if new_row.qty else 0
+ new_row.buying_rate = flt(new_row.buying_amount / new_row.qty, self.float_precision) if new_row.qty else 0
+ new_row.base_rate = flt(new_row.base_amount / new_row.qty, self.float_precision) if new_row.qty else 0
+
return new_row
def get_returned_invoice_items(self):
@@ -211,7 +216,7 @@ class GrossProfitGenerator(object):
if packed_item.get("parent_detail_docname")==row.item_row:
buying_amount += self.get_buying_amount(row, packed_item.item_code)
- return buying_amount
+ return flt(buying_amount, self.currency_precision)
def get_buying_amount(self, row, item_code):
# IMP NOTE
@@ -297,6 +302,12 @@ class GrossProfitGenerator(object):
sales_person_cols = ""
sales_team_table = ""
+ if self.filters.get("sales_invoice"):
+ conditions += " and `tabSales Invoice`.name = %(sales_invoice)s"
+
+ if self.filters.get("item_code"):
+ conditions += " and `tabSales Invoice Item`.item_code = %(item_code)s"
+
self.si_list = frappe.db.sql("""
select
`tabSales Invoice Item`.parenttype, `tabSales Invoice Item`.parent,
diff --git a/erpnext/accounts/report/inactive_sales_items/__init__.py b/erpnext/accounts/report/inactive_sales_items/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js
new file mode 100644
index 00000000000..ddf756263fc
--- /dev/null
+++ b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.js
@@ -0,0 +1,34 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Inactive Sales Items"] = {
+ "filters": [
+ {
+ fieldname: "item",
+ label: __("Item"),
+ fieldtype: "Link",
+ options: "Item"
+ },
+ {
+ fieldname: "item_group",
+ label: __("Item Group"),
+ fieldtype: "Link",
+ options: "Item Group"
+ },
+ {
+ fieldname: "based_on",
+ label: __("Based On"),
+ fieldtype: "Select",
+ options: "Sales Order\nSales Invoice",
+ default: "Sales Order"
+ },
+ {
+ fieldname: "days",
+ label: __("Days Since Last order"),
+ fieldtype: "Select",
+ options: [30, 60, 90],
+ default: 30
+ },
+ ]
+}
diff --git a/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.json b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.json
new file mode 100644
index 00000000000..e8fce9c0492
--- /dev/null
+++ b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.json
@@ -0,0 +1,30 @@
+{
+ "add_total_row": 0,
+ "creation": "2019-05-01 12:59:52.018850",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2019-05-01 13:00:26.545278",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Inactive Sales Items",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Sales Invoice",
+ "report_name": "Inactive Sales Items",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Accounts User"
+ },
+ {
+ "role": "Accounts Manager"
+ },
+ {
+ "role": "Auditor"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py
new file mode 100644
index 00000000000..fd169f8f70f
--- /dev/null
+++ b/erpnext/accounts/report/inactive_sales_items/inactive_sales_items.py
@@ -0,0 +1,144 @@
+# 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.utils import getdate, add_days, today, cint
+from frappe import _
+
+def execute(filters=None):
+
+ columns = get_columns()
+ data = get_data(filters)
+ return columns, data
+
+def get_columns():
+
+ columns = [
+ {
+ "fieldname": "territory",
+ "fieldtype": "Link",
+ "label": _("Territory"),
+ "options": "Territory",
+ "width": 100
+ },
+ {
+ "fieldname": "item_group",
+ "fieldtype": "Link",
+ "label": _("Item Group"),
+ "options": "Item Group",
+ "width": 150
+ },
+ {
+ "fieldname": "item_name",
+ "fieldtype": "Link",
+ "options": "Item",
+ "label": "Item",
+ "width": 150
+ },
+ {
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "label": _("Item Name"),
+ "width": 150
+ },
+
+ {
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "label": _("Customer"),
+ "options": "Customer",
+ "width": 100
+ },
+ {
+ "fieldname": "last_order_date",
+ "fieldtype": "Date",
+ "label": _("Last Order Date"),
+ "width": 100
+ },
+ {
+ "fieldname": "qty",
+ "fieldtype": "Float",
+ "label": _("Quantity"),
+ "width": 100
+ },
+ {
+ "fieldname": "days_since_last_order",
+ "fieldtype": "Int",
+ "label": _("Days Since Last Order"),
+ "width": 100
+ },
+ ]
+
+ return columns
+
+
+def get_data(filters):
+
+ data = []
+ items = get_items(filters)
+ sales_invoice_data = get_sales_details(filters)
+
+ for item in items:
+ row = {
+ "item_group": item.item_group,
+ "item": item.name,
+ "item_name": item.item_name
+ }
+
+ if sales_invoice_data.get(item.name):
+ item_obj = sales_invoice_data[item.name]
+ if item_obj.days_since_last_order > cint(filters['days']):
+ row.update({
+ "territory": item_obj.territory,
+ "customer": item_obj.customer,
+ "last_order_date": item_obj.last_order_date,
+ "qty": item_obj.qty,
+ "days_since_last_order": item_obj.days_since_last_order
+ })
+
+ data.append(row)
+
+ return data
+
+
+def get_sales_details(filters):
+
+ data = []
+ item_details_map = {}
+
+ date_field = "s.transaction_date" if filters["based_on"] == "Sales Order" else "s.posting_date"
+
+ sales_data = frappe.db.sql("""
+ select s.territory, s.customer, si.item_group, si.item_name, si.qty, {date_field} as last_order_date,
+ DATEDIFF(CURDATE(), {date_field}) as days_since_last_order
+ from `tab{doctype}` s, `tab{doctype} Item` si
+ where s.name = si.parent and s.docstatus = 1
+ group by si.name order by days_since_last_order """ #nosec
+ .format(date_field = date_field, doctype = filters['based_on']), as_dict=1)
+
+ for d in sales_data:
+ item_details_map.setdefault(d.item_name, d)
+
+ return item_details_map
+
+def get_items(filters):
+
+ filters_dict = {
+ "disabled": 0,
+ "is_stock_item": 1
+ }
+
+ if filters.get("item_group"):
+ filters_dict.update({
+ "item_group": filters["item_group"]
+ })
+
+ if filters.get("item"):
+ filters_dict.update({
+ "name": filters["item"]
+ })
+
+ items = frappe.get_all("Item", fields=["name", "item_group", "item_name"], filters=filters_dict, order_by="name")
+
+ return items
diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
index 88c612e7f6c..e8b19b40249 100644
--- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
+++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
@@ -54,8 +54,10 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
]
- row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] \
- if d.stock_uom != d.uom and d.stock_qty != 0 else [d.base_net_rate, d.base_net_amount]
+ if d.stock_uom != d.uom and d.stock_qty:
+ row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount]
+ else:
+ row += [d.base_net_rate, d.base_net_amount]
total_tax = 0
for tax in tax_columns:
@@ -108,13 +110,13 @@ def get_conditions(filters):
conditions += """ and exists(select name from `tabSales Invoice Payment`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
-
+
if filters.get("warehouse"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s)"""
-
+
if filters.get("brand"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
@@ -131,10 +133,10 @@ def get_conditions(filters):
def get_items(filters, additional_query_columns):
conditions = get_conditions(filters)
match_conditions = frappe.build_match_conditions("Sales Invoice")
-
+
if match_conditions:
match_conditions = " and {0} ".format(match_conditions)
-
+
if additional_query_columns:
additional_query_columns = ', ' + ', '.join(additional_query_columns)
diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py
index 39706acde0f..a0d8c5f0e4e 100644
--- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py
+++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py
@@ -133,6 +133,13 @@ def get_columns(filters):
"options": filters.get("based_on"),
"width": 300
},
+ {
+ "fieldname": "currency",
+ "label": _("Currency"),
+ "fieldtype": "Link",
+ "options": "Currency",
+ "hidden": 1
+ },
{
"fieldname": "income",
"label": _("Income"),
@@ -153,13 +160,6 @@ def get_columns(filters):
"fieldtype": "Currency",
"options": "currency",
"width": 120
- },
- {
- "fieldname": "currency",
- "label": _("Currency"),
- "fieldtype": "Link",
- "options": "Currency",
- "hidden": 1
}
]
@@ -191,4 +191,4 @@ def set_gl_entries_by_account(company, from_date, to_date, based_on, gl_entries_
for entry in gl_entries:
gl_entries_by_account.setdefault(entry.based_on, []).append(entry)
- return gl_entries_by_account
\ No newline at end of file
+ return gl_entries_by_account
diff --git a/erpnext/accounts/report/purchase_register/purchase_register.py b/erpnext/accounts/report/purchase_register/purchase_register.py
index e33b90d0196..3f8abb76e26 100644
--- a/erpnext/accounts/report/purchase_register/purchase_register.py
+++ b/erpnext/accounts/report/purchase_register/purchase_register.py
@@ -66,8 +66,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
total_tax += tax_amount
row.append(tax_amount)
- # total tax, grand total, outstanding amount & rounded total
- row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 2), inv.outstanding_amount]
+ # total tax, grand total, rounded total & outstanding amount
+ row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
data.append(row)
return columns, data
diff --git a/erpnext/accounts/report/sales_register/sales_register.py b/erpnext/accounts/report/sales_register/sales_register.py
index d37caaf59d7..de60995ca22 100644
--- a/erpnext/accounts/report/sales_register/sales_register.py
+++ b/erpnext/accounts/report/sales_register/sales_register.py
@@ -157,7 +157,7 @@ def get_conditions(filters):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)"""
-
+
if filters.get("item_group"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
@@ -171,7 +171,7 @@ def get_invoices(filters, additional_query_columns):
conditions = get_conditions(filters)
return frappe.db.sql("""
- select name, posting_date, debit_to, project, customer,
+ select name, posting_date, debit_to, project, customer,
customer_name, owner, remarks, territory, tax_id, customer_group,
base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
from `tabSales Invoice`
diff --git a/erpnext/accounts/report/share_ledger/share_ledger.json b/erpnext/accounts/report/share_ledger/share_ledger.json
index d374bb7747c..fe158a6f003 100644
--- a/erpnext/accounts/report/share_ledger/share_ledger.json
+++ b/erpnext/accounts/report/share_ledger/share_ledger.json
@@ -1,23 +1,27 @@
{
"add_total_row": 0,
- "apply_user_permissions": 1,
"creation": "2017-12-27 16:15:52.615453",
+ "disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
- "modified": "2017-12-27 16:46:54.422356",
+ "modified": "2019-04-19 10:50:36.061588",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Share Ledger",
"owner": "Administrator",
+ "prepared_report": 0,
"ref_doctype": "Share Transfer",
"report_name": "Share Ledger",
"report_type": "Script Report",
"roles": [
{
"role": "Administrator"
+ },
+ {
+ "role": "System Manager"
}
]
}
\ No newline at end of file
diff --git a/erpnext/accounts/report/supplier_ledger_summary/supplier_ledger_summary.js b/erpnext/accounts/report/supplier_ledger_summary/supplier_ledger_summary.js
index 6fd16f20908..f81297760ed 100644
--- a/erpnext/accounts/report/supplier_ledger_summary/supplier_ledger_summary.js
+++ b/erpnext/accounts/report/supplier_ledger_summary/supplier_ledger_summary.js
@@ -35,9 +35,9 @@ frappe.query_reports["Supplier Ledger Summary"] = {
},
{
"fieldname":"party",
- "label": __("Customer"),
+ "label": __("Supplier"),
"fieldtype": "Link",
- "options": "Customer",
+ "options": "Supplier",
on_change: () => {
var party = frappe.query_report.get_filter_value('party');
if (party) {
diff --git a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
index e55c022452d..8ca466e4b88 100644
--- a/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
+++ b/erpnext/accounts/report/tds_payable_monthly/tds_payable_monthly.py
@@ -55,12 +55,15 @@ def get_result(filters):
supplier = supplier_map[d]
tds_doc = tds_docs[supplier.tax_withholding_category]
- account = [i.account for i in tds_doc.accounts if i.company == filters.company][0]
+ account_list = [i.account for i in tds_doc.accounts if i.company == filters.company]
+
+ if account_list:
+ account = account_list[0]
for k in gle_map[d]:
if k.party == supplier_map[d] and k.credit > 0:
total_amount_credited += k.credit
- elif k.account == account and k.credit > 0:
+ elif account_list and k.account == account and k.credit > 0:
tds_deducted = k.credit
total_amount_credited += k.credit
diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py
index 8a397447383..0b17c8f964a 100644
--- a/erpnext/accounts/report/utils.py
+++ b/erpnext/accounts/report/utils.py
@@ -112,13 +112,15 @@ def convert_to_presentation_currency(gl_entries, currency_info):
if entry.get('debit'):
entry['debit'] = converted_value
- else:
+
+ if entry.get('credit'):
entry['credit'] = converted_value
elif account_currency == presentation_currency:
if entry.get('debit'):
entry['debit'] = debit_in_account_currency
- else:
+
+ if entry.get('credit'):
entry['credit'] = credit_in_account_currency
converted_gl_list.append(entry)
@@ -133,3 +135,22 @@ def get_appropriate_company(filters):
company = get_default_company()
return company
+
+@frappe.whitelist()
+def get_invoiced_item_gross_margin(sales_invoice=None, item_code=None, company=None):
+ from erpnext.accounts.report.gross_profit.gross_profit import GrossProfitGenerator
+
+ sales_invoice = sales_invoice or frappe.form_dict.get('sales_invoice')
+ item_code = item_code or frappe.form_dict.get('item_code')
+ company = company or frappe.get_cached_value("Sales Invoice", sales_invoice, 'company')
+
+ filters = {
+ 'sales_invoice': sales_invoice,
+ 'item_code': item_code,
+ 'company': company,
+ 'group_by': 'Invoice'
+ }
+
+ gross_profit_data = GrossProfitGenerator(filters)
+
+ return gross_profit_data.grouped_data
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index d4e1840eb9c..e9ae6ee21ac 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -544,14 +544,14 @@ def fix_total_debit_credit():
(dr_or_cr, dr_or_cr, '%s', '%s', '%s', dr_or_cr),
(d.diff, d.voucher_type, d.voucher_no))
-def get_stock_and_account_difference(account_list=None, posting_date=None):
+def get_stock_and_account_difference(account_list=None, posting_date=None, company=None):
from erpnext.stock.utils import get_stock_value_on
from erpnext.stock import get_warehouse_account_map
if not posting_date: posting_date = nowdate()
difference = {}
- warehouse_account = get_warehouse_account_map()
+ warehouse_account = get_warehouse_account_map(company)
for warehouse, account_data in iteritems(warehouse_account):
if account_data.get('account') in account_list:
@@ -615,7 +615,7 @@ def get_held_invoices(party_type, party):
return held_invoices
-def get_outstanding_invoices(party_type, party, account, condition=None, limit=None):
+def get_outstanding_invoices(party_type, party, account, condition=None):
outstanding_invoices = []
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
@@ -628,7 +628,6 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=N
invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
held_invoices = get_held_invoices(party_type, party)
- limit_cond = "limit %s" % limit if limit else ""
invoice_list = frappe.db.sql("""
select
@@ -643,11 +642,10 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=N
and (against_voucher = '' or against_voucher is null))
or (voucher_type not in ('Journal Entry', 'Payment Entry')))
group by voucher_type, voucher_no
- order by posting_date, name {limit_cond}""".format(
+ order by posting_date, name""".format(
dr_or_cr=dr_or_cr,
invoice = invoice,
- condition=condition or "",
- limit_cond = limit_cond
+ condition=condition or ""
), {
"party_type": party_type,
"party": party,
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index ed02d87e446..3b41006f2b3 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -31,7 +31,7 @@ frappe.ui.form.on('Asset', {
}
};
});
-
+
frm.set_query("cost_center", function() {
return {
"filters": {
@@ -206,12 +206,10 @@ frappe.ui.form.on('Asset', {
erpnext.asset.set_accululated_depreciation(frm);
},
- depreciation_method: function(frm) {
- frm.events.make_schedules_editable(frm);
- },
-
make_schedules_editable: function(frm) {
- var is_editable = frm.doc.depreciation_method==="Manual" ? true : false;
+ var is_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0
+ ? true : false;
+
frm.toggle_enable("schedules", is_editable);
frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable);
frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable);
@@ -296,6 +294,50 @@ frappe.ui.form.on('Asset', {
})
frm.toggle_reqd("finance_books", frm.doc.calculate_depreciation);
+ },
+
+ gross_purchase_amount: function(frm) {
+ frm.doc.finance_books.forEach(d => {
+ frm.events.set_depreciation_rate(frm, d);
+ })
+ },
+
+ set_depreciation_rate: function(frm, row) {
+ if (row.total_number_of_depreciations && row.frequency_of_depreciation) {
+ frappe.call({
+ method: "get_depreciation_rate",
+ doc: frm.doc,
+ args: row,
+ callback: function(r) {
+ if (r.message) {
+ frappe.model.set_value(row.doctype, row.name, "rate_of_depreciation", r.message);
+ }
+ }
+ });
+ }
+ }
+});
+
+frappe.ui.form.on('Asset Finance Book', {
+ depreciation_method: function(frm, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ frm.events.set_depreciation_rate(frm, row);
+ frm.events.make_schedules_editable(frm);
+ },
+
+ expected_value_after_useful_life: function(frm, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ frm.events.set_depreciation_rate(frm, row);
+ },
+
+ frequency_of_depreciation: function(frm, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ frm.events.set_depreciation_rate(frm, row);
+ },
+
+ total_number_of_depreciations: function(frm, cdt, cdn) {
+ const row = locals[cdt][cdn];
+ frm.events.set_depreciation_rate(frm, row);
}
});
diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json
index bbe92f636a7..45df6c838b7 100644
--- a/erpnext/assets/doctype/asset/asset.json
+++ b/erpnext/assets/doctype/asset/asset.json
@@ -1,1942 +1,1999 @@
{
- "allow_copy": 0,
+ "allow_copy": 0,
"allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2016-03-01 17:01:27.920130",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "naming_series:",
+ "beta": 0,
+ "creation": "2016-03-01 17:01:27.920130",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 0,
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Naming Series",
- "length": 0,
- "no_copy": 0,
- "options": "ACC-ASS-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fetch_if_empty": 0,
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Naming Series",
+ "length": 0,
+ "no_copy": 0,
+ "options": "ACC-ASS-.YYYY.-",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "asset_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Asset Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "asset_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Asset Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Item Code",
- "length": 0,
- "no_copy": 0,
- "options": "Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "item_code.item_name",
- "fieldname": "item_name",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Name",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "item_code.asset_category",
- "fieldname": "asset_category",
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "item_code",
"fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Asset Category",
- "length": 0,
- "no_copy": 0,
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Item Code",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "item_code.item_name",
+ "fetch_if_empty": 0,
+ "fieldname": "item_name",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item Name",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "item_code.asset_category",
+ "fetch_if_empty": 0,
+ "fieldname": "asset_category",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Asset Category",
+ "length": 0,
+ "no_copy": 0,
"options": "Asset Category",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "asset_owner",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Asset Owner",
- "length": 0,
- "no_copy": 0,
- "options": "\nCompany\nSupplier\nCustomer",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "asset_owner",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Asset Owner",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nCompany\nSupplier\nCustomer",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.asset_owner == \"Company\"",
- "fieldname": "asset_owner_company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Asset Owner Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.asset_owner == \"Supplier\"",
- "fieldname": "supplier",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Supplier",
- "length": 0,
- "no_copy": 0,
- "options": "Supplier",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.asset_owner == \"Customer\"",
- "fieldname": "customer",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Customer",
- "length": 0,
- "no_copy": 0,
- "options": "Customer",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "image",
- "fieldtype": "Attach Image",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Image",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 1,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "location",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Location",
- "length": 0,
- "no_copy": 0,
- "options": "Location",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "custodian",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Custodian",
- "length": 0,
- "no_copy": 0,
- "options": "Employee",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "department",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Department",
- "length": 0,
- "no_copy": 0,
- "options": "Department",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "purchase_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Purchase Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "disposal_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Disposal Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "journal_entry_for_scrap",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Journal Entry for Scrap",
- "length": 0,
- "no_copy": 1,
- "options": "Journal Entry",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_5",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "gross_purchase_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Gross Purchase Amount",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "available_for_use_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Available-for-use Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_18",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "calculate_depreciation",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Calculate Depreciation",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "is_existing_asset",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Existing Asset",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "is_existing_asset",
- "fieldname": "opening_accumulated_depreciation",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Opening Accumulated Depreciation",
- "length": 0,
- "no_copy": 1,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:(doc.is_existing_asset && doc.opening_accumulated_depreciation)",
- "fieldname": "number_of_depreciations_booked",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Number of Depreciations Booked",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "calculate_depreciation",
- "fieldname": "section_break_23",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Depreciation",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "finance_books",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Finance Books",
- "length": 0,
- "no_copy": 0,
- "options": "Asset Finance Book",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_33",
- "fieldtype": "Section Break",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "depends_on": "",
- "fieldname": "depreciation_method",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Depreciation Method",
- "length": 0,
- "no_copy": 0,
- "options": "\nStraight Line\nDouble Declining Balance\nManual",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "value_after_depreciation",
- "fieldtype": "Currency",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Value After Depreciation",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_number_of_depreciations",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Total Number of Depreciations",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_24",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "frequency_of_depreciation",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Frequency of Depreciation (Months)",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "next_depreciation_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Next Depreciation Date",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "calculate_depreciation",
- "fieldname": "section_break_14",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Depreciation Schedule",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "schedules",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Depreciation Schedules",
- "length": 0,
- "no_copy": 1,
- "options": "Depreciation Schedule",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "insurance_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Insurance details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "policy_number",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Policy number",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "insurer",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Insurer",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "insured_value",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Insured value",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_48",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "insurance_start_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Insurance Start Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "insurance_end_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Insurance End Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "comprehensive_insurance",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Comprehensive Insurance",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_31",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Maintenance",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Check if Asset requires Preventive Maintenance or Calibration",
- "fieldname": "maintenance_required",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Maintenance Required",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "other_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Other Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Draft",
- "fieldname": "status",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Status",
- "length": 0,
- "no_copy": 1,
- "options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "booked_fixed_asset",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Booked Fixed Asset",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_51",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "purchase_receipt",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Purchase Receipt",
- "length": 0,
- "no_copy": 1,
- "options": "Purchase Receipt",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "purchase_receipt_amount",
- "fieldtype": "Currency",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Purchase Receipt Amount",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "purchase_invoice",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Purchase Invoice",
- "length": 0,
- "no_copy": 1,
- "options": "Purchase Invoice",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "company.default_finance_book",
- "fieldname": "default_finance_book",
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.asset_owner == \"Company\"",
+ "fetch_if_empty": 0,
+ "fieldname": "asset_owner_company",
"fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Finance Book",
- "length": 0,
- "no_copy": 0,
- "options": "Finance Book",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Asset Owner Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amended_from",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Amended From",
- "length": 0,
- "no_copy": 1,
- "options": "Asset",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.asset_owner == \"Supplier\"",
+ "fetch_if_empty": 0,
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Supplier",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Supplier",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.asset_owner == \"Customer\"",
+ "fetch_if_empty": 0,
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Customer",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "image",
+ "fieldtype": "Attach Image",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Image",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 1,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "location",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Location",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Location",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "custodian",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Custodian",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Employee",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Department",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "purchase_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Purchase Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "disposal_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Disposal Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "journal_entry_for_scrap",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Journal Entry for Scrap",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Journal Entry",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "gross_purchase_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Gross Purchase Amount",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "available_for_use_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Available-for-use Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_18",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "calculate_depreciation",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Calculate Depreciation",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "is_existing_asset",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Existing Asset",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "is_existing_asset",
+ "fetch_if_empty": 0,
+ "fieldname": "opening_accumulated_depreciation",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Opening Accumulated Depreciation",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:(doc.is_existing_asset && doc.opening_accumulated_depreciation)",
+ "fetch_if_empty": 0,
+ "fieldname": "number_of_depreciations_booked",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Number of Depreciations Booked",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "calculate_depreciation",
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_23",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Depreciation",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "finance_books",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Finance Books",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Asset Finance Book",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_33",
+ "fieldtype": "Section Break",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "depreciation_method",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Depreciation Method",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nStraight Line\nDouble Declining Balance\nManual",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "value_after_depreciation",
+ "fieldtype": "Currency",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Value After Depreciation",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "total_number_of_depreciations",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Total Number of Depreciations",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_24",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "frequency_of_depreciation",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Frequency of Depreciation (Months)",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "next_depreciation_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Next Depreciation Date",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "calculate_depreciation",
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_14",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Depreciation Schedule",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "schedules",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Depreciation Schedules",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Depreciation Schedule",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "insurance_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Insurance details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "policy_number",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Policy number",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "insurer",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Insurer",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "insured_value",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Insured value",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_48",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "insurance_start_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Insurance Start Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "insurance_end_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Insurance End Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "comprehensive_insurance",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Comprehensive Insurance",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_31",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Maintenance",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Check if Asset requires Preventive Maintenance or Calibration",
+ "fetch_if_empty": 0,
+ "fieldname": "maintenance_required",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Maintenance Required",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "other_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Other Details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Draft",
+ "fetch_if_empty": 0,
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fetch_if_empty": 0,
+ "fieldname": "booked_fixed_asset",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Booked Fixed Asset",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_51",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "purchase_receipt",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Purchase Receipt",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Purchase Receipt",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "purchase_receipt_amount",
+ "fieldtype": "Currency",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Purchase Receipt Amount",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "purchase_invoice",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Purchase Invoice",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Purchase Invoice",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "company.default_finance_book",
+ "fetch_if_empty": 0,
+ "fieldname": "default_finance_book",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Finance Book",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Finance Book",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Asset",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 72,
- "image_field": "image",
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2019-02-12 11:29:01.747819",
- "modified_by": "Administrator",
- "module": "Assets",
- "name": "Asset",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 72,
+ "image_field": "image",
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-04-15 11:13:23.295772",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Asset",
+ "name_case": "",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Quality Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 0,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Quality Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 1,
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "title_field": "asset_name",
- "track_changes": 0,
- "track_seen": 0,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 1,
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "asset_name",
+ "track_changes": 0,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index a38b40bc60b..72f5c627a71 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -3,8 +3,9 @@
# For license information, please see license.txt
from __future__ import unicode_literals
-import frappe, erpnext
+import frappe, erpnext, math, json
from frappe import _
+from six import string_types
from frappe.utils import flt, add_months, cint, nowdate, getdate, today, date_diff
from frappe.model.document import Document
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
@@ -20,6 +21,7 @@ class Asset(AccountsController):
self.validate_item()
self.set_missing_values()
if self.calculate_depreciation:
+ self.set_depreciation_rate()
self.make_depreciation_schedule()
self.set_accumulated_depreciation()
else:
@@ -33,7 +35,7 @@ class Asset(AccountsController):
self.validate_in_use_date()
self.set_status()
self.update_stock_movement()
- if not self.booked_fixed_asset:
+ if not self.booked_fixed_asset and not is_cwip_accounting_disabled():
self.make_gl_entries()
def on_cancel(self):
@@ -71,14 +73,15 @@ class Asset(AccountsController):
if not flt(self.gross_purchase_amount):
frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
- if not self.is_existing_asset and not (self.purchase_receipt or self.purchase_invoice):
- frappe.throw(_("Please create purchase receipt or purchase invoice for the item {0}").
- format(self.item_code))
+ if not is_cwip_accounting_disabled():
+ if not self.is_existing_asset and not (self.purchase_receipt or self.purchase_invoice):
+ frappe.throw(_("Please create purchase receipt or purchase invoice for the item {0}").
+ format(self.item_code))
- if (not self.purchase_receipt and self.purchase_invoice
- and not frappe.db.get_value('Purchase Invoice', self.purchase_invoice, 'update_stock')):
- frappe.throw(_("Update stock must be enable for the purchase invoice {0}").
- format(self.purchase_invoice))
+ if (not self.purchase_receipt and self.purchase_invoice
+ and not frappe.db.get_value('Purchase Invoice', self.purchase_invoice, 'update_stock')):
+ frappe.throw(_("Update stock must be enable for the purchase invoice {0}").
+ format(self.purchase_invoice))
if not self.calculate_depreciation:
return
@@ -88,17 +91,22 @@ class Asset(AccountsController):
if self.is_existing_asset:
return
- date = nowdate()
docname = self.purchase_receipt or self.purchase_invoice
if docname:
doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
date = frappe.db.get_value(doctype, docname, 'posting_date')
- if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(date):
+ if self.available_for_use_date and getdate(self.available_for_use_date) < getdate(self.purchase_date):
frappe.throw(_("Available-for-use Date should be after purchase date"))
+ def set_depreciation_rate(self):
+ for d in self.get("finance_books"):
+ d.rate_of_depreciation = self.get_depreciation_rate(d, on_validate=True)
+
def make_depreciation_schedule(self):
- if self.depreciation_method != 'Manual':
+ depreciation_method = [d.depreciation_method for d in self.finance_books]
+
+ if 'Manual' not in depreciation_method:
self.schedules = []
if not self.get("schedules") and self.available_for_use_date:
@@ -117,7 +125,7 @@ class Asset(AccountsController):
no_of_depreciations * cint(d.frequency_of_depreciation))
total_days = date_diff(end_date, self.available_for_use_date)
- rate_per_day = value_after_depreciation / total_days
+ rate_per_day = (value_after_depreciation - d.get("expected_value_after_useful_life")) / total_days
number_of_pending_depreciations = cint(d.total_number_of_depreciations) - \
cint(self.number_of_depreciations_booked)
@@ -253,14 +261,16 @@ class Asset(AccountsController):
return flt(self.get('finance_books')[cint(idx)-1].value_after_depreciation)
def get_depreciation_amount(self, depreciable_value, total_number_of_depreciations, row):
- percentage_value = 100.0 if row.depreciation_method == 'Written Down Value' else 200.0
+ if row.depreciation_method in ["Straight Line", "Manual"]:
+ amt = (flt(self.gross_purchase_amount) - flt(row.expected_value_after_useful_life) -
+ flt(self.opening_accumulated_depreciation))
- factor = percentage_value / total_number_of_depreciations
- depreciation_amount = flt(depreciable_value * factor / 100, 0)
-
- value_after_depreciation = flt(depreciable_value) - depreciation_amount
- if value_after_depreciation < flt(row.expected_value_after_useful_life):
- depreciation_amount = flt(depreciable_value) - flt(row.expected_value_after_useful_life)
+ depreciation_amount = amt * row.rate_of_depreciation
+ else:
+ depreciation_amount = flt(depreciable_value) * (flt(row.rate_of_depreciation) / 100)
+ value_after_depreciation = flt(depreciable_value) - depreciation_amount
+ if value_after_depreciation < flt(row.expected_value_after_useful_life):
+ depreciation_amount = flt(depreciable_value) - flt(row.expected_value_after_useful_life)
return depreciation_amount
@@ -275,14 +285,14 @@ class Asset(AccountsController):
flt(row.expected_value_after_useful_life)) / (cint(row.total_number_of_depreciations) -
cint(self.number_of_depreciations_booked)) * prorata_temporis
else:
- depreciation_amount = self.get_depreciation_amount(depreciable_value, row)
+ depreciation_amount = self.get_depreciation_amount(depreciable_value, row.total_number_of_depreciations, row)
return depreciation_amount
def validate_expected_value_after_useful_life(self):
for row in self.get('finance_books'):
- accumulated_depreciation_after_full_schedule = \
- max([d.accumulated_depreciation_amount for d in self.get("schedules") if d.finance_book_id == row.idx])
+ accumulated_depreciation_after_full_schedule = max([d.accumulated_depreciation_amount
+ for d in self.get("schedules") if cint(d.finance_book_id) == row.idx])
asset_value_after_full_schedule = flt(flt(self.gross_purchase_amount) -
flt(accumulated_depreciation_after_full_schedule),
@@ -393,6 +403,35 @@ class Asset(AccountsController):
make_gl_entries(gl_entries)
self.db_set('booked_fixed_asset', 1)
+ def get_depreciation_rate(self, args, on_validate=False):
+ if isinstance(args, string_types):
+ args = json.loads(args)
+
+ number_of_depreciations_booked = 0
+ if self.is_existing_asset:
+ number_of_depreciations_booked = self.number_of_depreciations_booked
+
+ float_precision = cint(frappe.db.get_default("float_precision")) or 2
+ tot_no_of_depreciation = flt(args.get("total_number_of_depreciations")) - flt(number_of_depreciations_booked)
+
+ if args.get("depreciation_method") in ["Straight Line", "Manual"]:
+ return 1.0 / tot_no_of_depreciation
+
+ if args.get("depreciation_method") == 'Double Declining Balance':
+ return 200.0 / args.get("total_number_of_depreciations")
+
+ if args.get("depreciation_method") == "Written Down Value":
+ if args.get("rate_of_depreciation") and on_validate:
+ return args.get("rate_of_depreciation")
+
+ no_of_years = flt(args.get("total_number_of_depreciations") * flt(args.get("frequency_of_depreciation"))) / 12
+ value = flt(args.get("expected_value_after_useful_life")) / flt(self.gross_purchase_amount)
+
+ # square root of flt(salvage_value) / flt(asset_cost)
+ depreciation_rate = math.pow(value, 1.0/flt(no_of_years, 2))
+
+ return 100 * (1 - flt(depreciation_rate, float_precision))
+
def update_maintenance_status():
assets = frappe.get_all('Asset', filters = {'docstatus': 1, 'maintenance_required': 1})
@@ -404,6 +443,9 @@ def update_maintenance_status():
asset.set_status('Out of Order')
def make_post_gl_entry():
+ if is_cwip_accounting_disabled():
+ return
+
assets = frappe.db.sql_list(""" select name from `tabAsset`
where ifnull(booked_fixed_asset, 0) = 0 and available_for_use_date = %s""", nowdate())
@@ -476,7 +518,6 @@ def create_asset_adjustment(asset, asset_category, company):
@frappe.whitelist()
def transfer_asset(args):
- import json
args = json.loads(args)
if args.get('serial_no'):
@@ -551,3 +592,6 @@ def make_journal_entry(asset_name):
})
return je
+
+def is_cwip_accounting_disabled():
+ return cint(frappe.db.get_single_value("Asset Settings", "disable_cwip_accounting"))
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index a12348e451b..ef85ffa1cb8 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -102,9 +102,9 @@ class TestAsset(unittest.TestCase):
asset.save()
self.assertEqual(asset.status, "Draft")
expected_schedules = [
- ["2020-06-06", 163.93, 163.93],
- ["2021-04-06", 49836.07, 50000.0],
- ["2022-02-06", 40000.0, 90000.00]
+ ["2020-06-06", 147.54, 147.54],
+ ["2021-04-06", 44852.46, 45000.0],
+ ["2022-02-06", 45000.0, 90000.00]
]
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
@@ -130,8 +130,8 @@ class TestAsset(unittest.TestCase):
self.assertEqual(asset.status, "Draft")
asset.save()
expected_schedules = [
- ["2020-06-06", 197.37, 40197.37],
- ["2021-04-06", 49802.63, 90000.00]
+ ["2020-06-06", 164.47, 40164.47],
+ ["2021-04-06", 49835.53, 90000.00]
]
schedules = [[cstr(d.schedule_date), flt(d.depreciation_amount, 2), d.accumulated_depreciation_amount]
for d in asset.get("schedules")]
@@ -160,9 +160,9 @@ class TestAsset(unittest.TestCase):
asset.save()
expected_schedules = [
- ["2020-06-06", 66667.0, 66667.0],
- ["2021-04-06", 22222.0, 88889.0],
- ["2022-02-06", 1111.0, 90000.0]
+ ["2020-06-06", 66666.67, 66666.67],
+ ["2021-04-06", 22222.22, 88888.89],
+ ["2022-02-06", 1111.11, 90000.0]
]
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
@@ -192,8 +192,8 @@ class TestAsset(unittest.TestCase):
asset.save()
expected_schedules = [
- ["2020-06-06", 33333.0, 83333.0],
- ["2021-04-06", 6667.0, 90000.0]
+ ["2020-06-06", 33333.33, 83333.33],
+ ["2021-04-06", 6666.67, 90000.0]
]
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
@@ -209,7 +209,7 @@ class TestAsset(unittest.TestCase):
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
asset = frappe.get_doc('Asset', asset_name)
asset.calculate_depreciation = 1
- asset.purchase_date = '2020-06-06'
+ asset.purchase_date = '2020-01-30'
asset.is_existing_asset = 0
asset.available_for_use_date = "2020-01-30"
asset.append("finance_books", {
@@ -244,7 +244,7 @@ class TestAsset(unittest.TestCase):
asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
asset = frappe.get_doc('Asset', asset_name)
asset.calculate_depreciation = 1
- asset.purchase_date = '2020-06-06'
+ asset.purchase_date = '2020-01-30'
asset.available_for_use_date = "2020-01-30"
asset.append("finance_books", {
"expected_value_after_useful_life": 10000,
@@ -266,8 +266,8 @@ class TestAsset(unittest.TestCase):
self.assertEqual(asset.get("schedules")[0].journal_entry[:4], "DEPR")
expected_gle = (
- ("_Test Accumulated Depreciations - _TC", 0.0, 35699.15),
- ("_Test Depreciations - _TC", 35699.15, 0.0)
+ ("_Test Accumulated Depreciations - _TC", 0.0, 32129.24),
+ ("_Test Depreciations - _TC", 32129.24, 0.0)
)
gle = frappe.db.sql("""select account, debit, credit from `tabGL Entry`
@@ -277,6 +277,37 @@ class TestAsset(unittest.TestCase):
self.assertEqual(gle, expected_gle)
self.assertEqual(asset.get("value_after_depreciation"), 0)
+ def test_depreciation_entry_for_wdv(self):
+ pr = make_purchase_receipt(item_code="Macbook Pro",
+ qty=1, rate=8000.0, location="Test Location")
+
+ asset_name = frappe.db.get_value("Asset", {"purchase_receipt": pr.name}, 'name')
+ asset = frappe.get_doc('Asset', asset_name)
+ asset.calculate_depreciation = 1
+ asset.available_for_use_date = '2030-06-06'
+ asset.purchase_date = '2030-06-06'
+ asset.append("finance_books", {
+ "expected_value_after_useful_life": 1000,
+ "depreciation_method": "Written Down Value",
+ "total_number_of_depreciations": 3,
+ "frequency_of_depreciation": 12,
+ "depreciation_start_date": "2030-12-31"
+ })
+ asset.save(ignore_permissions=True)
+
+ self.assertEqual(asset.finance_books[0].rate_of_depreciation, 50.0)
+
+ expected_schedules = [
+ ["2030-12-31", 4000.0, 4000.0],
+ ["2031-12-31", 2000.0, 6000.0],
+ ["2032-12-31", 1000.0, 7000.0],
+ ]
+
+ schedules = [[cstr(d.schedule_date), flt(d.depreciation_amount, 2), flt(d.accumulated_depreciation_amount, 2)]
+ for d in asset.get("schedules")]
+
+ self.assertEqual(schedules, expected_schedules)
+
def test_depreciation_entry_cancellation(self):
pr = make_purchase_receipt(item_code="Macbook Pro",
qty=1, rate=100000.0, location="Test Location")
diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
index f75c8510dcb..c80f95e1555 100644
--- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
+++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -14,11 +15,13 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "finance_book",
"fieldtype": "Link",
"hidden": 0,
@@ -42,14 +45,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "depreciation_method",
"fieldtype": "Select",
"hidden": 0,
@@ -73,14 +79,17 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_number_of_depreciations",
"fieldtype": "Int",
"hidden": 0,
@@ -103,14 +112,17 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"hidden": 0,
@@ -133,14 +145,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "frequency_of_depreciation",
"fieldtype": "Int",
"hidden": 0,
@@ -163,15 +178,18 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:parent.doctype == 'Asset'",
+ "fetch_if_empty": 0,
"fieldname": "depreciation_start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -194,16 +212,19 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"depends_on": "eval:parent.doctype == 'Asset'",
+ "fetch_if_empty": 0,
"fieldname": "expected_value_after_useful_life",
"fieldtype": "Currency",
"hidden": 0,
@@ -227,14 +248,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "value_after_depreciation",
"fieldtype": "Currency",
"hidden": 1,
@@ -258,20 +282,54 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.depreciation_method == 'Written Down Value'",
+ "description": "In Percentage",
+ "fetch_if_empty": 0,
+ "fieldname": "rate_of_depreciation",
+ "fieldtype": "Percent",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Rate of Depreciation",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
- "hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
- "image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-05-12 14:56:44.800046",
+ "modified": "2019-04-09 19:45:14.523488",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Finance Book",
@@ -280,10 +338,10 @@
"permissions": [],
"quick_entry": 1,
"read_only": 0,
- "read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_settings/asset_settings.json b/erpnext/assets/doctype/asset_settings/asset_settings.json
index d6ddd33c302..a3fee96f4ee 100644
--- a/erpnext/assets/doctype/asset_settings/asset_settings.json
+++ b/erpnext/assets/doctype/asset_settings/asset_settings.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -14,10 +15,12 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "depreciation_options",
"fieldtype": "Section Break",
"hidden": 0,
@@ -40,14 +43,17 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "schedule_based_on_fiscal_year",
"fieldtype": "Check",
"hidden": 0,
@@ -70,10 +76,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -81,6 +89,7 @@
"default": "360",
"depends_on": "eval:doc.schedule_based_on_fiscal_year",
"description": "This value is used for pro-rata temporis calculation",
+ "fetch_if_empty": 0,
"fieldname": "number_of_days_in_fiscal_year",
"fieldtype": "Data",
"hidden": 0,
@@ -103,6 +112,40 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "disable_cwip_accounting",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Disable CWIP Accounting",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -116,7 +159,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-01-05 10:10:39.803255",
+ "modified": "2019-03-08 10:44:41.924547",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Settings",
@@ -125,7 +168,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -145,7 +187,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -171,5 +212,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index a4a636d6baa..56480144e85 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -379,7 +379,9 @@ def make_purchase_invoice(source_name, target_doc=None):
def postprocess(source, target):
set_missing_values(source, target)
#Get the advance paid Journal Entries in Purchase Invoice Advance
- target.set_advances()
+
+ if target.get("allocate_advances_automatically"):
+ target.set_advances()
def update_item(obj, target, source_parent):
target.amount = flt(obj.amount) - flt(obj.billed_amt)
@@ -388,11 +390,12 @@ def make_purchase_invoice(source_name, target_doc=None):
item = get_item_defaults(target.item_code, source_parent.company)
item_group = get_item_group_defaults(target.item_code, source_parent.company)
- target.cost_center = frappe.db.get_value("Project", obj.project, "cost_center") \
- or item.get("buying_cost_center") \
- or item_group.get("buying_cost_center")
+ target.cost_center = (obj.cost_center
+ or frappe.db.get_value("Project", obj.project, "cost_center")
+ or item.get("buying_cost_center")
+ or item_group.get("buying_cost_center"))
- doc = get_mapped_doc("Purchase Order", source_name, {
+ fields = {
"Purchase Order": {
"doctype": "Purchase Invoice",
"field_map": {
@@ -416,7 +419,15 @@ def make_purchase_invoice(source_name, target_doc=None):
"doctype": "Purchase Taxes and Charges",
"add_if_empty": True
}
- }, target_doc, postprocess)
+ }
+
+ if frappe.get_single("Accounts Settings").automatically_fetch_payment_terms == 1:
+ fields["Payment Schedule"] = {
+ "doctype": "Payment Schedule",
+ "add_if_empty": True
+ }
+
+ doc = get_mapped_doc("Purchase Order", source_name, fields, target_doc, postprocess)
return doc
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index f1507364dfb..c7401faeb2d 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -6,7 +6,7 @@ import unittest
import frappe
import frappe.defaults
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
-from frappe.utils import flt, add_days, nowdate
+from frappe.utils import flt, add_days, nowdate, getdate
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.buying.doctype.purchase_order.purchase_order import (make_purchase_receipt, make_purchase_invoice, make_rm_stock_entry as make_subcontract_transfer_entry)
from erpnext.stock.doctype.material_request.test_material_request import make_material_request
@@ -133,9 +133,9 @@ class TestPurchaseOrder(unittest.TestCase):
po.submit()
self.assertEqual(po.payment_schedule[0].payment_amount, 2500.0)
- self.assertEqual(po.payment_schedule[0].due_date, po.transaction_date)
+ self.assertEqual(getdate(po.payment_schedule[0].due_date), getdate(po.transaction_date))
self.assertEqual(po.payment_schedule[1].payment_amount, 2500.0)
- self.assertEqual(po.payment_schedule[1].due_date, add_days(po.transaction_date, 30))
+ self.assertEqual(getdate(po.payment_schedule[1].due_date), add_days(getdate(po.transaction_date), 30))
pi = make_purchase_invoice(po.name)
pi.save()
@@ -143,9 +143,9 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEqual(len(pi.get("items", [])), 1)
self.assertEqual(pi.payment_schedule[0].payment_amount, 2500.0)
- self.assertEqual(pi.payment_schedule[0].due_date, po.transaction_date)
+ self.assertEqual(getdate(pi.payment_schedule[0].due_date), getdate(po.transaction_date))
self.assertEqual(pi.payment_schedule[1].payment_amount, 2500.0)
- self.assertEqual(pi.payment_schedule[1].due_date, add_days(po.transaction_date, 30))
+ self.assertEqual(getdate(pi.payment_schedule[1].due_date), add_days(getdate(po.transaction_date), 30))
def test_subcontracting(self):
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes")
@@ -294,6 +294,10 @@ class TestPurchaseOrder(unittest.TestCase):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, basic_rate=100)
make_stock_entry(target="_Test Warehouse - _TC", item_code="_Test Item Home Desktop 100",
qty=20, basic_rate=100)
+ make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item",
+ qty=30, basic_rate=100)
+ make_stock_entry(target="_Test Warehouse 1 - _TC", item_code="_Test Item Home Desktop 100",
+ qty=30, basic_rate=100)
bin1 = frappe.db.get_value("Bin",
filters={"warehouse": "_Test Warehouse - _TC", "item_code": "_Test Item"},
diff --git a/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.json b/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.json
index f351f3b5735..55786ae4ccc 100644
--- a/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.json
+++ b/erpnext/buying/report/requested_items_to_be_ordered/requested_items_to_be_ordered.json
@@ -1,18 +1,19 @@
{
"add_total_row": 1,
- "apply_user_permissions": 1,
"creation": "2013-05-13 16:10:02",
+ "disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 3,
"is_standard": "Yes",
- "modified": "2017-02-24 20:10:53.005589",
+ "modified": "2019-04-19 14:54:49.123836",
"modified_by": "Administrator",
"module": "Buying",
"name": "Requested Items To Be Ordered",
"owner": "Administrator",
- "query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tsum(ifnull(mr_item.qty, 0)) as \"Qty:Float:100\",\n\tsum(ifnull(mr_item.ordered_qty, 0)) as \"Ordered Qty:Float:100\", \n\t(sum(mr_item.qty) - sum(ifnull(mr_item.ordered_qty, 0))) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\",\n\tmr.company as \"Company:Link/Company:\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\ngroup by mr.name, mr_item.item_code\nhaving\n\tsum(ifnull(mr_item.ordered_qty, 0)) < sum(ifnull(mr_item.qty, 0))\norder by mr.transaction_date asc",
+ "prepared_report": 0,
+ "query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n\tmr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tsum(ifnull(mr_item.stock_qty, 0)) as \"Qty:Float:100\",\n\tifnull(mr_item.stock_uom, '') as \"UOM:Link/UOM:100\",\n\tsum(ifnull(mr_item.ordered_qty, 0)) as \"Ordered Qty:Float:100\", \n\t(sum(mr_item.stock_qty) - sum(ifnull(mr_item.ordered_qty, 0))) as \"Qty to Order:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\",\n\tmr.company as \"Company:Link/Company:\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\ngroup by mr.name, mr_item.item_code\nhaving\n\tsum(ifnull(mr_item.ordered_qty, 0)) < sum(ifnull(mr_item.stock_qty, 0))\norder by mr.transaction_date asc",
"ref_doctype": "Purchase Order",
"report_name": "Requested Items To Be Ordered",
"report_type": "Query Report",
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index 42d0df0a06f..cd4edd8ccd6 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -27,6 +27,11 @@ def get_data():
"type": "doctype",
"name": "Payment Entry",
"description": _("Bank/Cash transactions against party or for internal transfer")
+ },
+ {
+ "type": "doctype",
+ "name": "Payment Term",
+ "description": _("Payment Terms based on conditions")
}
]
@@ -76,6 +81,14 @@ def get_data():
{
"type": "doctype",
"name": "Item",
+ },
+ {
+ "type": "doctype",
+ "name": "Bank",
+ },
+ {
+ "type": "doctype",
+ "name": "Bank Account",
}
]
},
@@ -135,6 +148,12 @@ def get_data():
"name": "Bank Reconciliation",
"description": _("Update bank payment dates with journals.")
},
+ {
+ "type": "page",
+ "label": _("Reconcile payments and bank transactions"),
+ "name": "bank-reconciliation",
+ "description": _("Link bank transactions with payments.")
+ },
{
"type": "doctype",
"label": _("Match Payments with Invoices"),
@@ -270,6 +289,11 @@ def get_data():
"name": "Currency Exchange",
"description": _("Currency exchange rate master.")
},
+ {
+ "type": "doctype",
+ "name": "Exchange Rate Revaluation",
+ "description": _("Exchange Rate Revaluation master.")
+ },
{
"type": "doctype",
"name": "Payment Gateway Account",
diff --git a/erpnext/config/integrations.py b/erpnext/config/integrations.py
index 01e077fba39..52c9ab8e46c 100644
--- a/erpnext/config/integrations.py
+++ b/erpnext/config/integrations.py
@@ -35,6 +35,11 @@ def get_data():
"type": "doctype",
"name": "Amazon MWS Settings",
"description": _("Connect Amazon with ERPNext"),
+ },
+ {
+ "type": "doctype",
+ "name": "Plaid Settings",
+ "description": _("Connect your bank accounts to ERPNext"),
}
]
}
diff --git a/erpnext/config/selling.py b/erpnext/config/selling.py
index 94f31028311..99b8ce0e5ec 100644
--- a/erpnext/config/selling.py
+++ b/erpnext/config/selling.py
@@ -325,7 +325,7 @@ def get_data():
{
"type": "help",
"label": _("Sales Order to Payment"),
- "youtube_id": "7AMq4lqkN4A"
+ "youtube_id": "1eP90MWoDQM"
},
{
"type": "help",
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 34bbe7b9994..6d767edbdcb 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -30,8 +30,8 @@ class AccountsController(TransactionBase):
return self.__company_currency
def onload(self):
- self.get("__onload").make_payment_via_journal_entry \
- = frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry')
+ self.set_onload("make_payment_via_journal_entry",
+ frappe.db.get_single_value('Accounts Settings', 'make_payment_via_journal_entry'))
if self.is_new():
relevant_docs = ("Quotation", "Purchase Order", "Sales Order",
@@ -88,7 +88,8 @@ class AccountsController(TransactionBase):
self.validate_paid_amount()
if self.doctype in ['Purchase Invoice', 'Sales Invoice']:
- if cint(self.allocate_advances_automatically):
+ pos_check_field = "is_pos" if self.doctype=="Sales Invoice" else "is_paid"
+ if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
self.set_advances()
if self.is_return:
@@ -959,11 +960,11 @@ def get_advance_journal_entries(party_type, party, party_account, amount_field,
def get_advance_payment_entries(party_type, party, party_account, order_doctype,
- order_list=None, include_unallocated=True, against_all_orders=False, limit=1000):
+ order_list=None, include_unallocated=True, against_all_orders=False, limit=None):
party_account_field = "paid_from" if party_type == "Customer" else "paid_to"
payment_type = "Receive" if party_type == "Customer" else "Pay"
payment_entries_against_order, unallocated_payment_entries = [], []
- limit_cond = "limit %s" % (limit or 1000)
+ limit_cond = "limit %s" % limit if limit else ""
if order_list or against_all_orders:
if order_list:
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 4c16323ca3d..f8f1e544596 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -172,8 +172,8 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
or tabItem.item_code LIKE %(txt)s
or tabItem.item_group LIKE %(txt)s
or tabItem.item_name LIKE %(txt)s
- or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s
- {description_cond}))
+ or tabItem.item_code IN (select parent from `tabItem Barcode` where barcode LIKE %(txt)s)
+ {description_cond})
{fcond} {mcond}
order by
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
diff --git a/erpnext/controllers/sales_and_purchase_return.py b/erpnext/controllers/sales_and_purchase_return.py
index 3106772239b..8cf11f785be 100644
--- a/erpnext/controllers/sales_and_purchase_return.py
+++ b/erpnext/controllers/sales_and_purchase_return.py
@@ -2,8 +2,9 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
from frappe import _
+from frappe.model.meta import get_field_precision
from frappe.utils import flt, get_datetime, format_datetime
class StockOverReturnError(frappe.ValidationError): pass
@@ -116,6 +117,10 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
already_returned_data = already_returned_items.get(args.item_code) or {}
+ company_currency = erpnext.get_company_currency(doc.company)
+ stock_qty_precision = get_field_precision(frappe.get_meta(doc.doctype + " Item")
+ .get_field("stock_qty"), company_currency)
+
for column in fields:
returned_qty = flt(already_returned_data.get(column, 0)) if len(already_returned_data) > 0 else 0
@@ -126,7 +131,7 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
reference_qty = ref.get(column) * ref.get("conversion_factor", 1.0)
current_stock_qty = args.get(column) * args.get("conversion_factor", 1.0)
- max_returnable_qty = flt(reference_qty) - returned_qty
+ max_returnable_qty = flt(reference_qty, stock_qty_precision) - returned_qty
label = column.replace('_', ' ').title()
if reference_qty:
@@ -135,7 +140,7 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
elif returned_qty >= reference_qty and args.get(column):
frappe.throw(_("Item {0} has already been returned")
.format(args.item_code), StockOverReturnError)
- elif abs(current_stock_qty) > max_returnable_qty:
+ elif abs(flt(current_stock_qty, stock_qty_precision)) > max_returnable_qty:
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
.format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
@@ -242,6 +247,10 @@ def make_return_doc(doctype, source_name, target_doc=None):
doc.paid_amount = -1 * source.paid_amount
doc.base_paid_amount = -1 * source.base_paid_amount
+ if doc.get("is_return") and hasattr(doc, "packed_items"):
+ for d in doc.get("packed_items"):
+ d.qty = d.qty * -1
+
doc.discount_amount = -1 * source.discount_amount
doc.run_method("calculate_taxes_and_totals")
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index d94564e4b5c..b7d2bad17ab 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -34,8 +34,8 @@ status_map = {
],
"Sales Order": [
["Draft", None],
- ["To Deliver and Bill", "eval:self.per_delivered < 100 and self.per_billed < 100 and self.docstatus == 1"],
- ["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"],
+ ["To Deliver and Bill", "eval:self.per_delivered < 100 and self.per_billed < 100 and self.docstatus == 1 and self.order_type in ['Sales', 'Shopping Cart']"],
+ ["To Bill", "eval:self.per_delivered == 100 or self.order_type == 'Maintenance' and self.per_billed < 100 and self.docstatus == 1"],
["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"],
["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"],
["Completed", "eval:self.order_type == 'Maintenance' and self.per_billed == 100 and self.docstatus == 1"],
@@ -95,6 +95,10 @@ status_map = {
["Ordered", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"]
+ ],
+ "Bank Transaction": [
+ ["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"],
+ ["Reconciled", "eval:self.docstatus == 1 and self.unallocated_amount<=0"]
]
}
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 0a3cd3499b1..d1ffd7db66d 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -26,7 +26,7 @@ class StockController(AccountsController):
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
if cint(erpnext.is_perpetual_inventory_enabled(self.company)):
- warehouse_account = get_warehouse_account_map()
+ warehouse_account = get_warehouse_account_map(self.company)
if self.docstatus==1:
if not gl_entries:
@@ -36,7 +36,7 @@ class StockController(AccountsController):
if repost_future_gle:
items, warehouses = self.get_items_and_warehouses()
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items,
- warehouse_account)
+ warehouse_account, company=self.company)
elif self.doctype in ['Purchase Receipt', 'Purchase Invoice'] and self.docstatus == 1:
gl_entries = []
gl_entries = self.get_asset_gl_entry(gl_entries)
@@ -46,7 +46,7 @@ class StockController(AccountsController):
default_cost_center=None):
if not warehouse_account:
- warehouse_account = get_warehouse_account_map()
+ warehouse_account = get_warehouse_account_map(self.company)
sle_map = self.get_stock_ledger_details()
voucher_details = self.get_voucher_details(default_expense_account, default_cost_center, sle_map)
@@ -199,7 +199,8 @@ class StockController(AccountsController):
def make_adjustment_entry(self, expected_gle, voucher_obj):
from erpnext.accounts.utils import get_stock_and_account_difference
account_list = [d.account for d in expected_gle]
- acc_diff = get_stock_and_account_difference(account_list, expected_gle[0].posting_date)
+ acc_diff = get_stock_and_account_difference(account_list,
+ expected_gle[0].posting_date, self.company)
cost_center = self.get_company_default("cost_center")
stock_adjustment_account = self.get_company_default("stock_adjustment_account")
@@ -361,13 +362,13 @@ class StockController(AccountsController):
frappe.get_doc("Blanket Order", blanket_order).update_ordered_qty()
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
- warehouse_account=None):
+ warehouse_account=None, company=None):
def _delete_gl_entries(voucher_type, voucher_no):
frappe.db.sql("""delete from `tabGL Entry`
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
if not warehouse_account:
- warehouse_account = get_warehouse_account_map()
+ warehouse_account = get_warehouse_account_map(company)
future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items)
gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 5bbef1831ad..2db18298d38 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -608,7 +608,7 @@ def get_itemised_tax_breakup_data(doc):
return itemised_tax, itemised_taxable_amount
-def get_itemised_tax(taxes):
+def get_itemised_tax(taxes, with_tax_account=False):
itemised_tax = {}
for tax in taxes:
if getattr(tax, "category", None) and tax.category=="Valuation":
@@ -633,6 +633,9 @@ def get_itemised_tax(taxes):
tax_amount = tax_amount
))
+ if with_tax_account:
+ itemised_tax[item_code][tax.description].tax_account = tax.account_head
+
return itemised_tax
def get_itemised_taxable_amount(items):
diff --git a/erpnext/controllers/tests/test_item_variant.py b/erpnext/controllers/tests/test_item_variant.py
index d4b5dd2e1ef..c257215e718 100644
--- a/erpnext/controllers/tests/test_item_variant.py
+++ b/erpnext/controllers/tests/test_item_variant.py
@@ -42,10 +42,10 @@ def create_variant_with_tables(item, args):
return variant
def make_item_variant():
- frappe.delete_doc_if_exists("Item", "_Test Variant Item-S", force=1)
- variant = create_variant_with_tables("_Test Variant Item", '{"Test Size": "Small"}')
- variant.item_code = "_Test Variant Item-S"
- variant.item_name = "_Test Variant Item-S"
+ frappe.delete_doc_if_exists("Item", "_Test Variant Item-XSL", force=1)
+ variant = create_variant_with_tables("_Test Variant Item", '{"Test Size": "Extra Small"}')
+ variant.item_code = "_Test Variant Item-XSL"
+ variant.item_name = "_Test Variant Item-XSL"
variant.save()
return variant
diff --git a/erpnext/crm/doctype/lead/lead.py b/erpnext/crm/doctype/lead/lead.py
index 29ca71bd88e..d3d31b8e702 100644
--- a/erpnext/crm/doctype/lead/lead.py
+++ b/erpnext/crm/doctype/lead/lead.py
@@ -10,6 +10,7 @@ from frappe.model.mapper import get_mapped_doc
from erpnext.controllers.selling_controller import SellingController
from frappe.contacts.address_and_contact import load_address_and_contact
from erpnext.accounts.party import set_taxes
+from frappe.email.inbox import link_communication_to_document
sender_field = "email_id"
@@ -89,11 +90,11 @@ class Lead(SellingController):
return frappe.db.get_value("Customer", {"lead_name": self.name})
def has_opportunity(self):
- return frappe.db.get_value("Opportunity", {"lead": self.name, "status": ["!=", "Lost"]})
+ return frappe.db.get_value("Opportunity", {"party_name": self.name, "status": ["!=", "Lost"]})
def has_quotation(self):
return frappe.db.get_value("Quotation", {
- "lead": self.name,
+ "party_name": self.name,
"docstatus": 1,
"status": ["!=", "Lost"]
@@ -185,7 +186,7 @@ def get_lead_details(lead, posting_date=None, company=None):
out.update({
"territory": lead.territory,
"customer_name": lead.company_name or lead.lead_name,
- "contact_display": lead.lead_name,
+ "contact_display": " ".join(filter(None, [lead.salutation, lead.lead_name])),
"contact_email": lead.email_id,
"contact_mobile": lead.mobile_no,
"contact_phone": lead.phone,
@@ -199,3 +200,29 @@ def get_lead_details(lead, posting_date=None, company=None):
out['taxes_and_charges'] = taxes_and_charges
return out
+
+@frappe.whitelist()
+def make_lead_from_communication(communication, ignore_communication_links=False):
+ """ raise a issue from email """
+
+ doc = frappe.get_doc("Communication", communication)
+ lead_name = None
+ if doc.sender:
+ lead_name = frappe.db.get_value("Lead", {"email_id": doc.sender})
+ if not lead_name and doc.phone_no:
+ lead_name = frappe.db.get_value("Lead", {"mobile_no": doc.phone_no})
+ if not lead_name:
+ lead = frappe.get_doc({
+ "doctype": "Lead",
+ "lead_name": doc.sender_full_name,
+ "email_id": doc.sender,
+ "mobile_no": doc.phone_no
+ })
+ lead.flags.ignore_mandatory = True
+ lead.flags.ignore_permissions = True
+ lead.insert()
+
+ lead_name = lead.name
+
+ link_communication_to_document(doc, "Lead", lead_name, ignore_communication_links)
+ return lead_name
\ No newline at end of file
diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js
index abe560ba5ee..88ce10c9561 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.js
+++ b/erpnext/crm/doctype/opportunity/opportunity.js
@@ -9,15 +9,22 @@ frappe.ui.form.on("Opportunity", {
frm.custom_make_buttons = {
'Quotation': 'Quotation',
'Supplier Quotation': 'Supplier Quotation'
- }
- },
- customer: function(frm) {
- frm.trigger('set_contact_link');
- erpnext.utils.get_party_details(frm);
+ },
+
+ frm.set_query("opportunity_from", function() {
+ return{
+ "filters": {
+ "name": ["in", ["Customer", "Lead"]],
+ }
+ }
+ });
},
- lead: function(frm) {
- frm.trigger('set_contact_link');
+ party_name: function(frm) {
+ if (frm.doc.opportunity_from == "Customer") {
+ frm.trigger('set_contact_link');
+ erpnext.utils.get_party_details(frm);
+ }
},
with_items: function(frm) {
@@ -30,15 +37,14 @@ frappe.ui.form.on("Opportunity", {
contact_person: erpnext.utils.get_contact_details,
- enquiry_from: function(frm) {
- frm.toggle_reqd("lead", frm.doc.enquiry_from==="Lead");
- frm.toggle_reqd("customer", frm.doc.enquiry_from==="Customer");
+ opportunity_from: function(frm) {
+ frm.toggle_reqd("party_name", frm.doc.opportunity_from);
+ frm.trigger("set_dynamic_field_label");
},
refresh: function(frm) {
var doc = frm.doc;
- frm.events.enquiry_from(frm);
- frm.trigger('set_contact_link');
+ frm.events.opportunity_from(frm);
frm.trigger('toggle_mandatory');
erpnext.toggle_naming_series();
@@ -75,13 +81,20 @@ frappe.ui.form.on("Opportunity", {
},
set_contact_link: function(frm) {
- if(frm.doc.customer) {
+ if(frm.doc.opportunity_from == "Customer" && frm.doc.party_name) {
frappe.dynamic_link = {doc: frm.doc, fieldname: 'customer', doctype: 'Customer'}
- } else if(frm.doc.lead) {
+ } else if(frm.doc.opportunity_from == "Lead" && frm.doc.party_name) {
frappe.dynamic_link = {doc: frm.doc, fieldname: 'lead', doctype: 'Lead'}
}
},
+ set_dynamic_field_label: function(frm){
+
+ if (frm.doc.opportunity_from) {
+ frm.set_df_property("party_name", "label", frm.doc.opportunity_from);
+ }
+ },
+
make_supplier_quotation: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.crm.doctype.opportunity.opportunity.make_supplier_quotation",
@@ -97,10 +110,6 @@ frappe.ui.form.on("Opportunity", {
// TODO commonify this code
erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
onload: function() {
- if(!this.frm.doc.enquiry_from && this.frm.doc.customer)
- this.frm.doc.enquiry_from = "Customer";
- if(!this.frm.doc.enquiry_from && this.frm.doc.lead)
- this.frm.doc.enquiry_from = "Lead";
if(!this.frm.doc.status)
set_multiple(this.frm.doc.doctype, this.frm.doc.name, { status:'Open' });
@@ -148,7 +157,7 @@ erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
$.extend(cur_frm.cscript, new erpnext.crm.Opportunity({frm: cur_frm}));
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
- if(doc.enquiry_from == 'Lead' && doc.lead)
+ if(doc.opportunity_from == 'Lead' && doc.party_name)
cur_frm.cscript.lead(doc, cdt, cdn);
}
@@ -171,10 +180,10 @@ cur_frm.cscript.item_code = function(doc, cdt, cdn) {
}
cur_frm.cscript.lead = function(doc, cdt, cdn) {
- cur_frm.toggle_display("contact_info", doc.customer || doc.lead);
+ cur_frm.toggle_display("contact_info", doc.party_name);
erpnext.utils.map_current_doc({
method: "erpnext.crm.doctype.lead.lead.make_opportunity",
- source_name: cur_frm.doc.lead,
+ source_name: cur_frm.doc.party_name,
frm: cur_frm
});
}
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index fc86842e01f..e3f43f40fd3 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -21,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "from_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -54,6 +55,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -88,8 +90,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "enquiry_from",
- "fieldtype": "Select",
+ "fetch_if_empty": 0,
+ "fieldname": "opportunity_from",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -102,7 +105,7 @@
"no_copy": 0,
"oldfieldname": "enquiry_from",
"oldfieldtype": "Select",
- "options": "\nLead\nCustomer",
+ "options": "DocType",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@@ -122,9 +125,10 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.enquiry_from===\"Customer\"",
- "fieldname": "customer",
- "fieldtype": "Link",
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "party_name",
+ "fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -132,54 +136,19 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
- "label": "Customer",
+ "label": "Customer/Lead",
"length": 0,
"no_copy": 0,
"oldfieldname": "customer",
"oldfieldtype": "Link",
- "options": "Customer",
+ "options": "opportunity_from",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.enquiry_from===\"Lead\"",
- "fieldname": "lead",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Lead",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "lead",
- "oldfieldtype": "Link",
- "options": "Lead",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -193,6 +162,8 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_from": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 0,
@@ -224,6 +195,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -256,6 +228,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
@@ -289,6 +262,7 @@
"collapsible": 0,
"columns": 0,
"default": "Sales",
+ "fetch_if_empty": 0,
"fieldname": "opportunity_type",
"fieldtype": "Link",
"hidden": 0,
@@ -324,6 +298,7 @@
"collapsible": 0,
"columns": 0,
"default": "Open",
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -359,6 +334,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.status===\"Lost\"",
+ "fetch_if_empty": 0,
"fieldname": "order_lost_reason",
"fieldtype": "Small Text",
"hidden": 0,
@@ -390,6 +366,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "mins_to_first_response",
"fieldtype": "Float",
"hidden": 0,
@@ -423,6 +400,7 @@
"collapsible": 1,
"collapsible_depends_on": "contact_by",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "next_contact",
"fieldtype": "Section Break",
"hidden": 0,
@@ -456,6 +434,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "contact_by",
"fieldtype": "Link",
"hidden": 0,
@@ -492,6 +471,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "contact_date",
"fieldtype": "Datetime",
"hidden": 0,
@@ -525,6 +505,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -557,6 +538,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "to_discuss",
"fieldtype": "Small Text",
"hidden": 0,
@@ -590,6 +572,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_14",
"fieldtype": "Section Break",
"hidden": 0,
@@ -622,6 +605,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -655,6 +639,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "opportunity_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -687,6 +672,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "with_items",
"fieldtype": "Check",
"hidden": 0,
@@ -719,6 +705,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_17",
"fieldtype": "Column Break",
"hidden": 0,
@@ -751,6 +738,7 @@
"collapsible": 0,
"columns": 0,
"default": "Prospecting",
+ "fetch_if_empty": 0,
"fieldname": "sales_stage",
"fieldtype": "Link",
"hidden": 0,
@@ -785,6 +773,7 @@
"collapsible": 0,
"columns": 0,
"default": "100",
+ "fetch_if_empty": 0,
"fieldname": "probability",
"fieldtype": "Percent",
"hidden": 0,
@@ -818,6 +807,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "with_items",
+ "fetch_if_empty": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -852,6 +842,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -888,6 +879,7 @@
"collapsible_depends_on": "next_contact_by",
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
+ "fetch_if_empty": 0,
"fieldname": "contact_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -921,6 +913,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.customer || doc.lead",
+ "fetch_if_empty": 0,
"fieldname": "customer_address",
"fieldtype": "Link",
"hidden": 0,
@@ -953,6 +946,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 1,
@@ -988,6 +982,7 @@
"columns": 0,
"depends_on": "customer",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
@@ -1022,6 +1017,7 @@
"columns": 0,
"depends_on": "customer",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_group",
"fieldtype": "Link",
"hidden": 0,
@@ -1056,6 +1052,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1087,6 +1084,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
+ "fetch_if_empty": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -1120,6 +1118,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
+ "fetch_if_empty": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1152,6 +1151,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
+ "fetch_if_empty": 0,
"fieldname": "contact_email",
"fieldtype": "Data",
"hidden": 0,
@@ -1184,6 +1184,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.lead || doc.customer",
+ "fetch_if_empty": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1216,6 +1217,7 @@
"collapsible": 1,
"collapsible_depends_on": "",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1249,6 +1251,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "source",
"fieldtype": "Link",
"hidden": 0,
@@ -1285,6 +1288,7 @@
"columns": 0,
"depends_on": "eval: doc.source==\"Campaign\"",
"description": "Enter name of campaign if source of enquiry is campaign",
+ "fetch_if_empty": 0,
"fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
@@ -1319,6 +1323,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1351,6 +1356,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -1386,6 +1392,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
+ "fetch_if_empty": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1420,6 +1427,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -1460,7 +1468,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-10-01 09:28:43.990999",
+ "modified": "2019-04-25 18:55:43.874656",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity",
@@ -1508,11 +1516,11 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
- "search_fields": "status,transaction_date,customer,lead,opportunity_type,territory,company",
+ "search_fields": "status,transaction_date,party_name,opportunity_type,territory,company",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
- "timeline_field": "customer",
+ "timeline_field": "party_name",
"title_field": "title",
"track_changes": 0,
"track_seen": 1,
diff --git a/erpnext/crm/doctype/opportunity/opportunity.py b/erpnext/crm/doctype/opportunity/opportunity.py
index e8da4e6436b..dad249213c7 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.py
+++ b/erpnext/crm/doctype/opportunity/opportunity.py
@@ -9,14 +9,15 @@ from frappe.model.mapper import get_mapped_doc
from erpnext.setup.utils import get_exchange_rate
from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import get_party_account_currency
+from frappe.email.inbox import link_communication_to_document
subject_field = "title"
sender_field = "contact_email"
class Opportunity(TransactionBase):
def after_insert(self):
- if self.lead:
- frappe.get_doc("Lead", self.lead).set_status(update=True)
+ if self.opportunity_from == "Lead":
+ frappe.get_doc("Lead", self.party_name).set_status(update=True)
def validate(self):
self._prev = frappe._dict({
@@ -28,12 +29,8 @@ class Opportunity(TransactionBase):
self.make_new_lead_if_required()
- if not self.enquiry_from:
- frappe.throw(_("Opportunity From field is mandatory"))
-
self.validate_item_details()
self.validate_uom_is_integer("uom", "qty")
- self.validate_lead_cust()
self.validate_cust_name()
if not self.title:
@@ -44,7 +41,7 @@ class Opportunity(TransactionBase):
def make_new_lead_if_required(self):
"""Set lead against new opportunity"""
- if not (self.lead or self.customer) and self.contact_email:
+ if (not self.get("party_name")) and self.contact_email:
# check if customer is already created agains the self.contact_email
customer = frappe.db.sql("""select
distinct `tabDynamic Link`.link_name as customer
@@ -60,8 +57,8 @@ class Opportunity(TransactionBase):
`tabDynamic Link`.link_doctype='Customer'
""".format(self.contact_email), as_dict=True)
if customer and customer[0].customer:
- self.customer = customer[0].customer
- self.enquiry_from = "Customer"
+ self.party_name = customer[0].customer
+ self.opportunity_from = "Customer"
return
lead_name = frappe.db.get_value("Lead", {"email_id": self.contact_email})
@@ -88,8 +85,8 @@ class Opportunity(TransactionBase):
lead.insert(ignore_permissions=True)
lead_name = lead.name
- self.enquiry_from = "Lead"
- self.lead = lead_name
+ self.opportunity_from = "Lead"
+ self.party_name = lead_name
def declare_enquiry_lost(self,arg):
if not self.has_active_quotation():
@@ -136,10 +133,10 @@ class Opportunity(TransactionBase):
return True
def validate_cust_name(self):
- if self.customer:
- self.customer_name = frappe.db.get_value("Customer", self.customer, "customer_name")
- elif self.lead:
- lead_name, company_name = frappe.db.get_value("Lead", self.lead, ["lead_name", "company_name"])
+ if self.party_name and self.opportunity_from == 'Customer':
+ self.customer_name = frappe.db.get_value("Customer", self.party_name, "customer_name")
+ elif self.party_name and self.opportunity_from == 'Lead':
+ lead_name, company_name = frappe.db.get_value("Lead", self.party_name, ["lead_name", "company_name"])
self.customer_name = company_name or lead_name
def on_update(self):
@@ -152,16 +149,16 @@ class Opportunity(TransactionBase):
opts.description = ""
opts.contact_date = self.contact_date
- if self.customer:
+ if self.party_name and self.opportunity_from == 'Customer':
if self.contact_person:
opts.description = 'Contact '+cstr(self.contact_person)
else:
- opts.description = 'Contact customer '+cstr(self.customer)
- elif self.lead:
+ opts.description = 'Contact customer '+cstr(self.party_name)
+ elif self.party_name and self.opportunity_from == 'Lead':
if self.contact_display:
opts.description = 'Contact '+cstr(self.contact_display)
else:
- opts.description = 'Contact lead '+cstr(self.lead)
+ opts.description = 'Contact lead '+cstr(self.party_name)
opts.subject = opts.description
opts.description += '. By : ' + cstr(self.contact_by)
@@ -186,17 +183,6 @@ class Opportunity(TransactionBase):
for key in item_fields:
if not d.get(key): d.set(key, item.get(key))
- def validate_lead_cust(self):
- if self.enquiry_from == 'Lead':
- if not self.lead:
- frappe.throw(_("Lead must be set if Opportunity is made from Lead"))
- else:
- self.customer = None
- elif self.enquiry_from == 'Customer':
- if not self.customer:
- msgprint(_("Customer is mandatory if 'Opportunity From' is selected as Customer"), raise_exception=1)
- else:
- self.lead = None
@frappe.whitelist()
def get_item_details(item_code):
@@ -218,8 +204,11 @@ def make_quotation(source_name, target_doc=None):
quotation = frappe.get_doc(target)
company_currency = frappe.get_cached_value('Company', quotation.company, "default_currency")
- party_account_currency = get_party_account_currency("Customer", quotation.customer,
- quotation.company) if quotation.customer else company_currency
+
+ if quotation.quotation_to == 'Customer' and quotation.party_name:
+ party_account_currency = get_party_account_currency("Customer", quotation.party_name, quotation.company)
+ else:
+ party_account_currency = company_currency
quotation.currency = party_account_currency or company_currency
@@ -245,7 +234,7 @@ def make_quotation(source_name, target_doc=None):
"Opportunity": {
"doctype": "Quotation",
"field_map": {
- "enquiry_from": "quotation_to",
+ "opportunity_from": "quotation_to",
"opportunity_type": "order_type",
"name": "enq_no",
}
@@ -321,3 +310,24 @@ def auto_close_opportunity():
doc.flags.ignore_permissions = True
doc.flags.ignore_mandatory = True
doc.save()
+
+@frappe.whitelist()
+def make_opportunity_from_communication(communication, ignore_communication_links=False):
+ from erpnext.crm.doctype.lead.lead import make_lead_from_communication
+ doc = frappe.get_doc("Communication", communication)
+
+ lead = doc.reference_name if doc.reference_doctype == "Lead" else None
+ if not lead:
+ lead = make_lead_from_communication(communication, ignore_communication_links=True)
+
+ enquiry_from = "Lead"
+
+ opportunity = frappe.get_doc({
+ "doctype": "Opportunity",
+ "enquiry_from": enquiry_from,
+ "lead": lead
+ }).insert(ignore_permissions=True)
+
+ link_communication_to_document(doc, "Opportunity", opportunity.name, ignore_communication_links)
+
+ return opportunity.name
diff --git a/erpnext/crm/doctype/opportunity/opportunity_list.js b/erpnext/crm/doctype/opportunity/opportunity_list.js
index 0dbbf8add1c..9712fb04c56 100644
--- a/erpnext/crm/doctype/opportunity/opportunity_list.js
+++ b/erpnext/crm/doctype/opportunity/opportunity_list.js
@@ -1,5 +1,5 @@
frappe.listview_settings['Opportunity'] = {
- add_fields: ["customer_name", "opportunity_type", "enquiry_from", "status"],
+ add_fields: ["customer_name", "opportunity_type", "opportunity_from", "status"],
get_indicator: function(doc) {
var indicator = [__(doc.status), frappe.utils.guess_colour(doc.status), "status,=," + doc.status];
if(doc.status=="Quotation") {
diff --git a/erpnext/crm/doctype/opportunity/test_opportunity.js b/erpnext/crm/doctype/opportunity/test_opportunity.js
index f2b04f86474..45b97ddc4d1 100644
--- a/erpnext/crm/doctype/opportunity/test_opportunity.js
+++ b/erpnext/crm/doctype/opportunity/test_opportunity.js
@@ -6,7 +6,7 @@ QUnit.test("test: opportunity", function (assert) {
() => frappe.timeout(1),
() => frappe.click_button('New'),
() => frappe.timeout(1),
- () => cur_frm.set_value('enquiry_from', 'Customer'),
+ () => cur_frm.set_value('opportunity_from', 'Customer'),
() => cur_frm.set_value('customer', 'Test Customer 1'),
// check items
diff --git a/erpnext/crm/doctype/opportunity/test_opportunity.py b/erpnext/crm/doctype/opportunity/test_opportunity.py
index ef2945b41f9..61dac90cd9f 100644
--- a/erpnext/crm/doctype/opportunity/test_opportunity.py
+++ b/erpnext/crm/doctype/opportunity/test_opportunity.py
@@ -37,13 +37,13 @@ class TestOpportunity(unittest.TestCase):
# new lead should be created against the new.opportunity@example.com
opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
- self.assertTrue(opp_doc.lead)
- self.assertEqual(opp_doc.enquiry_from, "Lead")
- self.assertEqual(frappe.db.get_value("Lead", opp_doc.lead, "email_id"),
+ self.assertTrue(opp_doc.party_name)
+ self.assertEqual(opp_doc.opportunity_from, "Lead")
+ self.assertEqual(frappe.db.get_value("Lead", opp_doc.party_name, "email_id"),
'new.opportunity@example.com')
# create new customer and create new contact against 'new.opportunity@example.com'
- customer = make_customer(opp_doc.lead).insert(ignore_permissions=True)
+ customer = make_customer(opp_doc.party_name).insert(ignore_permissions=True)
frappe.get_doc({
"doctype": "Contact",
"email_id": "new.opportunity@example.com",
@@ -55,9 +55,9 @@ class TestOpportunity(unittest.TestCase):
}).insert(ignore_permissions=True)
opp_doc = frappe.get_doc(args).insert(ignore_permissions=True)
- self.assertTrue(opp_doc.customer)
- self.assertEqual(opp_doc.enquiry_from, "Customer")
- self.assertEqual(opp_doc.customer, customer.name)
+ self.assertTrue(opp_doc.party_name)
+ self.assertEqual(opp_doc.opportunity_from, "Customer")
+ self.assertEqual(opp_doc.party_name, customer.name)
def make_opportunity(**args):
args = frappe._dict(args)
@@ -65,17 +65,17 @@ def make_opportunity(**args):
opp_doc = frappe.get_doc({
"doctype": "Opportunity",
"company": args.company or "_Test Company",
- "enquiry_from": args.enquiry_from or "Customer",
+ "opportunity_from": args.opportunity_from or "Customer",
"opportunity_type": "Sales",
"with_items": args.with_items or 0,
"transaction_date": today()
})
- if opp_doc.enquiry_from == 'Customer':
- opp_doc.customer = args.customer or "_Test Customer"
+ if opp_doc.opportunity_from == 'Customer':
+ opp_doc.party_name= args.customer or "_Test Customer"
- if opp_doc.enquiry_from == 'Lead':
- opp_doc.customer = args.lead or "_T-Lead-00001"
+ if opp_doc.opportunity_from == 'Lead':
+ opp_doc.party_name = args.lead or "_T-Lead-00001"
if args.with_items:
opp_doc.append('items', {
diff --git a/erpnext/crm/doctype/opportunity/test_records.json b/erpnext/crm/doctype/opportunity/test_records.json
index 84dfea515a0..a1e0ad921b4 100644
--- a/erpnext/crm/doctype/opportunity/test_records.json
+++ b/erpnext/crm/doctype/opportunity/test_records.json
@@ -2,9 +2,9 @@
{
"doctype": "Opportunity",
"name": "_Test Opportunity 1",
- "enquiry_from": "Lead",
+ "opportunity_from": "Lead",
"enquiry_type": "Sales",
- "lead": "_T-Lead-00001",
+ "party_name": "_T-Lead-00001",
"transaction_date": "2013-12-12",
"items": [{
"item_name": "Test Item",
diff --git a/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py b/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py
index b20fe15ce27..52b848ed504 100644
--- a/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py
+++ b/erpnext/crm/report/campaign_efficiency/campaign_efficiency.py
@@ -4,24 +4,70 @@
from __future__ import unicode_literals
import frappe
from frappe import _
+from frappe.utils import flt
def execute(filters=None):
columns, data = [], []
- columns=get_columns()
- data=get_lead_data(filters, "Campaign Name")
+ columns=get_columns("Campaign Name")
+ data=get_lead_data(filters or {}, "Campaign Name")
return columns, data
-def get_columns():
+def get_columns(based_on):
return [
- _("Campaign Name") + ":data:130",
- _("Lead Count") + ":Int:80",
- _("Opp Count") + ":Int:80",
- _("Quot Count") + ":Int:80",
- _("Order Count") + ":Int:100",
- _("Order Value") + ":Float:100",
- _("Opp/Lead %") + ":Float:100",
- _("Quot/Lead %") + ":Float:100",
- _("Order/Quot %") + ":Float:100"
+ {
+ "fieldname": frappe.scrub(based_on),
+ "label": _(based_on),
+ "fieldtype": "Data",
+ "width": 150
+ },
+ {
+ "fieldname": "lead_count",
+ "label": _("Lead Count"),
+ "fieldtype": "Int",
+ "width": 80
+ },
+ {
+ "fieldname": "opp_count",
+ "label": _("Opp Count"),
+ "fieldtype": "Int",
+ "width": 80
+ },
+ {
+ "fieldname": "quot_count",
+ "label": _("Quot Count"),
+ "fieldtype": "Int",
+ "width": 80
+ },
+ {
+ "fieldname": "order_count",
+ "label": _("Order Count"),
+ "fieldtype": "Int",
+ "width": 100
+ },
+ {
+ "fieldname": "order_value",
+ "label": _("Order Value"),
+ "fieldtype": "Float",
+ "width": 100
+ },
+ {
+ "fieldname": "opp_lead",
+ "label": _("Opp/Lead %"),
+ "fieldtype": "Float",
+ "width": 100
+ },
+ {
+ "fieldname": "quot_lead",
+ "label": _("Quot/Lead %"),
+ "fieldtype": "Float",
+ "width": 100
+ },
+ {
+ "fieldname": "order_quot",
+ "label": _("Order/Quot %"),
+ "fieldtype": "Float",
+ "width": 100
+ }
]
def get_lead_data(filters, based_on):
@@ -41,18 +87,18 @@ def get_lead_data(filters, based_on):
data = []
for based_on_value, leads in lead_map.items():
row = {
- based_on: based_on_value,
- "Lead Count": len(leads)
+ based_on_field: based_on_value,
+ "lead_count": len(leads)
}
- row["Quot Count"]= get_lead_quotation_count(leads)
- row["Opp Count"] = get_lead_opp_count(leads)
- row["Order Count"] = get_quotation_ordered_count(leads)
- row["Order Value"] = get_order_amount(leads)
+ row["quot_count"]= get_lead_quotation_count(leads)
+ row["opp_count"] = get_lead_opp_count(leads)
+ row["order_count"] = get_quotation_ordered_count(leads)
+ row["order_value"] = get_order_amount(leads) or 0
- row["Opp/Lead %"] = row["Opp Count"] / row["Lead Count"] * 100
- row["Quot/Lead %"] = row["Quot Count"] / row["Lead Count"] * 100
+ row["opp_lead"] = flt(row["opp_count"]) / flt(row["lead_count"] or 1.0) * 100.0
+ row["quot_lead"] = flt(row["quot_count"]) / flt(row["lead_count"] or 1.0) * 100.0
- row["Order/Quot %"] = row["Order Count"] / (row["Quot Count"] or 1) * 100
+ row["order_quot"] = flt(row["order_count"]) / flt(row["quot_count"] or 1.0) * 100.0
data.append(row)
diff --git a/erpnext/crm/report/lead_conversion_time/lead_conversion_time.py b/erpnext/crm/report/lead_conversion_time/lead_conversion_time.py
index d9ee30ec1ae..d91b9c5607d 100644
--- a/erpnext/crm/report/lead_conversion_time/lead_conversion_time.py
+++ b/erpnext/crm/report/lead_conversion_time/lead_conversion_time.py
@@ -66,7 +66,7 @@ def get_columns():
def get_communication_details(filters):
communication_count = None
communication_list = []
- opportunities = frappe.db.get_values('Opportunity', {'enquiry_from': 'Lead'},\
+ opportunities = frappe.db.get_values('Opportunity', {'opportunity_from': 'Lead'},\
['name', 'customer_name', 'lead', 'contact_email'], as_dict=1)
for d in opportunities:
diff --git a/erpnext/demo/user/sales.py b/erpnext/demo/user/sales.py
index 69ba9007a61..3809c1f0924 100644
--- a/erpnext/demo/user/sales.py
+++ b/erpnext/demo/user/sales.py
@@ -56,7 +56,7 @@ def work(domain="Manufacturing"):
def make_opportunity(domain):
b = frappe.get_doc({
"doctype": "Opportunity",
- "enquiry_from": "Customer",
+ "opportunity_from": "Customer",
"customer": get_random("Customer"),
"opportunity_type": "Sales",
"with_items": 1,
diff --git a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
index 04accd9b25a..4700202213f 100644
--- a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
+++ b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
@@ -19,27 +19,24 @@ def verify_request():
frappe.get_request_header("X-Wc-Webhook-Signature") and \
not sig == bytes(frappe.get_request_header("X-Wc-Webhook-Signature").encode()):
frappe.throw(_("Unverified Webhook Data"))
- frappe.set_user(woocommerce_settings.modified_by)
+ frappe.set_user(woocommerce_settings.creation_user)
@frappe.whitelist(allow_guest=True)
-def order(data=None):
- if not data:
- verify_request()
+def order():
+ woocommerce_settings = frappe.get_doc("Woocommerce Settings")
+ if frappe.flags.woocomm_test_order_data:
+ fd = frappe.flags.woocomm_test_order_data
+ event = "created"
- if frappe.request and frappe.request.data:
+ elif frappe.request and frappe.request.data:
+ verify_request()
fd = json.loads(frappe.request.data)
- elif data:
- fd = data
+ event = frappe.get_request_header("X-Wc-Webhook-Event")
+
else:
return "success"
- if not data:
- event = frappe.get_request_header("X-Wc-Webhook-Event")
- else:
- event = "created"
-
if event == "created":
-
raw_billing_data = fd.get("billing")
customer_woo_com_email = raw_billing_data.get("email")
@@ -73,7 +70,7 @@ def order(data=None):
new_sales_order.po_no = fd.get("id")
new_sales_order.woocommerce_id = fd.get("id")
- new_sales_order.naming_series = "SO-"
+ new_sales_order.naming_series = woocommerce_settings.sales_order_series or "SO-WOO-"
placed_order_date = created_date[0]
raw_date = datetime.datetime.strptime(placed_order_date, "%Y-%m-%d")
@@ -100,10 +97,10 @@ def order(data=None):
"item_name": found_item.item_name,
"description": found_item.item_name,
"delivery_date":order_delivery_date,
- "uom": "Nos",
+ "uom": woocommerce_settings.uom or _("Nos"),
"qty": item.get("quantity"),
"rate": item.get("price"),
- "warehouse": "Stores" + " - " + company_abbr
+ "warehouse": woocommerce_settings.warehouse or "Stores" + " - " + company_abbr
})
add_tax_details(new_sales_order,ordered_items_tax,"Ordered Item tax",0)
@@ -175,6 +172,7 @@ def link_customer_and_address(raw_billing_data,customer_status):
frappe.db.commit()
def link_item(item_data,item_status):
+ woocommerce_settings = frappe.get_doc("Woocommerce Settings")
if item_status == 0:
#Create Item
@@ -188,7 +186,8 @@ def link_item(item_data,item_status):
item.item_name = str(item_data.get("name"))
item.item_code = "woocommerce - " + str(item_data.get("product_id"))
item.woocommerce_id = str(item_data.get("product_id"))
- item.item_group = "WooCommerce Products"
+ item.item_group = _("WooCommerce Products")
+ item.stock_uom = woocommerce_settings.uom or _("Nos")
item.save()
frappe.db.commit()
@@ -209,4 +208,4 @@ def add_tax_details(sales_order,price,desc,status):
"account_head": account_head_type,
"tax_amount": price,
"description": desc
- })
\ No newline at end of file
+ })
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
index 3234e7a332a..124910e35de 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -162,6 +162,8 @@ def create_item_code(amazon_item_json, sku):
igroup.parent_item_group = mws_settings.item_group
igroup.insert()
+ item.append("item_defaults", {'company':mws_settings.company})
+
item.insert(ignore_permissions=True)
create_item_price(amazon_item_json, item.item_code)
@@ -213,7 +215,7 @@ def get_orders(after_date):
fulfillment_channels=["MFN", "AFN"],
lastupdatedafter=after_date,
orderstatus=statuses,
- max_results='20')
+ max_results='50')
while True:
orders_list = []
@@ -432,8 +434,8 @@ def get_order_items(market_place_order_id):
return final_order_items
def get_item_code(order_item):
- asin = order_item.ASIN
- item_code = frappe.db.get_value("Item", {"amazon_item_code": asin}, "item_code")
+ sku = order_item.SellerSKU
+ item_code = frappe.db.get_value("Item", {"item_code": sku}, "item_code")
if item_code:
return item_code
@@ -451,11 +453,16 @@ def get_charges_and_fees(market_place_order_id):
shipment_item_list = return_as_list(shipment_event.ShipmentEvent.ShipmentItemList.ShipmentItem)
for shipment_item in shipment_item_list:
- charges = return_as_list(shipment_item.ItemChargeList.ChargeComponent)
- fees = return_as_list(shipment_item.ItemFeeList.FeeComponent)
+ charges, fees = []
+
+ if 'ItemChargeList' in shipment_item.keys():
+ charges = return_as_list(shipment_item.ItemChargeList.ChargeComponent)
+
+ if 'ItemFeeList' in shipment_item.keys():
+ fees = return_as_list(shipment_item.ItemFeeList.FeeComponent)
for charge in charges:
- if(charge.ChargeType != "Principal"):
+ if(charge.ChargeType != "Principal") and float(charge.ChargeAmount.CurrencyAmount) != 0:
charge_account = get_account(charge.ChargeType)
charges_fees.get("charges").append({
"charge_type":"Actual",
@@ -465,13 +472,14 @@ def get_charges_and_fees(market_place_order_id):
})
for fee in fees:
- fee_account = get_account(fee.FeeType)
- charges_fees.get("fees").append({
- "charge_type":"Actual",
- "account_head": fee_account,
- "tax_amount": fee.FeeAmount.CurrencyAmount,
- "description": fee.FeeType + " for " + shipment_item.SellerSKU
- })
+ if float(fee.FeeAmount.CurrencyAmount) != 0:
+ fee_account = get_account(fee.FeeType)
+ charges_fees.get("fees").append({
+ "charge_type":"Actual",
+ "account_head": fee_account,
+ "tax_amount": fee.FeeAmount.CurrencyAmount,
+ "description": fee.FeeType + " for " + shipment_item.SellerSKU
+ })
return charges_fees
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/__init__.py b/erpnext/erpnext_integrations/doctype/plaid_settings/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py
new file mode 100644
index 00000000000..fbb0ebc2c80
--- /dev/null
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+import requests
+from plaid import Client
+from plaid.errors import APIError, ItemError
+
+class PlaidConnector():
+ def __init__(self, access_token=None):
+
+ if not(frappe.conf.get("plaid_client_id") and frappe.conf.get("plaid_secret") and frappe.conf.get("plaid_public_key")):
+ frappe.throw(_("Please complete your Plaid API configuration before synchronizing your account"))
+
+ self.config = {
+ "plaid_client_id": frappe.conf.get("plaid_client_id"),
+ "plaid_secret": frappe.conf.get("plaid_secret"),
+ "plaid_public_key": frappe.conf.get("plaid_public_key"),
+ "plaid_env": frappe.conf.get("plaid_env")
+ }
+
+ self.client = Client(client_id=self.config["plaid_client_id"],
+ secret=self.config["plaid_secret"],
+ public_key=self.config["plaid_public_key"],
+ environment=self.config["plaid_env"]
+ )
+
+ self.access_token = access_token
+
+ def get_access_token(self, public_token):
+ if public_token is None:
+ frappe.log_error(_("Public token is missing for this bank"), _("Plaid public token error"))
+
+ response = self.client.Item.public_token.exchange(public_token)
+ access_token = response['access_token']
+
+ return access_token
+
+ def auth(self):
+ try:
+ self.client.Auth.get(self.access_token)
+ print("Authentication successful.....")
+ except ItemError as e:
+ if e.code == 'ITEM_LOGIN_REQUIRED':
+ pass
+ else:
+ pass
+ except APIError as e:
+ if e.code == 'PLANNED_MAINTENANCE':
+ pass
+ else:
+ pass
+ except requests.Timeout:
+ pass
+ except Exception as e:
+ print(e)
+ frappe.log_error(frappe.get_traceback(), _("Plaid authentication error"))
+ frappe.msgprint({"title": _("Authentication Failed"), "message":e, "raise_exception":1, "indicator":'red'})
+
+ def get_transactions(self, start_date, end_date, account_id=None):
+ try:
+ self.auth()
+ if account_id:
+ account_ids = [account_id]
+
+ response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, account_ids=account_ids)
+
+ else:
+ response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date)
+
+ transactions = response['transactions']
+
+ while len(transactions) < response['total_transactions']:
+ response = self.client.Transactions.get(self.access_token, start_date=start_date, end_date=end_date, offset=len(transactions))
+ transactions.extend(response['transactions'])
+ return transactions
+ except Exception:
+ frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js
new file mode 100644
index 00000000000..ace4fbf9e30
--- /dev/null
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.js
@@ -0,0 +1,107 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.provide("erpnext.integrations");
+
+frappe.ui.form.on('Plaid Settings', {
+ link_new_account: function(frm) {
+ new erpnext.integrations.plaidLink(frm);
+ }
+});
+
+erpnext.integrations.plaidLink = class plaidLink {
+ constructor(parent) {
+ this.frm = parent;
+ this.product = ["transactions", "auth"];
+ this.plaidUrl = 'https://cdn.plaid.com/link/v2/stable/link-initialize.js';
+ this.init_config();
+ }
+
+ init_config() {
+ const me = this;
+ frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.plaid_configuration')
+ .then(result => {
+ if (result !== "disabled") {
+ if (result.plaid_env == undefined || result.plaid_public_key == undefined) {
+ frappe.throw(__("Please add valid Plaid api keys in site_config.json first"));
+ }
+ me.plaid_env = result.plaid_env;
+ me.plaid_public_key = result.plaid_public_key;
+ me.client_name = result.client_name;
+ me.init_plaid();
+ } else {
+ frappe.throw(__("Please save your document before adding a new account"));
+ }
+ });
+ }
+
+ init_plaid() {
+ const me = this;
+ me.loadScript(me.plaidUrl)
+ .then(() => {
+ me.onScriptLoaded(me);
+ })
+ .then(() => {
+ if (me.linkHandler) {
+ me.linkHandler.open();
+ }
+ })
+ .catch((error) => {
+ me.onScriptError(error);
+ });
+ }
+
+ loadScript(src) {
+ return new Promise(function (resolve, reject) {
+ if (document.querySelector('script[src="' + src + '"]')) {
+ resolve();
+ return;
+ }
+ const el = document.createElement('script');
+ el.type = 'text/javascript';
+ el.async = true;
+ el.src = src;
+ el.addEventListener('load', resolve);
+ el.addEventListener('error', reject);
+ el.addEventListener('abort', reject);
+ document.head.appendChild(el);
+ });
+ }
+
+ onScriptLoaded(me) {
+ me.linkHandler = window.Plaid.create({
+ clientName: me.client_name,
+ env: me.plaid_env,
+ key: me.plaid_public_key,
+ onSuccess: me.plaid_success,
+ product: me.product
+ });
+ }
+
+ onScriptError(error) {
+ frappe.msgprint('There was an issue loading the link-initialize.js script');
+ frappe.msgprint(error);
+ }
+
+ plaid_success(token, response) {
+ const me = this;
+
+ frappe.prompt({
+ fieldtype:"Link",
+ options: "Company",
+ label:__("Company"),
+ fieldname:"company",
+ reqd:1
+ }, (data) => {
+ me.company = data.company;
+ frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_institution', {token: token, response: response})
+ .then((result) => {
+ frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.add_bank_accounts', {response: response,
+ bank: result, company: me.company});
+ })
+ .then(() => {
+ frappe.show_alert({message:__("Bank accounts added"), indicator:'green'});
+ });
+ }, __("Select a company"), __("Continue"));
+ }
+};
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json
new file mode 100644
index 00000000000..ed51c4e8f80
--- /dev/null
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.json
@@ -0,0 +1,161 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-10-25 10:02:48.656165",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "enabled",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Enabled",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.enabled==1",
+ "fieldname": "automatic_sync",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Synchronize all accounts every hour",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:(doc.enabled==1)&&(!doc.__islocal)",
+ "fieldname": "link_new_account",
+ "fieldtype": "Button",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Link a new bank account",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 1,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-12-14 12:51:12.331395",
+ "modified_by": "Administrator",
+ "module": "ERPNext Integrations",
+ "name": "Plaid Settings",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
new file mode 100644
index 00000000000..8d31e24cd6c
--- /dev/null
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
@@ -0,0 +1,198 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import json
+from frappe import _
+from frappe.model.document import Document
+from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
+from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_connector import PlaidConnector
+from frappe.utils import getdate, formatdate, today, add_months
+
+class PlaidSettings(Document):
+ pass
+
+@frappe.whitelist()
+def plaid_configuration():
+ if frappe.db.get_value("Plaid Settings", None, "enabled") == "1":
+ return {"plaid_public_key": frappe.conf.get("plaid_public_key") or None, "plaid_env": frappe.conf.get("plaid_env") or None, "client_name": frappe.local.site }
+ else:
+ return "disabled"
+
+@frappe.whitelist()
+def add_institution(token, response):
+ response = json.loads(response)
+
+ plaid = PlaidConnector()
+ access_token = plaid.get_access_token(token)
+
+ if not frappe.db.exists("Bank", response["institution"]["name"]):
+ try:
+ bank = frappe.get_doc({
+ "doctype": "Bank",
+ "bank_name": response["institution"]["name"],
+ "plaid_access_token": access_token
+ })
+ bank.insert()
+ except Exception:
+ frappe.throw(frappe.get_traceback())
+
+ else:
+ bank = frappe.get_doc("Bank", response["institution"]["name"])
+ bank.plaid_access_token = access_token
+ bank.save()
+
+ return bank
+
+@frappe.whitelist()
+def add_bank_accounts(response, bank, company):
+ response = json.loads(response) if not "accounts" in response else response
+ bank = json.loads(bank)
+ result = []
+
+ default_gl_account = get_default_bank_cash_account(company, "Bank")
+ if not default_gl_account:
+ frappe.throw(_("Please setup a default bank account for company {0}".format(company)))
+
+ for account in response["accounts"]:
+ acc_type = frappe.db.get_value("Account Type", account["type"])
+ if not acc_type:
+ add_account_type(account["type"])
+
+ acc_subtype = frappe.db.get_value("Account Subtype", account["subtype"])
+ if not acc_subtype:
+ add_account_subtype(account["subtype"])
+
+ if not frappe.db.exists("Bank Account", dict(integration_id=account["id"])):
+ try:
+ new_account = frappe.get_doc({
+ "doctype": "Bank Account",
+ "bank": bank["bank_name"],
+ "account": default_gl_account.account,
+ "account_name": account["name"],
+ "account_type": account["type"] or "",
+ "account_subtype": account["subtype"] or "",
+ "mask": account["mask"] or "",
+ "integration_id": account["id"],
+ "is_company_account": 1,
+ "company": company
+ })
+ new_account.insert()
+
+ result.append(new_account.name)
+
+ except frappe.UniqueValidationError:
+ frappe.msgprint(_("Bank account {0} already exists and could not be created again").format(new_account.account_name))
+ except Exception:
+ frappe.throw(frappe.get_traceback())
+
+ else:
+ result.append(frappe.db.get_value("Bank Account", dict(integration_id=account["id"]), "name"))
+
+ return result
+
+def add_account_type(account_type):
+ try:
+ frappe.get_doc({
+ "doctype": "Account Type",
+ "account_type": account_type
+ }).insert()
+ except Exception:
+ frappe.throw(frappe.get_traceback())
+
+
+def add_account_subtype(account_subtype):
+ try:
+ frappe.get_doc({
+ "doctype": "Account Subtype",
+ "account_subtype": account_subtype
+ }).insert()
+ except Exception:
+ frappe.throw(frappe.get_traceback())
+
+@frappe.whitelist()
+def sync_transactions(bank, bank_account):
+
+ last_sync_date = frappe.db.get_value("Bank Account", bank_account, "last_integration_date")
+ if last_sync_date:
+ start_date = formatdate(last_sync_date, "YYYY-MM-dd")
+ else:
+ start_date = formatdate(add_months(today(), -12), "YYYY-MM-dd")
+ end_date = formatdate(today(), "YYYY-MM-dd")
+
+ try:
+ transactions = get_transactions(bank=bank, bank_account=bank_account, start_date=start_date, end_date=end_date)
+ result = []
+ if transactions:
+ for transaction in transactions:
+ result.append(new_bank_transaction(transaction))
+
+ frappe.db.set_value("Bank Account", bank_account, "last_integration_date", getdate(end_date))
+
+ return result
+ except Exception:
+ frappe.log_error(frappe.get_traceback(), _("Plaid transactions sync error"))
+
+def get_transactions(bank, bank_account=None, start_date=None, end_date=None):
+ access_token = None
+
+ if bank_account:
+ related_bank = frappe.db.get_values("Bank Account", bank_account, ["bank", "integration_id"], as_dict=True)
+ access_token = frappe.db.get_value("Bank", related_bank[0].bank, "plaid_access_token")
+ account_id = related_bank[0].integration_id
+
+ else:
+ access_token = frappe.db.get_value("Bank", bank, "plaid_access_token")
+ account_id = None
+
+ plaid = PlaidConnector(access_token)
+ transactions = plaid.get_transactions(start_date=start_date, end_date=end_date, account_id=account_id)
+
+ return transactions
+
+def new_bank_transaction(transaction):
+ result = []
+
+ bank_account = frappe.db.get_value("Bank Account", dict(integration_id=transaction["account_id"]))
+
+ if float(transaction["amount"]) >= 0:
+ debit = float(transaction["amount"])
+ credit = 0
+ else:
+ debit = 0
+ credit = abs(float(transaction["amount"]))
+
+ status = "Pending" if transaction["pending"] == "True" else "Settled"
+
+ if not frappe.db.exists("Bank Transaction", dict(transaction_id=transaction["transaction_id"])):
+ try:
+ new_transaction = frappe.get_doc({
+ "doctype": "Bank Transaction",
+ "date": getdate(transaction["date"]),
+ "status": status,
+ "bank_account": bank_account,
+ "debit": debit,
+ "credit": credit,
+ "currency": transaction["iso_currency_code"],
+ "description": transaction["name"]
+ })
+ new_transaction.insert()
+ new_transaction.submit()
+
+ result.append(new_transaction.name)
+
+ except Exception:
+ frappe.throw(frappe.get_traceback())
+
+ return result
+
+def automatic_synchronization():
+ settings = frappe.get_doc("Plaid Settings", "Plaid Settings")
+
+ if settings.enabled == 1 and settings.automatic_sync == 1:
+ plaid_accounts = frappe.get_all("Bank Account", filter={"integration_id": ["!=", ""]}, fields=["name", "bank"])
+
+ for plaid_account in plaid_accounts:
+ frappe.enqueue("erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions", bank=plaid_account.bank, bank_account=plaid_account.name)
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.js b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.js
new file mode 100644
index 00000000000..dc91347336d
--- /dev/null
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Plaid Settings", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Plaid Settings
+ () => frappe.tests.make('Plaid Settings', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
new file mode 100644
index 00000000000..29e8fa4fec8
--- /dev/null
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+import frappe
+from erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings import plaid_configuration, add_account_type, add_account_subtype, new_bank_transaction, add_bank_accounts
+import json
+from frappe.utils.response import json_handler
+from erpnext.accounts.doctype.journal_entry.journal_entry import get_default_bank_cash_account
+
+class TestPlaidSettings(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ for bt in frappe.get_all("Bank Transaction"):
+ doc = frappe.get_doc("Bank Transaction", bt.name)
+ doc.cancel()
+ doc.delete()
+
+ for ba in frappe.get_all("Bank Account"):
+ frappe.get_doc("Bank Account", ba.name).delete()
+
+ for at in frappe.get_all("Account Type"):
+ frappe.get_doc("Account Type", at.name).delete()
+
+ for ast in frappe.get_all("Account Subtype"):
+ frappe.get_doc("Account Subtype", ast.name).delete()
+
+ def test_plaid_disabled(self):
+ frappe.db.set_value("Plaid Settings", None, "enabled", 0)
+ self.assertTrue(plaid_configuration() == "disabled")
+
+ def test_add_account_type(self):
+ add_account_type("brokerage")
+ self.assertEqual(frappe.get_doc("Account Type", "brokerage").name, "brokerage")
+
+ def test_add_account_subtype(self):
+ add_account_subtype("loan")
+ self.assertEqual(frappe.get_doc("Account Subtype", "loan").name, "loan")
+
+ def test_default_bank_account(self):
+ if not frappe.db.exists("Bank", "Citi"):
+ frappe.get_doc({
+ "doctype": "Bank",
+ "bank_name": "Citi"
+ }).insert()
+
+ bank_accounts = {
+ 'account': {
+ 'subtype': 'checking',
+ 'mask': '0000',
+ 'type': 'depository',
+ 'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
+ 'name': 'Plaid Checking'
+ },
+ 'account_id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
+ 'link_session_id': 'db673d75-61aa-442a-864f-9b3f174f3725',
+ 'accounts': [{
+ 'type': 'depository',
+ 'subtype': 'checking',
+ 'mask': '0000',
+ 'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
+ 'name': 'Plaid Checking'
+ }],
+ 'institution': {
+ 'institution_id': 'ins_6',
+ 'name': 'Citi'
+ }
+ }
+
+ bank = json.dumps(frappe.get_doc("Bank", "Citi").as_dict(), default=json_handler)
+ company = frappe.db.get_single_value('Global Defaults', 'default_company')
+ frappe.db.set_value("Company", company, "default_bank_account", None)
+
+ self.assertRaises(frappe.ValidationError, add_bank_accounts, response=bank_accounts, bank=bank, company=company)
+
+ def test_new_transaction(self):
+ if not frappe.db.exists("Bank", "Citi"):
+ frappe.get_doc({
+ "doctype": "Bank",
+ "bank_name": "Citi"
+ }).insert()
+
+ bank_accounts = {
+ 'account': {
+ 'subtype': 'checking',
+ 'mask': '0000',
+ 'type': 'depository',
+ 'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
+ 'name': 'Plaid Checking'
+ },
+ 'account_id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
+ 'link_session_id': 'db673d75-61aa-442a-864f-9b3f174f3725',
+ 'accounts': [{
+ 'type': 'depository',
+ 'subtype': 'checking',
+ 'mask': '0000',
+ 'id': '6GbM6RRQgdfy3lAqGz4JUnpmR948WZFg8DjQK',
+ 'name': 'Plaid Checking'
+ }],
+ 'institution': {
+ 'institution_id': 'ins_6',
+ 'name': 'Citi'
+ }
+ }
+
+ bank = json.dumps(frappe.get_doc("Bank", "Citi").as_dict(), default=json_handler)
+ company = frappe.db.get_single_value('Global Defaults', 'default_company')
+
+ if frappe.db.get_value("Company", company, "default_bank_account") is None:
+ frappe.db.set_value("Company", company, "default_bank_account", get_default_bank_cash_account(company, "Cash").get("account"))
+
+ add_bank_accounts(bank_accounts, bank, company)
+
+ transactions = {
+ 'account_owner': None,
+ 'category': ['Food and Drink', 'Restaurants'],
+ 'account_id': 'b4Jkp1LJDZiPgojpr1ansXJrj5Q6w9fVmv6ov',
+ 'pending_transaction_id': None,
+ 'transaction_id': 'x374xPa7DvUewqlR5mjNIeGK8r8rl3Sn647LM',
+ 'unofficial_currency_code': None,
+ 'name': 'INTRST PYMNT',
+ 'transaction_type': 'place',
+ 'amount': -4.22,
+ 'location': {
+ 'city': None,
+ 'zip': None,
+ 'store_number': None,
+ 'lon': None,
+ 'state': None,
+ 'address': None,
+ 'lat': None
+ },
+ 'payment_meta': {
+ 'reference_number': None,
+ 'payer': None,
+ 'payment_method': None,
+ 'reason': None,
+ 'payee': None,
+ 'ppd_id': None,
+ 'payment_processor': None,
+ 'by_order_of': None
+ },
+ 'date': '2017-12-22',
+ 'category_id': '13005000',
+ 'pending': False,
+ 'iso_currency_code': 'USD'
+ }
+
+ new_bank_transaction(transactions)
+
+ self.assertTrue(len(frappe.get_all("Bank Transaction")) == 1)
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.js b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.js
index 7056931f6cf..d7a3d36a5f1 100644
--- a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.js
+++ b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.js
@@ -42,4 +42,15 @@ frappe.ui.form.on('Woocommerce Settings', {
frm.set_df_property("api_consumer_key", "reqd", frm.doc.enable_sync);
frm.set_df_property("api_consumer_secret", "reqd", frm.doc.enable_sync);
}
-});
\ No newline at end of file
+});
+
+frappe.ui.form.on("Woocommerce Settings", "onload", function () {
+ frappe.call({
+ method: "erpnext.erpnext_integrations.doctype.woocommerce_settings.woocommerce_settings.get_series",
+ callback: function (r) {
+ $.each(r.message, function (key, value) {
+ set_field_options(key, value);
+ });
+ }
+ });
+});
diff --git a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.json b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.json
index 2fa79600368..dd3c24dce59 100644
--- a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.json
+++ b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.json
@@ -1,465 +1,694 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2018-02-12 15:10:05.495713",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-02-12 15:10:05.495713",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "enable_sync",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Enable Sync",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "enable_sync",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Enable Sync",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb_00",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "sb_00",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "woocommerce_server_url",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Woocommerce Server URL",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "woocommerce_server_url",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Woocommerce Server URL",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "secret",
- "fieldtype": "Code",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Secret",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "secret",
+ "fieldtype": "Code",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Secret",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cb_00",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "cb_00",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "api_consumer_key",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "API consumer key",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "api_consumer_key",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "API consumer key",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "api_consumer_secret",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "API consumer secret",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "api_consumer_secret",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "API consumer secret",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "sb_accounting_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Accounting Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "sb_accounting_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Accounting Details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "tax_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Tax Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "tax_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Tax Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "f_n_f_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Freight and Forwarding Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "f_n_f_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Freight and Forwarding Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "endpoints",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Endpoints",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "defaults_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Defaults",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "endpoint",
- "fieldtype": "Code",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Endpoint",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "The user that will be used to create Customers, Items and Sales Orders. This user should have the relevant permissions.",
+ "fetch_if_empty": 0,
+ "fieldname": "creation_user",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Creation User",
+ "length": 0,
+ "no_copy": 0,
+ "options": "User",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "This warehouse will be used to create Sale Orders. The fallback warehouse is \"Stores\".",
+ "fetch_if_empty": 0,
+ "fieldname": "warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_14",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "The fallback series is \"SO-WOO-\".",
+ "fetch_if_empty": 0,
+ "fieldname": "sales_order_series",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Sales Order Series",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "This is the default UOM used for items and Sales orders. The fallback UOM is \"Nos\".",
+ "fetch_if_empty": 0,
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "endpoints",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Endpoints",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "endpoint",
+ "fieldtype": "Code",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Endpoint",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 1,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-03-23 16:57:20.880513",
- "modified_by": "Administrator",
- "module": "ERPNext Integrations",
- "name": "Woocommerce Settings",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 1,
+ "istable": 0,
+ "max_attachments": 0,
+ "menu_index": 0,
+ "modified": "2019-04-08 17:04:16.720696",
+ "modified_by": "Administrator",
+ "module": "ERPNext Integrations",
+ "name": "Woocommerce Settings",
+ "name_case": "",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py
index 1edc1029565..055684d4456 100644
--- a/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py
+++ b/erpnext/erpnext_integrations/doctype/woocommerce_settings/woocommerce_settings.py
@@ -4,8 +4,8 @@
from __future__ import unicode_literals
import frappe
-
from frappe import _
+from frappe.utils.nestedset import get_root_of
from frappe.model.document import Document
from six.moves.urllib.parse import urlparse
@@ -62,10 +62,10 @@ class WoocommerceSettings(Document):
custom.read_only = 1
custom.save()
- if not frappe.get_value("Item Group",{"name": "WooCommerce Products"}):
+ if not frappe.get_value("Item Group",{"name": _("WooCommerce Products")}):
item_group = frappe.new_doc("Item Group")
- item_group.item_group_name = "WooCommerce Products"
- item_group.parent_item_group = "All Item Groups"
+ item_group.item_group_name = _("WooCommerce Products")
+ item_group.parent_item_group = get_root_of("Item Group")
item_group.save()
@@ -83,7 +83,7 @@ class WoocommerceSettings(Document):
for name in email_names:
frappe.delete_doc("Custom Field",name)
- frappe.delete_doc("Item Group","WooCommerce Products")
+ frappe.delete_doc("Item Group", _("WooCommerce Products"))
frappe.db.commit()
@@ -122,3 +122,9 @@ def generate_secret():
woocommerce_settings = frappe.get_doc("Woocommerce Settings")
woocommerce_settings.secret = frappe.generate_hash()
woocommerce_settings.save()
+
+@frappe.whitelist()
+def get_series():
+ return {
+ "sales_order_series" : frappe.get_meta("Sales Order").get_options("naming_series") or "SO-WOO-",
+ }
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
index 84255b2930b..288ebc40b4e 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.js
@@ -49,7 +49,7 @@ frappe.ui.form.on('Healthcare Service Unit Type', {
var disable = function(frm){
var doc = frm.doc;
frappe.call({
- method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
+ method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
args: {status: 1, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
callback: function(){
cur_frm.reload_doc();
@@ -60,7 +60,7 @@ var disable = function(frm){
var enable = function(frm){
var doc = frm.doc;
frappe.call({
- method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
+ method: "erpnext.healthcare.doctype.healthcare_service_unit_type.healthcare_service_unit_type.disable_enable",
args: {status: 0, doc_name: doc.name, item: doc.item, is_billable: doc.is_billable},
callback: function(){
cur_frm.reload_doc();
diff --git a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
index 727d035a80f..650499454b9 100644
--- a/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
+++ b/erpnext/healthcare/doctype/healthcare_service_unit_type/healthcare_service_unit_type.py
@@ -111,7 +111,7 @@ def change_item_code(item, item_code, doc_name):
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "item_code", item_code)
@frappe.whitelist()
-def disable_enable(status, doc_name, item, is_billable):
+def disable_enable(status, doc_name, item=None, is_billable=None):
frappe.db.set_value("Healthcare Service Unit Type", doc_name, "disabled", status)
if(is_billable == 1):
frappe.db.set_value("Item", item, "disabled", status)
diff --git a/erpnext/healthcare/doctype/patient/patient.js b/erpnext/healthcare/doctype/patient/patient.js
index de5bce0aa65..169281430ce 100644
--- a/erpnext/healthcare/doctype/patient/patient.js
+++ b/erpnext/healthcare/doctype/patient/patient.js
@@ -123,13 +123,13 @@ var btn_invoice_registration = function (frm) {
frappe.ui.form.on('Patient Relation', {
patient_relation_add: function(frm){
- frm.fields_dict['patient_relation'].grid.get_field('patient').get_query = function(frm){
+ frm.fields_dict['patient_relation'].grid.get_field('patient').get_query = function(doc){
var patient_list = [];
- if(!frm.doc.__islocal) patient_list.push(frm.doc.name);
- $.each(frm.doc.patient_relation, function(idx, val){
+ if(!doc.__islocal) patient_list.push(doc.name);
+ $.each(doc.patient_relation, function(idx, val){
if (val.patient) patient_list.push(val.patient);
});
return { filters: [['Patient', 'name', 'not in', patient_list]] };
};
}
-});
\ No newline at end of file
+});
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index ccdd412c181..fb24aa93892 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -229,6 +229,7 @@ scheduler_events = {
'erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails',
"erpnext.accounts.doctype.subscription.subscription.process_all",
"erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_settings.schedule_get_order_details",
+ "erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.automatic_synchronization",
"erpnext.projects.doctype.project.project.hourly_reminder",
"erpnext.projects.doctype.project.project.collect_project_status"
],
@@ -255,7 +256,7 @@ scheduler_events = {
"daily_long": [
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms"
],
- "monthly": [
+ "monthly_long": [
"erpnext.accounts.deferred_revenue.convert_deferred_revenue_to_income",
"erpnext.accounts.deferred_revenue.convert_deferred_expense_to_expense",
"erpnext.hr.utils.allocate_earned_leaves"
diff --git a/erpnext/hr/doctype/additional_salary/additional_salary.py b/erpnext/hr/doctype/additional_salary/additional_salary.py
index 6f87954f502..9ca1260fe06 100644
--- a/erpnext/hr/doctype/additional_salary/additional_salary.py
+++ b/erpnext/hr/doctype/additional_salary/additional_salary.py
@@ -11,16 +11,14 @@ from frappe.utils import getdate, date_diff
class AdditionalSalary(Document):
def validate(self):
self.validate_dates()
- if self.amount <= 0:
- frappe.throw(_("Amount should be greater than zero."))
+ if self.amount < 0:
+ frappe.throw(_("Amount should not be less than zero."))
def validate_dates(self):
date_of_joining, relieving_date = frappe.db.get_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
if date_of_joining and getdate(self.payroll_date) < getdate(date_of_joining):
frappe.throw(_("Payroll date can not be less than employee's joining date"))
- elif relieving_date and getdate(self.payroll_date) > getdate(relieving_date):
- frappe.throw(_("To date can not greater than employee's relieving date"))
def get_amount(self, sal_start_date, sal_end_date):
start_date = getdate(sal_start_date)
@@ -53,7 +51,7 @@ def get_additional_salary_component(employee, start_date, end_date):
for d in additional_components:
component = frappe.get_doc("Salary Component", d.salary_component)
struct_row = {'salary_component': d.salary_component}
- for field in ["depends_on_lwp", "abbr", "is_tax_applicable", "variable_based_on_taxable_salary", "is_additional_component"]:
+ for field in ["depends_on_payment_days", "abbr", "is_tax_applicable", "variable_based_on_taxable_salary", "is_additional_component"]:
struct_row[field] = component.get(field)
additional_components_list.append({
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index d518cd89957..d925b144889 100755
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -78,7 +78,15 @@ class Employee(NestedSet):
def update_user_permissions(self):
if not self.create_user_permission: return
- if not has_permission('User Permission', ptype='write'): return
+ if not has_permission('User Permission', ptype='write', raise_exception=False): return
+
+ employee_user_permission_exists = frappe.db.exists('User Permission', {
+ 'allow': 'Employee',
+ 'for_value': self.name,
+ 'user': self.user_id
+ })
+
+ if employee_user_permission_exists: return
add_user_permission("Employee", self.name, self.user_id)
set_user_permission_if_allowed("Company", self.company, self.user_id)
@@ -229,7 +237,7 @@ def validate_employee_role(doc, method):
def update_user_permissions(doc, method):
# called via User hook
if "Employee" in [d.role for d in doc.get("roles")]:
- if not has_permission('User Permission', ptype='write'): return
+ if not has_permission('User Permission', ptype='write', raise_exception=False): return
employee = frappe.get_doc("Employee", {"user_id": doc.name})
employee.update_user_permissions()
diff --git a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
index 9b6dba5ff81..701ae2465ff 100644
--- a/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
+++ b/erpnext/hr/doctype/employee_benefit_application/employee_benefit_application.py
@@ -113,7 +113,7 @@ def get_max_benefits(employee, on_date):
def get_max_benefits_remaining(employee, on_date, payroll_period):
max_benefits = get_max_benefits(employee, on_date)
if max_benefits and max_benefits > 0:
- have_depends_on_lwp = False
+ have_depends_on_payment_days = False
per_day_amount_total = 0
payroll_period_days = get_payroll_period_days(on_date, on_date, employee)[0]
payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)
@@ -122,22 +122,22 @@ def get_max_benefits_remaining(employee, on_date, payroll_period):
prev_sal_slip_flexi_total = get_sal_slip_total_benefit_given(employee, payroll_period_obj)
if prev_sal_slip_flexi_total > 0:
- # Check salary structure hold depends_on_lwp component
+ # Check salary structure hold depends_on_payment_days component
# If yes then find the amount per day of each component and find the sum
sal_struct_name = get_assigned_salary_structure(employee, on_date)
if sal_struct_name:
sal_struct = frappe.get_doc("Salary Structure", sal_struct_name)
for sal_struct_row in sal_struct.get("earnings"):
salary_component = frappe.get_doc("Salary Component", sal_struct_row.salary_component)
- if salary_component.depends_on_lwp == 1 and salary_component.pay_against_benefit_claim != 1:
- have_depends_on_lwp = True
+ if salary_component.depends_on_payment_days == 1 and salary_component.pay_against_benefit_claim != 1:
+ have_depends_on_payment_days = True
benefit_amount = get_benefit_pro_rata_ratio_amount(sal_struct, salary_component.max_benefit_amount)
amount_per_day = benefit_amount / payroll_period_days
per_day_amount_total += amount_per_day
# Then the sum multiply with the no of lwp in that period
# Include that amount to the prev_sal_slip_flexi_total to get the actual
- if have_depends_on_lwp and per_day_amount_total > 0:
+ if have_depends_on_payment_days and per_day_amount_total > 0:
holidays = get_holidays_for_employee(employee, payroll_period_obj.start_date, on_date)
working_days = date_diff(on_date, payroll_period_obj.start_date) + 1
leave_days = calculate_lwp(employee, payroll_period_obj.start_date, holidays, working_days)
@@ -177,15 +177,18 @@ def get_benefit_component_amount(employee, start_date, end_date, struct_row, sal
# Considering there is only one application for a year
benefit_application_name = frappe.db.sql("""
- select name from `tabEmployee Benefit Application`
- where payroll_period=%(payroll_period)s and employee=%(employee)s
- and docstatus = 1
+ select name
+ from `tabEmployee Benefit Application`
+ where
+ payroll_period=%(payroll_period)s
+ and employee=%(employee)s
+ and docstatus = 1
""", {
'employee': employee,
'payroll_period': payroll_period
})
- if frappe.db.get_value("Salary Component", struct_row.salary_component, "depends_on_lwp") != 1:
+ if frappe.db.get_value("Salary Component", struct_row.salary_component, "depends_on_payment_days") != 1:
if frequency == "Monthly" and actual_payroll_days in range(360, 370):
period_length = 1
period_factor = 12
@@ -209,7 +212,8 @@ def get_benefit_pro_rata_ratio_amount(sal_struct, component_max):
total_pro_rata_max = 0
benefit_amount = 0
for sal_struct_row in sal_struct.get("earnings"):
- pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component", sal_struct_row.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
+ pay_against_benefit_claim, max_benefit_amount = frappe.db.get_value("Salary Component",
+ sal_struct_row.salary_component, ["pay_against_benefit_claim", "max_benefit_amount"])
if sal_struct_row.is_flexible_benefit == 1 and pay_against_benefit_claim != 1:
total_pro_rata_max += max_benefit_amount
if total_pro_rata_max > 0:
diff --git a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py b/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py
index bf150b12322..8be67a866ab 100644
--- a/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py
+++ b/erpnext/hr/doctype/employee_benefit_claim/employee_benefit_claim.py
@@ -170,7 +170,7 @@ def get_last_payroll_period_benefits(employee, sal_slip_start_date, sal_slip_end
amount += current_claimed_amount
struct_row = {}
salary_components_dict = {}
- struct_row['depends_on_lwp'] = salary_component.depends_on_lwp
+ struct_row['depends_on_payment_days'] = salary_component.depends_on_payment_days
struct_row['salary_component'] = salary_component.name
struct_row['abbr'] = salary_component.salary_component_abbr
struct_row['do_not_include_in_total'] = salary_component.do_not_include_in_total
diff --git a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
index ec640fc22b5..09bbcba0e4e 100644
--- a/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
+++ b/erpnext/hr/doctype/employee_onboarding/test_employee_onboarding.py
@@ -39,6 +39,7 @@ class TestEmployeeOnboarding(unittest.TestCase):
# complete the task
project = frappe.get_doc('Project', onboarding.project)
+ project.load_tasks()
project.tasks[0].status = 'Closed'
project.save()
diff --git a/erpnext/hr/doctype/employee_separation/test_employee_separation.py b/erpnext/hr/doctype/employee_separation/test_employee_separation.py
index 4c3e5667132..2fa114d3452 100644
--- a/erpnext/hr/doctype/employee_separation/test_employee_separation.py
+++ b/erpnext/hr/doctype/employee_separation/test_employee_separation.py
@@ -10,9 +10,9 @@ test_dependencies = ["Employee Onboarding"]
class TestEmployeeSeparation(unittest.TestCase):
def test_employee_separation(self):
- employee = get_employee()
+ employee = frappe.db.get_value("Employee", {"status": "Active"})
separation = frappe.new_doc('Employee Separation')
- separation.employee = employee.name
+ separation.employee = employee
separation.company = '_Test Company'
separation.append('activities', {
'activity_name': 'Deactivate Employee',
@@ -23,7 +23,4 @@ class TestEmployeeSeparation(unittest.TestCase):
separation.submit()
self.assertEqual(separation.docstatus, 1)
separation.cancel()
- self.assertEqual(separation.project, "")
-
-def get_employee():
- return frappe.get_doc('Employee', {'employee_name': 'Test Researcher'})
\ No newline at end of file
+ self.assertEqual(separation.project, "")
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json b/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json
index 7b2804b3262..66fac5bee5c 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_category/employee_tax_exemption_category.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -20,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "max_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -29,7 +31,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Max Amount",
+ "label": "Max Exemption Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -39,7 +41,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -52,6 +54,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "1",
+ "fetch_if_empty": 0,
"fieldname": "is_active",
"fieldtype": "Check",
"hidden": 0,
@@ -88,7 +92,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-06-19 16:33:48.419267",
+ "modified": "2019-04-25 13:20:31.367158",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Category",
@@ -159,6 +163,7 @@
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js
index 9560df53e13..a827eca1c46 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.js
@@ -10,6 +10,7 @@ frappe.ui.form.on('Employee Tax Exemption Declaration', {
}
}
});
+
frm.set_query('payroll_period', function() {
const fields = {'employee': 'Employee', 'company': 'Company'};
@@ -27,6 +28,7 @@ frappe.ui.form.on('Employee Tax Exemption Declaration', {
}
}
});
+
frm.set_query('exemption_sub_category', 'declarations', function() {
return {
filters: {
@@ -34,5 +36,16 @@ frappe.ui.form.on('Employee Tax Exemption Declaration', {
}
}
});
+ },
+
+ refresh: function(frm) {
+ if(frm.doc.docstatus==1) {
+ frm.add_custom_button(__('Submit Proof'), function() {
+ frappe.model.open_mapped_doc({
+ method: "erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission",
+ frm: frm
+ });
+ }).addClass("btn-primary");
+ }
}
});
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
index 865e8219b31..8891b97a5de 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -20,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
@@ -53,9 +55,10 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "employee.company",
- "fieldname": "company",
- "fieldtype": "Link",
+ "fetch_from": "employee.employee_name",
+ "fetch_if_empty": 0,
+ "fieldname": "employee_name",
+ "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -63,104 +66,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "payroll_period",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Payroll Period",
- "length": 0,
- "no_copy": 0,
- "options": "Payroll Period",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_exemption_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Total Exemption Amount",
+ "label": "Employee Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -184,6 +90,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "employee.department",
+ "fetch_if_empty": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -217,6 +124,108 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "payroll_period",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Payroll Period",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Payroll Period",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "employee.company",
+ "fetch_if_empty": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -249,6 +258,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
@@ -280,6 +290,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "declarations",
"fieldtype": "Table",
"hidden": 0,
@@ -300,7 +311,137 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "total_declared_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Total Declared Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "total_exemption_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Total Exemption Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -317,7 +458,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-21 16:15:49.363307",
+ "modified": "2019-04-25 16:38:05.847925",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Declaration",
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
index 186b2e10526..cbdfcf8ecdf 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/employee_tax_exemption_declaration.py
@@ -6,28 +6,61 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
-from erpnext.hr.utils import validate_tax_declaration, calculate_annual_eligible_hra_exemption
+from frappe.utils import flt
+from frappe.model.mapper import get_mapped_doc
+from erpnext.hr.utils import validate_tax_declaration, get_total_exemption_amount, calculate_annual_eligible_hra_exemption
+
+class DuplicateDeclarationError(frappe.ValidationError): pass
class EmployeeTaxExemptionDeclaration(Document):
def validate(self):
validate_tax_declaration(self.declarations)
- self.total_exemption_amount = 0
+ self.validate_duplicate()
+ self.set_total_declared_amount()
+ self.set_total_exemption_amount()
self.calculate_hra_exemption()
- for item in self.declarations:
- self.total_exemption_amount += item.amount
- def before_submit(self):
- if frappe.db.exists({"doctype": "Employee Tax Exemption Declaration",
- "employee": self.employee,
- "payroll_period": self.payroll_period,
- "docstatus": 1}):
- frappe.throw(_("Tax Declaration of {0} for period {1} already submitted.")\
- .format(self.employee, self.payroll_period), frappe.DocstatusTransitionError)
+ def validate_duplicate(self):
+ duplicate = frappe.db.get_value("Employee Tax Exemption Declaration",
+ filters = {
+ "employee": self.employee,
+ "payroll_period": self.payroll_period,
+ "name": ["!=", self.name]
+ }
+ )
+ if duplicate:
+ frappe.throw(_("Duplicate Tax Declaration of {0} for period {1}")
+ .format(self.employee, self.payroll_period), DuplicateDeclarationError)
+
+ def set_total_declared_amount(self):
+ self.total_declared_amount = 0.0
+ for d in self.declarations:
+ self.total_declared_amount += flt(d.amount)
+
+ def set_total_exemption_amount(self):
+ self.total_exemption_amount = get_total_exemption_amount(self.declarations)
def calculate_hra_exemption(self):
- hra_exemption = calculate_annual_eligible_hra_exemption(self)
- if hra_exemption:
- self.total_exemption_amount += hra_exemption["annual_exemption"]
- self.salary_structure_hra = hra_exemption["hra_amount"]
- self.annual_hra_exemption = hra_exemption["annual_exemption"]
- self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
+ self.salary_structure_hra, self.annual_hra_exemption, self.monthly_hra_exemption = 0, 0, 0
+ if self.get("monthly_house_rent"):
+ hra_exemption = calculate_annual_eligible_hra_exemption(self)
+ if hra_exemption:
+ self.total_exemption_amount += hra_exemption["annual_exemption"]
+ self.salary_structure_hra = hra_exemption["hra_amount"]
+ self.annual_hra_exemption = hra_exemption["annual_exemption"]
+ self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
+
+@frappe.whitelist()
+def make_proof_submission(source_name, target_doc=None):
+ doclist = get_mapped_doc("Employee Tax Exemption Declaration", source_name, {
+ "Employee Tax Exemption Declaration": {
+ "doctype": "Employee Tax Exemption Proof Submission",
+ "field_no_map": ["monthly_house_rent", "monthly_hra_exemption"]
+ },
+ "Employee Tax Exemption Declaration Category": {
+ "doctype": "Employee Tax Exemption Proof Submission Detail",
+ "add_if_empty": True
+ }
+ }, target_doc)
+
+ return doclist
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py b/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
index beaddd98dd0..9c87bbd1f30 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration/test_employee_tax_exemption_declaration.py
@@ -6,6 +6,7 @@ from __future__ import unicode_literals
import frappe, erpnext
import unittest
from erpnext.hr.doctype.employee.test_employee import make_employee
+from erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration import DuplicateDeclarationError
class TestEmployeeTaxExemptionDeclaration(unittest.TestCase):
def setUp(self):
@@ -15,71 +16,71 @@ class TestEmployeeTaxExemptionDeclaration(unittest.TestCase):
create_exemption_category()
frappe.db.sql("""delete from `tabEmployee Tax Exemption Declaration`""")
- def test_exemption_amount_greater_than_category_max(self):
- declaration = frappe.get_doc({
- "doctype": "Employee Tax Exemption Declaration",
- "employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
- "payroll_period": "_Test Payroll Period",
- "declarations": [dict(exemption_sub_category = "_Test Sub Category",
- exemption_category = "_Test Category",
- amount = 150000)]
- })
- self.assertRaises(frappe.ValidationError, declaration.save)
- declaration = frappe.get_doc({
- "doctype": "Employee Tax Exemption Declaration",
- "payroll_period": "_Test Payroll Period",
- "employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
- "declarations": [dict(exemption_sub_category = "_Test Sub Category",
- exemption_category = "_Test Category",
- amount = 90000)]
- })
- self.assertTrue(declaration.save)
-
def test_duplicate_category_in_declaration(self):
declaration = frappe.get_doc({
"doctype": "Employee Tax Exemption Declaration",
"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
"company": erpnext.get_default_company(),
"payroll_period": "_Test Payroll Period",
- "declarations": [dict(exemption_sub_category = "_Test Sub Category",
- exemption_category = "_Test Category",
- amount = 100000),
- dict(exemption_sub_category = "_Test Sub Category",
- exemption_category = "_Test Category",
- amount = 50000),
- ]
+ "declarations": [
+ dict(exemption_sub_category = "_Test Sub Category",
+ exemption_category = "_Test Category",
+ amount = 100000),
+ dict(exemption_sub_category = "_Test Sub Category",
+ exemption_category = "_Test Category",
+ amount = 50000)
+ ]
})
self.assertRaises(frappe.ValidationError, declaration.save)
- def test_duplicate_submission_for_payroll_period(self):
+ def test_duplicate_entry_for_payroll_period(self):
declaration = frappe.get_doc({
"doctype": "Employee Tax Exemption Declaration",
"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
"company": erpnext.get_default_company(),
"payroll_period": "_Test Payroll Period",
- "declarations": [dict(exemption_sub_category = "_Test Sub Category",
- exemption_category = "_Test Category",
- amount = 100000),
- dict(exemption_sub_category = "_Test1 Sub Category",
- exemption_category = "_Test Category",
- amount = 50000),
- ]
+ "declarations": [
+ dict(exemption_sub_category = "_Test Sub Category",
+ exemption_category = "_Test Category",
+ amount = 100000),
+ dict(exemption_sub_category = "_Test1 Sub Category",
+ exemption_category = "_Test Category",
+ amount = 50000),
+ ]
}).insert()
- declaration.submit()
- self.assertEquals(declaration.docstatus, 1)
+
duplicate_declaration = frappe.get_doc({
"doctype": "Employee Tax Exemption Declaration",
"employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
"company": erpnext.get_default_company(),
"payroll_period": "_Test Payroll Period",
- "declarations": [dict(exemption_sub_category = "_Test Sub Category",
- exemption_category = "_Test Category",
- amount = 100000)
- ]
- }).insert()
- self.assertRaises(frappe.DocstatusTransitionError, duplicate_declaration.submit)
+ "declarations": [
+ dict(exemption_sub_category = "_Test Sub Category",
+ exemption_category = "_Test Category",
+ amount = 100000)
+ ]
+ })
+ self.assertRaises(DuplicateDeclarationError, duplicate_declaration.insert)
duplicate_declaration.employee = frappe.get_value("Employee", {"user_id":"employee1@taxexepmtion.com"}, "name")
- self.assertTrue(duplicate_declaration.submit)
+ self.assertTrue(duplicate_declaration.insert)
+
+ def test_exemption_amount(self):
+ declaration = frappe.get_doc({
+ "doctype": "Employee Tax Exemption Declaration",
+ "employee": frappe.get_value("Employee", {"user_id":"employee@taxexepmtion.com"}, "name"),
+ "company": erpnext.get_default_company(),
+ "payroll_period": "_Test Payroll Period",
+ "declarations": [
+ dict(exemption_sub_category = "_Test Sub Category",
+ exemption_category = "_Test Category",
+ amount = 80000),
+ dict(exemption_sub_category = "_Test1 Sub Category",
+ exemption_category = "_Test Category",
+ amount = 60000),
+ ]
+ }).insert()
+
+ self.assertEqual(declaration.total_exemption_amount, 100000)
def create_payroll_period():
if not frappe.db.exists("Payroll Period", "_Test Payroll Period"):
diff --git a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json b/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json
index ebde4c9c717..7b3b8f5caae 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_declaration_category/employee_tax_exemption_declaration_category.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -19,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "exemption_sub_category",
"fieldtype": "Link",
"hidden": 0,
@@ -53,6 +55,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "exemption_sub_category.exemption_category",
+ "fetch_if_empty": 0,
"fieldname": "exemption_category",
"fieldtype": "Link",
"hidden": 0,
@@ -70,7 +73,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
@@ -86,6 +89,41 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "exemption_sub_category.max_amount",
+ "fetch_if_empty": 0,
+ "fieldname": "max_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Maximum Exempted Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -95,7 +133,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Amount",
+ "label": "Declared Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -122,7 +160,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-05-29 15:58:05.779031",
+ "modified": "2019-04-26 11:28:14.023086",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Declaration Category",
@@ -136,5 +174,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js
index 99bec14b180..66118c08111 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.js
@@ -10,6 +10,7 @@ frappe.ui.form.on('Employee Tax Exemption Proof Submission', {
}
}
});
+
frm.set_query('payroll_period', function() {
if(frm.doc.employee && frm.doc.company){
return {
@@ -21,6 +22,7 @@ frappe.ui.form.on('Employee Tax Exemption Proof Submission', {
frappe.msgprint(__("Please select Employee"));
}
});
+
frm.set_query('exemption_sub_category', 'tax_exemption_proofs', function() {
return {
filters: {
@@ -29,11 +31,28 @@ frappe.ui.form.on('Employee Tax Exemption Proof Submission', {
}
});
},
- employee: function(frm){
- if(frm.doc.employee){
- frm.add_fetch('employee', 'company', 'company');
- }else{
- frm.set_value('company', '');
+
+ refresh: function(frm) {
+ if(frm.doc.docstatus === 0) {
+ let filters = {
+ docstatus: 1,
+ company: frm.doc.company
+ };
+ if(frm.doc.employee) filters["employee"] = frm.doc.employee;
+ if(frm.doc.payroll_period) filters["payroll_period"] = frm.doc.payroll_period;
+
+ frm.add_custom_button(__('Get Details From Declaration'), function() {
+ erpnext.utils.map_current_doc({
+ method: "erpnext.hr.doctype.employee_tax_exemption_declaration.employee_tax_exemption_declaration.make_proof_submission",
+ source_doctype: "Employee Tax Exemption Declaration",
+ target: frm,
+ date_field: "creation",
+ setters: {
+ employee: frm.doc.employee || undefined
+ },
+ get_query_filters: filters
+ });
+ });
}
}
});
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
index ebc04353e0a..76c09d6c7b7 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.json
@@ -1,8 +1,9 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
"autoname": "HR-TAX-PRF-.YYYY.-.#####",
"beta": 0,
"creation": "2018-04-13 17:24:11.456132",
@@ -20,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
@@ -53,8 +55,10 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
+ "fetch_from": "employee.employee_name",
+ "fetch_if_empty": 0,
+ "fieldname": "employee_name",
+ "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -62,10 +66,9 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Company",
+ "label": "Employee Name",
"length": 0,
"no_copy": 0,
- "options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -79,70 +82,6 @@
"translatable": 0,
"unique": 0
},
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "payroll_period",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Payroll Period",
- "length": 0,
- "no_copy": 0,
- "options": "Payroll Period",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -151,6 +90,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "employee.department",
+ "fetch_if_empty": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -184,8 +124,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "submission_date",
- "fieldtype": "Date",
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -193,7 +134,6 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Submission Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -216,6 +156,273 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "Today",
+ "fetch_if_empty": 0,
+ "fieldname": "submission_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Submission Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "payroll_period",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Payroll Period",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Payroll Period",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "employee.company",
+ "fetch_if_empty": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "tax_exemption_proofs",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Tax Exemption Proofs",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Employee Tax Exemption Proof Submission Detail",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_10",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "total_actual_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Total Actual Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "exemption_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -248,70 +455,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "section_break_5",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "tax_exemption_proofs",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Tax Exemption Proofs",
- "length": 0,
- "no_copy": 0,
- "options": "Employee Tax Exemption Proof Submission Detail",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "attachment_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -344,6 +488,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "attachments",
"fieldtype": "Attach",
"hidden": 0,
@@ -376,6 +521,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -412,7 +558,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-21 16:15:38.096846",
+ "modified": "2019-04-25 17:06:36.569549",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Proof Submission",
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py
index 54e0b2041bc..97ceb63476b 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission/employee_tax_exemption_proof_submission.py
@@ -6,20 +6,30 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
-from erpnext.hr.utils import validate_tax_declaration, calculate_hra_exemption_for_period
+from frappe.utils import flt
+from erpnext.hr.utils import validate_tax_declaration, get_total_exemption_amount, calculate_hra_exemption_for_period
class EmployeeTaxExemptionProofSubmission(Document):
def validate(self):
validate_tax_declaration(self.tax_exemption_proofs)
- self.exemption_amount = 0
+ self.set_total_actual_amount()
+ self.set_total_exemption_amount()
self.calculate_hra_exemption()
- for proof in self.tax_exemption_proofs:
- self.exemption_amount += proof.amount
+
+ def set_total_actual_amount(self):
+ self.total_actual_amount = flt(self.get("house_rent_payment_amount"))
+ for d in self.tax_exemption_proofs:
+ self.total_actual_amount += flt(d.amount)
+
+ def set_total_exemption_amount(self):
+ self.exemption_amount = get_total_exemption_amount(self.tax_exemption_proofs)
def calculate_hra_exemption(self):
- hra_exemption = calculate_hra_exemption_for_period(self)
- if hra_exemption:
- self.exemption_amount += hra_exemption["total_eligible_hra_exemption"]
- self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
- self.monthly_house_rent = hra_exemption["monthly_house_rent"]
- self.total_eligible_hra_exemption = hra_exemption["total_eligible_hra_exemption"]
+ self.monthly_hra_exemption, self.monthly_house_rent, self.total_eligible_hra_exemption = 0, 0, 0
+ if self.get("house_rent_payment_amount"):
+ hra_exemption = calculate_hra_exemption_for_period(self)
+ if hra_exemption:
+ self.exemption_amount += hra_exemption["total_eligible_hra_exemption"]
+ self.monthly_hra_exemption = hra_exemption["monthly_exemption"]
+ self.monthly_house_rent = hra_exemption["monthly_house_rent"]
+ self.total_eligible_hra_exemption = hra_exemption["total_eligible_hra_exemption"]
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json b/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json
index c1c5896d7f9..b9254afad07 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_proof_submission_detail/employee_tax_exemption_proof_submission_detail.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -14,10 +15,12 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "exemption_sub_category",
"fieldtype": "Link",
"hidden": 0,
@@ -41,16 +44,18 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "exemption_sub_category.exemption_category",
+ "fetch_from": "exemption_sub_category.exemption_category",
+ "fetch_if_empty": 0,
"fieldname": "exemption_category",
"fieldtype": "Read Only",
"hidden": 0,
@@ -74,15 +79,51 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "exemption_sub_category.max_amount",
+ "fetch_if_empty": 0,
+ "fieldname": "max_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Maximum Exemption Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "type_of_proof",
"fieldtype": "Data",
"hidden": 0,
@@ -106,15 +147,17 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -124,7 +167,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Amount",
+ "label": "Actual Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -134,10 +177,10 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
- "translatable": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -151,7 +194,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-05-16 22:42:59.750733",
+ "modified": "2019-04-25 15:45:03.154904",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Proof Submission Detail",
@@ -165,5 +208,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json
index dc997850675..b0e492e7ca4 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json
+++ b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -15,10 +16,12 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "exemption_category",
"fieldtype": "Link",
"hidden": 0,
@@ -26,8 +29,8 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
"label": "Tax Exemption Category",
"length": 0,
"no_copy": 0,
@@ -42,14 +45,18 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "exemption_category.max_amount",
+ "fetch_if_empty": 1,
"fieldname": "max_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -59,7 +66,7 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Max Amount",
+ "label": "Max Exemption Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -69,17 +76,21 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "1",
+ "fetch_if_empty": 0,
"fieldname": "is_active",
"fieldtype": "Check",
"hidden": 0,
@@ -102,6 +113,7 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -115,7 +127,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-09 13:25:01.595240",
+ "modified": "2019-04-25 13:24:05.164877",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Tax Exemption Sub Category",
@@ -124,7 +136,6 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -144,7 +155,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -164,7 +174,6 @@
},
{
"amend": 0,
- "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
@@ -189,6 +198,7 @@
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py
index cd58136d8db..a8dd7e4d6dd 100644
--- a/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py
+++ b/erpnext/hr/doctype/employee_tax_exemption_sub_category/employee_tax_exemption_sub_category.py
@@ -4,7 +4,13 @@
from __future__ import unicode_literals
import frappe
+from frappe import _
+from frappe.utils import flt
from frappe.model.document import Document
class EmployeeTaxExemptionSubCategory(Document):
- pass
+ def validate(self):
+ category_max_amount = frappe.db.get_value("Employee Tax Exemption Category", self.exemption_category, "max_amount")
+ if flt(self.max_amount) > flt(category_max_amount):
+ frappe.throw(_("Max Exemption Amount cannot be greater than maximum exemption amount {0} of Tax Exemption Category {1}")
+ .format(category_max_amount, self.exemption_category))
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.js b/erpnext/hr/doctype/expense_claim/expense_claim.js
index 6bdab61d9df..6da718402bf 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.js
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.js
@@ -35,6 +35,7 @@ $.extend(cur_frm.cscript, new erpnext.hr.ExpenseClaimController({frm: cur_frm}))
cur_frm.add_fetch('employee', 'company', 'company');
cur_frm.add_fetch('employee','employee_name','employee_name');
+cur_frm.add_fetch('expense_type','description','description');
cur_frm.cscript.onload = function(doc) {
if (doc.__islocal) {
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.json b/erpnext/hr/doctype/expense_claim/expense_claim.json
index 44b70c67a13..187387c83e2 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.json
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.json
@@ -1,1253 +1,1285 @@
{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2013-01-10 16:34:14",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "naming_series:",
+ "beta": 0,
+ "creation": "2013-01-10 16:34:14",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Series",
- "length": 0,
- "no_copy": 1,
- "options": "HR-EXP-.YYYY.-",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Series",
+ "length": 0,
+ "no_copy": 1,
+ "options": "HR-EXP-.YYYY.-",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 1,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "employee",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "From Employee",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "employee",
- "oldfieldtype": "Link",
- "options": "Employee",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "employee",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "From Employee",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "employee",
+ "oldfieldtype": "Link",
+ "options": "Employee",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "employee.employee_name",
- "fieldname": "employee_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Employee Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "employee_name",
- "oldfieldtype": "Data",
- "options": "",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "employee.employee_name",
+ "fieldname": "employee_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Employee Name",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "employee_name",
+ "oldfieldtype": "Data",
+ "options": "",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "employee.department",
- "fieldname": "department",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Department",
- "length": 0,
- "no_copy": 0,
- "options": "Department",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "employee.department",
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Department",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_5",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "expense_approver",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Expense Approver",
- "length": 0,
- "no_copy": 0,
- "options": "User",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expense_approver",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Expense Approver",
+ "length": 0,
+ "no_copy": 0,
+ "options": "User",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Draft",
- "fieldname": "approval_status",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Approval Status",
- "length": 0,
- "no_copy": 1,
- "options": "Draft\nApproved\nRejected",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Draft",
+ "fieldname": "approval_status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Approval Status",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Draft\nApproved\nRejected",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_claimed_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Total Claimed Amount",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "total_claimed_amount",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_claimed_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Total Claimed Amount",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "total_claimed_amount",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "160px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_sanctioned_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Total Sanctioned Amount",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "total_sanctioned_amount",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_sanctioned_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Total Sanctioned Amount",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "total_sanctioned_amount",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "160px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:(doc.docstatus==0 || doc.is_paid)",
- "fieldname": "is_paid",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Is Paid",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:(doc.docstatus==0 || doc.is_paid)",
+ "fieldname": "is_paid",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Paid",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "expense_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Section Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expense_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "expenses",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Expenses",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "expense_voucher_details",
- "oldfieldtype": "Table",
- "options": "Expense Claim Detail",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expenses",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Expenses",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "expense_voucher_details",
+ "oldfieldtype": "Table",
+ "options": "Expense Claim Detail",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sb1",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "options": "Simple",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sb1",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "options": "Simple",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "posting_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Posting Date",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "posting_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Today",
+ "fieldname": "posting_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Posting Date",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "posting_date",
+ "oldfieldtype": "Date",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "vehicle_log",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Vehicle Log",
- "length": 0,
- "no_copy": 0,
- "options": "Vehicle Log",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "vehicle_log",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Vehicle Log",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Vehicle Log",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "project",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Project",
- "length": 0,
- "no_copy": 0,
- "options": "Project",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Project",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Project",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "task",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Task",
- "length": 0,
- "no_copy": 0,
- "options": "Task",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "task",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Task",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Task",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 1,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cb1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb1",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_amount_reimbursed",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Total Amount Reimbursed",
- "length": 0,
- "no_copy": 1,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_amount_reimbursed",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Total Amount Reimbursed",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "remark",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Remark",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "remark",
- "oldfieldtype": "Small Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "remark",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Remark",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "remark",
+ "oldfieldtype": "Small Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "{employee_name}",
- "fieldname": "title",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Title",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "{employee_name}",
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Title",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "email_id",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Employees Email Id",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "email_id",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "email_id",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Employees Email Id",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "email_id",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "accounting_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Accounting Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "accounting_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Accounting Details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "company",
- "oldfieldtype": "Link",
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 1,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "company",
+ "oldfieldtype": "Link",
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 1,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "is_paid",
- "fieldname": "mode_of_payment",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Mode of Payment",
- "length": 0,
- "no_copy": 0,
- "options": "Mode of Payment",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "is_paid",
+ "fieldname": "mode_of_payment",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Mode of Payment",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Mode of Payment",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_24",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "clearance_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Clearance Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "payable_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Payable Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_24",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "payable_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Payable Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "more_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "More Details",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Draft",
- "fieldname": "status",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Status",
- "length": 0,
- "no_copy": 1,
- "options": "Draft\nPaid\nUnpaid\nRejected\nSubmitted\nCancelled",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "columns": 0,
+ "fieldname": "more_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "More Details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amended_from",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Amended From",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "amended_from",
- "oldfieldtype": "Data",
- "options": "Expense Claim",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Draft",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Draft\nPaid\nUnpaid\nRejected\nSubmitted\nCancelled",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "amended_from",
+ "oldfieldtype": "Data",
+ "options": "Expense Claim",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "160px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "advance_payments",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Advance Payments",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "advance_payments",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Advance Payments",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "advances",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Advances",
- "length": 0,
- "no_copy": 0,
- "options": "Expense Claim Advance",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "advances",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Advances",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Expense Claim Advance",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_advance_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Total Advance Amount",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_advance_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Total Advance Amount",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-money",
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "menu_index": 0,
- "modified": "2019-01-30 11:28:10.324137",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Expense Claim",
- "name_case": "Title Case",
- "owner": "harshada@webnotestech.com",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "fa fa-money",
+ "idx": 1,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "menu_index": 0,
+ "modified": "2019-01-31 11:28:10.324137",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Expense Claim",
+ "name_case": "Title Case",
+ "owner": "harshada@webnotestech.com",
"permissions": [
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "HR Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Employee",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Employee",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Expense Approver",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Expense Approver",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "HR User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
"write": 1
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "employee,employee_name",
- "show_name_in_global_search": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "timeline_field": "employee",
- "title_field": "title",
- "track_changes": 0,
- "track_seen": 0,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "search_fields": "employee,employee_name",
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "timeline_field": "employee",
+ "title_field": "title",
+ "track_changes": 0,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/expense_claim.py b/erpnext/hr/doctype/expense_claim/expense_claim.py
index 09cdd547f5d..44879abf053 100644
--- a/erpnext/hr/doctype/expense_claim/expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/expense_claim.py
@@ -18,7 +18,7 @@ class ExpenseApproverIdentityError(frappe.ValidationError): pass
class ExpenseClaim(AccountsController):
def onload(self):
- self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings',
+ self.get("__onload").make_payment_via_journal_entry = frappe.db.get_single_value('Accounts Settings',
'make_payment_via_journal_entry')
def validate(self):
@@ -103,7 +103,7 @@ class ExpenseClaim(AccountsController):
self.validate_account_details()
payable_amount = flt(self.total_sanctioned_amount) - flt(self.total_advance_amount)
-
+
# payable entry
if payable_amount:
gl_entry.append(
@@ -233,7 +233,7 @@ class ExpenseClaim(AccountsController):
expense.default_account = get_expense_claim_account(expense.expense_type, self.company)["account"]
def update_reimbursed_amount(doc):
- amt = frappe.db.sql("""select ifnull(sum(debit_in_account_currency), 0) as amt
+ amt = frappe.db.sql("""select ifnull(sum(debit_in_account_currency), 0) as amt
from `tabGL Entry` where against_voucher_type = 'Expense Claim' and against_voucher = %s
and party = %s """, (doc.name, doc.employee) ,as_dict=1)[0].amt
@@ -288,7 +288,7 @@ def get_expense_claim_account(expense_claim_type, company):
if not account:
frappe.throw(_("Please set default account in Expense Claim Type {0}")
.format(expense_claim_type))
-
+
return {
"account": account
}
@@ -301,9 +301,9 @@ def get_advances(employee, advance_id=None):
condition = 'name="{0}"'.format(frappe.db.escape(advance_id))
return frappe.db.sql("""
- select
+ select
name, posting_date, paid_amount, claimed_amount, advance_account
- from
+ from
`tabEmployee Advance`
where {0}
""".format(condition), as_dict=1)
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.py b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
index 075bc63345d..dcf0e68400d 100644
--- a/erpnext/hr/doctype/expense_claim/test_expense_claim.py
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.py
@@ -13,19 +13,23 @@ test_dependencies = ['Employee']
class TestExpenseClaim(unittest.TestCase):
def test_total_expense_claim_for_project(self):
frappe.db.sql("""delete from `tabTask` where project = "_Test Project 1" """)
+ frappe.db.sql("""delete from `tabProject Task` where parent = "_Test Project 1" """)
frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
-
+ frappe.db.sql("delete from `tabExpense Claim` where project='_Test Project 1'")
frappe.get_doc({
"project_name": "_Test Project 1",
"doctype": "Project",
- "tasks" :
- [{ "title": "_Test Project Task 1", "status": "Open" }]
+ }).save()
+
+ task = frappe.get_doc({
+ "doctype": "Task",
+ "subject": "_Test Project Task 1",
+ "project": "_Test Project 1"
}).save()
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)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
@@ -103,9 +107,10 @@ 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):
+ employee = frappe.db.get_value("Employee", {"status": "Active"})
expense_claim = frappe.get_doc({
"doctype": "Expense Claim",
- "employee": "_T-Employee-00001",
+ "employee": employee,
"payable_account": payable_account,
"approval_status": "Approved",
"company": company,
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 b8089908502..d4e70575e91 100644
--- a/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
+++ b/erpnext/hr/doctype/expense_claim_detail/expense_claim_detail.json
@@ -1,366 +1,378 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2013-02-22 01:27:46",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "editable_grid": 1,
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2013-02-22 01:27:46",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "editable_grid": 1,
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "expense_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Expense Date",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "expense_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expense_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Expense Date",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "expense_date",
+ "oldfieldtype": "Date",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
- "unique": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "expense_type",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Expense Claim Type",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "expense_type",
- "oldfieldtype": "Link",
- "options": "Expense Claim Type",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expense_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Expense Claim Type",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "expense_type",
+ "oldfieldtype": "Link",
+ "options": "Expense Claim Type",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
- "unique": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "expense_type",
- "fieldname": "default_account",
- "fieldtype": "Link",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "expense_type",
+ "fieldname": "default_account",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_4",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_4",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "expense_type.description",
- "fieldname": "description",
- "fieldtype": "Text Editor",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Description",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "description",
- "oldfieldtype": "Small Text",
- "options": "",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "300px",
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "",
+ "fieldname": "description",
+ "fieldtype": "Text Editor",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Description",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "description",
+ "oldfieldtype": "Small Text",
+ "options": "",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "300px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
- "unique": 0,
+ "unique": 0,
"width": "300px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_6",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_6",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "claim_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Claim Amount",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "claim_amount",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "claim_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Claim Amount",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "claim_amount",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
- "unique": 0,
+ "unique": 0,
"width": "150px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_8",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_8",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sanctioned_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Sanctioned Amount",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "sanctioned_amount",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "150px",
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sanctioned_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Sanctioned Amount",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "sanctioned_amount",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "150px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"translatable": 0,
- "unique": 0,
+ "unique": 0,
"width": "150px"
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2018-05-16 22:42:56.727863",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Expense Claim Detail",
- "owner": "harshada@webnotestech.com",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 1,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2019-02-24 08:41:36.122565",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Expense Claim Detail",
+ "owner": "harshada@webnotestech.com",
+ "permissions": [],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index b85f38b295e..88b8f77b2e0 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -135,6 +135,7 @@ class LeaveApplication(Document):
date = dt.strftime("%Y-%m-%d")
doc = frappe.new_doc("Attendance")
doc.employee = self.employee
+ doc.employee_name = self.employee_name
doc.attendance_date = date
doc.company = self.company
doc.leave_type = self.leave_type
@@ -399,6 +400,19 @@ def get_leave_balance_on(employee, leave_type, date, allocation_records=None, do
return flt(allocation.total_leaves_allocated) - (flt(leaves_taken) + flt(leaves_encashed))
+def get_total_allocated_leaves(employee, leave_type, date):
+ filters= {
+ 'from_date': ['<=', date],
+ 'to_date': ['>=', date],
+ 'docstatus': 1,
+ 'leave_type': leave_type,
+ 'employee': employee
+ }
+
+ leave_allocation_records = frappe.db.get_all('Leave Allocation', filters=filters, fields=['total_leaves_allocated'])
+
+ return flt(leave_allocation_records[0]['total_leaves_allocated']) if leave_allocation_records else flt(0)
+
def get_leaves_for_period(employee, leave_type, from_date, to_date, status, docname=None):
leave_applications = frappe.db.sql("""
select name, employee, leave_type, from_date, to_date, total_leave_days
@@ -499,14 +513,12 @@ def add_department_leaves(events, start, end, employee, company):
department_employees = frappe.db.sql_list("""select name from tabEmployee where department=%s
and company=%s""", (department, company))
- filter_conditions = "employee in (\"%s\")" % '", "'.join(department_employees)
+ filter_conditions = " and employee in (\"%s\")" % '", "'.join(department_employees)
add_leaves(events, start, end, filter_conditions=filter_conditions)
def add_leaves(events, start, end, filter_conditions=None):
conditions = []
- if filter_conditions:
- conditions.append(filter_conditions)
if not cint(frappe.db.get_value("HR Settings", None, "show_leaves_of_all_department_members_in_calendar")):
from frappe.desk.reportview import build_match_conditions
@@ -520,11 +532,14 @@ def add_leaves(events, start, end, filter_conditions=None):
from `tabLeave Application` where
from_date <= %(end)s and to_date >= %(start)s <= to_date
and docstatus < 2
- and status!="Rejected" """
+ and status!='Rejected' """
if conditions:
query += ' and ' + ' and '.join(conditions)
+ if filter_conditions:
+ query += filter_conditions
+
for d in frappe.db.sql(query, {"start":start, "end": end}, as_dict=True):
e = {
"name": d.name,
diff --git a/erpnext/hr/doctype/payroll_period/payroll_period.json b/erpnext/hr/doctype/payroll_period/payroll_period.json
index d3a9612d786..c9bac095f9f 100644
--- a/erpnext/hr/doctype/payroll_period/payroll_period.json
+++ b/erpnext/hr/doctype/payroll_period/payroll_period.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
@@ -20,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -53,6 +55,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -84,6 +87,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -116,6 +120,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -148,6 +153,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"hidden": 1,
@@ -180,6 +186,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "periods",
"fieldtype": "Table",
"hidden": 0,
@@ -213,6 +220,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_7",
"fieldtype": "Section Break",
"hidden": 0,
@@ -245,6 +253,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxable_salary_slabs",
"fieldtype": "Table",
"hidden": 0,
@@ -270,6 +279,39 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "standard_tax_exemption_amount",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Standard Tax Exemption Amount",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
}
],
"has_web_view": 0,
@@ -282,7 +324,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-25 12:29:07.207927",
+ "modified": "2019-04-26 01:45:03.160929",
"modified_by": "Administrator",
"module": "HR",
"name": "Payroll Period",
@@ -354,5 +396,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
- "track_seen": 0
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_component/salary_component.js b/erpnext/hr/doctype/salary_component/salary_component.js
index b33451bc35c..f6afd5efebc 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.js
+++ b/erpnext/hr/doctype/salary_component/salary_component.js
@@ -5,10 +5,8 @@ frappe.ui.form.on('Salary Component', {
setup: function(frm) {
frm.set_query("default_account", "accounts", function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
- var root_types = ["Expense", "Liability"];
return {
filters: {
- "root_type": ["in", root_types],
"is_group": 0,
"company": d.company
}
@@ -75,5 +73,5 @@ var set_value_for_condition_and_formula = function(frm) {
frm.set_value("amount_based_on_formula", 0);
frm.set_value("statistical_component", 0);
frm.set_value("do_not_include_in_total", 0);
- frm.set_value("depends_on_lwp", 0);
+ frm.set_value("depends_on_payment_days", 0);
};
diff --git a/erpnext/hr/doctype/salary_component/salary_component.json b/erpnext/hr/doctype/salary_component/salary_component.json
index f7ce08c737a..697d224092c 100644
--- a/erpnext/hr/doctype/salary_component/salary_component.json
+++ b/erpnext/hr/doctype/salary_component/salary_component.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -19,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "salary_component",
"fieldtype": "Data",
"hidden": 0,
@@ -51,6 +53,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "salary_component_abbr",
"fieldtype": "Data",
"hidden": 0,
@@ -85,6 +88,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "type",
"fieldtype": "Select",
"hidden": 0,
@@ -119,6 +123,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_flexible_benefit != 1",
+ "fetch_if_empty": 0,
"fieldname": "is_additional_component",
"fieldtype": "Check",
"hidden": 0,
@@ -153,6 +158,7 @@
"columns": 0,
"default": "1",
"depends_on": "eval:doc.type == \"Earning\"",
+ "fetch_if_empty": 0,
"fieldname": "is_tax_applicable",
"fieldtype": "Check",
"hidden": 0,
@@ -186,6 +192,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "is_payable",
"fieldtype": "Check",
"hidden": 0,
@@ -218,7 +225,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "depends_on_lwp",
+ "default": "1",
+ "fetch_if_empty": 0,
+ "fieldname": "depends_on_payment_days",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -227,7 +236,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Depends on Leave Without Pay",
+ "label": "Depends on Payment Days",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -250,6 +259,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "do_not_include_in_total",
"fieldtype": "Check",
"hidden": 0,
@@ -282,6 +292,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -313,6 +324,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
@@ -345,6 +357,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
@@ -378,6 +391,7 @@
"collapsible": 0,
"columns": 0,
"description": "If selected, the value specified or calculated in this component will not contribute to the earnings or deductions. However, it's value can be referenced by other components that can be added or deducted. ",
+ "fetch_if_empty": 0,
"fieldname": "statistical_component",
"fieldtype": "Check",
"hidden": 0,
@@ -411,6 +425,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.type==\"Earning\" && doc.is_additional_component != 1 && doc.statistical_component!=1",
+ "fetch_if_empty": 0,
"fieldname": "flexible_benefits",
"fieldtype": "Section Break",
"hidden": 0,
@@ -444,6 +459,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_additional_component != 1",
+ "fetch_if_empty": 0,
"fieldname": "is_flexible_benefit",
"fieldtype": "Check",
"hidden": 0,
@@ -477,6 +493,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "is_flexible_benefit",
+ "fetch_if_empty": 0,
"fieldname": "max_benefit_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -509,6 +526,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"hidden": 0,
@@ -541,6 +559,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "is_flexible_benefit",
+ "fetch_if_empty": 0,
"fieldname": "pay_against_benefit_claim",
"fieldtype": "Check",
"hidden": 0,
@@ -574,6 +593,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_flexible_benefit == 1 & doc.create_separate_payment_entry_against_benefit_claim !=1",
+ "fetch_if_empty": 0,
"fieldname": "only_tax_impact",
"fieldtype": "Check",
"hidden": 0,
@@ -607,6 +627,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_flexible_benefit == 1 & doc.only_tax_impact !=1",
+ "fetch_if_empty": 0,
"fieldname": "create_separate_payment_entry_against_benefit_claim",
"fieldtype": "Check",
"hidden": 0,
@@ -640,6 +661,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.type=='Deduction'",
+ "fetch_if_empty": 0,
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
@@ -671,6 +693,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "variable_based_on_taxable_salary",
"fieldtype": "Check",
"hidden": 0,
@@ -704,6 +727,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.statistical_component != 1",
+ "fetch_if_empty": 0,
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"hidden": 0,
@@ -736,6 +760,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "accounts",
"fieldtype": "Table",
"hidden": 0,
@@ -771,6 +796,7 @@
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "eval:doc.is_flexible_benefit != 1 && doc.variable_based_on_taxable_salary != 1",
+ "fetch_if_empty": 0,
"fieldname": "condition_and_formula",
"fieldtype": "Section Break",
"hidden": 0,
@@ -803,6 +829,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "condition",
"fieldtype": "Code",
"hidden": 0,
@@ -836,6 +863,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "amount_based_on_formula",
"fieldtype": "Check",
"hidden": 0,
@@ -869,6 +897,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.amount_based_on_formula!==0",
+ "fetch_if_empty": 0,
"fieldname": "formula",
"fieldtype": "Code",
"hidden": 0,
@@ -902,6 +931,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.amount_based_on_formula!==1",
+ "fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -934,6 +964,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_28",
"fieldtype": "Column Break",
"hidden": 0,
@@ -965,6 +996,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "help",
"fieldtype": "HTML",
"hidden": 0,
@@ -1003,7 +1035,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-09-20 16:44:58.876044",
+ "modified": "2019-04-16 19:08:55.323567",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Component",
diff --git a/erpnext/hr/doctype/salary_detail/salary_detail.json b/erpnext/hr/doctype/salary_detail/salary_detail.json
index 0ec3cd64138..8f2649ad21b 100644
--- a/erpnext/hr/doctype/salary_detail/salary_detail.json
+++ b/erpnext/hr/doctype/salary_detail/salary_detail.json
@@ -19,6 +19,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "salary_component",
"fieldtype": "Link",
"hidden": 0,
@@ -55,6 +56,7 @@
"default": "",
"depends_on": "eval:doc.parenttype=='Salary Structure'",
"fetch_from": "salary_component.salary_component_abbr",
+ "fetch_if_empty": 0,
"fieldname": "abbr",
"fieldtype": "Data",
"hidden": 0,
@@ -88,6 +90,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -121,6 +124,7 @@
"columns": 0,
"description": "If selected, the value specified or calculated in this component will not contribute to the earnings or deductions. However, it's value can be referenced by other components that can be added or deducted. ",
"fetch_from": "salary_component.statistical_component",
+ "fetch_if_empty": 0,
"fieldname": "statistical_component",
"fieldtype": "Check",
"hidden": 0,
@@ -154,6 +158,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "salary_component.is_tax_applicable",
+ "fetch_if_empty": 0,
"fieldname": "is_tax_applicable",
"fieldtype": "Check",
"hidden": 0,
@@ -187,6 +192,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "salary_component.is_flexible_benefit",
+ "fetch_if_empty": 0,
"fieldname": "is_flexible_benefit",
"fieldtype": "Check",
"hidden": 0,
@@ -221,6 +227,7 @@
"columns": 0,
"default": "",
"fetch_from": "salary_component.is_additional_component",
+ "fetch_if_empty": 0,
"fieldname": "is_additional_component",
"fieldtype": "Check",
"hidden": 1,
@@ -255,6 +262,7 @@
"columns": 0,
"default": "",
"fetch_from": "salary_component.variable_based_on_taxable_salary",
+ "fetch_if_empty": 0,
"fieldname": "variable_based_on_taxable_salary",
"fieldtype": "Check",
"hidden": 0,
@@ -288,8 +296,9 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
- "fetch_from": "salary_component.depends_on_lwp",
- "fieldname": "depends_on_lwp",
+ "fetch_from": "salary_component.depends_on_payment_days",
+ "fetch_if_empty": 0,
+ "fieldname": "depends_on_payment_days",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -298,7 +307,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Depends on Leave Without Pay",
+ "label": "Depends on Payment Days",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -322,6 +331,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_flexible_benefit != 1",
+ "fetch_if_empty": 0,
"fieldname": "section_break_2",
"fieldtype": "Section Break",
"hidden": 0,
@@ -354,6 +364,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.parenttype=='Salary Structure'",
+ "fetch_if_empty": 0,
"fieldname": "condition",
"fieldtype": "Code",
"hidden": 0,
@@ -389,6 +400,7 @@
"default": "0",
"depends_on": "eval:doc.parenttype=='Salary Structure'",
"fetch_from": "",
+ "fetch_if_empty": 0,
"fieldname": "amount_based_on_formula",
"fieldtype": "Check",
"hidden": 0,
@@ -425,6 +437,7 @@
"default": "",
"depends_on": "eval:doc.amount_based_on_formula!==0 && doc.parenttype==='Salary Structure'",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "formula",
"fieldtype": "Code",
"hidden": 0,
@@ -458,6 +471,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.amount_based_on_formula!==1 || doc.parenttype==='Salary Slip'",
+ "fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -491,6 +505,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "do_not_include_in_total",
"fieldtype": "Check",
"hidden": 0,
@@ -524,6 +539,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.parenttype=='Salary Structure'",
+ "fetch_if_empty": 0,
"fieldname": "default_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -558,6 +574,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.parenttype=='Salary Slip' && doc.parentfield=='deductions' && doc.variable_based_on_taxable_salary == 1",
+ "fetch_if_empty": 0,
"fieldname": "tax_on_flexible_benefit",
"fieldtype": "Currency",
"hidden": 0,
@@ -591,6 +608,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.parenttype=='Salary Slip' && doc.parentfield=='deductions' && doc.variable_based_on_taxable_salary == 1",
+ "fetch_if_empty": 0,
"fieldname": "tax_on_additional_salary",
"fieldtype": "Currency",
"hidden": 0,
@@ -624,6 +642,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.parenttype=='Salary Structure'",
+ "fetch_if_empty": 0,
"fieldname": "section_break_11",
"fieldtype": "Column Break",
"hidden": 0,
@@ -656,6 +675,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.parenttype=='Salary Structure'",
+ "fetch_if_empty": 0,
"fieldname": "condition_and_formula_help",
"fieldtype": "HTML",
"hidden": 0,
@@ -693,7 +713,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2019-02-04 14:41:56.030991",
+ "modified": "2019-04-16 19:09:31.726597",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Detail",
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.js b/erpnext/hr/doctype/salary_slip/salary_slip.js
index 86c50d08ba1..4e9fcce8982 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.js
@@ -132,9 +132,6 @@ var get_emp_and_leave_details = function(doc, dt, dn) {
});
}
-cur_frm.cscript.employee = function(doc,dt,dn){
- get_emp_and_leave_details(doc, dt, dn);
-}
cur_frm.cscript.leave_without_pay = function(doc,dt,dn){
if (doc.employee && doc.start_date && doc.end_date) {
@@ -160,7 +157,7 @@ cur_frm.cscript.amount = function(doc,dt,dn){
calculate_all(doc, dt, dn);
}
-cur_frm.cscript.depends_on_lwp = function(doc,dt,dn){
+cur_frm.cscript.depends_on_payment_days = function(doc,dt,dn){
calculate_earning_total(doc, dt, dn, true);
calculate_ded_total(doc, dt, dn, true);
calculate_net_pay(doc, dt, dn);
@@ -174,7 +171,7 @@ var calculate_earning_total = function(doc, dt, dn, reset_amount) {
var tbl = doc.earnings || [];
var total_earn = 0;
for(var i = 0; i < tbl.length; i++){
- if(cint(tbl[i].depends_on_lwp) == 1) {
+ if(cint(tbl[i].depends_on_payment_days) == 1) {
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days) /
cint(doc.total_working_days)*100)/100;
} else if(reset_amount && tbl[i].default_amount) {
@@ -196,7 +193,7 @@ var calculate_ded_total = function(doc, dt, dn, reset_amount) {
var tbl = doc.deductions || [];
var total_ded = 0;
for(var i = 0; i < tbl.length; i++){
- if(cint(tbl[i].depends_on_lwp) == 1) {
+ if(cint(tbl[i].depends_on_payment_days) == 1) {
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_working_days)*100)/100;
} else if(reset_amount && tbl[i].default_amount) {
tbl[i].amount = tbl[i].default_amount;
@@ -209,16 +206,12 @@ var calculate_ded_total = function(doc, dt, dn, reset_amount) {
refresh_many(['deductions', 'total_deduction']);
}
-// Calculate net payable amount
-// ------------------------------------------------------------------------
var calculate_net_pay = function(doc, dt, dn) {
doc.net_pay = flt(doc.gross_pay) - flt(doc.total_deduction);
doc.rounded_total = Math.round(doc.net_pay);
refresh_many(['net_pay', 'rounded_total']);
}
-// validate
-// ------------------------------------------------------------------------
cur_frm.cscript.validate = function(doc, dt, dn) {
calculate_all(doc, dt, dn);
}
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 3fd266b4bba..bbfca7db681 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -107,8 +107,8 @@ class SalarySlip(TransactionBase):
for d in self.get("earnings"):
if d.is_flexible_benefit == 1:
current_flexi_amount += d.amount
- last_benefits = get_last_payroll_period_benefits(self.employee, self.start_date, self.end_date,\
- current_flexi_amount, payroll_period, self._salary_structure_doc)
+ last_benefits = get_last_payroll_period_benefits(self.employee, self.start_date, self.end_date,
+ current_flexi_amount, payroll_period, self._salary_structure_doc)
if last_benefits:
for last_benefit in last_benefits:
last_benefit = frappe._dict(last_benefit)
@@ -118,7 +118,7 @@ class SalarySlip(TransactionBase):
def add_employee_flexi_benefits(self, struct_row):
if frappe.db.get_value("Salary Component", struct_row.salary_component, "pay_against_benefit_claim") != 1:
benefit_component_amount = get_benefit_component_amount(self.employee, self.start_date, self.end_date, \
- struct_row, self._salary_structure_doc, self.total_working_days, self.payroll_frequency)
+ struct_row, self._salary_structure_doc, self.total_working_days, self.payroll_frequency)
if benefit_component_amount:
self.update_component_row(struct_row, benefit_component_amount, "earnings")
else:
@@ -131,11 +131,12 @@ class SalarySlip(TransactionBase):
for d in self.get(key):
if d.salary_component == struct_row.salary_component:
component_row = d
+
if not component_row:
self.append(key, {
'amount': amount,
'default_amount': amount,
- 'depends_on_lwp' : struct_row.depends_on_lwp,
+ 'depends_on_payment_days' : struct_row.depends_on_payment_days,
'salary_component' : struct_row.salary_component,
'abbr' : struct_row.abbr,
'do_not_include_in_total' : struct_row.do_not_include_in_total,
@@ -147,12 +148,11 @@ class SalarySlip(TransactionBase):
'tax_on_additional_salary': additional_tax
})
else:
- if overwrite:
- component_row.default_amount = amount
- component_row.amount = amount
- else:
- component_row.default_amount += amount
- component_row.amount = component_row.default_amount
+ if not overwrite:
+ amount += struct_row.get("default_amount", 0)
+
+ component_row.default_amount = amount
+ component_row.amount = amount
component_row.tax_on_flexible_benefit = benefit_tax
component_row.tax_on_additional_salary = additional_tax
@@ -167,7 +167,7 @@ class SalarySlip(TransactionBase):
if d.amount_based_on_formula:
formula = d.formula.strip() if d.formula else None
if formula:
- amount = frappe.safe_eval(formula, self.whitelisted_globals, data)
+ amount = rounded(frappe.safe_eval(formula, self.whitelisted_globals, data))
if amount:
data[d.abbr] = amount
@@ -418,7 +418,7 @@ class SalarySlip(TransactionBase):
for d in self.get(component_type):
if (self.salary_structure and
- cint(d.depends_on_lwp) and
+ cint(d.depends_on_payment_days) and cint(self.total_working_days) and
(not
self.salary_slip_based_on_timesheet or
getdate(self.start_date) < joining_date or
@@ -431,7 +431,7 @@ class SalarySlip(TransactionBase):
)
elif not self.payment_days and not self.salary_slip_based_on_timesheet and \
- cint(d.depends_on_lwp):
+ cint(d.depends_on_payment_days):
d.amount = 0
elif not d.amount:
d.amount = d.default_amount
@@ -441,7 +441,7 @@ class SalarySlip(TransactionBase):
def calculate_net_pay(self):
if self.salary_structure:
self.calculate_component_amounts()
-
+
disable_rounded_total = cint(frappe.db.get_value("Global Defaults", None, "disable_rounded_total"))
precision = frappe.defaults.get_global_default("currency_precision")
self.total_deduction = 0
@@ -455,7 +455,7 @@ class SalarySlip(TransactionBase):
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
self.rounded_total = rounded(self.net_pay,
self.precision("net_pay") if disable_rounded_total else 0)
-
+
if self.net_pay < 0:
frappe.throw(_("Net Pay cannnot be negative"))
@@ -574,8 +574,8 @@ class SalarySlip(TransactionBase):
def calculate_variable_tax(self, tax_component, payroll_period):
annual_taxable_earning, period_factor = 0, 0
- pro_rata_tax_paid, additional_tax_paid, benefit_tax_paid = 0, 0, 0
- unclaimed_earning, unclaimed_benefit, additional_income = 0, 0, 0
+ pro_rata_tax_paid, additional_tax_paid, benefit_tax_paid = 0.0, 0.0, 0.0
+ unclaimed_earning, unclaimed_benefit, additional_income = 0.0, 0.0, 0.0
# get taxable_earning, additional_income in this slip
taxable_earning = self.get_taxable_earnings()
@@ -590,7 +590,7 @@ class SalarySlip(TransactionBase):
unclaimed_earning = self.calculate_unclaimed_taxable_earning(payroll_period, tax_component)
earning_in_period = taxable_earning["taxable_earning"] + unclaimed_earning
period_factor = self.get_period_factor(payroll_period.start_date, payroll_period.end_date,
- payroll_period.start_date, self.end_date)
+ payroll_period.start_date, self.end_date)
annual_taxable_earning = earning_in_period * period_factor
additional_income += self.get_total_additional_income(payroll_period.start_date)
else:
@@ -599,7 +599,7 @@ class SalarySlip(TransactionBase):
annual_earning = taxable_earning["taxable_earning"] * period_factor
exemption_amount = 0
if frappe.db.exists("Employee Tax Exemption Declaration", {"employee": self.employee,
- "payroll_period": payroll_period.name, "docstatus": 1}):
+ "payroll_period": payroll_period.name, "docstatus": 1}):
exemption_amount = frappe.db.get_value("Employee Tax Exemption Declaration",
{"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1},
"total_exemption_amount")
@@ -614,11 +614,17 @@ class SalarySlip(TransactionBase):
# add any additional income in this slip
additional_income += taxable_earning["additional_income"]
- args = {"payroll_period": payroll_period.name, "tax_component": tax_component,
- "annual_taxable_earning": annual_taxable_earning, "period_factor": period_factor,
- "unclaimed_benefit": unclaimed_benefit, "additional_income": additional_income,
- "pro_rata_tax_paid": pro_rata_tax_paid, "benefit_tax_paid": benefit_tax_paid,
- "additional_tax_paid": additional_tax_paid}
+ args = {
+ "payroll_period": payroll_period.name,
+ "tax_component": tax_component,
+ "period_factor": period_factor,
+ "annual_taxable_earning": annual_taxable_earning,
+ "additional_income": additional_income,
+ "unclaimed_benefit": unclaimed_benefit,
+ "pro_rata_tax_paid": pro_rata_tax_paid,
+ "benefit_tax_paid": benefit_tax_paid,
+ "additional_tax_paid": additional_tax_paid
+ }
return self.calculate_tax(args)
def calculate_unclaimed_taxable_benefit(self, payroll_period):
@@ -665,27 +671,49 @@ class SalarySlip(TransactionBase):
return total_taxable_earning
def get_total_additional_income(self, from_date):
- total_additional_pay = 0
- sum_additional_earning = frappe.db.sql("""select sum(sd.amount) from `tabSalary Detail` sd join
- `tabSalary Slip` ss on sd.parent=ss.name where sd.parentfield='earnings'
- and sd.is_tax_applicable=1 and is_additional_component=1 and is_flexible_benefit=0
- and ss.docstatus=1 and ss.employee='{0}' and ss.start_date between '{1}' and '{2}'
- and ss.end_date between '{1}' and '{2}'""".format(self.employee,
- from_date, self.start_date))
- if sum_additional_earning and sum_additional_earning[0][0]:
- total_additional_pay = sum_additional_earning[0][0]
- return total_additional_pay
+ sum_additional_earning = frappe.db.sql("""
+ select sum(sd.amount)
+ from
+ `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name
+ where
+ sd.parentfield='earnings'
+ and sd.is_tax_applicable=1 and is_additional_component=1
+ and is_flexible_benefit=0 and ss.docstatus=1
+ and ss.employee=%(employee)s
+ and ss.start_date between %(from_date)s and %(to_date)s
+ and ss.end_date between %(from_date)s and %(to_date)s
+ """, {
+ "employee": self.employee,
+ "from_date": from_date,
+ "to_date": self.start_date
+ })
+ return flt(sum_additional_earning[0][0]) if sum_additional_earning else 0
def get_tax_paid_in_period(self, payroll_period, tax_component, only_total=False):
# find total_tax_paid, tax paid for benefit, additional_salary
- sum_tax_paid = frappe.db.sql("""select sum(sd.amount), sum(tax_on_flexible_benefit),
- sum(tax_on_additional_salary) from `tabSalary Detail` sd join `tabSalary Slip`
- ss on sd.parent=ss.name where sd.parentfield='deductions' and sd.salary_component='{3}'
- and sd.variable_based_on_taxable_salary=1 and ss.docstatus=1 and ss.employee='{0}'
- and ss.start_date between '{1}' and '{2}' and ss.end_date between '{1}' and
- '{2}'""".format(self.employee, payroll_period.start_date, self.start_date, tax_component))
+ sum_tax_paid = frappe.db.sql("""
+ select
+ sum(sd.amount), sum(tax_on_flexible_benefit), sum(tax_on_additional_salary)
+ from
+ `tabSalary Detail` sd join `tabSalary Slip` ss on sd.parent=ss.name
+ where
+ sd.parentfield='deductions' and sd.salary_component=%(salary_component)s
+ and sd.variable_based_on_taxable_salary=1
+ and ss.docstatus=1 and ss.employee=%(employee)s
+ and ss.start_date between %(from_date)s and %(to_date)s
+ and ss.end_date between %(from_date)s and %(to_date)s
+ """, {
+ "salary_component": tax_component,
+ "employee": self.employee,
+ "from_date": payroll_period.start_date,
+ "to_date": self.start_date
+ })
if sum_tax_paid and sum_tax_paid[0][0]:
- return {'total_tax_paid': sum_tax_paid[0][0], 'benefit_tax':sum_tax_paid[0][1], 'additional_tax': sum_tax_paid[0][2]}
+ return {
+ 'total_tax_paid': sum_tax_paid[0][0],
+ 'benefit_tax':sum_tax_paid[0][1],
+ 'additional_tax': sum_tax_paid[0][2]
+ }
def get_taxable_earnings(self, include_flexi=0, only_flexi=0):
taxable_earning = 0
@@ -696,22 +724,22 @@ class SalarySlip(TransactionBase):
additional_income += earning.amount
continue
if only_flexi:
- if earning.is_tax_applicable and earning.is_flexible_benefit:
+ if earning.is_flexible_benefit:
taxable_earning += earning.amount
continue
- if include_flexi:
- if earning.is_tax_applicable or (earning.is_tax_applicable and earning.is_flexible_benefit):
- taxable_earning += earning.amount
- else:
- if earning.is_tax_applicable and not earning.is_flexible_benefit:
- taxable_earning += earning.amount
- return {"taxable_earning": taxable_earning, "additional_income": additional_income}
+ if include_flexi or not earning.is_flexible_benefit:
+ taxable_earning += earning.amount
+ return {
+ "taxable_earning": taxable_earning,
+ "additional_income": additional_income
+ }
def calculate_tax(self, args):
tax_amount, benefit_tax, additional_tax = 0, 0, 0
annual_taxable_earning = args.get("annual_taxable_earning")
benefit_to_tax = args.get("unclaimed_benefit")
additional_income = args.get("additional_income")
+
# Get tax calc by period
annual_tax = self.calculate_tax_by_tax_slab(args.get("payroll_period"), annual_taxable_earning)
@@ -736,22 +764,26 @@ class SalarySlip(TransactionBase):
# less paid taxes
if args.get("pro_rata_tax_paid"):
tax_amount -= args.get("pro_rata_tax_paid")
+ tax_amount = rounded(tax_amount)
struct_row = self.get_salary_slip_row(args.get("tax_component"))
return [struct_row, tax_amount, benefit_tax, additional_tax]
- def calculate_tax_by_tax_slab(self, payroll_period, annual_earning):
+ def calculate_tax_by_tax_slab(self, payroll_period, annual_taxable_earning):
payroll_period_obj = frappe.get_doc("Payroll Period", payroll_period)
+ annual_taxable_earning -= flt(payroll_period_obj.standard_tax_exemption_amount)
data = self.get_data_for_eval()
+ data.update({"annual_taxable_earning": annual_taxable_earning})
+
taxable_amount = 0
for slab in payroll_period_obj.taxable_salary_slabs:
if slab.condition and not self.eval_tax_slab_condition(slab.condition, data):
continue
- if not slab.to_amount and annual_earning > slab.from_amount:
- taxable_amount += (annual_earning - slab.from_amount) * slab.percent_deduction *.01
+ if not slab.to_amount and annual_taxable_earning > slab.from_amount:
+ taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
continue
- if annual_earning > slab.from_amount and annual_earning < slab.to_amount:
- taxable_amount += (annual_earning - slab.from_amount) * slab.percent_deduction *.01
- elif annual_earning > slab.from_amount and annual_earning > slab.to_amount:
+ if annual_taxable_earning > slab.from_amount and annual_taxable_earning < slab.to_amount:
+ taxable_amount += (annual_taxable_earning - slab.from_amount) * slab.percent_deduction *.01
+ elif annual_taxable_earning > slab.from_amount and annual_taxable_earning > slab.to_amount:
taxable_amount += (slab.to_amount - slab.from_amount) * slab.percent_deduction * .01
return taxable_amount
@@ -770,13 +802,21 @@ class SalarySlip(TransactionBase):
def get_period_factor(self, period_start, period_end, start_date=None, end_date=None):
# TODO if both deduct checked update the factor to make tax consistent
+ joining_date, relieving_date = frappe.db.get_value("Employee", self.employee, ["date_of_joining", "relieving_date"])
+ if getdate(joining_date) > getdate(period_start):
+ period_start = joining_date
+ if relieving_date and getdate(relieving_date) < getdate(period_end):
+ period_end = relieving_date
+
payroll_days = date_diff(period_end, period_start) + 1
if start_date and end_date:
salary_days = date_diff(end_date, start_date) + 1
return flt(payroll_days)/flt(salary_days)
+
# if period configured for a year and monthly frequency return 12 to make tax calc consistent
if 360 <= payroll_days <= 370 and self.payroll_frequency == "Monthly":
return 12
+
salary_days = date_diff(self.end_date, self.start_date) + 1
return flt(payroll_days)/flt(salary_days)
@@ -784,7 +824,7 @@ class SalarySlip(TransactionBase):
component = frappe.get_doc("Salary Component", salary_component)
# Data for update_component_row
struct_row = {}
- struct_row['depends_on_lwp'] = component.depends_on_lwp
+ struct_row['depends_on_payment_days'] = component.depends_on_payment_days
struct_row['salary_component'] = component.name
struct_row['abbr'] = component.salary_component_abbr
struct_row['do_not_include_in_total'] = component.do_not_include_in_total
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 079bec51b2e..75c1e420b8e 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -13,7 +13,8 @@ from frappe.utils import getdate, nowdate, add_days, add_months, flt, get_first_
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
from erpnext.hr.doctype.payroll_entry.payroll_entry import get_month_details
from erpnext.hr.doctype.employee.test_employee import make_employee
-from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration import create_payroll_period, create_exemption_category
+from erpnext.hr.doctype.employee_tax_exemption_declaration.test_employee_tax_exemption_declaration \
+ import create_payroll_period, create_exemption_category
class TestSalarySlip(unittest.TestCase):
def setUp(self):
@@ -36,8 +37,10 @@ class TestSalarySlip(unittest.TestCase):
no_of_days = self.get_no_of_days()
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 1)
make_employee("test_employee@salary.com")
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
ss = make_employee_salary_slip("test_employee@salary.com", "Monthly")
self.assertEqual(ss.total_working_days, no_of_days[0])
@@ -53,8 +56,10 @@ class TestSalarySlip(unittest.TestCase):
no_of_days = self.get_no_of_days()
frappe.db.set_value("HR Settings", None, "include_holidays_in_total_working_days", 0)
make_employee("test_employee@salary.com")
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
ss = make_employee_salary_slip("test_employee@salary.com", "Monthly")
self.assertEqual(ss.total_working_days, no_of_days[0] - no_of_days[1])
@@ -100,16 +105,21 @@ class TestSalarySlip(unittest.TestCase):
self.assertEqual(ss.payment_days, (no_of_days[0] - getdate(date_of_joining).day + 1))
# set relieving date in the same month
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", relieving_date)
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
+ frappe.db.set_value("Employee",frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "date_of_joining", (add_days(nowdate(),-60)))
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", relieving_date)
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "status", "Left")
ss.save()
self.assertEqual(ss.total_working_days, no_of_days[0])
self.assertEqual(ss.payment_days, getdate(relieving_date).day)
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
- frappe.db.set_value("Employee", frappe.get_value("Employee", {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "relieving_date", None)
+ frappe.db.set_value("Employee", frappe.get_value("Employee",
+ {"employee_name":"test_employee@salary.com"}, "name"), "status", "Active")
def test_employee_salary_slip_read_permission(self):
make_employee("test_employee@salary.com")
@@ -149,36 +159,41 @@ class TestSalarySlip(unittest.TestCase):
month = "%02d" % getdate(nowdate()).month
m = get_month_details(fiscal_year, month)
- for payroll_frequncy in ["Monthly", "Bimonthly", "Fortnightly", "Weekly", "Daily"]:
- make_employee(payroll_frequncy + "_test_employee@salary.com")
- ss = make_employee_salary_slip(payroll_frequncy + "_test_employee@salary.com", payroll_frequncy)
- if payroll_frequncy == "Monthly":
+ for payroll_frequency in ["Monthly", "Bimonthly", "Fortnightly", "Weekly", "Daily"]:
+ make_employee(payroll_frequency + "_test_employee@salary.com")
+ ss = make_employee_salary_slip(payroll_frequency + "_test_employee@salary.com", payroll_frequency)
+ if payroll_frequency == "Monthly":
self.assertEqual(ss.end_date, m['month_end_date'])
- elif payroll_frequncy == "Bimonthly":
+ elif payroll_frequency == "Bimonthly":
if getdate(ss.start_date).day <= 15:
self.assertEqual(ss.end_date, m['month_mid_end_date'])
else:
self.assertEqual(ss.end_date, m['month_end_date'])
- elif payroll_frequncy == "Fortnightly":
+ elif payroll_frequency == "Fortnightly":
self.assertEqual(ss.end_date, add_days(nowdate(),13))
- elif payroll_frequncy == "Weekly":
+ elif payroll_frequency == "Weekly":
self.assertEqual(ss.end_date, add_days(nowdate(),6))
- elif payroll_frequncy == "Daily":
+ elif payroll_frequency == "Daily":
self.assertEqual(ss.end_date, nowdate())
def test_tax_for_payroll_period(self):
data = {}
- # test the impact of tax exemption declaration, tax exemption proof submission and deduct check boxes in annual tax calculation
+ # test the impact of tax exemption declaration, tax exemption proof submission
+ # and deduct check boxes in annual tax calculation
# as per assigned salary structure 40500 in monthly salary so 236000*5/100/12
frappe.db.sql("""delete from `tabPayroll Period`""")
frappe.db.sql("""delete from `tabSalary Component`""")
payroll_period = create_payroll_period()
create_tax_slab(payroll_period)
employee = make_employee("test_tax@salary.slip")
- delete_docs = ["Salary Slip", "Additional Salary",
- "Employee Tax Exemption Declaration",
- "Employee Tax Exemption Proof Submission",
- "Employee Benefit Claim", "Salary Structure Assignment"]
+ delete_docs = [
+ "Salary Slip",
+ "Additional Salary",
+ "Employee Tax Exemption Declaration",
+ "Employee Tax Exemption Proof Submission",
+ "Employee Benefit Claim",
+ "Salary Structure Assignment"
+ ]
for doc in delete_docs:
frappe.db.sql("delete from `tab%s` where employee='%s'" % (doc, employee))
@@ -298,12 +313,11 @@ def make_employee_salary_slip(user, payroll_frequency, salary_structure=None):
if not salary_slip:
salary_slip = make_salary_slip(salary_structure_doc.name, employee = employee)
- salary_slip.employee_name = frappe.get_value("Employee", {"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name")
+ salary_slip.employee_name = frappe.get_value("Employee",
+ {"name":frappe.db.get_value("Employee", {"user_id": user})}, "employee_name")
salary_slip.payroll_frequency = payroll_frequency
salary_slip.posting_date = nowdate()
salary_slip.insert()
- # salary_slip.submit()
- # salary_slip = salary_slip.name
return salary_slip
@@ -338,99 +352,99 @@ def create_account(company):
salary_account = frappe.db.get_value("Account", "Salary - " + frappe.get_cached_value('Company', company, 'abbr'))
if not salary_account:
frappe.get_doc({
- "doctype": "Account",
- "account_name": "Salary",
- "parent_account": "Indirect Expenses - " + frappe.get_cached_value('Company', company, 'abbr'),
- "company": company
+ "doctype": "Account",
+ "account_name": "Salary",
+ "parent_account": "Indirect Expenses - " + frappe.get_cached_value('Company', company, 'abbr'),
+ "company": company
}).insert()
return salary_account
def make_earning_salary_component(setup=False, test_tax=False):
data = [
+ {
+ "salary_component": 'Basic Salary',
+ "abbr":'BS',
+ "condition": 'base > 10000',
+ "formula": 'base*.5',
+ "type": "Earning",
+ "amount_based_on_formula": 1
+ },
+ {
+ "salary_component": 'HRA',
+ "abbr":'H',
+ "amount": 3000,
+ "type": "Earning"
+ },
+ {
+ "salary_component": 'Special Allowance',
+ "abbr":'SA',
+ "condition": 'H < 10000',
+ "formula": 'BS*.5',
+ "type": "Earning",
+ "amount_based_on_formula": 1
+ },
+ {
+ "salary_component": "Leave Encashment",
+ "abbr": 'LE',
+ "is_additional_component": 1,
+ "type": "Earning"
+ }
+ ]
+ if test_tax:
+ data.extend([
{
- "salary_component": 'Basic Salary',
- "abbr":'BS',
- "condition": 'base > 10000',
- "formula": 'base*.5',
+ "salary_component": "Leave Travel Allowance",
+ "abbr": 'B',
+ "is_flexible_benefit": 1,
"type": "Earning",
- "amount_based_on_formula": 1
+ "pay_against_benefit_claim": 1,
+ "max_benefit_amount": 100000
},
{
- "salary_component": 'HRA',
- "abbr":'H',
- "amount": 3000,
- "type": "Earning"
- },
- {
- "salary_component": 'Special Allowance',
- "abbr":'SA',
- "condition": 'H < 10000',
- "formula": 'BS*.5',
+ "salary_component": "Medical Allowance",
+ "abbr": 'B',
+ "is_flexible_benefit": 1,
+ "pay_against_benefit_claim": 0,
"type": "Earning",
- "amount_based_on_formula": 1
+ "max_benefit_amount": 15000
},
{
- "salary_component": "Leave Encashment",
- "abbr": 'LE',
+ "salary_component": "Perfomance Bonus",
+ "abbr": 'B',
"is_additional_component": 1,
"type": "Earning"
}
- ]
- if test_tax:
- data.extend([
- {
- "salary_component": "Leave Travel Allowance",
- "abbr": 'B',
- "is_flexible_benefit": 1,
- "type": "Earning",
- "pay_against_benefit_claim": 1,
- "max_benefit_amount": 100000
- },
- {
- "salary_component": "Medical Allowance",
- "abbr": 'B',
- "is_flexible_benefit": 1,
- "pay_against_benefit_claim": 0,
- "type": "Earning",
- "max_benefit_amount": 15000
- },
- {
- "salary_component": "Perfomance Bonus",
- "abbr": 'B',
- "is_additional_component": 1,
- "type": "Earning"
- }
- ])
+ ])
if setup or test_tax:
make_salary_component(data, test_tax)
data.append({
- "salary_component": 'Basic Salary',
- "abbr":'BS',
- "condition": 'base < 10000',
- "formula": 'base*.2',
- "type": "Earning",
- "amount_based_on_formula": 1
- })
+ "salary_component": 'Basic Salary',
+ "abbr":'BS',
+ "condition": 'base < 10000',
+ "formula": 'base*.2',
+ "type": "Earning",
+ "amount_based_on_formula": 1
+ })
return data
def make_deduction_salary_component(setup=False, test_tax=False):
data = [
- {
- "salary_component": 'Professional Tax',
- "abbr":'PT',
- "condition": 'base > 10000',
- "formula": 'base*.1',
- "type": "Deduction",
- "amount_based_on_formula": 1
- },
- {
- "salary_component": 'TDS',
- "abbr":'T',
- "formula": 'base*.1',
- "type": "Deduction",
- "amount_based_on_formula": 1
- }
- ]
+ {
+ "salary_component": 'Professional Tax',
+ "abbr":'PT',
+ "condition": 'base > 10000',
+ "formula": 'base*.1',
+ "type": "Deduction",
+ "amount_based_on_formula": 1
+ },
+ {
+ "salary_component": 'TDS',
+ "abbr":'T',
+ "formula": 'base*.1',
+ "type": "Deduction",
+ "amount_based_on_formula": 1
+ }
+ ]
if not test_tax:
data.append({
"salary_component": 'TDS',
@@ -453,48 +467,63 @@ def get_tax_paid_in_period(employee):
def create_exemption_declaration(employee, payroll_period):
create_exemption_category()
- declaration = frappe.get_doc({"doctype": "Employee Tax Exemption Declaration",
- "employee": employee,
- "payroll_period": payroll_period,
- "company": erpnext.get_default_company()})
- declaration.append("declarations", {"exemption_sub_category": "_Test Sub Category",
- "exemption_category": "_Test Category",
- "amount": 100000})
+ declaration = frappe.get_doc({
+ "doctype": "Employee Tax Exemption Declaration",
+ "employee": employee,
+ "payroll_period": payroll_period,
+ "company": erpnext.get_default_company()
+ })
+ declaration.append("declarations", {
+ "exemption_sub_category": "_Test Sub Category",
+ "exemption_category": "_Test Category",
+ "amount": 100000
+ })
declaration.submit()
def create_proof_submission(employee, payroll_period, amount):
submission_date = add_months(payroll_period.start_date, random.randint(0, 11))
- proof_submission = frappe.get_doc({"doctype": "Employee Tax Exemption Proof Submission",
- "employee": employee,
- "payroll_period": payroll_period.name,
- "submission_date": submission_date})
- proof_submission.append("tax_exemption_proofs", {"exemption_sub_category": "_Test Sub Category",
- "exemption_category": "_Test Category", "type_of_proof": "Test", "amount": amount})
+ proof_submission = frappe.get_doc({
+ "doctype": "Employee Tax Exemption Proof Submission",
+ "employee": employee,
+ "payroll_period": payroll_period.name,
+ "submission_date": submission_date
+ })
+ proof_submission.append("tax_exemption_proofs", {
+ "exemption_sub_category": "_Test Sub Category",
+ "exemption_category": "_Test Category",
+ "type_of_proof": "Test", "amount": amount
+ })
proof_submission.submit()
return submission_date
def create_benefit_claim(employee, payroll_period, amount, component):
claim_date = add_months(payroll_period.start_date, random.randint(0, 11))
- frappe.get_doc({"doctype": "Employee Benefit Claim", "employee": employee,
- "claimed_amount": amount, "claim_date": claim_date, "earning_component":
- component}).submit()
+ frappe.get_doc({
+ "doctype": "Employee Benefit Claim",
+ "employee": employee,
+ "claimed_amount": amount,
+ "claim_date": claim_date,
+ "earning_component": component
+ }).submit()
return claim_date
def create_tax_slab(payroll_period):
- data = [{
- "from_amount": 250000,
- "to_amount": 500000,
- "percent_deduction": 5
- },
- {
- "from_amount": 500000,
- "to_amount": 1000000,
- "percent_deduction": 20
- },
- {
- "from_amount": 1000000,
- "percent_deduction": 30
- }]
+ data = [
+ {
+ "from_amount": 250000,
+ "to_amount": 500000,
+ "percent_deduction": 5
+ },
+ {
+ "from_amount": 500000,
+ "to_amount": 1000000,
+ "percent_deduction": 20
+ },
+ {
+ "from_amount": 1000000,
+ "percent_deduction": 30
+ }
+ ]
payroll_period.taxable_salary_slabs = []
for item in data:
payroll_period.append("taxable_salary_slabs", item)
@@ -526,9 +555,13 @@ def create_salary_slips_for_payroll_period(employee, salary_structure, payroll_p
def create_additional_salary(employee, payroll_period, amount):
salary_date = add_months(payroll_period.start_date, random.randint(0, 11))
- frappe.get_doc({"doctype": "Additional Salary", "employee": employee,
- "company": erpnext.get_default_company(),
- "salary_component": "Perfomance Bonus",
- "payroll_date": salary_date,
- "amount": amount, "type": "Earning"}).submit()
+ frappe.get_doc({
+ "doctype": "Additional Salary",
+ "employee": employee,
+ "company": erpnext.get_default_company(),
+ "salary_component": "Perfomance Bonus",
+ "payroll_date": salary_date,
+ "amount": amount,
+ "type": "Earning"
+ }).submit()
return salary_date
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.js b/erpnext/hr/doctype/salary_structure/salary_structure.js
index 79d75bfdf6e..e3f37e71059 100755
--- a/erpnext/hr/doctype/salary_structure/salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.js
@@ -246,7 +246,7 @@ frappe.ui.form.on('Salary Detail', {
frappe.model.set_value(cdt, cdn, 'amount', result.amount);
}
frappe.model.set_value(cdt, cdn, 'statistical_component', result.statistical_component);
- frappe.model.set_value(cdt, cdn, 'depends_on_lwp', result.depends_on_lwp);
+ frappe.model.set_value(cdt, cdn, 'depends_on_payment_days', result.depends_on_payment_days);
frappe.model.set_value(cdt, cdn, 'do_not_include_in_total', result.do_not_include_in_total);
frappe.model.set_value(cdt, cdn, 'variable_based_on_taxable_salary', result.variable_based_on_taxable_salary);
frappe.model.set_value(cdt, cdn, 'is_tax_applicable', result.is_tax_applicable);
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py
index 202ae9bcfe5..3431d3d4a8e 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.py
@@ -18,7 +18,7 @@ class SalaryStructure(Document):
self.validate_max_benefits_with_flexi()
def set_missing_values(self):
- overwritten_fields = ["depends_on_lwp", "variable_based_on_taxable_salary", "is_tax_applicable", "is_flexible_benefit"]
+ overwritten_fields = ["depends_on_payment_days", "variable_based_on_taxable_salary", "is_tax_applicable", "is_flexible_benefit"]
overwritten_fields_if_missing = ["amount_based_on_formula", "formula", "amount"]
for table in ["earnings", "deductions"]:
for d in self.get(table):
@@ -57,11 +57,12 @@ class SalaryStructure(Document):
have_a_flexi = True
max_of_component = frappe.db.get_value("Salary Component", earning_component.salary_component, "max_benefit_amount")
flexi_amount += max_of_component
+
if have_a_flexi and flt(self.max_benefits) == 0:
frappe.throw(_("Max benefits should be greater than zero to dispense benefits"))
- if have_a_flexi and flt(self.max_benefits) > flexi_amount:
- frappe.throw(_("Total flexible benefit component amount {0} should not be less \
- than max benefits {1}").format(flexi_amount, self.max_benefits))
+ if have_a_flexi and flexi_amount and flt(self.max_benefits) > flexi_amount:
+ frappe.throw(_("Total flexible benefit component amount {0} should not be less than max benefits {1}")
+ .format(flexi_amount, self.max_benefits))
if not have_a_flexi and flt(self.max_benefits) > 0:
frappe.throw(_("Salary Structure should have flexible benefit component(s) to dispense benefit amount"))
@@ -126,7 +127,7 @@ def create_salary_structures_assignment(employee, salary_structure, from_date, b
def get_existing_assignments(employees, salary_structure,from_date):
salary_structures_assignments = frappe.db.sql_list("""
- select distinct employee from `tabSalary Structure Assignment`
+ select distinct employee from `tabSalary Structure Assignment`
where salary_structure=%s and employee in (%s)
and from_date=%s and docstatus=1
""" % ('%s', ', '.join(['%s']*len(employees)),'%s'), [salary_structure] + employees+[from_date])
diff --git a/erpnext/hr/doctype/staffing_plan/staffing_plan.py b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
index 70e185cde56..83e53135ef4 100644
--- a/erpnext/hr/doctype/staffing_plan/staffing_plan.py
+++ b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
@@ -20,6 +20,7 @@ class StaffingPlan(Document):
self.total_estimated_budget = 0
for detail in self.get("staffing_details"):
+ self.set_vacancies(detail)
self.validate_overlap(detail)
self.validate_with_subsidiary_plans(detail)
self.validate_with_parent_plan(detail)
@@ -39,6 +40,15 @@ class StaffingPlan(Document):
else: detail.vacancies = detail.number_of_positions = detail.total_estimated_cost = 0
self.total_estimated_budget += detail.total_estimated_cost
+ def set_vacancies(self, row):
+ if not row.vacancies:
+ current_openings = 0
+ for field in ['current_count', 'current_openings']:
+ if row.get(field):
+ current_openings += row.get(field)
+
+ row.vacancies = row.number_of_positions - current_openings
+
def validate_overlap(self, staffing_plan_detail):
# Validate if any submitted Staffing Plan exist for any Designations in this plan
# and spd.vacancies>0 ?
diff --git a/erpnext/hr/doctype/staffing_plan/test_staffing_plan.py b/erpnext/hr/doctype/staffing_plan/test_staffing_plan.py
index 66d9cdd07a5..22dba99af00 100644
--- a/erpnext/hr/doctype/staffing_plan/test_staffing_plan.py
+++ b/erpnext/hr/doctype/staffing_plan/test_staffing_plan.py
@@ -18,7 +18,7 @@ class TestStaffingPlan(unittest.TestCase):
if frappe.db.exists("Staffing Plan", "Test"):
return
staffing_plan = frappe.new_doc("Staffing Plan")
- staffing_plan.company = "_Test Company 3"
+ staffing_plan.company = "_Test Company 10"
staffing_plan.name = "Test"
staffing_plan.from_date = nowdate()
staffing_plan.to_date = add_days(nowdate(), 10)
@@ -67,7 +67,7 @@ class TestStaffingPlan(unittest.TestCase):
if frappe.db.exists("Staffing Plan", "Test 1"):
return
staffing_plan = frappe.new_doc("Staffing Plan")
- staffing_plan.company = "_Test Company 3"
+ staffing_plan.company = "_Test Company 10"
staffing_plan.name = "Test 1"
staffing_plan.from_date = nowdate()
staffing_plan.to_date = add_days(nowdate(), 10)
@@ -85,11 +85,11 @@ def _set_up():
make_company()
def make_company():
- if frappe.db.exists("Company", "_Test Company 3"):
+ if frappe.db.exists("Company", "_Test Company 10"):
return
company = frappe.new_doc("Company")
- company.company_name = "_Test Company 3"
- company.abbr = "_TC3"
+ company.company_name = "_Test Company 10"
+ company.abbr = "_TC10"
company.parent_company = "_Test Company"
company.default_currency = "INR"
company.country = "India"
diff --git a/erpnext/hr/doctype/training_feedback/training_feedback.py b/erpnext/hr/doctype/training_feedback/training_feedback.py
index b7eae38ae48..b47e2b4be88 100644
--- a/erpnext/hr/doctype/training_feedback/training_feedback.py
+++ b/erpnext/hr/doctype/training_feedback/training_feedback.py
@@ -15,9 +15,11 @@ class TrainingFeedback(Document):
def on_submit(self):
training_event = frappe.get_doc("Training Event", self.training_event)
+ status = None
for e in training_event.employees:
if e.employee == self.employee:
- training_event.status = 'Feedback Submitted'
+ status = 'Feedback Submitted'
break
- training_event.save()
+ if status:
+ frappe.db.set_value("Training Event", self.training_event, "status", status)
diff --git a/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json b/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json
index 20c7d232494..ceaf4a6ac71 100644
--- a/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json
+++ b/erpnext/hr/print_format/salary_slip_based_on_timesheet/salary_slip_based_on_timesheet.json
@@ -1,18 +1,18 @@
{
- "creation": "2016-07-07 12:38:32.447281",
- "custom_format": 0,
- "disabled": 0,
- "doc_type": "Salary Slip",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \"
{{doc.name}}
\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_hours\"}, {\"print_hide\": 0, \"fieldname\": \"hour_rate\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"time_sheet\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"working_hours\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"timesheets\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]",
- "idx": 0,
- "modified": "2016-08-21 21:02:59.896033",
- "modified_by": "Administrator",
- "name": "Salary Slip based on Timesheet",
- "owner": "Administrator",
- "print_format_builder": 1,
- "print_format_type": "Server",
+ "creation": "2016-07-07 12:38:32.447281",
+ "custom_format": 0,
+ "disabled": 0,
+ "doc_type": "Salary Slip",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "font": "Default",
+ "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"HTML\", \"options\": \"
{{doc.name}}
\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\"}, {\"print_hide\": 0, \"fieldname\": \"department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_hours\"}, {\"print_hide\": 0, \"fieldname\": \"hour_rate\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"time_sheet\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"working_hours\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"timesheets\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_payment_days\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_payment_days\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\"}, {\"fieldtype\": \"Section Break\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\"}]",
+ "idx": 0,
+ "modified": "2016-08-21 21:02:59.896033",
+ "modified_by": "Administrator",
+ "name": "Salary Slip based on Timesheet",
+ "owner": "Administrator",
+ "print_format_builder": 1,
+ "print_format_type": "Server",
"standard": "Yes"
}
\ No newline at end of file
diff --git a/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json b/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
index 9f299df0ed3..b01239fe02d 100644
--- a/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
+++ b/erpnext/hr/print_format/salary_slip_standard/salary_slip_standard.json
@@ -1,22 +1,22 @@
{
- "align_labels_right": 0,
- "creation": "2016-07-07 11:45:14.872204",
- "custom_format": 0,
- "disabled": 0,
- "doc_type": "Salary Slip",
- "docstatus": 0,
- "doctype": "Print Format",
- "font": "Default",
- "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
{{doc.name}}
\\n
\\n
\\n \"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\", \"label\": \"Employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\", \"label\": \"Employee Name\"}, {\"print_hide\": 0, \"fieldname\": \"department\", \"label\": \"Department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\", \"label\": \"Designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\", \"label\": \"Branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\", \"label\": \"Start Date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\", \"label\": \"End Date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_days\", \"label\": \"Working Days\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\", \"label\": \"Leave Without Pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\", \"label\": \"Payment Days\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\", \"label\": \"Earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_lwp\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\", \"label\": \"Deductions\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\", \"label\": \"Gross Pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\", \"label\": \"Total Deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\", \"label\": \"Net Pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\", \"label\": \"Total in words\"}]",
- "idx": 0,
- "line_breaks": 0,
- "modified": "2018-07-24 19:31:39.040701",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Salary Slip Standard",
- "owner": "Administrator",
- "print_format_builder": 1,
- "print_format_type": "Server",
- "show_section_headings": 0,
+ "align_labels_right": 0,
+ "creation": "2016-07-07 11:45:14.872204",
+ "custom_format": 0,
+ "disabled": 0,
+ "doc_type": "Salary Slip",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "font": "Default",
+ "format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"
{{doc.name}}
\\n
\\n
\\n \"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"employee\", \"label\": \"Employee\"}, {\"print_hide\": 0, \"fieldname\": \"company\", \"label\": \"Company\"}, {\"print_hide\": 0, \"fieldname\": \"employee_name\", \"label\": \"Employee Name\"}, {\"print_hide\": 0, \"fieldname\": \"department\", \"label\": \"Department\"}, {\"print_hide\": 0, \"fieldname\": \"designation\", \"label\": \"Designation\"}, {\"print_hide\": 0, \"fieldname\": \"branch\", \"label\": \"Branch\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"start_date\", \"label\": \"Start Date\"}, {\"print_hide\": 0, \"fieldname\": \"end_date\", \"label\": \"End Date\"}, {\"print_hide\": 0, \"fieldname\": \"total_working_days\", \"label\": \"Working Days\"}, {\"print_hide\": 0, \"fieldname\": \"leave_without_pay\", \"label\": \"Leave Without Pay\"}, {\"print_hide\": 0, \"fieldname\": \"payment_days\", \"label\": \"Payment Days\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"earnings\", \"label\": \"Earnings\"}, {\"fieldtype\": \"Column Break\"}, {\"visible_columns\": [{\"print_hide\": 0, \"fieldname\": \"salary_component\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"amount\", \"print_width\": \"\"}, {\"print_hide\": 0, \"fieldname\": \"depends_on_payment_days\", \"print_width\": \"\"}], \"print_hide\": 0, \"fieldname\": \"deductions\", \"label\": \"Deductions\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldtype\": \"Column Break\"}, {\"print_hide\": 0, \"fieldname\": \"gross_pay\", \"label\": \"Gross Pay\"}, {\"print_hide\": 0, \"fieldname\": \"total_deduction\", \"label\": \"Total Deduction\"}, {\"print_hide\": 0, \"fieldname\": \"net_pay\", \"label\": \"Net Pay\"}, {\"print_hide\": 0, \"fieldname\": \"rounded_total\", \"label\": \"Rounded Total\"}, {\"print_hide\": 0, \"fieldname\": \"total_in_words\", \"label\": \"Total in words\"}]",
+ "idx": 0,
+ "line_breaks": 0,
+ "modified": "2018-07-24 19:31:39.040701",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Salary Slip Standard",
+ "owner": "Administrator",
+ "print_format_builder": 1,
+ "print_format_type": "Server",
+ "show_section_headings": 0,
"standard": "Yes"
}
\ No newline at end of file
diff --git a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
index ed44d639f52..95cb30b7918 100644
--- a/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
+++ b/erpnext/hr/report/employee_leave_balance/employee_leave_balance.py
@@ -5,21 +5,21 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from erpnext.hr.doctype.leave_application.leave_application \
- import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period
+ import get_leave_allocation_records, get_leave_balance_on, get_approved_leaves_for_period, get_total_allocated_leaves
def execute(filters=None):
leave_types = frappe.db.sql_list("select name from `tabLeave Type` order by name asc")
-
+
columns = get_columns(leave_types)
data = get_data(filters, leave_types)
-
+
return columns, data
-
+
def get_columns(leave_types):
columns = [
- _("Employee") + ":Link/Employee:150",
- _("Employee Name") + "::200",
+ _("Employee") + ":Link/Employee:150",
+ _("Employee Name") + "::200",
_("Department") +"::150"
]
@@ -27,18 +27,18 @@ def get_columns(leave_types):
columns.append(_(leave_type) + " " + _("Opening") + ":Float:160")
columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
-
+
return columns
-
+
def get_data(filters, leave_types):
user = frappe.session.user
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
allocation_records_based_on_from_date = get_leave_allocation_records(filters.from_date)
- active_employees = frappe.get_all("Employee",
- filters = { "status": "Active", "company": filters.company},
+ active_employees = frappe.get_all("Employee",
+ filters = { "status": "Active", "company": filters.company},
fields = ["name", "employee_name", "department", "user_id"])
-
+
data = []
for employee in active_employees:
leave_approvers = get_approvers(employee.department)
@@ -51,8 +51,7 @@ def get_data(filters, leave_types):
filters.from_date, filters.to_date)
# opening balance
- opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
- allocation_records_based_on_from_date.get(employee.name, frappe._dict()))
+ opening = get_total_allocated_leaves(employee.name, leave_type, filters.to_date)
# closing balance
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
@@ -61,7 +60,7 @@ def get_data(filters, leave_types):
row += [opening, leaves_taken, closing]
data.append(row)
-
+
return data
def get_approvers(department):
diff --git a/erpnext/hr/utils.py b/erpnext/hr/utils.py
index 02262012f1c..70752c65323 100644
--- a/erpnext/hr/utils.py
+++ b/erpnext/hr/utils.py
@@ -220,16 +220,30 @@ def get_employee_leave_policy(employee):
def validate_tax_declaration(declarations):
subcategories = []
- for declaration in declarations:
- if declaration.exemption_sub_category in subcategories:
- frappe.throw(_("More than one selection for {0} not \
- allowed").format(declaration.exemption_sub_category), frappe.ValidationError)
- subcategories.append(declaration.exemption_sub_category)
- max_amount = frappe.db.get_value("Employee Tax Exemption Sub Category", \
- declaration.exemption_sub_category, "max_amount")
- if declaration.amount > max_amount:
- frappe.throw(_("Max exemption amount for {0} is {1}").format(\
- declaration.exemption_sub_category, max_amount), frappe.ValidationError)
+ for d in declarations:
+ if d.exemption_sub_category in subcategories:
+ frappe.throw(_("More than one selection for {0} not allowed").format(d.exemption_sub_category))
+ subcategories.append(d.exemption_sub_category)
+
+def get_total_exemption_amount(declarations):
+ exemptions = frappe._dict()
+ for d in declarations:
+ exemptions.setdefault(d.exemption_category, frappe._dict())
+ category_max_amount = exemptions.get(d.exemption_category).max_amount
+ if not category_max_amount:
+ category_max_amount = frappe.db.get_value("Employee Tax Exemption Category", d.exemption_category, "max_amount")
+ exemptions.get(d.exemption_category).max_amount = category_max_amount
+ sub_category_exemption_amount = d.max_amount \
+ if (d.max_amount and flt(d.amount) > flt(d.max_amount)) else d.amount
+
+ exemptions.get(d.exemption_category).setdefault("total_exemption_amount", 0.0)
+ exemptions.get(d.exemption_category).total_exemption_amount += flt(sub_category_exemption_amount)
+
+ if category_max_amount and exemptions.get(d.exemption_category).total_exemption_amount > category_max_amount:
+ exemptions.get(d.exemption_category).total_exemption_amount = category_max_amount
+
+ total_exemption_amount = sum([flt(d.total_exemption_amount) for d in exemptions.values()])
+ return total_exemption_amount
def get_leave_period(from_date, to_date, company):
leave_period = frappe.db.sql("""
diff --git a/erpnext/hub_node/legacy.py b/erpnext/hub_node/legacy.py
index 9daee2752fa..95ada76a6a5 100644
--- a/erpnext/hub_node/legacy.py
+++ b/erpnext/hub_node/legacy.py
@@ -28,7 +28,7 @@ def make_opportunity(buyer_name, email_id):
lead.save(ignore_permissions=True)
o = frappe.new_doc("Opportunity")
- o.enquiry_from = "Lead"
+ o.opportunity_from = "Lead"
o.lead = frappe.get_all("Lead", filters={"email_id": email_id}, fields = ["name"])[0]["name"]
o.save(ignore_permissions=True)
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index 7b5339b4f0b..3c35e6cc5e1 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -5,11 +5,6 @@ frappe.provide("erpnext.bom");
frappe.ui.form.on("BOM", {
setup: function(frm) {
- frm.add_fetch("item", "description", "description");
- frm.add_fetch("item", "image", "image");
- frm.add_fetch("item", "item_name", "item_name");
- frm.add_fetch("item", "stock_uom", "uom");
-
frm.set_query("bom_no", "items", function() {
return {
filters: {
@@ -413,8 +408,4 @@ frappe.ui.form.on("BOM", "with_operations", function(frm) {
frm.set_value("operations", []);
}
toggle_operations(frm);
-});
-
-cur_frm.cscript.image = function() {
- refresh_field("image_view");
-};
+});
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index 79c883a734f..7865a2476f9 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -20,6 +20,7 @@
"collapsible": 0,
"columns": 0,
"description": "Item to be manufactured or repacked",
+ "fetch_if_empty": 0,
"fieldname": "item",
"fieldtype": "Link",
"hidden": 0,
@@ -55,6 +56,8 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_from": "item.item_name",
+ "fetch_if_empty": 0,
"fieldname": "item_name",
"fieldtype": "Data",
"hidden": 0,
@@ -87,6 +90,43 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "item.image",
+ "fetch_if_empty": 0,
+ "fieldname": "image",
+ "fieldtype": "Attach Image",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Image",
+ "length": 0,
+ "no_copy": 0,
+ "options": "image",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "item.stock_uom",
+ "fetch_if_empty": 0,
"fieldname": "uom",
"fieldtype": "Link",
"hidden": 0,
@@ -121,6 +161,7 @@
"columns": 0,
"default": "1",
"description": "Quantity of item obtained after manufacturing / repacking from given quantities of raw materials",
+ "fetch_if_empty": 0,
"fieldname": "quantity",
"fieldtype": "Float",
"hidden": 0,
@@ -154,6 +195,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "cb0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -185,6 +227,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "is_active",
"fieldtype": "Check",
"hidden": 0,
@@ -219,6 +262,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "is_default",
"fieldtype": "Check",
"hidden": 0,
@@ -253,6 +297,7 @@
"collapsible": 0,
"columns": 0,
"description": "Manage cost of operations",
+ "fetch_if_empty": 0,
"fieldname": "with_operations",
"fieldtype": "Check",
"hidden": 0,
@@ -284,6 +329,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "inspection_required",
"fieldtype": "Check",
"hidden": 0,
@@ -316,6 +362,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "allow_alternative_item",
"fieldtype": "Check",
"hidden": 0,
@@ -348,6 +395,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "allow_same_item_multiple_times",
"fieldtype": "Check",
"hidden": 0,
@@ -381,6 +429,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "set_rate_of_sub_assembly_item_based_on_bom",
"fieldtype": "Check",
"hidden": 0,
@@ -414,6 +463,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "inspection_required",
+ "fetch_if_empty": 0,
"fieldname": "quality_inspection_template",
"fieldtype": "Link",
"hidden": 0,
@@ -447,6 +497,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency_detail",
"fieldtype": "Section Break",
"hidden": 0,
@@ -479,6 +530,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -513,6 +565,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "transfer_material_against",
"fieldtype": "Select",
"hidden": 0,
@@ -546,6 +599,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -578,6 +632,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_12",
"fieldtype": "Column Break",
"hidden": 0,
@@ -609,6 +664,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -643,6 +699,7 @@
"collapsible": 0,
"columns": 0,
"default": "Valuation Rate",
+ "fetch_if_empty": 0,
"fieldname": "rm_cost_as_per",
"fieldtype": "Select",
"hidden": 0,
@@ -676,6 +733,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.rm_cost_as_per===\"Price List\"",
+ "fetch_if_empty": 0,
"fieldname": "buying_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -710,6 +768,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "operations_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -742,6 +801,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "routing",
"fieldtype": "Link",
"hidden": 0,
@@ -775,6 +835,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "operations",
"fieldtype": "Table",
"hidden": 0,
@@ -809,6 +870,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "materials_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -841,6 +903,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -875,6 +938,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "scrap_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -907,6 +971,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "scrap_items",
"fieldtype": "Table",
"hidden": 0,
@@ -940,6 +1005,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "costing",
"fieldtype": "Section Break",
"hidden": 0,
@@ -972,6 +1038,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "operating_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -1004,6 +1071,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "raw_material_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -1036,6 +1104,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "scrap_material_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -1069,6 +1138,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "cb1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1099,6 +1169,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_operating_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -1132,6 +1203,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_raw_material_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -1165,6 +1237,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_scrap_material_cost",
"fieldtype": "Data",
"hidden": 0,
@@ -1198,6 +1271,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_cost_of_bom",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1229,6 +1303,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -1261,6 +1336,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_26",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1292,6 +1368,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_total_cost",
"fieldtype": "Currency",
"hidden": 0,
@@ -1325,6 +1402,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "more_info_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1356,6 +1434,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -1390,6 +1469,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -1422,6 +1502,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "col_break23",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1452,6 +1533,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_25",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1483,6 +1565,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_from": "item.description",
+ "fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1514,6 +1598,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_27",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1538,71 +1623,6 @@
"translatable": 0,
"unique": 0
},
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "image",
- "fieldtype": "Attach",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Image",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "image_view",
- "fieldtype": "Image",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Image View",
- "length": 0,
- "no_copy": 0,
- "options": "image",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -1611,6 +1631,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
+ "fetch_if_empty": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1642,6 +1663,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "exploded_items",
"fieldtype": "Table",
"hidden": 0,
@@ -1676,6 +1698,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "website_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1710,6 +1733,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "show_in_website",
"fieldtype": "Check",
"hidden": 0,
@@ -1742,6 +1766,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "route",
"fieldtype": "Small Text",
"hidden": 0,
@@ -1776,6 +1801,7 @@
"columns": 0,
"depends_on": "show_in_website",
"description": "Item Image (if not slideshow)",
+ "fetch_if_empty": 0,
"fieldname": "website_image",
"fieldtype": "Attach Image",
"hidden": 0,
@@ -1808,6 +1834,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "thumbnail",
"fieldtype": "Data",
"hidden": 0,
@@ -1842,6 +1869,7 @@
"collapsible_depends_on": "website_items",
"columns": 0,
"depends_on": "show_in_website",
+ "fetch_if_empty": 0,
"fieldname": "sb_web_spec",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1875,6 +1903,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "show_in_website",
+ "fetch_if_empty": 0,
"fieldname": "web_long_description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -1908,6 +1937,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "show_in_website",
+ "fetch_if_empty": 0,
"fieldname": "show_items",
"fieldtype": "Check",
"hidden": 0,
@@ -1941,6 +1971,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:(doc.show_in_website && doc.with_operations)",
+ "fetch_if_empty": 0,
"fieldname": "show_operations",
"fieldtype": "Check",
"hidden": 0,
@@ -1972,13 +2003,14 @@
"hide_toolbar": 0,
"icon": "fa fa-sitemap",
"idx": 1,
+ "image_field": "image",
"image_view": 0,
"in_create": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2019-01-30 16:39:34.353721",
+ "modified": "2019-05-01 16:36:05.197126",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",
@@ -2026,7 +2058,7 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
- "search_fields": "item",
+ "search_fields": "item, item_name",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 88d346ff0f3..b04ba7c4fb0 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -201,7 +201,7 @@ class BOM(WebsiteGenerator):
if not rate:
if self.rm_cost_as_per == "Price List":
- frappe.msgprint(_("Price not found for item {0} and price list {1}")
+ frappe.msgprint(_("Price not found for item {0} in price list {1}")
.format(arg["item_code"], self.buying_price_list), alert=True)
else:
frappe.msgprint(_("{0} not found for item {1}")
@@ -580,7 +580,7 @@ def get_list_context(context):
context.title = _("Bill of Materials")
# context.introduction = _('Boms')
-def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_items=0, include_non_stock_items=False):
+def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_items=0, include_non_stock_items=False, fetch_qty_in_stock_uom=True):
item_dict = {}
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
@@ -588,7 +588,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
bom_item.item_code,
bom_item.idx,
item.item_name,
- sum(bom_item.stock_qty/ifnull(bom.quantity, 1)) * %(qty)s as qty,
+ sum(bom_item.{qty_field}/ifnull(bom.quantity, 1)) * %(qty)s as qty,
item.description,
item.image,
item.stock_uom,
@@ -616,16 +616,18 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
query = query.format(table="BOM Explosion Item",
where_conditions="",
is_stock_item=is_stock_item,
+ qty_field="stock_qty",
select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.include_item_in_manufacturing,
- (Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx""")
+ (Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s limit 1) as idx""")
items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
elif fetch_scrap_items:
- query = query.format(table="BOM Scrap Item", where_conditions="", select_columns=", bom_item.idx", is_stock_item=is_stock_item)
+ query = query.format(table="BOM Scrap Item", where_conditions="", select_columns=", bom_item.idx", is_stock_item=is_stock_item, qty_field="stock_qty")
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
else:
query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item,
- select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing")
+ qty_field="stock_qty" if fetch_qty_in_stock_uom else "qty",
+ select_columns = ", bom_item.uom, bom_item.conversion_factor, bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing")
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
for item in items:
@@ -706,8 +708,11 @@ def get_children(doctype, parent=None, is_root=False, **filters):
def get_boms_in_bottom_up_order(bom_no=None):
def _get_parent(bom_no):
- return frappe.db.sql_list("""select distinct parent from `tabBOM Item`
- where bom_no = %s and docstatus=1 and parenttype='BOM'""", bom_no)
+ return frappe.db.sql_list("""
+ select distinct bom_item.parent from `tabBOM Item` bom_item
+ where bom_item.bom_no = %s and bom_item.docstatus=1 and bom_item.parenttype='BOM'
+ and exists(select bom.name from `tabBOM` bom where bom.name=bom_item.parent and bom.is_active=1)
+ """, bom_no)
count = 0
bom_list = []
@@ -715,9 +720,10 @@ def get_boms_in_bottom_up_order(bom_no=None):
bom_list.append(bom_no)
else:
# get all leaf BOMs
- bom_list = frappe.db.sql_list("""select name from `tabBOM` bom where docstatus=1
- and not exists(select bom_no from `tabBOM Item`
- where parent=bom.name and ifnull(bom_no, '')!='')""")
+ bom_list = frappe.db.sql_list("""select name from `tabBOM` bom
+ where docstatus=1 and is_active=1
+ and not exists(select bom_no from `tabBOM Item`
+ where parent=bom.name and ifnull(bom_no, '')!='')""")
while(count < len(bom_list)):
for child_bom in _get_parent(bom_list[count]):
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index 22583605777..febf315988c 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -78,6 +78,39 @@
"translatable": 0,
"unique": 0
},
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "operation",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item operation",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Operation",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -893,6 +926,38 @@
"translatable": 0,
"unique": 0
},
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "allow_alternative_item",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow Alternative Item",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
@@ -958,71 +1023,6 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "operation",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item operation",
- "length": 0,
- "no_copy": 0,
- "options": "Operation",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "allow_alternative_item",
- "fieldtype": "Check",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow Alternative Item",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
}
],
"has_web_view": 0,
@@ -1035,7 +1035,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-11-23 15:05:55.187136",
+ "modified": "2019-02-21 19:19:54.872459",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Item",
@@ -1050,4 +1050,4 @@
"track_changes": 0,
"track_seen": 0,
"track_views": 0
-}
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
index 3fe9b8af30d..95549d5a248 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -18,20 +18,27 @@ frappe.ui.form.on('Job Card', {
}
if (frm.doc.docstatus == 0) {
- if (!frm.doc.actual_start_date || !frm.doc.actual_end_date) {
- frm.trigger("make_dashboard");
- }
+ frm.trigger("make_dashboard");
- if (!frm.doc.actual_start_date) {
+ if (!frm.doc.job_started) {
frm.add_custom_button(__("Start Job"), () => {
- frm.set_value('actual_start_date', frappe.datetime.now_datetime());
+ let row = frappe.model.add_child(frm.doc, 'Job Card Time Log', 'time_logs');
+ row.from_time = frappe.datetime.now_datetime();
+ frm.set_value('job_started', 1);
+ frm.set_value('started_time' , row.from_time);
frm.save();
});
- } else if (!frm.doc.actual_end_date) {
+ } else {
frm.add_custom_button(__("Complete Job"), () => {
- frm.set_value('actual_end_date', frappe.datetime.now_datetime());
- frm.save();
- frm.savesubmit();
+ let completed_time = frappe.datetime.now_datetime();
+ frm.doc.time_logs.forEach(d => {
+ if (d.from_time && !d.to_time) {
+ d.to_time = completed_time;
+ frm.set_value('started_time' , '');
+ frm.set_value('job_started', 0);
+ frm.save();
+ }
+ })
});
}
}
@@ -53,8 +60,8 @@ frappe.ui.form.on('Job Card', {
var section = frm.dashboard.add_section(timer);
- if (frm.doc.actual_start_date) {
- let currentIncrement = moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.actual_start_date),"seconds");
+ if (frm.doc.started_time) {
+ let currentIncrement = moment(frappe.datetime.now_datetime()).diff(moment(frm.doc.started_time),"seconds");
initialiseTimer();
function initialiseTimer() {
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json
index b020c89053c..39c5cce313b 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.json
+++ b/erpnext/manufacturing/doctype/job_card/job_card.json
@@ -21,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "work_order",
"fieldtype": "Link",
"hidden": 0,
@@ -54,6 +55,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "bom_no",
"fieldtype": "Link",
"hidden": 0,
@@ -87,6 +89,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "workstation",
"fieldtype": "Link",
"hidden": 0,
@@ -120,6 +123,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "operation",
"fieldtype": "Link",
"hidden": 0,
@@ -153,6 +157,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -185,6 +190,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
+ "fetch_if_empty": 0,
"fieldname": "posting_date",
"fieldtype": "Date",
"hidden": 0,
@@ -217,6 +223,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -250,6 +257,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "for_quantity",
"fieldtype": "Float",
"hidden": 0,
@@ -282,6 +290,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "wip_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -315,6 +324,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "timing_detail",
"fieldtype": "Section Break",
"hidden": 0,
@@ -347,6 +357,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
@@ -380,7 +391,74 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "time_in_mins",
+ "fetch_if_empty": 0,
+ "fieldname": "time_logs",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Time Logs",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Job Card Time Log",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_13",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "total_completed_qty",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -389,7 +467,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Time In Mins",
+ "label": "Total Completed Qty",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -412,7 +490,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "column_break_13",
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_15",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -443,8 +522,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "actual_start_date",
- "fieldtype": "Datetime",
+ "fetch_if_empty": 0,
+ "fieldname": "total_time_in_mins",
+ "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -452,46 +532,14 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Actual Start Date",
+ "label": "Total Time in Mins",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "actual_end_date",
- "fieldtype": "Datetime",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Actual End Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -507,6 +555,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
@@ -539,6 +588,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -572,6 +622,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "more_information",
"fieldtype": "Section Break",
"hidden": 0,
@@ -604,6 +655,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "operation_id",
"fieldtype": "Data",
"hidden": 1,
@@ -637,6 +689,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
+ "fetch_if_empty": 0,
"fieldname": "transferred_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -670,6 +723,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
+ "fetch_if_empty": 0,
"fieldname": "requested_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -702,6 +756,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -735,6 +790,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "remarks",
"fieldtype": "Small Text",
"hidden": 0,
@@ -767,6 +823,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_20",
"fieldtype": "Column Break",
"hidden": 0,
@@ -799,6 +856,7 @@
"collapsible": 0,
"columns": 0,
"default": "Open",
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -832,6 +890,73 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "job_started",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Job Started",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "started_time",
+ "fieldtype": "Datetime",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Started Time",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -868,7 +993,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-12-13 17:23:57.986381",
+ "modified": "2019-03-10 17:38:37.499871",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Job Card",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index ea9f714fc84..23a4e5105c0 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -11,44 +11,56 @@ from frappe.model.document import Document
class JobCard(Document):
def validate(self):
- self.validate_actual_dates()
- self.set_time_in_mins()
+ self.validate_time_logs()
self.set_status()
- def validate_actual_dates(self):
- if get_datetime(self.actual_start_date) > get_datetime(self.actual_end_date):
- frappe.throw(_("Actual start date must be less than actual end date"))
+ def validate_time_logs(self):
+ self.total_completed_qty = 0.0
+ self.total_time_in_mins = 0.0
- if not (self.employee and self.actual_start_date and self.actual_end_date):
- return
+ for d in self.get('time_logs'):
+ if get_datetime(d.from_time) > get_datetime(d.to_time):
+ frappe.throw(_("Row {0}: From time must be less than to time").format(d.idx))
- data = frappe.db.sql(""" select name from `tabJob Card`
- where
- ((%(actual_start_date)s > actual_start_date and %(actual_start_date)s < actual_end_date) or
- (%(actual_end_date)s > actual_start_date and %(actual_end_date)s < actual_end_date) or
- (%(actual_start_date)s <= actual_start_date and %(actual_end_date)s >= actual_end_date)) and
- name != %(name)s and employee = %(employee)s and docstatus =1
- """, {
- 'actual_start_date': self.actual_start_date,
- 'actual_end_date': self.actual_end_date,
- 'employee': self.employee,
- 'name': self.name
- }, as_dict=1)
+ data = self.get_overlap_for(d)
+ if data:
+ frappe.throw(_("Row {0}: From Time and To Time of {1} is overlapping with {2}")
+ .format(d.idx, self.name, data.name))
- if data:
- frappe.throw(_("Start date and end date is overlapping with the job card
{1}")
- .format(data[0].name, data[0].name))
+ if d.from_time and d.to_time:
+ d.time_in_mins = time_diff_in_hours(d.to_time, d.from_time) * 60
+ self.total_time_in_mins += d.time_in_mins
- def set_time_in_mins(self):
- if self.actual_start_date and self.actual_end_date:
- self.time_in_mins = time_diff_in_hours(self.actual_end_date, self.actual_start_date) * 60
+ if d.completed_qty:
+ self.total_completed_qty += d.completed_qty
+
+ def get_overlap_for(self, args):
+ existing = frappe.db.sql("""select jc.name as name from
+ `tabJob Card Time Log` jctl, `tabJob Card` jc where jctl.parent = jc.name and
+ (
+ (%(from_time)s > jctl.from_time and %(from_time)s < jctl.to_time) or
+ (%(to_time)s > jctl.from_time and %(to_time)s < jctl.to_time) or
+ (%(from_time)s <= jctl.from_time and %(to_time)s >= jctl.to_time))
+ and jctl.name!=%(name)s
+ and jc.name!=%(parent)s
+ and jc.docstatus < 2
+ and jc.employee = %(employee)s """,
+ {
+ "from_time": args.from_time,
+ "to_time": args.to_time,
+ "name": args.name or "No Name",
+ "parent": args.parent or "No Name",
+ "employee": self.employee
+ }, as_dict=True)
+
+ return existing[0] if existing else None
def get_required_items(self):
if not self.get('work_order'):
return
doc = frappe.get_doc('Work Order', self.get('work_order'))
- if doc.transfer_material_against == 'Work Order' and doc.skip_transfer:
+ if doc.transfer_material_against == 'Work Order' or doc.skip_transfer:
return
for d in doc.required_items:
@@ -67,36 +79,51 @@ class JobCard(Document):
})
def on_submit(self):
- self.validate_dates()
+ self.validate_job_card()
self.update_work_order()
self.set_transferred_qty()
- def validate_dates(self):
- if not self.actual_start_date and not self.actual_end_date:
- frappe.throw(_("Actual start date and actual end date is mandatory"))
-
def on_cancel(self):
self.update_work_order()
self.set_transferred_qty()
+ def validate_job_card(self):
+ if not self.time_logs:
+ frappe.throw(_("Time logs are required for job card {0}").format(self.name))
+
+ if self.total_completed_qty <= 0.0:
+ frappe.throw(_("Total completed qty must be greater than zero"))
+
+ if self.total_completed_qty > self.for_quantity:
+ frappe.throw(_("Total completed qty can not be greater than for quantity"))
+
def update_work_order(self):
if not self.work_order:
return
- data = frappe.db.get_value("Job Card", {'docstatus': 1, 'operation_id': self.operation_id},
- ['sum(time_in_mins)', 'min(actual_start_date)', 'max(actual_end_date)', 'sum(for_quantity)'])
+ for_quantity, time_in_mins = 0, 0
+ from_time_list, to_time_list = [], []
- if data:
- time_in_mins, actual_start_date, actual_end_date, for_quantity = data
+ for d in frappe.get_all('Job Card',
+ filters = {'docstatus': 1, 'operation_id': self.operation_id}):
+ doc = frappe.get_doc('Job Card', d.name)
+
+ for_quantity += doc.total_completed_qty
+ time_in_mins += doc.total_time_in_mins
+ for time_log in doc.time_logs:
+ from_time_list.append(time_log.from_time)
+ to_time_list.append(time_log.to_time)
+
+ if for_quantity:
wo = frappe.get_doc('Work Order', self.work_order)
for data in wo.operations:
if data.name == self.operation_id:
data.completed_qty = for_quantity
data.actual_operation_time = time_in_mins
- data.actual_start_time = actual_start_date
- data.actual_end_time = actual_end_date
+ data.actual_start_time = min(from_time_list)
+ data.actual_end_time = max(to_time_list)
wo.flags.ignore_validate_update_after_submit = True
wo.update_operation_status()
@@ -132,9 +159,11 @@ class JobCard(Document):
break
if completed:
- job_cards = frappe.get_all('Job Card', filters = {'work_order': self.work_order,
+ job_cards = frappe.get_all('Job Card', filters = {'work_order': self.work_order,
'docstatus': ('!=', 2)}, fields = 'sum(transferred_qty) as qty', group_by='operation_id')
- qty = min([d.qty for d in job_cards])
+
+ if job_cards:
+ qty = min([d.qty for d in job_cards])
doc.db_set('material_transferred_for_manufacturing', qty)
@@ -147,7 +176,7 @@ class JobCard(Document):
2: "Cancelled"
}[self.docstatus or 0]
- if self.actual_start_date:
+ if self.time_logs:
self.status = 'Work In Progress'
if (self.docstatus == 1 and
diff --git a/erpnext/manufacturing/doctype/job_card_time_log/__init__.py b/erpnext/manufacturing/doctype/job_card_time_log/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json
new file mode 100644
index 00000000000..2aab71dee4f
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json
@@ -0,0 +1,208 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2019-03-08 23:56:43.187569",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "from_time",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "From Time",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "to_time",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "To Time",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "time_in_mins",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Time In Mins",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fetch_if_empty": 0,
+ "fieldname": "completed_qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Completed Qty",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2019-03-10 17:08:46.504910",
+ "modified_by": "Administrator",
+ "module": "Manufacturing",
+ "name": "Job Card Time Log",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "ASC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.py b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.py
new file mode 100644
index 00000000000..3dc66891216
--- /dev/null
+++ b/erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class JobCardTimeLog(Document):
+ pass
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 69381c53b3e..b292047aa63 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -302,6 +302,19 @@ class TestWorkOrder(unittest.TestCase):
self.assertEqual(len(ste.additional_costs), 1)
self.assertEqual(ste.total_additional_costs, 1000)
+ def test_job_card(self):
+ data = frappe.get_cached_value('BOM',
+ {'docstatus': 1, 'with_operations': 1, 'company': '_Test Company'}, ['name', 'item'])
+
+ if data:
+ bom, bom_item = data
+
+ bom_doc = frappe.get_doc('BOM', bom)
+ work_order = make_wo_order_test_record(item=bom_item, qty=1, bom_no=bom)
+
+ job_cards = frappe.get_all('Job Card', filters = {'work_order': work_order})
+ self.assertEqual(len(job_cards), len(bom_doc.operations))
+
def test_work_order_with_non_transfer_item(self):
items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0}
for item, allow_transfer in items.items():
@@ -346,7 +359,7 @@ def make_wo_order_test_record(**args):
wo_order = frappe.new_doc("Work Order")
wo_order.production_item = args.production_item or args.item or args.item_code or "_Test FG Item"
- wo_order.bom_no = frappe.db.get_value("BOM", {"item": wo_order.production_item,
+ wo_order.bom_no = args.bom_no or frappe.db.get_value("BOM", {"item": wo_order.production_item,
"is_active": 1, "is_default": 1})
wo_order.qty = args.qty or 10
wo_order.wip_warehouse = args.wip_warehouse or "_Test Warehouse - _TC"
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index a65d04f61b8..0f936144adc 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -1,1732 +1,1818 @@
{
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2013-01-10 16:34:16",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "naming_series:",
+ "beta": 0,
+ "creation": "2013-01-10 16:34:16",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-gift",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "item",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-gift",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Series",
- "length": 0,
- "no_copy": 0,
- "options": "MFG-WO-.YYYY.-",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 1,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fetch_if_empty": 0,
+ "fieldname": "naming_series",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Series",
+ "length": 0,
+ "no_copy": 0,
+ "options": "MFG-WO-.YYYY.-",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 1,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Draft",
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "status",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Status",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "status",
- "oldfieldtype": "Select",
- "options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Draft",
+ "depends_on": "eval:!doc.__islocal",
+ "fetch_if_empty": 0,
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "status",
+ "oldfieldtype": "Select",
+ "options": "\nDraft\nSubmitted\nNot Started\nIn Process\nCompleted\nStopped\nCancelled",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "production_item",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Item To Manufacture",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "production_item",
- "oldfieldtype": "Link",
- "options": "Item",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "production_item",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Item To Manufacture",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "production_item",
+ "oldfieldtype": "Link",
+ "options": "Item",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "description": "",
- "fieldname": "bom_no",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "BOM No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "bom_no",
- "oldfieldtype": "Link",
- "options": "BOM",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "production_item.image",
+ "fetch_if_empty": 0,
+ "fieldname": "image",
+ "fieldtype": "Attach Image",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Image",
+ "length": 0,
+ "no_copy": 0,
+ "options": "image",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "allow_alternative_item",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow Alternative Item",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "description": "",
+ "fetch_if_empty": 0,
+ "fieldname": "bom_no",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "BOM No",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "bom_no",
+ "oldfieldtype": "Link",
+ "options": "BOM",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "description": "Plan material for sub-assemblies",
- "fieldname": "use_multi_level_bom",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Use Multi-Level BOM",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "allow_alternative_item",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow Alternative Item",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Check if material transfer entry is not required",
- "fieldname": "skip_transfer",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Skip Material Transfer",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "description": "Plan material for sub-assemblies",
+ "fetch_if_empty": 0,
+ "fieldname": "use_multi_level_bom",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Use Multi-Level BOM",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Check if material transfer entry is not required",
+ "fetch_if_empty": 0,
+ "fieldname": "skip_transfer",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Skip Material Transfer",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "company",
- "oldfieldtype": "Link",
- "options": "Company",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 1,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "company",
+ "oldfieldtype": "Link",
+ "options": "Company",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 1,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "qty",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Qty To Manufacture",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "qty",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Qty To Manufacture",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "qty",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "depends_on": "eval:doc.docstatus==1 && doc.skip_transfer==0",
- "description": "",
- "fieldname": "material_transferred_for_manufacturing",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Material Transferred for Manufacturing",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.docstatus==1 && doc.skip_transfer==0",
+ "description": "",
+ "fetch_if_empty": 0,
+ "fieldname": "material_transferred_for_manufacturing",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Material Transferred for Manufacturing",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "depends_on": "eval:doc.docstatus==1",
- "description": "",
- "fieldname": "produced_qty",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Manufactured Qty",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "produced_qty",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "depends_on": "eval:doc.docstatus==1",
+ "description": "",
+ "fetch_if_empty": 0,
+ "fieldname": "produced_qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Manufactured Qty",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "produced_qty",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
- "fieldname": "sales_order",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sales Order",
- "length": 0,
- "no_copy": 0,
- "options": "Sales Order",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fetch_if_empty": 0,
+ "fieldname": "sales_order",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Sales Order",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Sales Order",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "project",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Project",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "project",
- "oldfieldtype": "Link",
- "options": "Project",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Project",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "project",
+ "oldfieldtype": "Link",
+ "options": "Project",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "skip_transfer",
- "fieldname": "from_wip_warehouse",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Backflush raw materials from work-in-progress warehouse",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "skip_transfer",
+ "fetch_if_empty": 0,
+ "fieldname": "from_wip_warehouse",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Backflush raw materials from work-in-progress warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "warehouses",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Warehouses",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-building",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "warehouses",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Warehouses",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-building",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "wip_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Work-in-Progress Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "wip_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Work-in-Progress Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "description": "",
- "fieldname": "fg_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Target Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "description": "",
+ "fetch_if_empty": 0,
+ "fieldname": "fg_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Target Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_12",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "scrap_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Scrap Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "scrap_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Scrap Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "required_items_section",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Required Items",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "required_items_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Required Items",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "required_items",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Required Items",
- "length": 0,
- "no_copy": 1,
- "options": "Work Order Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "required_items",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Required Items",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Work Order Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "time",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Time",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-time",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "time",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Time",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-time",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "now",
- "fieldname": "planned_start_date",
- "fieldtype": "Datetime",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Planned Start Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "now",
+ "fetch_if_empty": 0,
+ "fieldname": "planned_start_date",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Planned Start Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "actual_start_date",
- "fieldtype": "Datetime",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Actual Start Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "actual_start_date",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Actual Start Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_13",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_13",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "planned_end_date",
- "fieldtype": "Datetime",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Planned End Date",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "planned_end_date",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Planned End Date",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "actual_end_date",
- "fieldtype": "Datetime",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Actual End Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "actual_end_date",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Actual End Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "expected_delivery_date",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Expected Delivery Date",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "expected_delivery_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Expected Delivery Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "operations_section",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Operations",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-wrench",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "operations_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Operations",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-wrench",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Work Order",
- "depends_on": "operations",
- "fieldname": "transfer_material_against",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Transfer Material Against",
- "length": 0,
- "no_copy": 0,
- "options": "\nWork Order\nJob Card",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Work Order",
+ "depends_on": "operations",
+ "fetch_if_empty": 0,
+ "fieldname": "transfer_material_against",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Transfer Material Against",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nWork Order\nJob Card",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "operations",
- "fieldtype": "Table",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Operations",
- "length": 0,
- "no_copy": 0,
- "options": "Work Order Operation",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "operations",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Operations",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Work Order Operation",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "operations",
- "fieldname": "section_break_22",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Operation Cost",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "operations",
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_22",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Operation Cost",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "planned_operating_cost",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Planned Operating Cost",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "planned_operating_cost",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Planned Operating Cost",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "actual_operating_cost",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Actual Operating Cost",
- "length": 0,
- "no_copy": 1,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "actual_operating_cost",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Actual Operating Cost",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "additional_operating_cost",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Additional Operating Cost",
- "length": 0,
- "no_copy": 1,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "additional_operating_cost",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Additional Operating Cost",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_24",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_24",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "total_operating_cost",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Total Operating Cost",
- "length": 0,
- "no_copy": 1,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "total_operating_cost",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Total Operating Cost",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "more_info",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "More Information",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-file-text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "more_info",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "More Information",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-file-text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "description",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Description",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item Description",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "stock_uom",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock UOM",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "stock_uom",
- "oldfieldtype": "Data",
- "options": "UOM",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "stock_uom",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Stock UOM",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "stock_uom",
+ "oldfieldtype": "Data",
+ "options": "UOM",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Manufacture against Material Request",
- "fieldname": "material_request",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Material Request",
- "length": 0,
- "no_copy": 0,
- "options": "Material Request",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Manufacture against Material Request",
+ "fetch_if_empty": 0,
+ "fieldname": "material_request",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Material Request",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Material Request",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "material_request_item",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Material Request Item",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "material_request_item",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Material Request Item",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sales_order_item",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sales Order Item",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "sales_order_item",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Sales Order Item",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "production_plan",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Production Plan",
- "length": 0,
- "no_copy": 1,
- "options": "Production Plan",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "production_plan",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Production Plan",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Production Plan",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "production_plan_item",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Production Plan Item",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "production_plan_item",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Production Plan Item",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "product_bundle_item",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Product Bundle Item",
- "length": 0,
- "no_copy": 1,
- "options": "Item",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "product_bundle_item",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Product Bundle Item",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amended_from",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Amended From",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "amended_from",
- "oldfieldtype": "Data",
- "options": "Work Order",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "amended_from",
+ "oldfieldtype": "Data",
+ "options": "Work Order",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-cogs",
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-12-13 15:33:12.490710",
- "modified_by": "Administrator",
- "module": "Manufacturing",
- "name": "Work Order",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "fa fa-cogs",
+ "idx": 1,
+ "image_field": "image",
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-05-01 16:25:01.545139",
+ "modified_by": "Administrator",
+ "module": "Manufacturing",
+ "name": "Work Order",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 1,
- "cancel": 1,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Manufacturing User",
- "set_user_permissions": 1,
- "share": 1,
- "submit": 1,
+ "amend": 1,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Manufacturing User",
+ "set_user_permissions": 1,
+ "share": 1,
+ "submit": 1,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 1,
- "role": "Stock User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 1,
+ "role": "Stock User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_order": "ASC",
- "title_field": "production_item",
- "track_changes": 1,
- "track_seen": 1,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_order": "ASC",
+ "title_field": "production_item",
+ "track_changes": 1,
+ "track_seen": 1,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index 9873efa124b..947d6931e21 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -282,6 +282,10 @@ class WorkOrder(Document):
total_bundle_qty = frappe.db.sql(""" select sum(qty) from
`tabProduct Bundle Item` where parent = %s""", (frappe.db.escape(self.product_bundle_item)))[0][0]
+ if not total_bundle_qty:
+ # product bundle is 0 (product bundle allows 0 qty for items)
+ total_bundle_qty = 1
+
cond = "product_bundle_item = %s" if self.product_bundle_item else "production_item = %s"
qty = frappe.db.sql(""" select sum(qty) from
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index b1a393bdf3e..a57070b13a6 100755
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -571,7 +571,7 @@ execute:frappe.delete_doc_if_exists("Page", "sales-analytics")
execute:frappe.delete_doc_if_exists("Page", "purchase-analytics")
execute:frappe.delete_doc_if_exists("Page", "stock-analytics")
execute:frappe.delete_doc_if_exists("Page", "production-analytics")
-erpnext.patches.v11_0.ewaybill_fields_gst_india #2018-11-13 #2019-01-09
+erpnext.patches.v11_0.ewaybill_fields_gst_india #2018-11-13 #2019-01-09 #2019-04-01 #2019-04-26 #2019-05-03
erpnext.patches.v11_0.drop_column_max_days_allowed
erpnext.patches.v11_0.change_healthcare_desktop_icons
erpnext.patches.v10_0.update_user_image_in_employee
@@ -587,4 +587,13 @@ erpnext.patches.v11_1.setup_guardian_role
execute:frappe.delete_doc('DocType', 'Notification Control')
erpnext.patches.v11_0.remove_barcodes_field_from_copy_fields_to_variants
erpnext.patches.v10_0.item_barcode_childtable_migrate # 16-02-2019
-erpnext.patches.v11_0.make_italian_localization_fields
+erpnext.patches.v11_0.make_italian_localization_fields # 26-03-2019
+erpnext.patches.v11_1.make_job_card_time_logs
+erpnext.patches.v11_1.set_variant_based_on
+erpnext.patches.v11_1.move_customer_lead_to_dynamic_column
+erpnext.patches.v11_1.woocommerce_set_creation_user
+erpnext.patches.v11_1.delete_bom_browser
+erpnext.patches.v11_1.set_salary_details_submittable
+erpnext.patches.v11_1.rename_depends_on_lwp
+erpnext.patches.v11_1.set_missing_title_for_quotation
+execute:frappe.delete_doc("Report", "Inactive Items")
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
index bc6005677db..e30e0a74c00 100644
--- a/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
+++ b/erpnext/patches/v10_0/item_barcode_childtable_migrate.py
@@ -27,5 +27,5 @@ def execute():
'parent': item.name,
'parentfield': 'barcodes'
}).insert()
- except frappe.DuplicateEntryError:
+ except (frappe.DuplicateEntryError, frappe.UniqueValidationError):
continue
diff --git a/erpnext/patches/v11_0/make_italian_localization_fields.py b/erpnext/patches/v11_0/make_italian_localization_fields.py
index fa77149752b..79958b9189c 100644
--- a/erpnext/patches/v11_0/make_italian_localization_fields.py
+++ b/erpnext/patches/v11_0/make_italian_localization_fields.py
@@ -6,7 +6,6 @@ from erpnext.regional.italy.setup import make_custom_fields, setup_report
from erpnext.regional.italy import state_codes
import frappe
-
def execute():
company = frappe.get_all('Company', filters = {'country': 'Italy'})
if not company:
@@ -22,7 +21,17 @@ def execute():
condition += " when '{0}' then '{1}'".format(frappe.db.escape(state), frappe.db.escape(code))
if condition:
- frappe.db.sql("""
- UPDATE tabAddress set state_code = (case state {condition} end)
- WHERE country in ('Italy', 'Italia', 'Italian Republic', 'Repubblica Italiana')
- """.format(condition=condition))
+ condition = "state_code = (case state {0} end),".format(condition)
+
+ frappe.db.sql("""
+ UPDATE tabAddress set {condition} country_code = UPPER(ifnull((select code
+ from `tabCountry` where name = `tabAddress`.country), ''))
+ where country_code is null and state_code is null
+ """.format(condition=condition))
+
+ frappe.db.sql("""
+ UPDATE `tabSales Invoice Item` si, `tabSales Order` so
+ set si.customer_po_no = so.po_no, si.customer_po_date = so.po_date
+ WHERE
+ si.sales_order = so.name and so.po_no is not null
+ """)
diff --git a/erpnext/patches/v11_1/delete_bom_browser.py b/erpnext/patches/v11_1/delete_bom_browser.py
new file mode 100644
index 00000000000..457f5116670
--- /dev/null
+++ b/erpnext/patches/v11_1/delete_bom_browser.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.delete_doc_if_exists('Page', 'bom-browser')
\ No newline at end of file
diff --git a/erpnext/patches/v11_1/make_job_card_time_logs.py b/erpnext/patches/v11_1/make_job_card_time_logs.py
new file mode 100644
index 00000000000..6e708df48d8
--- /dev/null
+++ b/erpnext/patches/v11_1/make_job_card_time_logs.py
@@ -0,0 +1,29 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.reload_doc('manufacturing', 'doctype', 'job_card_time_log')
+
+ if (frappe.db.table_exists("Job Card")
+ and frappe.get_meta("Job Card").has_field("actual_start_date")):
+ time_logs = []
+ for d in frappe.get_all('Job Card',
+ fields = ["actual_start_date", "actual_end_date", "time_in_mins", "name", "for_quantity"],
+ filters = {'docstatus': ("<", 2)}):
+ if d.actual_start_date:
+ time_logs.append([d.actual_start_date, d.actual_end_date, d.time_in_mins,
+ d.for_quantity, d.name, 'Job Card', 'time_logs', frappe.generate_hash("", 10)])
+
+ if time_logs:
+ frappe.db.sql(""" INSERT INTO
+ `tabJob Card Time Log`
+ (from_time, to_time, time_in_mins, completed_qty, parent, parenttype, parentfield, name)
+ values {values}
+ """.format(values = ','.join(['%s'] * len(time_logs))), tuple(time_logs))
+
+ frappe.reload_doc('manufacturing', 'doctype', 'job_card')
+ frappe.db.sql(""" update `tabJob Card` set total_completed_qty = for_quantity,
+ total_time_in_mins = time_in_mins where docstatus < 2 """)
\ No newline at end of file
diff --git a/erpnext/patches/v11_1/move_customer_lead_to_dynamic_column.py b/erpnext/patches/v11_1/move_customer_lead_to_dynamic_column.py
new file mode 100644
index 00000000000..5b1251c31cf
--- /dev/null
+++ b/erpnext/patches/v11_1/move_customer_lead_to_dynamic_column.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.reload_doctype("Quotation")
+ frappe.db.sql(""" UPDATE `tabQuotation` set party_name = lead WHERE quotation_to = 'Lead' """)
+ frappe.db.sql(""" UPDATE `tabQuotation` set party_name = customer WHERE quotation_to = 'Customer' """)
+
+ frappe.reload_doctype("Opportunity")
+ frappe.db.sql(""" UPDATE `tabOpportunity` set party_name = lead WHERE opportunity_from = 'Lead' """)
+ frappe.db.sql(""" UPDATE `tabOpportunity` set party_name = customer WHERE opportunity_from = 'Customer' """)
\ No newline at end of file
diff --git a/erpnext/patches/v11_1/rename_depends_on_lwp.py b/erpnext/patches/v11_1/rename_depends_on_lwp.py
new file mode 100644
index 00000000000..20d8867e1d2
--- /dev/null
+++ b/erpnext/patches/v11_1/rename_depends_on_lwp.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import scrub
+from frappe.model.utils.rename_field import rename_field
+
+def execute():
+ for doctype in ("Salary Component", "Salary Detail"):
+ if "depends_on_lwp" in frappe.db.get_table_columns(doctype):
+ frappe.reload_doc("hr", "doctype", scrub(doctype))
+ rename_field(doctype, "depends_on_lwp", "depends_on_payment_days")
\ No newline at end of file
diff --git a/erpnext/patches/v11_1/set_missing_title_for_quotation.py b/erpnext/patches/v11_1/set_missing_title_for_quotation.py
new file mode 100644
index 00000000000..e86b8320c31
--- /dev/null
+++ b/erpnext/patches/v11_1/set_missing_title_for_quotation.py
@@ -0,0 +1,27 @@
+import frappe
+
+def execute():
+ # update customer_name from Customer document if quotation_to is set to Customer
+ frappe.db.sql('''
+ update tabQuotation, tabCustomer
+ set
+ tabQuotation.customer_name = tabCustomer.customer_name,
+ tabQuotation.title = tabCustomer.customer_name
+ where
+ tabQuotation.customer_name is null
+ and tabQuotation.party_name = tabCustomer.name
+ and tabQuotation.quotation_to = 'Customer'
+ ''')
+
+ # update customer_name from Lead document if quotation_to is set to Lead
+
+ frappe.db.sql('''
+ update tabQuotation, tabLead
+ set
+ tabQuotation.customer_name = case when ifnull(tabLead.company_name, '') != '' then tabLead.company_name else tabLead.lead_name end,
+ tabQuotation.title = case when ifnull(tabLead.company_name, '') != '' then tabLead.company_name else tabLead.lead_name end
+ where
+ tabQuotation.customer_name is null
+ and tabQuotation.party_name = tabLead.name
+ and tabQuotation.quotation_to = 'Lead'
+ ''')
diff --git a/erpnext/patches/v11_1/set_salary_details_submittable.py b/erpnext/patches/v11_1/set_salary_details_submittable.py
new file mode 100644
index 00000000000..6d847ec3d05
--- /dev/null
+++ b/erpnext/patches/v11_1/set_salary_details_submittable.py
@@ -0,0 +1,9 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.db.sql("""
+ update `tabSalary Structure` ss, `tabSalary Detail` sd
+ set sd.docstatus=1
+ where ss.name=sd.parent and ss.docstatus=1 and sd.parenttype='Salary Structure'
+ """)
diff --git a/erpnext/patches/v11_1/set_variant_based_on.py b/erpnext/patches/v11_1/set_variant_based_on.py
new file mode 100644
index 00000000000..019eefd68f4
--- /dev/null
+++ b/erpnext/patches/v11_1/set_variant_based_on.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ frappe.db.sql("""update tabItem set variant_based_on = 'Item Attribute'
+ where ifnull(variant_based_on, '') = ''
+ and (has_variants=1 or ifnull(variant_of, '') != '')
+ """)
\ No newline at end of file
diff --git a/erpnext/patches/v11_1/woocommerce_set_creation_user.py b/erpnext/patches/v11_1/woocommerce_set_creation_user.py
new file mode 100644
index 00000000000..5ccdec6d262
--- /dev/null
+++ b/erpnext/patches/v11_1/woocommerce_set_creation_user.py
@@ -0,0 +1,11 @@
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import cint
+
+def execute():
+ frappe.reload_doc("erpnext_integrations", "doctype","woocommerce_settings")
+ doc = frappe.get_doc("Woocommerce Settings")
+
+ if cint(doc.enable_sync):
+ doc.creation_user = doc.modified_by
+ doc.save(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/patches/v7_0/rename_salary_components.py b/erpnext/patches/v7_0/rename_salary_components.py
index de92fc6083b..bc48e343174 100644
--- a/erpnext/patches/v7_0/rename_salary_components.py
+++ b/erpnext/patches/v7_0/rename_salary_components.py
@@ -5,79 +5,79 @@ from frappe.model.utils.rename_field import update_property_setters
def execute():
if not frappe.db.exists("DocType", "Salary Structure Earning"):
return
-
+
frappe.reload_doc("hr", "doctype", "salary_detail")
frappe.reload_doc("hr", "doctype", "salary_component")
-
+
standard_cols = ["name", "creation", "modified", "owner", "modified_by", "parent", "parenttype", "parentfield", "idx"]
-
+
dt_cols = {
"Salary Structure Deduction": ["d_type", "d_modified_amt", "depend_on_lwp"],
"Salary Structure Earning": ["e_type", "modified_value", "depend_on_lwp"],
"Salary Slip Earning": ["e_type", "e_modified_amount", "e_depends_on_lwp", "e_amount"],
"Salary Slip Deduction": ["d_type", "d_modified_amount", "d_depends_on_lwp", "d_amount"],
}
-
+
earning_type_exists = True if "earning_type" in frappe.db.get_table_columns("Salary Slip Earning") else False
e_type_exists = True if "e_type" in frappe.db.get_table_columns("Salary Slip Earning") else False
-
-
+
+
if e_type_exists and earning_type_exists:
- frappe.db.sql("""update `tabSalary Slip Earning`
+ frappe.db.sql("""update `tabSalary Slip Earning`
set e_type = earning_type, e_modified_amount = earning_amount
where e_type is null and earning_type is not null""")
- frappe.db.sql("""update `tabSalary Structure Earning` set e_type = earning_type
+ frappe.db.sql("""update `tabSalary Structure Earning` set e_type = earning_type
where e_type is null and earning_type is not null""")
- frappe.db.sql("""update `tabSalary Slip Deduction` set
+ frappe.db.sql("""update `tabSalary Slip Deduction` set
d_type = deduction_type, d_modified_amount = deduction_amount
where d_type is null and deduction_type is not null""")
- frappe.db.sql("""update `tabSalary Structure Deduction` set d_type = deduction_type
+ frappe.db.sql("""update `tabSalary Structure Deduction` set d_type = deduction_type
where d_type is null and deduction_type is not null""")
-
+
if earning_type_exists and not e_type_exists:
for val in dt_cols.values():
if val[0] == "e_type":
val[0] = "earning_type"
-
+
if val[0] == "d_type":
val[0] = "deduction_type"
-
+
if val[1] == "e_modified_amount":
val[1] ="earning_amount"
-
+
if val[1] == "d_modified_amount":
val[1] ="deduction_amount"
-
-
- target_cols = standard_cols + ["salary_component", "amount", "depends_on_lwp", "default_amount"]
- target_cols = "`" + "`, `".join(target_cols) + "`"
-
- for doctype, cols in dt_cols.items():
+
+
+ target_cols = standard_cols + ["salary_component", "amount", "depends_on_payment_days", "default_amount"]
+ target_cols = "`" + "`, `".join(target_cols) + "`"
+
+ for doctype, cols in dt_cols.items():
source_cols = "`" + "`, `".join(standard_cols + cols) + "`"
if len(cols) == 3:
source_cols += ", 0"
-
-
+
+
frappe.db.sql("""INSERT INTO `tabSalary Detail` ({0}) SELECT {1} FROM `tab{2}`"""
.format(target_cols, source_cols, doctype))
-
-
+
+
dt_cols_de = {
"Deduction Type": ["deduction_name", "description"],
"Earning Type": ["earning_name", "description"],
}
-
+
standard_cols_de = standard_cols
-
+
target_cols = standard_cols_de + ["salary_component", "description"]
- target_cols = "`" + "`, `".join(target_cols) + "`"
-
- for doctype, cols in dt_cols_de.items():
+ target_cols = "`" + "`, `".join(target_cols) + "`"
+
+ for doctype, cols in dt_cols_de.items():
source_cols = "`" + "`, `".join(standard_cols_de + cols) + "`"
try:
frappe.db.sql("""INSERT INTO `tabSalary Component` ({0}) SELECT {1} FROM `tab{2}`"""
@@ -85,10 +85,10 @@ def execute():
except Exception as e:
if e.args[0]==1062:
pass
-
+
update_customizations()
-
- for doctype in ["Salary Structure Deduction", "Salary Structure Earning", "Salary Slip Earning",
+
+ for doctype in ["Salary Structure Deduction", "Salary Structure Earning", "Salary Slip Earning",
"Salary Slip Deduction", "Deduction Type", "Earning Type"] :
frappe.delete_doc("DocType", doctype)
@@ -96,35 +96,35 @@ def execute():
def update_customizations():
dt_cols = {
"Salary Structure Deduction": {
- "d_type": "salary_component",
- "deduction_type": "salary_component",
+ "d_type": "salary_component",
+ "deduction_type": "salary_component",
"d_modified_amt": "amount",
- "depend_on_lwp": "depends_on_lwp"
+ "depend_on_lwp": "depends_on_payment_days"
},
"Salary Structure Earning": {
- "e_type": "salary_component",
- "earning_type": "salary_component",
+ "e_type": "salary_component",
+ "earning_type": "salary_component",
"modified_value": "amount",
- "depend_on_lwp": "depends_on_lwp"
+ "depend_on_lwp": "depends_on_payment_days"
},
"Salary Slip Earning": {
- "e_type": "salary_component",
- "earning_type": "salary_component",
+ "e_type": "salary_component",
+ "earning_type": "salary_component",
"e_modified_amount": "amount",
"e_amount" : "default_amount",
- "e_depends_on_lwp": "depends_on_lwp"
+ "e_depends_on_lwp": "depends_on_payment_days"
},
"Salary Slip Deduction": {
- "d_type": "salary_component",
- "deduction_type": "salary_component",
+ "d_type": "salary_component",
+ "deduction_type": "salary_component",
"d_modified_amount": "amount",
"d_amount" : "default_amount",
- "d_depends_on_lwp": "depends_on_lwp"
+ "d_depends_on_lwp": "depends_on_payment_days"
}
}
-
+
update_property_setters_and_custom_fields("Salary Detail", dt_cols)
-
+
dt_cols = {
"Earning Type": {
"earning_name": "salary_component"
@@ -133,17 +133,17 @@ def update_customizations():
"deduction_name": "salary_component"
}
}
-
+
update_property_setters_and_custom_fields("Salary Component", dt_cols)
-
-
-
-
+
+
+
+
def update_property_setters_and_custom_fields(new_dt, dt_cols):
for doctype, cols in dt_cols.items():
frappe.db.sql("update `tabProperty Setter` set doc_type = %s where doc_type=%s", (new_dt, doctype))
frappe.db.sql("update `tabCustom Field` set dt = %s where dt=%s", (new_dt, doctype))
-
-
+
+
for old_fieldname, new_fieldname in cols.items():
update_property_setters(new_dt, old_fieldname, new_fieldname)
diff --git a/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py b/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py
index 22f9db6b2be..9e21fb699b9 100644
--- a/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py
+++ b/erpnext/patches/v7_0/repost_future_gle_for_purchase_invoice.py
@@ -10,14 +10,15 @@ from erpnext.controllers.stock_controller import update_gl_entries_after
def execute():
company_list = frappe.db.sql_list("""Select name from tabCompany where enable_perpetual_inventory = 1""")
frappe.reload_doc('accounts', 'doctype', 'sales_invoice')
-
- frappe.reload_doctype("Purchase Invoice")
+
+ frappe.reload_doctype("Purchase Invoice")
wh_account = get_warehouse_account_map()
-
+
for pi in frappe.get_all("Purchase Invoice", fields=["name", "company"], filters={"docstatus": 1, "update_stock": 1}):
if pi.company in company_list:
pi_doc = frappe.get_doc("Purchase Invoice", pi.name)
items, warehouses = pi_doc.get_items_and_warehouses()
- update_gl_entries_after(pi_doc.posting_date, pi_doc.posting_time, warehouses, items, wh_account)
-
+ update_gl_entries_after(pi_doc.posting_date, pi_doc.posting_time,
+ warehouses, items, wh_account, company = pi.company)
+
frappe.db.commit()
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index e3fd1a8622b..fc58df0ffc5 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -30,11 +30,13 @@ class Project(Document):
self.update_costing()
- def __setup__(self):
+ def before_print(self):
self.onload()
def load_tasks(self):
"""Load `tasks` from the database"""
+ project_task_custom_fields = frappe.get_all("Custom Field", {"dt": "Project Task"}, "fieldname")
+
self.tasks = []
for task in self.get_tasks():
task_map = {
@@ -47,7 +49,7 @@ class Project(Document):
"task_weight": task.task_weight
}
- self.map_custom_fields(task, task_map)
+ self.map_custom_fields(task, task_map, project_task_custom_fields)
self.append("tasks", task_map)
@@ -72,7 +74,7 @@ class Project(Document):
self.load_tasks()
self.validate_dates()
self.send_welcome_email()
- self.update_percent_complete()
+ self.update_percent_complete(from_validate=True)
def validate_project_name(self):
if self.get("__islocal") and frappe.db.exists("Project", self.project_name):
@@ -149,7 +151,7 @@ class Project(Document):
"task_weight": t.task_weight
})
- self.map_custom_fields(t, task)
+ self.map_custom_fields(t, task, custom_fields)
task.flags.ignore_links = True
task.flags.from_project = True
@@ -173,10 +175,6 @@ class Project(Document):
for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
self.deleted_task_list.append(t.name)
- def update_costing_and_percentage_complete(self):
- self.update_percent_complete()
- self.update_costing()
-
def is_row_updated(self, row, existing_task_data, fields):
if self.get("__islocal") or not existing_task_data: return True
@@ -186,10 +184,8 @@ class Project(Document):
if row.get(field) != d.get(field):
return True
- def map_custom_fields(self, source, target):
- project_task_custom_fields = frappe.get_all("Custom Field", {"dt": "Project Task"}, "fieldname")
-
- for field in project_task_custom_fields:
+ def map_custom_fields(self, source, target, custom_fields):
+ for field in custom_fields:
target.update({
field.fieldname: source.get(field.fieldname)
})
@@ -197,14 +193,12 @@ class Project(Document):
def update_project(self):
self.update_percent_complete()
self.update_costing()
- self.flags.dont_sync_tasks = True
- self.save(ignore_permissions=True)
def after_insert(self):
if self.sales_order:
frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
- def update_percent_complete(self):
+ def update_percent_complete(self, from_validate=False):
if not self.tasks: return
total = frappe.db.sql("""select count(name) from tabTask where project=%s""", self.name)[0][0]
if not total and self.percent_complete:
@@ -234,6 +228,9 @@ class Project(Document):
elif not self.status == "Cancelled":
self.status = "Open"
+ if not from_validate:
+ self.db_update()
+
def update_costing(self):
from_time_sheet = frappe.db.sql("""select
sum(costing_amount) as costing_amount,
@@ -260,6 +257,7 @@ class Project(Document):
self.update_sales_amount()
self.update_billed_amount()
self.calculate_gross_margin()
+ self.db_update()
def calculate_gross_margin(self):
expense_amount = (flt(self.total_costing_amount) + flt(self.total_expense_claim)
@@ -313,7 +311,7 @@ class Project(Document):
def on_update(self):
self.delete_task()
self.load_tasks()
- self.update_costing_and_percentage_complete()
+ self.update_project()
self.update_dependencies_on_duplicated_project()
def delete_task(self):
diff --git a/erpnext/projects/doctype/task/task.json b/erpnext/projects/doctype/task/task.json
index c22a2962c87..b7f547dbcaf 100644
--- a/erpnext/projects/doctype/task/task.json
+++ b/erpnext/projects/doctype/task/task.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
@@ -19,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "subject",
"fieldtype": "Data",
"hidden": 0,
@@ -27,7 +29,7 @@
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
- "in_standard_filter": 0,
+ "in_standard_filter": 1,
"label": "Subject",
"length": 0,
"no_copy": 0,
@@ -51,6 +53,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -86,6 +89,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
+ "fetch_if_empty": 0,
"fieldname": "is_group",
"fieldtype": "Check",
"hidden": 0,
@@ -118,6 +122,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -151,6 +156,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -185,6 +191,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "priority",
"fieldtype": "Select",
"hidden": 0,
@@ -219,6 +226,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "parent_task",
"fieldtype": "Link",
"hidden": 0,
@@ -254,6 +262,7 @@
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "section_break_10",
"fieldtype": "Section Break",
"hidden": 0,
@@ -286,6 +295,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "exp_start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -322,6 +332,7 @@
"default": "0",
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "expected_time",
"fieldtype": "Float",
"hidden": 0,
@@ -356,6 +367,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "task_weight",
"fieldtype": "Float",
"hidden": 0,
@@ -388,6 +400,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
@@ -420,6 +433,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "exp_end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -454,6 +468,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "progress",
"fieldtype": "Percent",
"hidden": 0,
@@ -487,6 +502,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "is_milestone",
"fieldtype": "Check",
"hidden": 0,
@@ -519,6 +535,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "color",
"fieldtype": "Color",
"hidden": 0,
@@ -553,6 +570,7 @@
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@@ -586,6 +604,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -623,6 +642,7 @@
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -656,6 +676,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "depends_on",
"fieldtype": "Table",
"hidden": 0,
@@ -690,6 +711,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "depends_on_tasks",
"fieldtype": "Data",
"hidden": 1,
@@ -725,6 +747,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "actual",
"fieldtype": "Section Break",
"hidden": 0,
@@ -760,6 +783,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "act_start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -796,6 +820,7 @@
"default": "",
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "actual_time",
"fieldtype": "Float",
"hidden": 0,
@@ -829,6 +854,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_15",
"fieldtype": "Column Break",
"hidden": 0,
@@ -861,6 +887,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "act_end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -895,6 +922,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "section_break_17",
"fieldtype": "Section Break",
"hidden": 0,
@@ -927,6 +955,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "total_costing_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -962,6 +991,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "total_expense_claim",
"fieldtype": "Currency",
"hidden": 0,
@@ -995,6 +1025,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_20",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1027,6 +1058,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "total_billing_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1059,6 +1091,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "more_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1091,6 +1124,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.status == \"Closed\" || doc.status == \"Pending Review\"",
+ "fetch_if_empty": 0,
"fieldname": "review_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1125,6 +1159,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.status == \"Closed\"",
+ "fetch_if_empty": 0,
"fieldname": "closing_date",
"fieldtype": "Date",
"hidden": 0,
@@ -1158,6 +1193,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_22",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1188,6 +1224,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "department",
"fieldtype": "Link",
"hidden": 0,
@@ -1221,6 +1258,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -1253,6 +1291,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "lft",
"fieldtype": "Int",
"hidden": 1,
@@ -1285,6 +1324,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "rgt",
"fieldtype": "Int",
"hidden": 1,
@@ -1317,6 +1357,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "old_parent",
"fieldtype": "Data",
"hidden": 1,
@@ -1355,7 +1396,7 @@
"istable": 0,
"max_attachments": 5,
"menu_index": 0,
- "modified": "2018-08-21 16:15:56.299895",
+ "modified": "2019-04-24 23:10:00.014378",
"modified_by": "Administrator",
"module": "Projects",
"name": "Task",
@@ -1385,7 +1426,7 @@
"read_only": 0,
"read_only_onload": 0,
"search_fields": "subject",
- "show_name_in_global_search": 0,
+ "show_name_in_global_search": 1,
"sort_order": "DESC",
"timeline_field": "project",
"title_field": "subject",
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index fffa9c1657c..12302789a9b 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -159,6 +159,13 @@ class Task(NestedSet):
self.update_nsm_model()
+ def update_status(self):
+ if self.status not in ('Cancelled', 'Closed') and self.exp_end_date:
+ from datetime import datetime
+ if self.exp_end_date < datetime.now().date():
+ self.db_set('status', 'Overdue')
+ self.update_project()
+
@frappe.whitelist()
def check_if_child_exists(name):
child_tasks = frappe.get_all("Task", filters={"parent_task": name})
@@ -186,10 +193,9 @@ def set_multiple_status(names, status):
task.save()
def set_tasks_as_overdue():
- frappe.db.sql("""update tabTask set `status`='Overdue'
- where exp_end_date is not null
- and exp_end_date < CURDATE()
- and `status` not in ('Closed', 'Cancelled')""")
+ tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Closed']]})
+ for task in tasks:
+ frappe.get_doc("Task", task.name).update_status()
@frappe.whitelist()
def get_children(doctype, parent, task=None, project=None, is_root=False):
diff --git a/erpnext/projects/doctype/task/test_task.py b/erpnext/projects/doctype/task/test_task.py
index 9971946cb4f..b733f67a980 100644
--- a/erpnext/projects/doctype/task/test_task.py
+++ b/erpnext/projects/doctype/task/test_task.py
@@ -117,4 +117,4 @@ def create_task(subject, start=None, end=None, depends_on=None, project=None, sa
if save:
task.save()
- return task
\ No newline at end of file
+ return task
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 8811ab95438..8ffc10ee972 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -10,8 +10,8 @@ frappe.ui.form.on("Timesheet", {
filters:{
'status': 'Active'
}
- }
- }
+ };
+ };
frm.fields_dict['time_logs'].grid.get_field('task').get_query = function(frm, cdt, cdn) {
var child = locals[cdt][cdn];
@@ -20,33 +20,37 @@ frappe.ui.form.on("Timesheet", {
'project': child.project,
'status': ["!=", "Cancelled"]
}
- }
- }
+ };
+ };
frm.fields_dict['time_logs'].grid.get_field('project').get_query = function() {
return{
filters: {
'company': frm.doc.company
}
- }
- }
+ };
+ };
},
onload: function(frm){
if (frm.doc.__islocal && frm.doc.time_logs) {
calculate_time_and_amount(frm);
}
+
+ if (frm.is_new()) {
+ set_employee_and_company(frm);
+ }
},
refresh: function(frm) {
if(frm.doc.docstatus==1) {
if(frm.doc.per_billed < 100 && frm.doc.total_billable_hours && frm.doc.total_billable_hours > frm.doc.total_billed_hours){
- frm.add_custom_button(__("Make Sales Invoice"), function() { frm.trigger("make_invoice") },
+ frm.add_custom_button(__("Make Sales Invoice"), function() { frm.trigger("make_invoice"); },
"fa fa-file-alt");
}
if(!frm.doc.salary_slip && frm.doc.employee){
- frm.add_custom_button(__("Make Salary Slip"), function() { frm.trigger("make_salary_slip") },
+ frm.add_custom_button(__("Make Salary Slip"), function() { frm.trigger("make_salary_slip"); },
"fa fa-file-alt");
}
}
@@ -58,7 +62,7 @@ frappe.ui.form.on("Timesheet", {
if ((row.from_time <= frappe.datetime.now_datetime()) && !row.completed) {
button = 'Resume Timer';
}
- })
+ });
frm.add_custom_button(__(button), function() {
var flag = true;
@@ -77,7 +81,7 @@ frappe.ui.form.on("Timesheet", {
erpnext.timesheet.timer(frm, row, timestamp);
flag = false;
}
- })
+ });
// If no activities found to start a timer, create new
if (flag) {
erpnext.timesheet.timer(frm);
@@ -94,7 +98,7 @@ frappe.ui.form.on("Timesheet", {
frappe.db.get_value('Company', { 'company_name' : frm.doc.company }, 'standard_working_hours')
.then(({ message }) => {
(frappe.working_hours = message.standard_working_hours || 0);
- });
+ });
},
make_invoice: function(frm) {
@@ -125,8 +129,8 @@ frappe.ui.form.on("Timesheet", {
frappe.set_route("Form", r.message.doctype, r.message.name);
}
}
- })
- })
+ });
+ });
dialog.show();
},
@@ -136,7 +140,7 @@ frappe.ui.form.on("Timesheet", {
frm: frm
});
},
-})
+});
frappe.ui.form.on("Timesheet Detail", {
time_logs_remove: function(frm) {
@@ -171,22 +175,22 @@ frappe.ui.form.on("Timesheet Detail", {
.find('[data-fieldname="timer"]')
.append(frappe.render_template("timesheet"));
frm.trigger("control_timer");
- })
+ });
},
hours: function(frm, cdt, cdn) {
- calculate_end_time(frm, cdt, cdn)
+ calculate_end_time(frm, cdt, cdn);
},
billing_hours: function(frm, cdt, cdn) {
- calculate_billing_costing_amount(frm, cdt, cdn)
+ calculate_billing_costing_amount(frm, cdt, cdn);
},
billing_rate: function(frm, cdt, cdn) {
- calculate_billing_costing_amount(frm, cdt, cdn)
+ calculate_billing_costing_amount(frm, cdt, cdn);
},
costing_rate: function(frm, cdt, cdn) {
- calculate_billing_costing_amount(frm, cdt, cdn)
+ calculate_billing_costing_amount(frm, cdt, cdn);
},
billable: function(frm, cdt, cdn) {
@@ -212,7 +216,7 @@ frappe.ui.form.on("Timesheet Detail", {
calculate_billing_costing_amount(frm, cdt, cdn);
}
}
- })
+ });
}
});
@@ -240,23 +244,23 @@ var calculate_end_time = function(frm, cdt, cdn) {
frm._setting_hours = true;
frappe.model.set_value(cdt, cdn, "to_time",
d.format(frappe.defaultDatetimeFormat)).then(() => {
- frm._setting_hours = false;
- });
+ frm._setting_hours = false;
+ });
}
}
-}
+};
var update_billing_hours = function(frm, cdt, cdn){
var child = locals[cdt][cdn];
if(!child.billable) frappe.model.set_value(cdt, cdn, 'billing_hours', 0.0);
-}
+};
var update_time_rates = function(frm, cdt, cdn){
var child = locals[cdt][cdn];
if(!child.billable){
frappe.model.set_value(cdt, cdn, 'billing_rate', 0.0);
}
-}
+};
var calculate_billing_costing_amount = function(frm, cdt, cdn){
var child = locals[cdt][cdn];
@@ -270,7 +274,7 @@ var calculate_billing_costing_amount = function(frm, cdt, cdn){
frappe.model.set_value(cdt, cdn, 'billing_amount', billing_amount);
frappe.model.set_value(cdt, cdn, 'costing_amount', costing_amount);
calculate_time_and_amount(frm);
-}
+};
var calculate_time_and_amount = function(frm) {
var tl = frm.doc.time_logs || [];
@@ -294,4 +298,17 @@ var calculate_time_and_amount = function(frm) {
frm.set_value("total_hours", total_working_hr);
frm.set_value("total_billable_amount", total_billable_amount);
frm.set_value("total_costing_amount", total_costing_amount);
-}
\ No newline at end of file
+};
+
+// set employee (and company) to the one that's currently logged in
+const set_employee_and_company = function(frm) {
+ const options = { user_id: frappe.session.user };
+ const fields = ['name', 'company'];
+ frappe.db.get_value('Employee', options, fields).then(({ message }) => {
+ if (message) {
+ // there is an employee with the currently logged in user_id
+ frm.set_value("employee", message.name);
+ frm.set_value("company", message.company);
+ }
+ });
+};
diff --git a/erpnext/projects/doctype/timesheet/timesheet.json b/erpnext/projects/doctype/timesheet/timesheet.json
index 5ad2ab3a379..c29c11b7465 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.json
+++ b/erpnext/projects/doctype/timesheet/timesheet.json
@@ -739,7 +739,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "total_costing_amount",
- "fieldtype": "Float",
+ "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -805,7 +805,7 @@
"depends_on": "",
"description": "",
"fieldname": "total_billable_amount",
- "fieldtype": "Float",
+ "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -837,7 +837,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "total_billed_amount",
- "fieldtype": "Float",
+ "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -1000,7 +1000,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2019-01-30 11:28:18.518590",
+ "modified": "2019-03-05 21:54:02.654690",
"modified_by": "Administrator",
"module": "Projects",
"name": "Timesheet",
diff --git a/erpnext/projects/report/billing_summary.py b/erpnext/projects/report/billing_summary.py
new file mode 100644
index 00000000000..929a13f6683
--- /dev/null
+++ b/erpnext/projects/report/billing_summary.py
@@ -0,0 +1,146 @@
+# 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 time_diff_in_hours, flt
+
+def get_columns():
+ return [
+ {
+ "label": _("Employee ID"),
+ "fieldtype": "Link",
+ "fieldname": "employee",
+ "options": "Employee",
+ "width": 300
+ },
+ {
+ "label": _("Employee Name"),
+ "fieldtype": "data",
+ "fieldname": "employee_name",
+ "hidden": 1,
+ "width": 200
+ },
+ {
+ "label": _("Timesheet"),
+ "fieldtype": "Link",
+ "fieldname": "timesheet",
+ "options": "Timesheet",
+ "width": 150
+ },
+ {
+ "label": _("Billable Hours"),
+ "fieldtype": "Float",
+ "fieldname": "total_billable_hours",
+ "width": 50
+ },
+ {
+ "label": _("Working Hours"),
+ "fieldtype": "Float",
+ "fieldname": "total_hours",
+ "width": 50
+ },
+ {
+ "label": _("Billing Amount"),
+ "fieldtype": "Currency",
+ "fieldname": "amount",
+ "width": 100
+ }
+ ]
+
+def get_data(filters):
+ data = []
+ if(filters.from_date > filters.to_date):
+ frappe.msgprint(_(" From Date can not be greater than To Date"))
+ return data
+
+ timesheets = get_timesheets(filters)
+
+ filters.from_date = frappe.utils.get_datetime(filters.from_date)
+ filters.to_date = frappe.utils.add_to_date(frappe.utils.get_datetime(filters.to_date), days=1, seconds=-1)
+
+ timesheet_details = get_timesheet_details(filters, timesheets.keys())
+
+ for ts, ts_details in timesheet_details.items():
+ total_hours = 0
+ total_billing_hours = 0
+ total_amount = 0
+
+ for row in ts_details:
+ from_time, to_time = filters.from_date, filters.to_date
+
+ if row.to_time < from_time or row.from_time > to_time:
+ continue
+
+ if row.from_time > from_time:
+ from_time = row.from_time
+
+ if row.to_time < to_time:
+ to_time = row.to_time
+
+ activity_duration, billing_duration = get_billable_and_total_duration(row, from_time, to_time)
+
+ total_hours += activity_duration
+ total_billing_hours += billing_duration
+ total_amount += billing_duration * flt(row.billing_rate)
+
+ if total_hours:
+ data.append({
+ "employee": timesheets.get(ts).employee,
+ "employee_name": timesheets.get(ts).employee_name,
+ "timesheet": ts,
+ "total_billable_hours": total_billing_hours,
+ "total_hours": total_hours,
+ "amount": total_amount
+ })
+
+ return data
+
+def get_timesheets(filters):
+ record_filters = [
+ ["start_date", "<=", filters.to_date],
+ ["end_date", ">=", filters.from_date],
+ ["docstatus", "=", 1]
+ ]
+
+ if "employee" in filters:
+ record_filters.append(["employee", "=", filters.employee])
+
+ timesheets = frappe.get_all("Timesheet", filters=record_filters, fields=["employee", "employee_name", "name"])
+ timesheet_map = frappe._dict()
+ for d in timesheets:
+ timesheet_map.setdefault(d.name, d)
+
+ return timesheet_map
+
+def get_timesheet_details(filters, timesheet_list):
+ timesheet_details_filter = {
+ "parent": ["in", timesheet_list]
+ }
+
+ if "project" in filters:
+ timesheet_details_filter["project"] = filters.project
+
+ timesheet_details = frappe.get_all(
+ "Timesheet Detail",
+ filters = timesheet_details_filter,
+ fields=["from_time", "to_time", "hours", "billable", "billing_hours", "billing_rate", "parent"]
+ )
+
+ timesheet_details_map = frappe._dict()
+ for d in timesheet_details:
+ timesheet_details_map.setdefault(d.parent, []).append(d)
+
+ return timesheet_details_map
+
+def get_billable_and_total_duration(activity, start_time, end_time):
+ activity_duration = time_diff_in_hours(end_time, start_time)
+ billing_duration = 0.0
+ if activity.billable:
+ billing_duration = activity.billing_hours
+ if activity_duration != activity.billing_hours:
+ billing_duration = activity_duration * activity.billing_hours / activity.hours
+
+ return flt(activity_duration, 2), flt(billing_duration, 2)
\ No newline at end of file
diff --git a/erpnext/projects/report/employee_billing_summary/__init__.py b/erpnext/projects/report/employee_billing_summary/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js
new file mode 100644
index 00000000000..13f49ed6bed
--- /dev/null
+++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.js
@@ -0,0 +1,29 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Employee Billing Summary"] = {
+ "filters": [
+ {
+ fieldname: "employee",
+ label: __("Employee"),
+ fieldtype: "Link",
+ options: "Employee",
+ reqd: 1
+ },
+ {
+ fieldname:"from_date",
+ label: __("From Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
+ reqd: 1
+ },
+ {
+ fieldname:"to_date",
+ label: __("To Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.add_days(frappe.datetime.month_start(), -1),
+ reqd: 1
+ },
+ ]
+}
diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json
new file mode 100644
index 00000000000..cab8db251c8
--- /dev/null
+++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.json
@@ -0,0 +1,36 @@
+{
+ "add_total_row": 1,
+ "creation": "2019-03-08 15:08:19.929728",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2019-04-16 17:29:18.376932",
+ "modified_by": "Administrator",
+ "module": "Projects",
+ "name": "Employee Billing Summary",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Timesheet",
+ "report_name": "Employee Billing Summary",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Projects User"
+ },
+ {
+ "role": "HR User"
+ },
+ {
+ "role": "Manufacturing User"
+ },
+ {
+ "role": "Employee"
+ },
+ {
+ "role": "Accounts User"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py
new file mode 100644
index 00000000000..cd5ad7803a5
--- /dev/null
+++ b/erpnext/projects/report/employee_billing_summary/employee_billing_summary.py
@@ -0,0 +1,14 @@
+# 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 erpnext.projects.report.billing_summary import get_columns, get_data
+
+def execute(filters=None):
+ filters = frappe._dict(filters or {})
+ columns = get_columns()
+
+ data = get_data(filters)
+ return columns, data
\ No newline at end of file
diff --git a/erpnext/projects/report/project_billing_summary/__init__.py b/erpnext/projects/report/project_billing_summary/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.js b/erpnext/projects/report/project_billing_summary/project_billing_summary.js
new file mode 100644
index 00000000000..caac1d86b45
--- /dev/null
+++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.js
@@ -0,0 +1,29 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Project Billing Summary"] = {
+ "filters": [
+ {
+ fieldname: "project",
+ label: __("Project"),
+ fieldtype: "Link",
+ options: "Project",
+ reqd: 1
+ },
+ {
+ fieldname:"from_date",
+ label: __("From Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
+ reqd: 1
+ },
+ {
+ fieldname:"to_date",
+ label: __("To Date"),
+ fieldtype: "Date",
+ default: frappe.datetime.add_days(frappe.datetime.month_start(),-1),
+ reqd: 1
+ },
+ ]
+}
diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.json b/erpnext/projects/report/project_billing_summary/project_billing_summary.json
new file mode 100644
index 00000000000..c65053e85be
--- /dev/null
+++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.json
@@ -0,0 +1,36 @@
+{
+ "add_total_row": 1,
+ "creation": "2019-03-11 16:22:39.460524",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2019-04-16 17:28:32.749633",
+ "modified_by": "Administrator",
+ "module": "Projects",
+ "name": "Project Billing Summary",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Timesheet",
+ "report_name": "Project Billing Summary",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "Projects User"
+ },
+ {
+ "role": "HR User"
+ },
+ {
+ "role": "Manufacturing User"
+ },
+ {
+ "role": "Employee"
+ },
+ {
+ "role": "Accounts User"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/projects/report/project_billing_summary/project_billing_summary.py b/erpnext/projects/report/project_billing_summary/project_billing_summary.py
new file mode 100644
index 00000000000..cd5ad7803a5
--- /dev/null
+++ b/erpnext/projects/report/project_billing_summary/project_billing_summary.py
@@ -0,0 +1,14 @@
+# 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 erpnext.projects.report.billing_summary import get_columns, get_data
+
+def execute(filters=None):
+ filters = frappe._dict(filters or {})
+ columns = get_columns()
+
+ data = get_data(filters)
+ return columns, data
\ No newline at end of file
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index c34eef25080..1f702e69cca 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -1,58 +1,58 @@
{
- "css/erpnext.css": [
- "public/less/erpnext.less",
- "public/less/hub.less"
- ],
- "css/marketplace.css": [
- "public/less/hub.less"
- ],
- "js/erpnext-web.min.js": [
- "public/js/website_utils.js",
- "public/js/shopping_cart.js"
- ],
+ "css/erpnext.css": [
+ "public/less/erpnext.less",
+ "public/less/hub.less"
+ ],
+ "css/marketplace.css": [
+ "public/less/hub.less"
+ ],
+ "js/erpnext-web.min.js": [
+ "public/js/website_utils.js",
+ "public/js/shopping_cart.js"
+ ],
"css/erpnext-web.css": [
"public/less/website.less"
],
- "js/marketplace.min.js": [
- "public/js/hub/marketplace.js"
- ],
- "js/erpnext.min.js": [
- "public/js/conf.js",
- "public/js/utils.js",
- "public/js/queries.js",
- "public/js/sms_manager.js",
- "public/js/utils/party.js",
- "public/js/templates/address_list.html",
- "public/js/templates/contact_list.html",
- "public/js/controllers/stock_controller.js",
- "public/js/payment/payments.js",
- "public/js/controllers/taxes_and_totals.js",
- "public/js/controllers/transaction.js",
- "public/js/pos/pos.html",
- "public/js/pos/pos_bill_item.html",
- "public/js/pos/pos_bill_item_new.html",
- "public/js/pos/pos_selected_item.html",
- "public/js/pos/pos_item.html",
- "public/js/pos/pos_tax_row.html",
- "public/js/pos/customer_toolbar.html",
- "public/js/pos/pos_invoice_list.html",
- "public/js/payment/pos_payment.html",
- "public/js/payment/payment_details.html",
- "public/js/templates/item_selector.html",
+ "js/marketplace.min.js": [
+ "public/js/hub/marketplace.js"
+ ],
+ "js/erpnext.min.js": [
+ "public/js/conf.js",
+ "public/js/utils.js",
+ "public/js/queries.js",
+ "public/js/sms_manager.js",
+ "public/js/utils/party.js",
+ "public/js/templates/address_list.html",
+ "public/js/templates/contact_list.html",
+ "public/js/controllers/stock_controller.js",
+ "public/js/payment/payments.js",
+ "public/js/controllers/taxes_and_totals.js",
+ "public/js/controllers/transaction.js",
+ "public/js/pos/pos.html",
+ "public/js/pos/pos_bill_item.html",
+ "public/js/pos/pos_bill_item_new.html",
+ "public/js/pos/pos_selected_item.html",
+ "public/js/pos/pos_item.html",
+ "public/js/pos/pos_tax_row.html",
+ "public/js/pos/customer_toolbar.html",
+ "public/js/pos/pos_invoice_list.html",
+ "public/js/payment/pos_payment.html",
+ "public/js/payment/payment_details.html",
+ "public/js/templates/item_selector.html",
"public/js/templates/employees_to_mark_attendance.html",
- "public/js/utils/item_selector.js",
- "public/js/help_links.js",
- "public/js/agriculture/ternary_plot.js",
- "public/js/templates/item_quick_entry.html",
- "public/js/utils/item_quick_entry.js",
+ "public/js/utils/item_selector.js",
+ "public/js/help_links.js",
+ "public/js/agriculture/ternary_plot.js",
+ "public/js/templates/item_quick_entry.html",
+ "public/js/utils/item_quick_entry.js",
"public/js/utils/customer_quick_entry.js",
- "public/js/education/student_button.html",
- "public/js/education/assessment_result_tool.html",
- "public/js/hub/hub_factory.js"
- ],
- "js/item-dashboard.min.js": [
- "stock/dashboard/item_dashboard.html",
- "stock/dashboard/item_dashboard_list.html",
- "stock/dashboard/item_dashboard.js"
- ]
+ "public/js/education/student_button.html",
+ "public/js/education/assessment_result_tool.html",
+ "public/js/hub/hub_factory.js"
+ ],
+ "js/item-dashboard.min.js": [
+ "stock/dashboard/item_dashboard.html",
+ "stock/dashboard/item_dashboard_list.html",
+ "stock/dashboard/item_dashboard.js"
+ ]
}
diff --git a/erpnext/public/js/communication.js b/erpnext/public/js/communication.js
index e85107e77aa..02357ef086c 100644
--- a/erpnext/public/js/communication.js
+++ b/erpnext/public/js/communication.js
@@ -33,7 +33,7 @@ frappe.ui.form.on("Communication", {
make_lead_from_communication: (frm) => {
return frappe.call({
- method: "frappe.email.inbox.make_lead_from_communication",
+ method: "erpnext.crm.doctype.lead.lead.make_lead_from_communication",
args: {
communication: frm.doc.name
},
@@ -48,7 +48,7 @@ frappe.ui.form.on("Communication", {
make_issue_from_communication: (frm) => {
return frappe.call({
- method: "frappe.email.inbox.make_issue_from_communication",
+ method: "erpnext.support.doctype.issue.issue.make_issue_from_communication",
args: {
communication: frm.doc.name
},
@@ -63,7 +63,7 @@ frappe.ui.form.on("Communication", {
make_opportunity_from_communication: (frm) => {
return frappe.call({
- method: "frappe.email.inbox.make_opportunity_from_communication",
+ method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
args: {
communication: frm.doc.name
},
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 56e6bdb8dbe..477781bc805 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -27,8 +27,6 @@ $(document).bind('toolbar_setup', function() {
target="_blank">'+__('Documentation')+'').insertBefore($help_menu);
$('
'+__('User Forum')+'').insertBefore($help_menu);
- $('
'+__('Gitter Chat')+'').insertBefore($help_menu);
$('
'+__('Report an Issue')+'').insertBefore($help_menu);
diff --git a/erpnext/public/js/controllers/stock_controller.js b/erpnext/public/js/controllers/stock_controller.js
index 1b8e0791323..1c12c352ed4 100644
--- a/erpnext/public/js/controllers/stock_controller.js
+++ b/erpnext/public/js/controllers/stock_controller.js
@@ -73,7 +73,7 @@ erpnext.stock.StockController = frappe.ui.form.Controller.extend({
from_date: me.frm.doc.posting_date,
to_date: me.frm.doc.posting_date,
company: me.frm.doc.company,
- group_by: ""
+ group_by: "Group by Voucher (Consolidated)"
};
frappe.set_route("query-report", "General Ledger");
}, __("View"));
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index cf62af7b70e..75b09fb8f4a 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -290,7 +290,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
args: { search_value: this.frm.doc.scan_barcode }
}).then(r => {
const data = r && r.message;
- if (!data) {
+ if (!data || Object.keys(data).length === 0) {
scan_barcode_field.set_new_description(__('Cannot find Item with this barcode'));
return;
}
@@ -314,14 +314,21 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
show_description(row_to_modify.idx, row_to_modify.item_code);
+ this.frm.from_barcode = true;
frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, {
item_code: data.item_code,
qty: (row_to_modify.qty || 0) + 1
});
- this.frm.refresh_field('items');
+ ['serial_no', 'batch_no', 'barcode'].forEach(field => {
+ if (data[field] && frappe.meta.has_field(row_to_modify.doctype, field)) {
+ frappe.model.set_value(row_to_modify.doctype,
+ row_to_modify.name, field, data[field]);
+ }
+ });
+
+ scan_barcode_field.set_value('');
});
- scan_barcode_field.set_value('');
}
return false;
},
@@ -384,10 +391,12 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
// barcode cleared, remove item
d.item_code = "";
}
- this.item_code(doc, cdt, cdn, true);
+
+ this.frm.from_barcode = true;
+ this.item_code(doc, cdt, cdn);
},
- item_code: function(doc, cdt, cdn, from_barcode) {
+ item_code: function(doc, cdt, cdn) {
var me = this;
var item = frappe.get_doc(cdt, cdn);
var update_stock = 0, show_batch_dialog = 0;
@@ -400,9 +409,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
show_batch_dialog = 1;
}
// clear barcode if setting item (else barcode will take priority)
- if(!from_barcode) {
+ if(!this.frm.from_barcode) {
item.barcode = null;
}
+
+ this.frm.from_barcode = false;
if(item.item_code || item.barcode || item.serial_no) {
if(!this.validate_company_and_party()) {
this.frm.fields_dict["items"].grid.grid_rows[item.idx - 1].remove();
@@ -1143,6 +1154,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
"brand": d.brand,
"qty": d.qty,
"uom": d.uom,
+ "stock_uom": d.stock_uom,
"parenttype": d.parenttype,
"parent": d.parent,
"pricing_rule": d.pricing_rule,
diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js
index eab04006c21..5869c4da4c2 100644
--- a/erpnext/public/js/utils/party.js
+++ b/erpnext/public/js/utils/party.js
@@ -103,7 +103,7 @@ erpnext.utils.get_address_display = function(frm, address_field, display_field,
erpnext.utils.set_taxes = function(frm, address_field, display_field, is_your_company_address) {
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes") && !is_your_company_address) {
if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
- frm.doc.customer || frm.doc.supplier || frm.doc.lead, address_field)) {
+ frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name , address_field)) {
return;
}
@@ -125,6 +125,9 @@ erpnext.utils.set_taxes = function(frm, address_field, display_field, is_your_co
} else if (frm.doc.supplier) {
party_type = 'Supplier';
party = frm.doc.supplier;
+ } else if (frm.doc.quotation_to){
+ party_type = frm.doc.quotation_to;
+ party = frm.doc.party_name;
}
frappe.call({
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index b746cc138f6..8ed5f1adb05 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -25,10 +25,10 @@
.app-icon-svg {
display: inline-block;
- margin: auto;
- text-align: center;
- border-radius: 16px;
- cursor: pointer;
+ margin: auto;
+ text-align: center;
+ border-radius: 16px;
+ cursor: pointer;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.15);
}
@@ -458,4 +458,4 @@ body[data-route="pos"] {
.list-item_content {
padding-right: 45px;
}
-}
+}
\ No newline at end of file
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index c5498c77700..2f255b65471 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -93,7 +93,7 @@ def add_print_formats():
def make_custom_fields(update=True):
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Data', fetch_from='item_code.gst_hsn_code', insert_after='description',
- allow_on_submit=1, print_hide=1)
+ allow_on_submit=1, print_hide=1, fetch_if_empty=1)
invoice_gst_fields = [
dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break',
insert_after='language', print_hide=1, collapsible=1),
@@ -189,9 +189,10 @@ def make_custom_fields(update=True):
'fieldname': 'gst_transporter_id',
'label': 'GST Transporter ID',
'fieldtype': 'Data',
- 'insert_after': 'transporter_name',
+ 'insert_after': 'transporter',
'fetch_from': 'transporter.gst_transporter_id',
- 'print_hide': 1
+ 'print_hide': 1,
+ 'translatable': 0
},
{
'fieldname': 'mode_of_transport',
@@ -199,18 +200,142 @@ def make_custom_fields(update=True):
'fieldtype': 'Select',
'options': '\nRoad\nAir\nRail\nShip',
'default': 'Road',
+ 'insert_after': 'transporter_name',
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'gst_vehicle_type',
+ 'label': 'GST Vehicle Type',
+ 'fieldtype': 'Select',
+ 'options': 'Regular\nOver Dimensional Cargo (ODC)',
+ 'depends_on': 'eval:(doc.mode_of_transport === "Road")',
+ 'default': 'Regular',
'insert_after': 'lr_date',
+ 'print_hide': 1,
+ 'translatable': 0
+ }
+ ]
+
+ si_ewaybill_fields = [
+ {
+ 'fieldname': 'transporter_info',
+ 'label': 'Transporter Info',
+ 'fieldtype': 'Section Break',
+ 'insert_after': 'terms',
+ 'collapsible': 1,
+ 'collapsible_depends_on': 'transporter',
+ 'print_hide': 1
+ },
+ {
+ 'fieldname': 'transporter',
+ 'label': 'Transporter',
+ 'fieldtype': 'Link',
+ 'insert_after': 'transporter_info',
+ 'options': 'Supplier',
+ 'print_hide': 1
+ },
+ {
+ 'fieldname': 'gst_transporter_id',
+ 'label': 'GST Transporter ID',
+ 'fieldtype': 'Data',
+ 'insert_after': 'transporter',
+ 'fetch_from': 'transporter.gst_transporter_id',
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'driver',
+ 'label': 'Driver',
+ 'fieldtype': 'Link',
+ 'insert_after': 'gst_transporter_id',
+ 'options': 'Driver',
+ 'print_hide': 1
+ },
+ {
+ 'fieldname': 'lr_no',
+ 'label': 'Transport Receipt No',
+ 'fieldtype': 'Data',
+ 'insert_after': 'driver',
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'vehicle_no',
+ 'label': 'Vehicle No',
+ 'fieldtype': 'Data',
+ 'insert_after': 'lr_no',
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'distance',
+ 'label': 'Distance (in km)',
+ 'fieldtype': 'Float',
+ 'insert_after': 'vehicle_no',
+ 'print_hide': 1
+ },
+ {
+ 'fieldname': 'transporter_col_break',
+ 'fieldtype': 'Column Break',
+ 'insert_after': 'distance'
+ },
+ {
+ 'fieldname': 'transporter_name',
+ 'label': 'Transporter Name',
+ 'fieldtype': 'Data',
+ 'insert_after': 'transporter_col_break',
+ 'fetch_from': 'transporter.name',
+ 'read_only': 1,
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'mode_of_transport',
+ 'label': 'Mode of Transport',
+ 'fieldtype': 'Select',
+ 'options': '\nRoad\nAir\nRail\nShip',
+ 'default': 'Road',
+ 'insert_after': 'transporter_name',
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'driver_name',
+ 'label': 'Driver Name',
+ 'fieldtype': 'Data',
+ 'insert_after': 'mode_of_transport',
+ 'fetch_from': 'driver.full_name',
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'lr_date',
+ 'label': 'Transport Receipt Date',
+ 'fieldtype': 'Date',
+ 'insert_after': 'driver_name',
+ 'default': 'Today',
'print_hide': 1
},
{
'fieldname': 'gst_vehicle_type',
'label': 'GST Vehicle Type',
'fieldtype': 'Select',
- 'options': '\nRegular\nOver Dimensional Cargo (ODC)',
- 'default': 'Regular',
+ 'options': 'Regular\nOver Dimensional Cargo (ODC)',
'depends_on': 'eval:(doc.mode_of_transport === "Road")',
- 'insert_after': 'mode_of_transport',
- 'print_hide': 1
+ 'default': 'Regular',
+ 'insert_after': 'lr_date',
+ 'print_hide': 1,
+ 'translatable': 0
+ },
+ {
+ 'fieldname': 'ewaybill',
+ 'label': 'e-Way Bill No.',
+ 'fieldtype': 'Data',
+ 'depends_on': 'eval:(doc.docstatus === 1)',
+ 'allow_on_submit': 1,
+ 'insert_after': 'project',
+ 'translatable': 0
}
]
@@ -226,7 +351,8 @@ def make_custom_fields(update=True):
'Purchase Invoice': invoice_gst_fields + purchase_invoice_gst_fields + purchase_invoice_itc_fields,
'Purchase Order': purchase_invoice_gst_fields,
'Purchase Receipt': purchase_invoice_gst_fields,
- 'Sales Invoice': invoice_gst_fields + sales_invoice_gst_fields + sales_invoice_shipping_fields,
+ 'Sales Invoice': (invoice_gst_fields + sales_invoice_gst_fields
+ + sales_invoice_shipping_fields + si_ewaybill_fields),
'Delivery Note': sales_invoice_gst_fields + ewaybill_fields + sales_invoice_shipping_fields,
'Sales Order': sales_invoice_gst_fields,
'Sales Taxes and Charges Template': inter_state_gst_field,
@@ -243,6 +369,7 @@ def make_custom_fields(update=True):
'Purchase Order Item': [hsn_sac_field],
'Purchase Receipt Item': [hsn_sac_field],
'Purchase Invoice Item': [hsn_sac_field],
+ 'Material Request Item': [hsn_sac_field],
'Employee': [
dict(fieldname='ifsc_code', label='IFSC Code',
fieldtype='Data', insert_after='bank_ac_no', print_hide=1,
@@ -261,18 +388,18 @@ def make_custom_fields(update=True):
'Employee Tax Exemption Declaration':[
dict(fieldname='hra_section', label='HRA Exemption',
fieldtype='Section Break', insert_after='declarations'),
- dict(fieldname='salary_structure_hra', label='HRA as per Salary Structure',
- fieldtype='Currency', insert_after='hra_section', read_only=1),
dict(fieldname='monthly_house_rent', label='Monthly House Rent',
- fieldtype='Currency', insert_after='salary_structure_hra'),
+ fieldtype='Currency', insert_after='hra_section'),
dict(fieldname='rented_in_metro_city', label='Rented in Metro City',
- fieldtype='Check', insert_after='monthly_house_rent'),
+ fieldtype='Check', insert_after='monthly_house_rent', depends_on='monthly_house_rent'),
+ dict(fieldname='salary_structure_hra', label='HRA as per Salary Structure',
+ fieldtype='Currency', insert_after='rented_in_metro_city', read_only=1, depends_on='monthly_house_rent'),
dict(fieldname='hra_column_break', fieldtype='Column Break',
- insert_after='rented_in_metro_city'),
+ insert_after='salary_structure_hra', depends_on='monthly_house_rent'),
dict(fieldname='annual_hra_exemption', label='Annual HRA Exemption',
- fieldtype='Currency', insert_after='hra_column_break', read_only=1),
+ fieldtype='Currency', insert_after='hra_column_break', read_only=1, depends_on='monthly_house_rent'),
dict(fieldname='monthly_hra_exemption', label='Monthly HRA Exemption',
- fieldtype='Currency', insert_after='annual_hra_exemption', read_only=1)
+ fieldtype='Currency', insert_after='annual_hra_exemption', read_only=1, depends_on='monthly_house_rent')
],
'Employee Tax Exemption Proof Submission': [
dict(fieldname='hra_section', label='HRA Exemption',
@@ -280,19 +407,19 @@ def make_custom_fields(update=True):
dict(fieldname='house_rent_payment_amount', label='House Rent Payment Amount',
fieldtype='Currency', insert_after='hra_section'),
dict(fieldname='rented_in_metro_city', label='Rented in Metro City',
- fieldtype='Check', insert_after='house_rent_payment_amount'),
+ fieldtype='Check', insert_after='house_rent_payment_amount', depends_on='house_rent_payment_amount'),
dict(fieldname='rented_from_date', label='Rented From Date',
- fieldtype='Date', insert_after='rented_in_metro_city'),
+ fieldtype='Date', insert_after='rented_in_metro_city', depends_on='house_rent_payment_amount'),
dict(fieldname='rented_to_date', label='Rented To Date',
- fieldtype='Date', insert_after='rented_from_date'),
+ fieldtype='Date', insert_after='rented_from_date', depends_on='house_rent_payment_amount'),
dict(fieldname='hra_column_break', fieldtype='Column Break',
- insert_after='rented_to_date'),
+ insert_after='rented_to_date', depends_on='house_rent_payment_amount'),
dict(fieldname='monthly_house_rent', label='Monthly House Rent',
- fieldtype='Currency', insert_after='hra_column_break', read_only=1),
+ fieldtype='Currency', insert_after='hra_column_break', read_only=1, depends_on='house_rent_payment_amount'),
dict(fieldname='monthly_hra_exemption', label='Monthly Eligible Amount',
- fieldtype='Currency', insert_after='monthly_house_rent', read_only=1),
+ fieldtype='Currency', insert_after='monthly_house_rent', read_only=1, depends_on='house_rent_payment_amount'),
dict(fieldname='total_eligible_hra_exemption', label='Total Eligible HRA Exemption',
- fieldtype='Currency', insert_after='monthly_hra_exemption', read_only=1)
+ fieldtype='Currency', insert_after='monthly_hra_exemption', read_only=1, depends_on='house_rent_payment_amount')
],
'Supplier': [
{
@@ -305,7 +432,7 @@ def make_custom_fields(update=True):
]
}
- create_custom_fields(custom_fields, ignore_validate = frappe.flags.in_patch, update=update)
+ create_custom_fields(custom_fields, update=update)
def make_fixtures(company=None):
docs = []
diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py
index e7d0d5052ec..82bff0f4238 100644
--- a/erpnext/regional/india/utils.py
+++ b/erpnext/regional/india/utils.py
@@ -1,7 +1,7 @@
from __future__ import unicode_literals
-import frappe, re
+import frappe, re, json
from frappe import _
-from frappe.utils import cstr, flt, date_diff, getdate
+from frappe.utils import cstr, flt, date_diff, nowdate
from erpnext.regional.india import states, state_numbers
from erpnext.controllers.taxes_and_totals import get_itemised_tax, get_itemised_taxable_amount
from erpnext.controllers.accounts_controller import get_taxes_and_charges
@@ -9,9 +9,13 @@ from erpnext.hr.utils import get_salary_assignment
from erpnext.hr.doctype.salary_structure.salary_structure import make_salary_slip
def validate_gstin_for_india(doc, method):
+ if hasattr(doc, 'gst_state') and doc.gst_state:
+ doc.gst_state_number = state_numbers[doc.gst_state]
if not hasattr(doc, 'gstin') or not doc.gstin:
return
+ set_gst_state_and_state_number(doc)
+
doc.gstin = doc.gstin.upper().strip() if doc.gstin else ""
if not doc.gstin or doc.gstin == 'NA':
return
@@ -25,6 +29,11 @@ def validate_gstin_for_india(doc, method):
validate_gstin_check_digit(doc.gstin)
+ if doc.gst_state_number != doc.gstin[:2]:
+ frappe.throw(_("Invalid GSTIN! First 2 digits of GSTIN should match with State number {0}.")
+ .format(doc.gst_state_number))
+
+def set_gst_state_and_state_number(doc):
if not doc.gst_state:
if not doc.state:
return
@@ -36,11 +45,9 @@ def validate_gstin_for_india(doc, method):
return
doc.gst_state_number = state_numbers[doc.gst_state]
- if doc.gst_state_number != doc.gstin[:2]:
- frappe.throw(_("Invalid GSTIN! First 2 digits of GSTIN should match with State number {0}.")
- .format(doc.gst_state_number))
-def validate_gstin_check_digit(gstin):
+
+def validate_gstin_check_digit(gstin, label='GSTIN'):
''' Function to validate the check digit of the GSTIN.'''
factor = 1
total = 0
@@ -53,8 +60,8 @@ def validate_gstin_check_digit(gstin):
total += digit
factor = 2 if factor == 1 else 1
if gstin[-1] != code_point_chars[((mod - (total % mod)) % mod)]:
- frappe.throw(_("Invalid GSTIN! The check digit validation has failed. " +
- "Please ensure you've typed the GSTIN correctly."))
+ frappe.throw(_("Invalid {0}! The check digit validation has failed. " +
+ "Please ensure you've typed the {0} correctly.".format(label)))
def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
if frappe.get_meta(item_doctype).has_field('gst_hsn_code'):
@@ -62,8 +69,8 @@ def get_itemised_tax_breakup_header(item_doctype, tax_accounts):
else:
return [_("Item"), _("Taxable Amount")] + tax_accounts
-def get_itemised_tax_breakup_data(doc):
- itemised_tax = get_itemised_tax(doc.taxes)
+def get_itemised_tax_breakup_data(doc, account_wise=False):
+ itemised_tax = get_itemised_tax(doc.taxes, with_tax_account=account_wise)
itemised_taxable_amount = get_itemised_taxable_amount(doc.items)
@@ -78,14 +85,17 @@ def get_itemised_tax_breakup_data(doc):
for item, taxes in itemised_tax.items():
hsn_code = item_hsn_map.get(item)
hsn_tax.setdefault(hsn_code, frappe._dict())
- for tax_account, tax_detail in taxes.items():
- hsn_tax[hsn_code].setdefault(tax_account, {"tax_rate": 0, "tax_amount": 0})
- hsn_tax[hsn_code][tax_account]["tax_rate"] = tax_detail.get("tax_rate")
- hsn_tax[hsn_code][tax_account]["tax_amount"] += tax_detail.get("tax_amount")
+ for tax_desc, tax_detail in taxes.items():
+ key = tax_desc
+ if account_wise:
+ key = tax_detail.get('tax_account')
+ hsn_tax[hsn_code].setdefault(key, {"tax_rate": 0, "tax_amount": 0})
+ hsn_tax[hsn_code][key]["tax_rate"] = tax_detail.get("tax_rate")
+ hsn_tax[hsn_code][key]["tax_amount"] += tax_detail.get("tax_amount")
# set taxable amount
hsn_taxable_amount = frappe._dict()
- for item, taxable_amount in itemised_taxable_amount.items():
+ for item in itemised_taxable_amount:
hsn_code = item_hsn_map.get(item)
hsn_taxable_amount.setdefault(hsn_code, 0)
hsn_taxable_amount[hsn_code] += itemised_taxable_amount.get(item)
@@ -142,24 +152,40 @@ def get_regional_address_details(out, doctype, company):
def calculate_annual_eligible_hra_exemption(doc):
basic_component = frappe.get_cached_value('Company', doc.company, "basic_component")
hra_component = frappe.get_cached_value('Company', doc.company, "hra_component")
+ if not (basic_component and hra_component):
+ frappe.throw(_("Please mention Basic and HRA component in Company"))
+
annual_exemption, monthly_exemption, hra_amount = 0, 0, 0
if hra_component and basic_component:
- assignment = get_salary_assignment(doc.employee, getdate())
- if assignment and frappe.db.exists("Salary Detail", {
- "parent": assignment.salary_structure,
- "salary_component": hra_component, "parentfield": "earnings"}):
- basic_amount, hra_amount = get_component_amt_from_salary_slip(doc.employee,
- assignment.salary_structure, basic_component, hra_component)
- if hra_amount:
- if doc.monthly_house_rent:
- annual_exemption = calculate_hra_exemption(assignment.salary_structure,
- basic_amount, hra_amount, doc.monthly_house_rent,
- doc.rented_in_metro_city)
- if annual_exemption > 0:
- monthly_exemption = annual_exemption / 12
- else:
- annual_exemption = 0
- return {"hra_amount": hra_amount, "annual_exemption": annual_exemption, "monthly_exemption": monthly_exemption}
+ assignment = get_salary_assignment(doc.employee, nowdate())
+
+ if assignment:
+ hra_component_exists = frappe.db.exists("Salary Detail", {
+ "parent": assignment.salary_structure,
+ "salary_component": hra_component,
+ "parentfield": "earnings",
+ "parenttype": "Salary Structure"
+ })
+ if hra_component_exists:
+ basic_amount, hra_amount = get_component_amt_from_salary_slip(doc.employee,
+ assignment.salary_structure, basic_component, hra_component)
+ if hra_amount:
+ if doc.monthly_house_rent:
+ annual_exemption = calculate_hra_exemption(assignment.salary_structure,
+ basic_amount, hra_amount, doc.monthly_house_rent,
+ doc.rented_in_metro_city)
+ if annual_exemption > 0:
+ monthly_exemption = annual_exemption / 12
+ else:
+ annual_exemption = 0
+ elif doc.docstatus == 1:
+ frappe.throw(_("Salary Structure must be submitted before submission of Tax Ememption Declaration"))
+
+ return frappe._dict({
+ "hra_amount": hra_amount,
+ "annual_exemption": annual_exemption,
+ "monthly_exemption": monthly_exemption
+ })
def get_component_amt_from_salary_slip(employee, salary_structure, basic_component, hra_component):
salary_slip = make_salary_slip(salary_structure, employee=employee)
@@ -179,8 +205,10 @@ def calculate_hra_exemption(salary_structure, basic, monthly_hra, monthly_house_
frequency = frappe.get_value("Salary Structure", salary_structure, "payroll_frequency")
# case 1: The actual amount allotted by the employer as the HRA.
exemptions.append(get_annual_component_pay(frequency, monthly_hra))
+
actual_annual_rent = monthly_house_rent * 12
annual_basic = get_annual_component_pay(frequency, basic)
+
# case 2: Actual rent paid less 10% of the basic salary.
exemptions.append(flt(actual_annual_rent) - flt(annual_basic * 0.1))
# case 3: 50% of the basic salary, if the employee is staying in a metro city (40% for a non-metro city).
@@ -203,15 +231,25 @@ def get_annual_component_pay(frequency, amount):
def validate_house_rent_dates(doc):
if not doc.rented_to_date or not doc.rented_from_date:
frappe.throw(_("House rented dates required for exemption calculation"))
+
if date_diff(doc.rented_to_date, doc.rented_from_date) < 14:
frappe.throw(_("House rented dates should be atleast 15 days apart"))
- proofs = frappe.db.sql("""select name from `tabEmployee Tax Exemption Proof Submission`
- where docstatus=1 and employee='{0}' and payroll_period='{1}' and
- (rented_from_date between '{2}' and '{3}' or rented_to_date between
- '{2}' and '{3}')""".format(doc.employee, doc.payroll_period,
- doc.rented_from_date, doc.rented_to_date))
+
+ proofs = frappe.db.sql("""
+ select name
+ from `tabEmployee Tax Exemption Proof Submission`
+ where
+ docstatus=1 and employee=%(employee)s and payroll_period=%(payroll_period)s
+ and (rented_from_date between %(from_date)s and %(to_date)s or rented_to_date between %(from_date)s and %(to_date)s)
+ """, {
+ "employee": doc.employee,
+ "payroll_period": doc.payroll_period,
+ "from_date": doc.rented_from_date,
+ "to_date": doc.rented_to_date
+ })
+
if proofs:
- frappe.throw(_("House rent paid days overlap with {0}").format(proofs[0][0]))
+ frappe.throw(_("House rent paid days overlapping with {0}").format(proofs[0][0]))
def calculate_hra_exemption_for_period(doc):
monthly_rent, eligible_hra = 0, 0
@@ -232,3 +270,271 @@ def calculate_hra_exemption_for_period(doc):
exemptions["monthly_house_rent"] = monthly_rent
exemptions["total_eligible_hra_exemption"] = eligible_hra
return exemptions
+
+
+def get_ewb_data(dt, dn):
+ if dt != 'Sales Invoice':
+ frappe.throw(_('e-Way Bill JSON can only be generated from Sales Invoice'))
+
+ dn = dn.split(',')
+
+ ewaybills = []
+ for doc_name in dn:
+ doc = frappe.get_doc(dt, doc_name)
+
+ validate_sales_invoice(doc)
+
+ data = frappe._dict({
+ "transporterId": "",
+ "TotNonAdvolVal": 0,
+ })
+
+ data.userGstin = data.fromGstin = doc.company_gstin
+ data.supplyType = 'O'
+
+ if doc.invoice_type in ['Regular', 'SEZ']:
+ data.subSupplyType = 1
+ elif doc.invoice_type in ['Export', 'Deemed Export']:
+ data.subSupplyType = 3
+ else:
+ frappe.throw(_('Unsupported Invoice Type for e-Way Bill JSON generation'))
+
+ data.docType = 'INV'
+ data.docDate = frappe.utils.formatdate(doc.posting_date, 'dd/mm/yyyy')
+
+ company_address = frappe.get_doc('Address', doc.company_address)
+ billing_address = frappe.get_doc('Address', doc.customer_address)
+
+ shipping_address = frappe.get_doc('Address', doc.shipping_address_name)
+
+ data = get_address_details(data, doc, company_address, billing_address)
+
+ data.itemList = []
+ data.totalValue = doc.total
+
+ data = get_item_list(data, doc)
+
+ disable_rounded = frappe.db.get_single_value('Global Defaults', 'disable_rounded_total')
+ data.totInvValue = doc.grand_total if disable_rounded else doc.rounded_total
+
+ data = get_transport_details(data, doc)
+
+ fields = {
+ "/. -": {
+ 'docNo': doc.name,
+ 'fromTrdName': doc.company,
+ 'toTrdName': doc.customer_name,
+ 'transDocNo': doc.lr_no,
+ },
+ "@#/,&. -": {
+ 'fromAddr1': company_address.address_line1,
+ 'fromAddr2': company_address.address_line2,
+ 'fromPlace': company_address.city,
+ 'toAddr1': shipping_address.address_line1,
+ 'toAddr2': shipping_address.address_line2,
+ 'toPlace': shipping_address.city,
+ 'transporterName': doc.transporter_name
+ }
+ }
+
+ for allowed_chars, field_map in fields.items():
+ for key, value in field_map.items():
+ if not value:
+ data[key] = ''
+ else:
+ data[key] = re.sub(r'[^\w' + allowed_chars + ']', '', value)
+
+ ewaybills.append(data)
+
+ data = {
+ 'version': '1.0.1118',
+ 'billLists': ewaybills
+ }
+
+ return data
+
+@frappe.whitelist()
+def generate_ewb_json(dt, dn):
+
+ data = get_ewb_data(dt, dn)
+
+ frappe.local.response.filecontent = json.dumps(data, indent=4, sort_keys=True)
+ frappe.local.response.type = 'download'
+
+ if len(data['billLists']) > 1:
+ doc_name = 'Bulk'
+ else:
+ doc_name = dn
+
+ frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(doc_name, frappe.utils.random_string(5))
+
+
+def get_address_details(data, doc, company_address, billing_address):
+ data.fromPincode = validate_pincode(company_address.pincode, 'Company Address')
+ data.fromStateCode = data.actualFromStateCode = validate_state_code(
+ company_address.gst_state_number, 'Company Address')
+
+ if not doc.billing_address_gstin or len(doc.billing_address_gstin) < 15:
+ data.toGstin = 'URP'
+ set_gst_state_and_state_number(billing_address)
+ else:
+ data.toGstin = doc.billing_address_gstin
+
+ data.toPincode = validate_pincode(billing_address.pincode, 'Customer Address')
+ data.toStateCode = validate_state_code(billing_address.gst_state_number, 'Customer Address')
+
+ if doc.customer_address != doc.shipping_address_name:
+ data.transType = 2
+ shipping_address = frappe.get_doc('Address', doc.shipping_address_name)
+ set_gst_state_and_state_number(shipping_address)
+ data.actualToStateCode = validate_state_code(shipping_address.gst_state_number, 'Shipping Address')
+ else:
+ data.transType = 1
+ data.actualToStateCode = data.toStateCode
+ shipping_address = billing_address
+
+ return data
+
+def get_item_list(data, doc):
+ for attr in ['cgstValue', 'sgstValue', 'igstValue', 'cessValue', 'OthValue']:
+ data[attr] = 0
+
+ gst_accounts = get_gst_accounts(doc.company, account_wise=True)
+ tax_map = {
+ 'sgst_account': ['sgstRate', 'sgstValue'],
+ 'cgst_account': ['cgstRate', 'cgstValue'],
+ 'igst_account': ['igstRate', 'igstValue'],
+ 'cess_account': ['cessRate', 'cessValue']
+ }
+ item_data_attrs = ['sgstRate', 'cgstRate', 'igstRate', 'cessRate', 'cessNonAdvol']
+ hsn_wise_charges, hsn_taxable_amount = get_itemised_tax_breakup_data(doc, account_wise=True)
+ for hsn_code, taxable_amount in hsn_taxable_amount.items():
+ item_data = frappe._dict()
+ if not hsn_code:
+ frappe.throw(_('GST HSN Code does not exist for one or more items'))
+ item_data.hsnCode = int(hsn_code)
+ item_data.taxableAmount = taxable_amount
+ item_data.qtyUnit = ""
+ for attr in item_data_attrs:
+ item_data[attr] = 0
+
+ for account, tax_detail in hsn_wise_charges.get(hsn_code, {}).items():
+ account_type = gst_accounts.get(account, '')
+ for tax_acc, attrs in tax_map.items():
+ if account_type == tax_acc:
+ item_data[attrs[0]] = tax_detail.get('tax_rate')
+ data[attrs[1]] += tax_detail.get('tax_amount')
+ break
+ else:
+ data.OthValue += tax_detail.get('tax_amount')
+
+ data.itemList.append(item_data)
+
+ return data
+
+def validate_sales_invoice(doc):
+ if doc.docstatus != 1:
+ frappe.throw(_('e-Way Bill JSON can only be generated from submitted document'))
+
+ if doc.is_return:
+ frappe.throw(_('e-Way Bill JSON cannot be generated for Sales Return as of now'))
+
+ if doc.ewaybill:
+ frappe.throw(_('e-Way Bill already exists for this document'))
+
+ reqd_fields = ['company_gstin', 'company_address', 'customer_address',
+ 'shipping_address_name', 'mode_of_transport', 'distance']
+
+ for fieldname in reqd_fields:
+ if not doc.get(fieldname):
+ frappe.throw(_('{} is required to generate e-Way Bill JSON'.format(
+ doc.meta.get_label(fieldname)
+ )))
+
+ if len(doc.company_gstin) < 15:
+ frappe.throw(_('You must be a registered supplier to generate e-Way Bill'))
+
+def get_transport_details(data, doc):
+ if doc.distance > 4000:
+ frappe.throw(_('Distance cannot be greater than 4000 kms'))
+
+ data.transDistance = round(doc.distance)
+
+ transport_modes = {
+ 'Road': 1,
+ 'Rail': 2,
+ 'Air': 3,
+ 'Ship': 4
+ }
+
+ vehicle_types = {
+ 'Regular': 'R',
+ 'Over Dimensional Cargo (ODC)': 'O'
+ }
+
+ data.transMode = transport_modes.get(doc.mode_of_transport)
+
+ if doc.mode_of_transport == 'Road':
+ if not doc.gst_transporter_id and not doc.vehicle_no:
+ frappe.throw(_('Either GST Transporter ID or Vehicle No is required if Mode of Transport is Road'))
+ if doc.vehicle_no:
+ data.vehicleNo = doc.vehicle_no.replace(' ', '')
+ if not doc.gst_vehicle_type:
+ frappe.throw(_('Vehicle Type is required if Mode of Transport is Road'))
+ else:
+ data.vehicleType = vehicle_types.get(doc.gst_vehicle_type)
+ else:
+ if not doc.lr_no or not doc.lr_date:
+ frappe.throw(_('Transport Receipt No and Date are mandatory for your chosen Mode of Transport'))
+
+ if doc.lr_no:
+ data.transDocNo = doc.lr_no
+
+ if doc.lr_date:
+ data.transDocDate = frappe.utils.formatdate(doc.lr_date, 'dd/mm/yyyy')
+
+ if doc.gst_transporter_id:
+ validate_gstin_check_digit(doc.gst_transporter_id, label='GST Transporter ID')
+ data.transporterId = doc.gst_transporter_id
+
+ return data
+
+
+def validate_pincode(pincode, address):
+ pin_not_found = "Pin Code doesn't exist for {}"
+ incorrect_pin = "Pin Code for {} is incorrecty formatted. It must be 6 digits (without spaces)"
+
+ if not pincode:
+ frappe.throw(_(pin_not_found.format(address)))
+
+ pincode = pincode.replace(' ', '')
+ if not pincode.isdigit() or len(pincode) != 6:
+ frappe.throw(_(incorrect_pin.format(address)))
+ else:
+ return int(pincode)
+
+def validate_state_code(state_code, address):
+ no_state_code = "GST State Code not found for {0}. Please set GST State in {0}"
+ if not state_code:
+ frappe.throw(_(no_state_code.format(address)))
+ else:
+ return int(state_code)
+
+def get_gst_accounts(company, account_wise=False):
+ gst_accounts = frappe._dict()
+ gst_settings_accounts = frappe.get_all("GST Account",
+ filters={"parent": "GST Settings", "company": company},
+ fields=["cgst_account", "sgst_account", "igst_account", "cess_account"])
+
+ if not gst_settings_accounts:
+ frappe.throw(_("Please set GST Accounts in GST Settings"))
+
+ for d in gst_settings_accounts:
+ for acc, val in d.items():
+ if not account_wise:
+ gst_accounts.setdefault(acc, []).append(val)
+ elif val:
+ gst_accounts[val] = acc
+
+
+ return gst_accounts
\ No newline at end of file
diff --git a/erpnext/regional/italy/e-invoice.xml b/erpnext/regional/italy/e-invoice.xml
index 34053bdc99a..b725b964f2e 100644
--- a/erpnext/regional/italy/e-invoice.xml
+++ b/erpnext/regional/italy/e-invoice.xml
@@ -9,7 +9,7 @@
{%- if address.state_code %}
{{ address.state_code }}
{%- endif %}
-
{{ address.country_code|upper }}
+
{{ address.country_code }}
{%- endmacro %}
{%- macro render_discount_or_margin(item) -%}
@@ -32,15 +32,15 @@
{%- endmacro -%}
-
- {{ doc.company_address_data.country_code|upper or "IT" }}
+ {{ doc.company_address_data.country_code }}
{{ doc.company_fiscal_code or doc.company_tax_id | replace("IT","") }}
{{ doc.progressive_number }}
@@ -56,7 +56,7 @@
- {{ doc.company_address_data.country_code|upper or "IT"}}
+ {{ doc.company_address_data.country_code }}
{{ doc.company_tax_id | replace("IT","") }}
{%- if doc.company_fiscal_code %}
@@ -95,13 +95,12 @@
{{ doc.customer_data.last_name }}
{%- else %}
- {%- if doc.customer_data.is_public_administration %}
- {{ doc.customer_data.fiscal_code }}
- {%- else %}
- {{ doc.customer_address_data.country_code|upper or "IT" }}
+ {{ doc.customer_address_data.country_code }}
{{ doc.tax_id | replace("IT","") }}
+ {%- if doc.customer_data.fiscal_code %}
+ {{ doc.customer_data.fiscal_code }}
{%- endif %}
{{ doc.customer_name }}
@@ -128,22 +127,42 @@
{{ format_float(doc.stamp_duty) }}
{%- endif %}
- {{ format_float(doc.grand_total) }}
+ {%- if doc.discount_amount %}
+
+ {%- if doc.discount_amount > 0.0 %}
+ SC
+ {%- else %}
+ MG
+ {%- endif %}
+ {%- if doc.additional_discount_percentage > 0.0 %}
+ {{ format_float(doc.additional_discount_percentage) }}
+ {%- endif %}
+ {{ format_float(doc.discount_amount) }}
+
+ {%- endif %}
+ {{ format_float(doc.rounded_total or doc.grand_total) }}
VENDITA
- {%- if doc.po_no %}
-
- {{ doc.po_no }}
- {%- if doc.po_date %}
- {{ doc.po_date }}
- {%- endif %}
-
- {%- endif %}
+ {%- for po_no, po_date in doc.customer_po_data.items() %}
+
+ {{ po_no }}
+ {{ po_date }}
+
+ {%- endfor %}
{%- if doc.is_return and doc.return_against_unamended %}
{{ doc.return_against_unamended }}
{%- endif %}
+ {%- for row in doc.e_invoice_items %}
+ {%- if row.delivery_note %}
+
+ {{ row.delivery_note }}
+ {{ frappe.db.get_value('Delivery Note', row.delivery_note, 'posting_date') }}
+ {{ row.idx }}
+
+ {%- endif %}
+ {%- endfor %}
{%- if doc.shipping_address_data %}
@@ -160,7 +179,7 @@
CODICE
{{ item.item_code }}
- {{ item.description or item.item_name }}
+ {{ html2text(item.description or '') or item.item_name }}
{{ format_float(item.qty) }}
{{ item.stock_uom }}
{{ format_float(item.price_list_rate or item.rate) }}
@@ -199,7 +218,17 @@
{{ payment_term.mode_of_payment_code.split("-")[0] }}
{{ payment_term.due_date }}
{{ format_float(payment_term.payment_amount) }}
- {%- if payment_term.bank_account_iban %}{{ payment_term.bank_account_iban }}{%- endif %}
+ {%- if payment_term.bank_account_name %}
+ {{ payment_term.bank_account_name }}
+ {%- endif %}
+ {%- if payment_term.bank_account_iban %}
+ {{ payment_term.bank_account_iban }}
+ {{ payment_term.bank_account_iban[5:10] }}
+ {{ payment_term.bank_account_iban[10:15] }}
+ {%- endif %}
+ {%- if payment_term.bank_account_swift_number %}
+ {{ payment_term.bank_account_swift_number }}
+ {%- endif %}
{%- endfor %}
diff --git a/erpnext/regional/italy/sales_invoice.js b/erpnext/regional/italy/sales_invoice.js
new file mode 100644
index 00000000000..586a52937b5
--- /dev/null
+++ b/erpnext/regional/italy/sales_invoice.js
@@ -0,0 +1,30 @@
+erpnext.setup_e_invoice_button = (doctype) => {
+ frappe.ui.form.on(doctype, {
+ refresh: (frm) => {
+ if(frm.doc.docstatus == 1) {
+ frm.add_custom_button('Generate E-Invoice', () => {
+ frm.call({
+ method: "erpnext.regional.italy.utils.generate_single_invoice",
+ args: {
+ docname: frm.doc.name
+ },
+ callback: function(r) {
+ frm.reload_doc();
+ if(r.message) {
+ var w = window.open(
+ frappe.urllib.get_full_url(
+ "/api/method/erpnext.regional.italy.utils.download_e_invoice_file?"
+ + "file_name=" + r.message
+ )
+ )
+ if (!w) {
+ frappe.msgprint(__("Please enable pop-ups")); return;
+ }
+ }
+ }
+ });
+ });
+ }
+ }
+ });
+};
diff --git a/erpnext/regional/italy/setup.py b/erpnext/regional/italy/setup.py
index a9de2d1f18a..1526d6f62f0 100644
--- a/erpnext/regional/italy/setup.py
+++ b/erpnext/regional/italy/setup.py
@@ -26,18 +26,34 @@ def make_custom_fields(update=True):
print_hide=1, hidden=1, read_only=1, options="currency")
]
+ customer_po_fields = [
+ dict(fieldname='customer_po_details', label='Customer PO',
+ fieldtype='Section Break', insert_after='image'),
+ dict(fieldname='customer_po_no', label='Customer PO No',
+ fieldtype='Data', insert_after='customer_po_details',
+ fetch_from = 'sales_order.po_no',
+ print_hide=1, allow_on_submit=1, fetch_if_empty= 1, read_only=1, no_copy=1),
+ dict(fieldname='customer_po_clm_brk', label='',
+ fieldtype='Column Break', insert_after='customer_po_no',
+ print_hide=1, read_only=1),
+ dict(fieldname='customer_po_date', label='Customer PO Date',
+ fieldtype='Date', insert_after='customer_po_clm_brk',
+ fetch_from = 'sales_order.po_date',
+ print_hide=1, allow_on_submit=1, fetch_if_empty= 1, read_only=1, no_copy=1)
+ ]
+
custom_fields = {
'Company': [
dict(fieldname='sb_e_invoicing', label='E-Invoicing',
fieldtype='Section Break', insert_after='date_of_establishment', print_hide=1),
dict(fieldname='fiscal_regime', label='Fiscal Regime',
fieldtype='Select', insert_after='sb_e_invoicing', print_hide=1,
- options="\n".join(map(lambda x: x.decode('utf-8'), fiscal_regimes))),
+ options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), fiscal_regimes))),
dict(fieldname='fiscal_code', label='Fiscal Code', fieldtype='Data', insert_after='fiscal_regime', print_hide=1,
description=_("Applicable if the company is an Individual or a Proprietorship")),
dict(fieldname='vat_collectability', label='VAT Collectability',
fieldtype='Select', insert_after='fiscal_code', print_hide=1,
- options="\n".join(map(lambda x: x.decode('utf-8'), vat_collectability_options))),
+ options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), vat_collectability_options))),
dict(fieldname='cb_e_invoicing1', fieldtype='Column Break', insert_after='vat_collectability', print_hide=1),
dict(fieldname='registrar_office_province', label='Province of the Registrar Office',
fieldtype='Data', insert_after='cb_e_invoicing1', print_hide=1, length=2),
@@ -57,7 +73,7 @@ def make_custom_fields(update=True):
dict(fieldname='tax_exemption_reason', label='Tax Exemption Reason',
fieldtype='Select', insert_after='included_in_print_rate', print_hide=1,
depends_on='eval:doc.charge_type!="Actual" && doc.rate==0.0',
- options="\n" + "\n".join(map(lambda x: x.decode('utf-8'), tax_exemption_reasons))),
+ options="\n" + "\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), tax_exemption_reasons))),
dict(fieldname='tax_exemption_law', label='Tax Exempt Under',
fieldtype='Text', insert_after='tax_exemption_reason', print_hide=1,
depends_on='eval:doc.charge_type!="Actual" && doc.rate==0.0')
@@ -80,30 +96,33 @@ def make_custom_fields(update=True):
'Mode of Payment': [
dict(fieldname='mode_of_payment_code', label='Code',
fieldtype='Select', insert_after='included_in_print_rate', print_hide=1,
- options="\n".join(map(lambda x: x.decode('utf-8'), mode_of_payment_codes)))
+ options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), mode_of_payment_codes)))
],
'Payment Schedule': [
dict(fieldname='mode_of_payment_code', label='Code',
fieldtype='Select', insert_after='mode_of_payment', print_hide=1,
- options="\n".join(map(lambda x: x.decode('utf-8'), mode_of_payment_codes)),
+ options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), mode_of_payment_codes)),
fetch_from="mode_of_payment.mode_of_payment_code", read_only=1),
dict(fieldname='bank_account', label='Bank Account',
fieldtype='Link', insert_after='mode_of_payment_code', print_hide=1,
options="Bank Account"),
- dict(fieldname='bank_account_name', label='Bank Account Name',
+ dict(fieldname='bank_account_name', label='Bank Name',
fieldtype='Data', insert_after='bank_account', print_hide=1,
- fetch_from="bank_account.account_name", read_only=1),
+ fetch_from="bank_account.bank", read_only=1),
dict(fieldname='bank_account_no', label='Bank Account No',
fieldtype='Data', insert_after='bank_account_name', print_hide=1,
fetch_from="bank_account.bank_account_no", read_only=1),
dict(fieldname='bank_account_iban', label='IBAN',
fieldtype='Data', insert_after='bank_account_name', print_hide=1,
fetch_from="bank_account.iban", read_only=1),
+ dict(fieldname='bank_account_swift_number', label='Swift Code (BIC)',
+ fieldtype='Data', insert_after='bank_account_iban', print_hide=1,
+ fetch_from="bank_account.swift_number", read_only=1),
],
"Sales Invoice": [
dict(fieldname='vat_collectability', label='VAT Collectability',
fieldtype='Select', insert_after='taxes_and_charges', print_hide=1,
- options="\n".join(map(lambda x: x.decode('utf-8'), vat_collectability_options)),
+ options="\n".join(map(lambda x: frappe.safe_decode(x, encoding='utf-8'), vat_collectability_options)),
fetch_from="company.vat_collectability"),
dict(fieldname='sb_e_invoicing_reference', label='E-Invoicing',
fieldtype='Section Break', insert_after='pos_total_qty', print_hide=1),
@@ -125,14 +144,14 @@ def make_custom_fields(update=True):
'Purchase Invoice Item': invoice_item_fields,
'Sales Order Item': invoice_item_fields,
'Delivery Note Item': invoice_item_fields,
- 'Sales Invoice Item': invoice_item_fields,
+ 'Sales Invoice Item': invoice_item_fields + customer_po_fields,
'Quotation Item': invoice_item_fields,
'Purchase Order Item': invoice_item_fields,
'Purchase Receipt Item': invoice_item_fields,
'Supplier Quotation Item': invoice_item_fields,
'Address': [
dict(fieldname='country_code', label='Country Code',
- fieldtype='Data', insert_after='country', print_hide=1, read_only=1,
+ fieldtype='Data', insert_after='country', print_hide=1, read_only=0,
fetch_from="country.code"),
dict(fieldname='state_code', label='State Code',
fieldtype='Data', insert_after='state', print_hide=1)
diff --git a/erpnext/regional/italy/utils.py b/erpnext/regional/italy/utils.py
index 421994c398f..5fae858efeb 100644
--- a/erpnext/regional/italy/utils.py
+++ b/erpnext/regional/italy/utils.py
@@ -4,6 +4,7 @@ import frappe, json, os
from frappe.utils import flt, cstr
from erpnext.controllers.taxes_and_totals import get_itemised_tax
from frappe import _
+from six import string_types
from frappe.utils.file_manager import save_file, remove_file
from frappe.desk.form.load import get_attachments
from erpnext.regional.italy import state_codes
@@ -82,6 +83,14 @@ def prepare_invoice(invoice, progressive_number):
if item.tax_rate == 0.0 and item.tax_amount == 0.0:
item.tax_exemption_reason = tax_data["0.0"]["tax_exemption_reason"]
+ customer_po_data = {}
+ for d in invoice.e_invoice_items:
+ if (d.customer_po_no and d.customer_po_date
+ and d.customer_po_no not in customer_po_data):
+ customer_po_data[d.customer_po_no] = d.customer_po_date
+
+ invoice.customer_po_data = customer_po_data
+
return invoice
def get_conditions(filters):
@@ -134,6 +143,7 @@ def get_invoice_summary(items, taxes):
idx=len(items)+1,
item_code=reference_row.description,
item_name=reference_row.description,
+ description=reference_row.description,
rate=reference_row.tax_amount,
qty=1.0,
amount=reference_row.tax_amount,
@@ -142,7 +152,7 @@ def get_invoice_summary(items, taxes):
tax_amount=(reference_row.tax_amount * tax.rate) / 100,
net_amount=reference_row.tax_amount,
taxable_amount=reference_row.tax_amount,
- item_tax_rate="{}",
+ item_tax_rate={tax.account_head: tax.rate},
charges=True
)
)
@@ -150,10 +160,16 @@ def get_invoice_summary(items, taxes):
#Check item tax rates if tax rate is zero.
if tax.rate == 0:
for item in items:
- item_tax_rate = json.loads(item.item_tax_rate)
- if tax.account_head in item_tax_rate:
+ item_tax_rate = item.item_tax_rate
+ if isinstance(item.item_tax_rate, string_types):
+ item_tax_rate = json.loads(item.item_tax_rate)
+
+ if item_tax_rate and tax.account_head in item_tax_rate:
key = cstr(item_tax_rate[tax.account_head])
- summary_data.setdefault(key, {"tax_amount": 0.0, "taxable_amount": 0.0, "tax_exemption_reason": "", "tax_exemption_law": ""})
+ if key not in summary_data:
+ summary_data.setdefault(key, {"tax_amount": 0.0, "taxable_amount": 0.0,
+ "tax_exemption_reason": "", "tax_exemption_law": ""})
+
summary_data[key]["tax_amount"] += item.tax_amount
summary_data[key]["taxable_amount"] += item.net_amount
if key == "0.0":
@@ -189,28 +205,41 @@ def sales_invoice_validate(doc):
if not doc.company_address:
frappe.throw(_("Please set an Address on the Company '%s'" % doc.company), title=_("E-Invoicing Information Missing"))
else:
- validate_address(doc.company_address, "Company")
+ validate_address(doc.company_address)
+ company_fiscal_regime = frappe.get_cached_value("Company", doc.company, 'fiscal_regime')
+ if not company_fiscal_regime:
+ frappe.throw(_("Fiscal Regime is mandatory, kindly set the fiscal regime in the company {0}")
+ .format(doc.company))
+ else:
+ doc.company_fiscal_regime = company_fiscal_regime
+
+ doc.company_tax_id = frappe.get_cached_value("Company", doc.company, 'tax_id')
+ doc.company_fiscal_code = frappe.get_cached_value("Company", doc.company, 'fiscal_code')
if not doc.company_tax_id and not doc.company_fiscal_code:
frappe.throw(_("Please set either the Tax ID or Fiscal Code on Company '%s'" % doc.company), title=_("E-Invoicing Information Missing"))
#Validate customer details
- customer_type, is_public_administration = frappe.db.get_value("Customer", doc.customer, ["customer_type", "is_public_administration"])
- if customer_type == _("Individual"):
+ customer = frappe.get_doc("Customer", doc.customer)
+
+ if customer.customer_type == _("Individual"):
+ doc.customer_fiscal_code = customer.fiscal_code
if not doc.customer_fiscal_code:
frappe.throw(_("Please set Fiscal Code for the customer '%s'" % doc.customer), title=_("E-Invoicing Information Missing"))
else:
- if is_public_administration:
+ if customer.is_public_administration:
+ doc.customer_fiscal_code = customer.fiscal_code
if not doc.customer_fiscal_code:
frappe.throw(_("Please set Fiscal Code for the public administration '%s'" % doc.customer), title=_("E-Invoicing Information Missing"))
else:
+ doc.tax_id = customer.tax_id
if not doc.tax_id:
frappe.throw(_("Please set Tax ID for the customer '%s'" % doc.customer), title=_("E-Invoicing Information Missing"))
if not doc.customer_address:
frappe.throw(_("Please set the Customer Address"), title=_("E-Invoicing Information Missing"))
else:
- validate_address(doc.customer_address, "Customer")
+ validate_address(doc.customer_address)
if not len(doc.taxes):
frappe.throw(_("Please set at least one row in the Taxes and Charges Table"), title=_("E-Invoicing Information Missing"))
@@ -220,6 +249,10 @@ def sales_invoice_validate(doc):
frappe.throw(_("Row {0}: Please set at Tax Exemption Reason in Sales Taxes and Charges".format(row.idx)),
title=_("E-Invoicing Information Missing"))
+ for schedule in doc.payment_schedule:
+ if schedule.mode_of_payment and not schedule.mode_of_payment_code:
+ schedule.mode_of_payment_code = frappe.get_cached_value('Mode of Payment',
+ schedule.mode_of_payment, 'mode_of_payment_code')
#Ensure payment details are valid for e-invoice.
def sales_invoice_on_submit(doc, method):
@@ -241,14 +274,34 @@ def sales_invoice_on_submit(doc, method):
prepare_and_attach_invoice(doc)
-def prepare_and_attach_invoice(doc):
- progressive_name, progressive_number = get_progressive_name_and_number(doc)
+def prepare_and_attach_invoice(doc, replace=False):
+ progressive_name, progressive_number = get_progressive_name_and_number(doc, replace)
invoice = prepare_invoice(doc, progressive_number)
invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml', context={"doc": invoice}, is_path=True)
+ invoice_xml = invoice_xml.replace("&", "&")
xml_filename = progressive_name + ".xml"
- save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True)
+ return save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True)
+
+@frappe.whitelist()
+def generate_single_invoice(docname):
+ doc = frappe.get_doc("Sales Invoice", docname)
+
+
+ e_invoice = prepare_and_attach_invoice(doc, True)
+
+ return e_invoice.file_name
+
+@frappe.whitelist()
+def download_e_invoice_file(file_name):
+ content = None
+ with open(frappe.get_site_path('private', 'files', file_name), "r") as f:
+ content = f.read()
+
+ frappe.local.response.filename = file_name
+ frappe.local.response.filecontent = content
+ frappe.local.response.type = "download"
#Delete e-invoice attachment on cancel.
def sales_invoice_on_cancel(doc, method):
@@ -268,18 +321,19 @@ def get_e_invoice_attachments(invoice):
company_tax_id = invoice.company_tax_id if invoice.company_tax_id.startswith("IT") else "IT" + invoice.company_tax_id
for attachment in attachments:
- if attachment.file_name.startswith(company_tax_id) and attachment.file_name.endswith(".xml"):
+ if attachment.file_name and attachment.file_name.startswith(company_tax_id) and attachment.file_name.endswith(".xml"):
out.append(attachment)
return out
-def validate_address(address_name, address_context):
- pincode, city = frappe.db.get_value("Address", address_name, ["pincode", "city"])
- if not pincode:
- frappe.throw(_("Please set pin code on %s Address" % address_context), title=_("E-Invoicing Information Missing"))
- if not city:
- frappe.throw(_("Please set city on %s Address" % address_context), title=_("E-Invoicing Information Missing"))
+def validate_address(address_name):
+ fields = ["pincode", "city", "country_code"]
+ data = frappe.get_cached_value("Address", address_name, fields, as_dict=1) or {}
+ for field in fields:
+ if not data.get(field):
+ frappe.throw(_("Please set {0} for address {1}".format(field.replace('-',''), address_name)),
+ title=_("E-Invoicing Information Missing"))
def get_unamended_name(doc):
attributes = ["naming_series", "amended_from"]
@@ -292,7 +346,13 @@ def get_unamended_name(doc):
else:
return doc.name
-def get_progressive_name_and_number(doc):
+def get_progressive_name_and_number(doc, replace=False):
+ if replace:
+ for attachment in get_e_invoice_attachments(doc):
+ remove_file(attachment.name, attached_to_doctype=doc.doctype, attached_to_name=doc.name)
+ filename = attachment.file_name.split(".xml")[0]
+ return filename, filename.split("_")[1]
+
company_tax_id = doc.company_tax_id if doc.company_tax_id.startswith("IT") else "IT" + doc.company_tax_id
progressive_name = frappe.model.naming.make_autoname(company_tax_id + "_.#####")
progressive_number = progressive_name.split("_")[1]
@@ -300,6 +360,9 @@ def get_progressive_name_and_number(doc):
return progressive_name, progressive_number
def set_state_code(doc, method):
+ if doc.get('country_code'):
+ doc.country_code = doc.country_code.upper()
+
if not doc.get('state'):
return
@@ -307,4 +370,7 @@ def set_state_code(doc, method):
return
state_codes_lower = {key.lower():value for key,value in state_codes.items()}
- doc.state_code = state_codes_lower.get(doc.get('state','').lower())
+
+ state = doc.get('state','').lower()
+ if state_codes_lower.get(state):
+ doc.state_code = state_codes_lower.get(state)
diff --git a/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py b/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
index 5fbf7007f4c..6b8d3f0139e 100644
--- a/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
+++ b/erpnext/regional/report/fichier_des_ecritures_comptables_[fec]/fichier_des_ecritures_comptables_[fec].py
@@ -87,8 +87,8 @@ def get_gl_entries(filters):
left join `tabPurchase Invoice` pur on gl.voucher_no = pur.name
left join `tabJournal Entry` jnl on gl.voucher_no = jnl.name
left join `tabPayment Entry` pay on gl.voucher_no = pay.name
- left join `tabCustomer` cus on gl.party = cus.customer_name
- left join `tabSupplier` sup on gl.party = sup.supplier_name
+ left join `tabCustomer` cus on gl.party = cus.name
+ left join `tabSupplier` sup on gl.party = sup.name
where gl.company=%(company)s and gl.fiscal_year=%(fiscal_year)s
{group_by_condition}
order by GlPostDate, voucher_no"""\
diff --git a/erpnext/regional/report/gstr_1/gstr_1.py b/erpnext/regional/report/gstr_1/gstr_1.py
index 0c7d066216a..514ebd8c77e 100644
--- a/erpnext/regional/report/gstr_1/gstr_1.py
+++ b/erpnext/regional/report/gstr_1/gstr_1.py
@@ -7,6 +7,7 @@ from frappe import _
from frappe.utils import flt, formatdate
from datetime import date
from six import iteritems
+from erpnext.regional.india.utils import get_gst_accounts
def execute(filters=None):
return Gstr1Report(filters).run()
@@ -38,11 +39,10 @@ class Gstr1Report(object):
shipping_bill_date,
reason_for_issuing_document
"""
- self.customer_type = "Company" if self.filters.get("type_of_business") == "B2B" else "Individual"
def run(self):
self.get_columns()
- self.get_gst_accounts()
+ self.gst_accounts = get_gst_accounts(self.filters.company)
self.get_invoice_data()
if self.invoices:
@@ -54,18 +54,50 @@ class Gstr1Report(object):
return self.columns, self.data
def get_data(self):
+
+ if self.filters.get("type_of_business") == "B2C Small":
+ self.get_b2cs_data()
+ else:
+ for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
+ invoice_details = self.invoices.get(inv)
+ for rate, items in items_based_on_rate.items():
+ row = 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")
+ row.append("C" if invoice_details.return_against else "R")
+
+ self.data.append(row)
+
+ def get_b2cs_data(self):
+ b2cs_output = {}
+
for inv, items_based_on_rate in self.items_based_on_tax_rate.items():
invoice_details = self.invoices.get(inv)
+
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") == "B2C Small":
- row.append("E" if invoice_details.ecommerce_gstin else "OE")
+ place_of_supply = invoice_details.get("place_of_supply")
+ ecommerce_gstin = invoice_details.get("ecommerce_gstin")
- if self.filters.get("type_of_business") == "CDNR":
- row.append("Y" if invoice_details.posting_date <= date(2017, 7, 1) else "N")
- row.append("C" if invoice_details.return_against else "R")
+ b2cs_output.setdefault((rate, place_of_supply, ecommerce_gstin),{
+ "place_of_supply": "",
+ "ecommerce_gstin": "",
+ "rate": "",
+ "taxable_value": 0,
+ "cess_amount": 0,
+ "type": 0
+ })
- self.data.append(row)
+ row = b2cs_output.get((rate, place_of_supply, ecommerce_gstin))
+ row["place_of_supply"] = place_of_supply
+ row["ecommerce_gstin"] = ecommerce_gstin
+ row["rate"] = rate
+ row["taxable_value"] += sum([abs(net_amount)
+ for item_code, net_amount in self.invoice_items.get(inv).items() if item_code in items])
+ row["type"] = "E" if ecommerce_gstin else "OE"
+
+ for key, value in iteritems(b2cs_output):
+ self.data.append(value)
def get_row_data_for_invoice(self, invoice, invoice_details, tax_rate, items):
row = []
@@ -86,7 +118,7 @@ class Gstr1Report(object):
for item_code, net_amount in self.invoice_items.get(invoice).items() if item_code in items])
row += [tax_rate or 0, taxable_value]
- return row, taxable_value
+ return row
def get_invoice_data(self):
self.invoices = frappe._dict()
@@ -113,7 +145,7 @@ class Gstr1Report(object):
if self.filters.get(opts[0]):
conditions += opts[1]
- customers = frappe.get_all("Customer", filters={"customer_type": self.customer_type})
+ customers = frappe.get_all("Customer", filters={"disabled": 0})
if self.filters.get("type_of_business") == "B2B":
conditions += """ and ifnull(invoice_type, '') != 'Export' and is_return != 1
@@ -208,19 +240,6 @@ class Gstr1Report(object):
and frappe.db.get_value(self.doctype, invoice, "export_type") == "Without Payment of Tax":
self.items_based_on_tax_rate.setdefault(invoice, {}).setdefault(0, items.keys())
- def get_gst_accounts(self):
- self.gst_accounts = frappe._dict()
- gst_settings_accounts = frappe.get_all("GST Account",
- filters={"parent": "GST Settings", "company": self.filters.company},
- fields=["cgst_account", "sgst_account", "igst_account", "cess_account"])
-
- if not gst_settings_accounts:
- frappe.throw(_("Please set GST Accounts in GST Settings"))
-
- for d in gst_settings_accounts:
- for acc, val in d.items():
- self.gst_accounts.setdefault(acc, []).append(val)
-
def get_columns(self):
self.tax_columns = [
{
diff --git a/erpnext/regional/united_arab_emirates/setup.py b/erpnext/regional/united_arab_emirates/setup.py
index 3c8328b1074..250659e54da 100644
--- a/erpnext/regional/united_arab_emirates/setup.py
+++ b/erpnext/regional/united_arab_emirates/setup.py
@@ -28,24 +28,24 @@ def make_custom_fields():
purchase_invoice_fields = [
dict(fieldname='company_trn', label='Company TRN',
fieldtype='Read Only', insert_after='shipping_address',
- options='company.tax_id', print_hide=1),
+ fetch_from='company.tax_id', print_hide=1),
dict(fieldname='supplier_name_in_arabic', label='Supplier Name in Arabic',
fieldtype='Read Only', insert_after='supplier_name',
- options='supplier.supplier_name_in_arabic', print_hide=1)
+ fetch_from='supplier.supplier_name_in_arabic', print_hide=1)
]
sales_invoice_fields = [
dict(fieldname='company_trn', label='Company TRN',
fieldtype='Read Only', insert_after='company_address',
- options='company.tax_id', print_hide=1),
+ fetch_from='company.tax_id', print_hide=1),
dict(fieldname='customer_name_in_arabic', label='Customer Name in Arabic',
fieldtype='Read Only', insert_after='customer_name',
- options='customer.customer_name_in_arabic', print_hide=1),
+ fetch_from='customer.customer_name_in_arabic', print_hide=1),
]
invoice_item_fields = [
dict(fieldname='tax_code', label='Tax Code',
- fieldtype='Read Only', options='item_code.tax_code', insert_after='description',
+ fieldtype='Read Only', fetch_from='item_code.tax_code', insert_after='description',
allow_on_submit=1, print_hide=1),
dict(fieldname='tax_rate', label='Tax Rate',
fieldtype='Float', insert_after='tax_code',
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index 3b0e75ff6ca..89811656eed 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -123,5 +123,11 @@ frappe.ui.form.on("Customer", {
},
validate: function(frm) {
if(frm.doc.lead_name) frappe.model.clear_doc("Lead", frm.doc.lead_name);
+
+ var total = 0;
+ for (var idx in frm.doc.sales_team) {
+ total += frm.doc.sales_team[idx].allocated_percentage;
+ if (total > 100) frappe.throw(__("Total contribution percentage can't exceed 100"));
+ }
},
});
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 2970d7a5e82..f815e5f97cb 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -104,10 +104,6 @@ class Customer(TransactionBase):
if self.lead_name:
frappe.db.set_value('Lead', self.lead_name, 'status', 'Converted', update_modified=False)
- for doctype in ('Opportunity', 'Quotation'):
- for d in frappe.get_all(doctype, {'lead': self.lead_name}):
- frappe.db.set_value(doctype, d.name, 'customer', self.name, update_modified=False)
-
def create_lead_address_contact(self):
if self.lead_name:
# assign lead address to customer (if already not set)
diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py
index f2f430a61e2..6d6c86fbefd 100644
--- a/erpnext/selling/doctype/customer/customer_dashboard.py
+++ b/erpnext/selling/doctype/customer/customer_dashboard.py
@@ -6,6 +6,10 @@ def get_data():
'heatmap': True,
'heatmap_message': _('This is based on transactions against this Customer. See timeline below for details'),
'fieldname': 'customer',
+ 'non_standard_fieldnames': {
+ 'Quotation': 'party_name',
+ 'Opportunity': 'party_name'
+ },
'transactions': [
{
'label': _('Pre Sales'),
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index 6f7bfb3febf..397c853097b 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -8,15 +8,27 @@ frappe.ui.form.on('Quotation', {
setup: function(frm) {
frm.custom_make_buttons = {
'Sales Order': 'Make Sales Order'
- }
+ },
+
+ frm.set_query("quotation_to", function() {
+ return{
+ "filters": {
+ "name": ["in", ["Customer", "Lead"]],
+ }
+ }
+ });
+
},
refresh: function(frm) {
frm.trigger("set_label");
+ frm.trigger("set_dynamic_field_label");
},
quotation_to: function(frm) {
frm.trigger("set_label");
+ frm.trigger("toggle_reqd_lead_customer");
+ frm.trigger("set_dynamic_field_label");
},
set_label: function(frm) {
@@ -28,10 +40,6 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
onload: function(doc, dt, dn) {
var me = this;
this._super(doc, dt, dn);
- if(doc.customer && !doc.quotation_to)
- doc.quotation_to = "Customer";
- else if(doc.lead && !doc.quotation_to)
- doc.quotation_to = "Lead";
},
refresh: function(doc, dt, dn) {
@@ -97,33 +105,46 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
},
- quotation_to: function() {
- var me = this;
- if (this.frm.doc.quotation_to == "Lead") {
- this.frm.set_value("customer", null);
- this.frm.set_value("contact_person", null);
- } else if (this.frm.doc.quotation_to == "Customer") {
- this.frm.set_value("lead", null);
+ set_dynamic_field_label: function(){
+ if (this.frm.doc.quotation_to == "Customer")
+ {
+ this.frm.set_df_property("party_name", "label", "Customer");
+ this.frm.fields_dict.party_name.get_query = null;
}
- this.toggle_reqd_lead_customer();
+ if (this.frm.doc.quotation_to == "Lead")
+ {
+ this.frm.set_df_property("party_name", "label", "Lead");
+
+ this.frm.fields_dict.party_name.get_query = function() {
+ return{ query: "erpnext.controllers.queries.lead_query" }
+ }
+ }
},
toggle_reqd_lead_customer: function() {
var me = this;
- this.frm.toggle_reqd("lead", this.frm.doc.quotation_to == "Lead");
- this.frm.toggle_reqd("customer", this.frm.doc.quotation_to == "Customer");
-
// to overwrite the customer_filter trigger from queries.js
- this.frm.set_query('customer_address', erpnext.queries.address_query);
- this.frm.set_query('shipping_address_name', erpnext.queries.address_query);
+ this.frm.toggle_reqd("party_name", this.frm.doc.quotation_to);
+ this.frm.set_query('customer_address', this.address_query);
+ this.frm.set_query('shipping_address_name', this.address_query);
},
tc_name: function() {
this.get_terms();
},
+ address_query: function(doc) {
+ return {
+ query: 'frappe.contacts.doctype.address.address.address_query',
+ filters: {
+ link_doctype: frappe.dynamic_link.doctype,
+ link_name: doc.party_name
+ }
+ };
+ },
+
validate_company_and_party: function(party_field) {
if(!this.frm.doc.quotation_to) {
frappe.msgprint(__("Please select a value for {0} quotation_to {1}", [this.frm.doc.doctype, this.frm.doc.name]));
@@ -163,10 +184,6 @@ erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
cur_frm.script_manager.make(erpnext.selling.QuotationController);
-cur_frm.fields_dict.lead.get_query = function(doc,cdt,cdn) {
- return{ query: "erpnext.controllers.queries.lead_query" }
-}
-
cur_frm.cscript['Make Sales Order'] = function() {
frappe.model.open_mapped_doc({
method: "erpnext.selling.doctype.quotation.quotation.make_sales_order",
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index 6cc09933e8e..abafbbf6a16 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -20,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -53,6 +54,7 @@
"collapsible": 0,
"columns": 0,
"default": "{customer_name}",
+ "fetch_if_empty": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
@@ -86,6 +88,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -121,8 +124,9 @@
"collapsible": 0,
"columns": 0,
"default": "Customer",
+ "fetch_if_empty": 0,
"fieldname": "quotation_to",
- "fieldtype": "Select",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -135,7 +139,7 @@
"no_copy": 0,
"oldfieldname": "quotation_to",
"oldfieldtype": "Select",
- "options": "\nLead\nCustomer",
+ "options": "DocType",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@@ -155,9 +159,10 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.quotation_to == \"Customer\"",
- "fieldname": "customer",
- "fieldtype": "Link",
+ "depends_on": "",
+ "fetch_if_empty": 0,
+ "fieldname": "party_name",
+ "fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -165,12 +170,12 @@
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 1,
- "label": "Customer",
+ "label": "Customer/Lead",
"length": 0,
"no_copy": 0,
"oldfieldname": "customer",
"oldfieldtype": "Link",
- "options": "Customer",
+ "options": "quotation_to",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@@ -190,42 +195,8 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.quotation_to == \"Lead\"",
- "fieldname": "lead",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Lead",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "lead",
- "oldfieldtype": "Link",
- "options": "Lead",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "customer.customer_name",
+ "fetch_from": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 1,
@@ -258,6 +229,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -290,6 +262,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
@@ -326,6 +299,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -362,6 +336,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
+ "fetch_if_empty": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 0,
@@ -396,6 +371,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "valid_till",
"fieldtype": "Date",
"hidden": 0,
@@ -429,6 +405,7 @@
"collapsible": 0,
"columns": 0,
"default": "Sales",
+ "fetch_if_empty": 0,
"fieldname": "order_type",
"fieldtype": "Select",
"hidden": 0,
@@ -464,7 +441,8 @@
"collapsible": 1,
"collapsible_depends_on": "",
"columns": 0,
- "depends_on": "eval:(doc.customer || doc.lead)",
+ "depends_on": "eval:doc.party_name",
+ "fetch_if_empty": 0,
"fieldname": "contact_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -497,6 +475,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_address",
"fieldtype": "Link",
"hidden": 0,
@@ -529,6 +508,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -562,7 +542,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "eval:doc.customer",
+ "depends_on": "eval:doc.quotaion_to=='Customer' && doc.party_name",
+ "fetch_if_empty": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -597,6 +578,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -628,6 +610,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@@ -659,6 +642,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_email",
"fieldtype": "Data",
"hidden": 1,
@@ -692,6 +676,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "customer",
+ "fetch_if_empty": 0,
"fieldname": "col_break98",
"fieldtype": "Column Break",
"hidden": 0,
@@ -723,6 +708,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_address_name",
"fieldtype": "Link",
"hidden": 0,
@@ -755,6 +741,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_address",
"fieldtype": "Small Text",
"hidden": 0,
@@ -788,6 +775,7 @@
"columns": 0,
"depends_on": "customer",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_group",
"fieldtype": "Link",
"hidden": 1,
@@ -823,6 +811,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
@@ -855,6 +844,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -887,6 +877,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -923,6 +914,7 @@
"collapsible": 0,
"columns": 0,
"description": "Rate at which customer's currency is converted to company's base currency",
+ "fetch_if_empty": 0,
"fieldname": "conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -958,6 +950,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -989,6 +982,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "selling_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -1024,6 +1018,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "price_list_currency",
"fieldtype": "Link",
"hidden": 0,
@@ -1057,6 +1052,7 @@
"collapsible": 0,
"columns": 0,
"description": "Rate at which Price list currency is converted to company's base currency",
+ "fetch_if_empty": 0,
"fieldname": "plc_conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -1089,6 +1085,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
@@ -1120,6 +1117,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1153,6 +1151,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -1188,6 +1187,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sec_break23",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1218,6 +1218,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -1250,6 +1251,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1283,6 +1285,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1318,6 +1321,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_28",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1348,6 +1352,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1381,6 +1386,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1413,6 +1419,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_net_weight",
"fieldtype": "Float",
"hidden": 0,
@@ -1445,6 +1452,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1478,6 +1486,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
@@ -1512,6 +1521,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_34",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1542,6 +1552,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_rule",
"fieldtype": "Link",
"hidden": 0,
@@ -1575,6 +1586,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_36",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1605,6 +1617,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@@ -1639,6 +1652,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sec_tax_breakup",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1671,6 +1685,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Text",
"hidden": 0,
@@ -1703,6 +1718,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_39",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1733,6 +1749,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -1767,6 +1784,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_42",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1797,6 +1815,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -1830,6 +1849,7 @@
"collapsible": 1,
"collapsible_depends_on": "discount_amount",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_44",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1863,6 +1883,7 @@
"collapsible": 0,
"columns": 0,
"default": "Grand Total",
+ "fetch_if_empty": 0,
"fieldname": "apply_discount_on",
"fieldtype": "Select",
"hidden": 0,
@@ -1896,6 +1917,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1929,6 +1951,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_46",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1960,6 +1983,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "additional_discount_percentage",
"fieldtype": "Float",
"hidden": 0,
@@ -1992,6 +2016,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -2024,6 +2049,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "totals",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2057,6 +2083,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2092,6 +2119,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2126,6 +2154,7 @@
"collapsible": 0,
"columns": 0,
"description": "In Words will be visible once you save the Quotation.",
+ "fetch_if_empty": 0,
"fieldname": "base_in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2160,6 +2189,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2195,6 +2225,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2227,6 +2258,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2262,6 +2294,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2295,6 +2328,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2330,6 +2364,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2366,6 +2401,7 @@
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "payment_schedule_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2398,6 +2434,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_terms_template",
"fieldtype": "Link",
"hidden": 0,
@@ -2431,6 +2468,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_schedule",
"fieldtype": "Table",
"hidden": 0,
@@ -2465,6 +2503,7 @@
"collapsible": 1,
"collapsible_depends_on": "terms",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2498,6 +2537,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@@ -2532,6 +2572,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -2565,6 +2606,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "print_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2597,6 +2639,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -2631,6 +2674,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "group_same_items",
"fieldtype": "Check",
"hidden": 0,
@@ -2663,6 +2707,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_73",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2694,6 +2739,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -2728,6 +2774,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
@@ -2760,6 +2807,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2792,6 +2840,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "auto_repeat",
"fieldtype": "Link",
"hidden": 0,
@@ -2826,6 +2875,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.auto_repeat",
+ "fetch_if_empty": 0,
"fieldname": "update_auto_repeat_reference",
"fieldtype": "Button",
"hidden": 0,
@@ -2858,6 +2908,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2891,6 +2942,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
@@ -2925,6 +2977,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "source",
"fieldtype": "Link",
"hidden": 0,
@@ -2960,6 +3013,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.status===\"Lost\"",
+ "fetch_if_empty": 0,
"fieldname": "order_lost_reason",
"fieldtype": "Small Text",
"hidden": 0,
@@ -2993,6 +3047,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3026,6 +3081,7 @@
"collapsible": 0,
"columns": 0,
"default": "Draft",
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -3060,6 +3116,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "enq_det",
"fieldtype": "Text",
"hidden": 1,
@@ -3093,6 +3150,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "supplier_quotation",
"fieldtype": "Link",
"hidden": 0,
@@ -3126,6 +3184,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "opportunity",
"fieldtype": "Link",
"hidden": 0,
@@ -3165,7 +3224,7 @@
"istable": 0,
"max_attachments": 1,
"menu_index": 0,
- "modified": "2019-01-07 16:51:55.604845",
+ "modified": "2019-05-02 15:16:37.394455",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",
@@ -3331,11 +3390,11 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 1,
- "search_fields": "status,transaction_date,customer,lead,order_type",
+ "search_fields": "status,transaction_date,party_name,order_type",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
- "timeline_field": "customer",
+ "timeline_field": "party_name",
"title_field": "title",
"track_changes": 0,
"track_seen": 0,
diff --git a/erpnext/selling/doctype/quotation/quotation.py b/erpnext/selling/doctype/quotation/quotation.py
index 729256068be..3ba8adc3c8e 100644
--- a/erpnext/selling/doctype/quotation/quotation.py
+++ b/erpnext/selling/doctype/quotation/quotation.py
@@ -28,11 +28,11 @@ class Quotation(SellingController):
self.update_opportunity()
self.validate_order_type()
self.validate_uom_is_integer("stock_uom", "qty")
- self.validate_quotation_to()
self.validate_valid_till()
+ self.set_customer_name()
if self.items:
self.with_items = 1
-
+
def validate_valid_till(self):
if self.valid_till and self.valid_till < self.transaction_date:
frappe.throw(_("Valid till date cannot be before transaction date"))
@@ -43,16 +43,16 @@ class Quotation(SellingController):
def validate_order_type(self):
super(Quotation, self).validate_order_type()
- def validate_quotation_to(self):
- if self.customer:
- self.quotation_to = "Customer"
- self.lead = None
- elif self.lead:
- self.quotation_to = "Lead"
-
def update_lead(self):
- if self.lead:
- frappe.get_doc("Lead", self.lead).set_status(update=True)
+ if self.quotation_to == "Lead" and self.party_name:
+ frappe.get_doc("Lead", self.party_name).set_status(update=True)
+
+ def set_customer_name(self):
+ if self.party_name and self.quotation_to == 'Customer':
+ self.customer_name = frappe.db.get_value("Customer", self.party_name, "customer_name")
+ elif self.party_name and self.quotation_to == 'Lead':
+ lead_name, company_name = frappe.db.get_value("Lead", self.party_name, ["lead_name", "company_name"])
+ self.customer_name = company_name or lead_name
def update_opportunity(self):
for opportunity in list(set([d.prevdoc_docname for d in self.get("items")])):
@@ -209,12 +209,12 @@ def _make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
}
}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)
- return doclist
+ return doclist
def _make_customer(source_name, ignore_permissions=False):
- quotation = frappe.db.get_value("Quotation", source_name, ["lead", "order_type", "customer"])
- if quotation and quotation[0] and not quotation[2]:
- lead_name = quotation[0]
+ quotation = frappe.db.get_value("Quotation", source_name, ["order_type", "party_name", "customer_name"])
+ if quotation and quotation[1] and not quotation[2]:
+ lead_name = quotation[1]
customer_name = frappe.db.get_value("Customer", {"lead_name": lead_name},
["name", "customer_name"], as_dict=True)
if not customer_name:
@@ -242,3 +242,5 @@ def _make_customer(source_name, ignore_permissions=False):
frappe.throw(_("Please create Customer from Lead {0}").format(lead_name))
else:
return customer_name
+ else:
+ return frappe.get_doc("Customer",quotation[2])
diff --git a/erpnext/selling/doctype/quotation/test_quotation.py b/erpnext/selling/doctype/quotation/test_quotation.py
index 78fb0c14042..8bb8c618f29 100644
--- a/erpnext/selling/doctype/quotation/test_quotation.py
+++ b/erpnext/selling/doctype/quotation/test_quotation.py
@@ -203,15 +203,15 @@ class TestQuotation(unittest.TestCase):
test_records = frappe.get_test_records('Quotation')
-def get_quotation_dict(customer=None, item_code=None):
- if not customer:
- customer = '_Test Customer'
+def get_quotation_dict(party_name=None, item_code=None):
+ if not party_name:
+ party_name = '_Test Customer'
if not item_code:
item_code = '_Test Item'
return {
'doctype': 'Quotation',
- 'customer': customer,
+ 'party_name': party_name,
'items': [
{
'item_code': item_code,
@@ -229,7 +229,7 @@ def make_quotation(**args):
qo.transaction_date = args.transaction_date
qo.company = args.company or "_Test Company"
- qo.customer = args.customer or "_Test Customer"
+ qo.party_name = args.party_name or "_Test Customer"
qo.currency = args.currency or "INR"
if args.selling_price_list:
qo.selling_price_list = args.selling_price_list
diff --git a/erpnext/selling/doctype/quotation/test_records.json b/erpnext/selling/doctype/quotation/test_records.json
index 7a9d3eb1e25..1564f7de0ce 100644
--- a/erpnext/selling/doctype/quotation/test_records.json
+++ b/erpnext/selling/doctype/quotation/test_records.json
@@ -1,37 +1,37 @@
[
- {
- "company": "_Test Company",
- "conversion_rate": 1.0,
- "currency": "INR",
- "customer": "_Test Customer",
- "customer_group": "_Test Customer Group",
- "customer_name": "_Test Customer",
- "doctype": "Quotation",
- "base_grand_total": 1000.0,
- "grand_total": 1000.0,
- "order_type": "Sales",
- "plc_conversion_rate": 1.0,
- "price_list_currency": "INR",
- "items": [
- {
- "base_amount": 1000.0,
- "base_rate": 100.0,
- "description": "CPU",
- "doctype": "Quotation Item",
- "item_code": "_Test Item Home Desktop 100",
- "item_name": "CPU",
- "parentfield": "items",
- "qty": 10.0,
- "rate": 100.0,
- "uom": "_Test UOM 1",
- "stock_uom": "_Test UOM 1",
- "conversion_factor": 1.0
- }
- ],
- "quotation_to": "Customer",
- "selling_price_list": "_Test Price List",
- "territory": "_Test Territory",
- "transaction_date": "2013-02-21",
- "valid_till": "2013-03-21"
- }
+ {
+ "company": "_Test Company",
+ "conversion_rate": 1.0,
+ "currency": "INR",
+ "party_name": "_Test Customer",
+ "customer_group": "_Test Customer Group",
+ "customer_name": "_Test Customer",
+ "doctype": "Quotation",
+ "base_grand_total": 1000.0,
+ "grand_total": 1000.0,
+ "order_type": "Sales",
+ "plc_conversion_rate": 1.0,
+ "price_list_currency": "INR",
+ "items": [
+ {
+ "base_amount": 1000.0,
+ "base_rate": 100.0,
+ "description": "CPU",
+ "doctype": "Quotation Item",
+ "item_code": "_Test Item Home Desktop 100",
+ "item_name": "CPU",
+ "parentfield": "items",
+ "qty": 10.0,
+ "rate": 100.0,
+ "uom": "_Test UOM 1",
+ "stock_uom": "_Test UOM 1",
+ "conversion_factor": 1.0
+ }
+ ],
+ "quotation_to": "Customer",
+ "selling_price_list": "_Test Price List",
+ "territory": "_Test Territory",
+ "transaction_date": "2013-02-21",
+ "valid_till": "2013-03-21"
+ }
]
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index b916505a0f0..3dba26238c2 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -21,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -53,6 +54,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -86,6 +88,7 @@
"collapsible": 0,
"columns": 0,
"default": "{customer_name}",
+ "fetch_if_empty": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 1,
@@ -119,6 +122,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -153,6 +157,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer",
"fieldtype": "Link",
"hidden": 0,
@@ -188,6 +193,7 @@
"collapsible": 0,
"columns": 0,
"fetch_from": "customer.customer_name",
+ "fetch_if_empty": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 0,
@@ -222,6 +228,7 @@
"columns": 0,
"default": "Sales",
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "order_type",
"fieldtype": "Select",
"hidden": 0,
@@ -256,6 +263,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -288,6 +296,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 1,
@@ -324,6 +333,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -360,6 +370,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
+ "fetch_if_empty": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 0,
@@ -394,6 +405,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "delivery_date",
"fieldtype": "Date",
"hidden": 0,
@@ -428,6 +440,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "po_no",
"fieldtype": "Data",
"hidden": 0,
@@ -464,6 +477,7 @@
"columns": 0,
"depends_on": "eval:doc.po_no",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "po_date",
"fieldtype": "Date",
"hidden": 0,
@@ -498,6 +512,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "tax_id",
"fieldtype": "Data",
"hidden": 0,
@@ -533,6 +548,7 @@
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "customer",
+ "fetch_if_empty": 0,
"fieldname": "contact_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -565,6 +581,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_address",
"fieldtype": "Link",
"hidden": 0,
@@ -597,6 +614,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "address_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -628,6 +646,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_person",
"fieldtype": "Link",
"hidden": 0,
@@ -660,6 +679,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_display",
"fieldtype": "Small Text",
"hidden": 0,
@@ -691,6 +711,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_mobile",
"fieldtype": "Small Text",
"hidden": 0,
@@ -722,6 +743,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact_email",
"fieldtype": "Data",
"hidden": 1,
@@ -754,38 +776,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "company_address_display",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company_address",
"fieldtype": "Link",
"hidden": 0,
@@ -795,7 +786,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Company Address",
+ "label": "Company Address Name",
"length": 0,
"no_copy": 0,
"options": "Address",
@@ -819,6 +810,40 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "company_address_display",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Company Address",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "col_break46",
"fieldtype": "Column Break",
"hidden": 0,
@@ -850,6 +875,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_address_name",
"fieldtype": "Link",
"hidden": 0,
@@ -882,6 +908,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_address",
"fieldtype": "Small Text",
"hidden": 0,
@@ -914,6 +941,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_group",
"fieldtype": "Link",
"hidden": 1,
@@ -947,6 +975,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "territory",
"fieldtype": "Link",
"hidden": 0,
@@ -979,6 +1008,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency_and_price_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1011,6 +1041,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "currency",
"fieldtype": "Link",
"hidden": 0,
@@ -1047,6 +1078,7 @@
"collapsible": 0,
"columns": 0,
"description": "Rate at which customer's currency is converted to company's base currency",
+ "fetch_if_empty": 0,
"fieldname": "conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -1082,6 +1114,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1113,6 +1146,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "selling_price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -1148,6 +1182,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "price_list_currency",
"fieldtype": "Link",
"hidden": 0,
@@ -1181,6 +1216,7 @@
"collapsible": 0,
"columns": 0,
"description": "Rate at which Price list currency is converted to company's base currency",
+ "fetch_if_empty": 0,
"fieldname": "plc_conversion_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -1214,6 +1250,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
@@ -1245,6 +1282,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sec_warehouse",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1276,6 +1314,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "set_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -1309,6 +1348,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1342,6 +1382,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "scan_barcode",
"fieldtype": "Data",
"hidden": 0,
@@ -1374,6 +1415,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "items",
"fieldtype": "Table",
"hidden": 0,
@@ -1408,6 +1450,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_31",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1438,6 +1481,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_33a",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1468,6 +1512,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -1500,6 +1545,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1533,6 +1579,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1568,6 +1615,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_33",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1598,6 +1646,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1631,6 +1680,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "net_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -1663,6 +1713,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_net_weight",
"fieldtype": "Float",
"hidden": 0,
@@ -1695,6 +1746,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1728,6 +1780,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes_and_charges",
"fieldtype": "Link",
"hidden": 0,
@@ -1762,6 +1815,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_38",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1792,6 +1846,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shipping_rule",
"fieldtype": "Link",
"hidden": 0,
@@ -1825,6 +1880,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_40",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1855,6 +1911,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@@ -1889,6 +1946,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sec_tax_breakup",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1921,6 +1979,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "other_charges_calculation",
"fieldtype": "Text",
"hidden": 0,
@@ -1953,6 +2012,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_43",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1983,6 +2043,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -2018,6 +2079,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_46",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2049,6 +2111,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_taxes_and_charges",
"fieldtype": "Currency",
"hidden": 0,
@@ -2081,6 +2144,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "loyalty_points_redemption",
"fieldtype": "Section Break",
"hidden": 1,
@@ -2113,6 +2177,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "loyalty_points",
"fieldtype": "Int",
"hidden": 1,
@@ -2145,6 +2210,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "loyalty_amount",
"fieldtype": "Currency",
"hidden": 1,
@@ -2178,6 +2244,7 @@
"collapsible": 1,
"collapsible_depends_on": "discount_amount",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_48",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2211,6 +2278,7 @@
"collapsible": 0,
"columns": 0,
"default": "Grand Total",
+ "fetch_if_empty": 0,
"fieldname": "apply_discount_on",
"fieldtype": "Select",
"hidden": 0,
@@ -2244,6 +2312,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -2277,6 +2346,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_50",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2308,6 +2378,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "additional_discount_percentage",
"fieldtype": "Float",
"hidden": 0,
@@ -2341,6 +2412,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -2373,6 +2445,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "totals",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2406,6 +2479,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2441,6 +2515,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2474,6 +2549,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2510,6 +2586,7 @@
"collapsible": 0,
"columns": 0,
"description": "In Words will be visible once you save the Sales Order.",
+ "fetch_if_empty": 0,
"fieldname": "base_in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2544,6 +2621,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2576,6 +2654,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "grand_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2612,6 +2691,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "rounding_adjustment",
"fieldtype": "Currency",
"hidden": 0,
@@ -2645,6 +2725,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "rounded_total",
"fieldtype": "Currency",
"hidden": 0,
@@ -2680,6 +2761,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "in_words",
"fieldtype": "Data",
"hidden": 0,
@@ -2714,6 +2796,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "advance_paid",
"fieldtype": "Currency",
"hidden": 0,
@@ -2748,6 +2831,7 @@
"collapsible_depends_on": "packed_items",
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "packing_list",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2781,6 +2865,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "packed_items",
"fieldtype": "Table",
"hidden": 0,
@@ -2815,6 +2900,7 @@
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_schedule_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2847,6 +2933,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_terms_template",
"fieldtype": "Link",
"hidden": 0,
@@ -2880,6 +2967,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_schedule",
"fieldtype": "Table",
"hidden": 0,
@@ -2914,6 +3002,7 @@
"collapsible": 1,
"collapsible_depends_on": "terms",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "terms_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2947,6 +3036,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "tc_name",
"fieldtype": "Link",
"hidden": 0,
@@ -2981,6 +3071,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "terms",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -3015,6 +3106,7 @@
"collapsible": 1,
"collapsible_depends_on": "project",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "more_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3049,6 +3141,7 @@
"collapsible": 0,
"columns": 0,
"description": "Track this Sales Order against any Project",
+ "fetch_if_empty": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -3083,6 +3176,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "party_account_currency",
"fieldtype": "Link",
"hidden": 1,
@@ -3116,6 +3210,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_77",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3147,6 +3242,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "source",
"fieldtype": "Link",
"hidden": 0,
@@ -3182,6 +3278,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
@@ -3216,6 +3313,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "printing_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3248,6 +3346,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "language",
"fieldtype": "Data",
"hidden": 0,
@@ -3280,6 +3379,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
@@ -3314,6 +3414,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3346,6 +3447,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "select_print_heading",
"fieldtype": "Link",
"hidden": 0,
@@ -3380,6 +3482,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "group_same_items",
"fieldtype": "Check",
"hidden": 0,
@@ -3412,6 +3515,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_78",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3446,6 +3550,7 @@
"collapsible": 0,
"columns": 0,
"default": "Draft",
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -3481,6 +3586,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "delivery_status",
"fieldtype": "Select",
"hidden": 1,
@@ -3515,6 +3621,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "% of materials delivered against this Sales Order",
+ "fetch_if_empty": 0,
"fieldname": "per_delivered",
"fieldtype": "Percent",
"hidden": 0,
@@ -3549,6 +3656,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_81",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3581,6 +3689,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "% of materials billed against this Sales Order",
+ "fetch_if_empty": 0,
"fieldname": "per_billed",
"fieldtype": "Percent",
"hidden": 0,
@@ -3615,6 +3724,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "billing_status",
"fieldtype": "Select",
"hidden": 1,
@@ -3648,6 +3758,7 @@
"collapsible": 1,
"collapsible_depends_on": "commission_rate",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sales_team_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3681,6 +3792,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sales_partner",
"fieldtype": "Link",
"hidden": 0,
@@ -3716,6 +3828,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break7",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3747,6 +3860,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "commission_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -3781,6 +3895,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_commission",
"fieldtype": "Currency",
"hidden": 0,
@@ -3816,6 +3931,7 @@
"collapsible": 1,
"collapsible_depends_on": "sales_team",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break1",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3847,6 +3963,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sales_team",
"fieldtype": "Table",
"hidden": 0,
@@ -3881,6 +3998,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3915,6 +4033,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "from_date",
"fieldtype": "Date",
"hidden": 0,
@@ -3948,6 +4067,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "to_date",
"fieldtype": "Date",
"hidden": 0,
@@ -3979,6 +4099,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_108",
"fieldtype": "Column Break",
"hidden": 0,
@@ -4010,6 +4131,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "auto_repeat",
"fieldtype": "Link",
"hidden": 0,
@@ -4044,6 +4166,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.auto_repeat",
+ "fetch_if_empty": 0,
"fieldname": "update_auto_repeat_reference",
"fieldtype": "Button",
"hidden": 0,
@@ -4081,7 +4204,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2019-01-09 16:51:47.917329",
+ "modified": "2019-04-05 03:44:46.037178",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index b589cdeaa43..184c6bd70d6 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -202,9 +202,8 @@ class SalesOrder(SellingController):
if self.project:
project = frappe.get_doc("Project", self.project)
- project.flags.dont_sync_tasks = True
project.update_sales_amount()
- project.save()
+ project.db_update()
def check_credit_limit(self):
# if bypass credit limit check is set to true (1) at sales order level,
@@ -388,6 +387,7 @@ class SalesOrder(SellingController):
items.append(dict(
name= i.name,
item_code= i.item_code,
+ description= i.description,
bom = bom,
warehouse = i.warehouse,
pending_qty = pending_qty,
@@ -398,6 +398,7 @@ class SalesOrder(SellingController):
items.append(dict(
name= i.name,
item_code= i.item_code,
+ description= i.description,
bom = '',
warehouse = i.warehouse,
pending_qty = pending_qty,
@@ -543,7 +544,7 @@ def make_project(source_name, target_doc=None):
"Sales Order Item": {
"doctype": "Project Task",
"field_map": {
- "description": "title",
+ "item_code": "title",
},
}
}, target_doc, postprocess)
@@ -610,7 +611,8 @@ def make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
def postprocess(source, target):
set_missing_values(source, target)
#Get the advance paid Journal Entries in Sales Invoice Advance
- target.set_advances()
+ if target.get("allocate_advances_automatically"):
+ target.set_advances()
def set_missing_values(source, target):
target.is_pos = 0
@@ -901,7 +903,8 @@ def make_work_orders(items, sales_order, company, project=None):
sales_order=sales_order,
sales_order_item=i['sales_order_item'],
project=project,
- fg_warehouse=i['warehouse']
+ fg_warehouse=i['warehouse'],
+ description=i['description']
)).insert()
work_order.set_work_order_operations()
work_order.save()
diff --git a/erpnext/selling/doctype/sales_order/test_sales_order.py b/erpnext/selling/doctype/sales_order/test_sales_order.py
index 0eb19e3417c..f270938ad3a 100644
--- a/erpnext/selling/doctype/sales_order/test_sales_order.py
+++ b/erpnext/selling/doctype/sales_order/test_sales_order.py
@@ -573,7 +573,8 @@ class TestSalesOrder(unittest.TestCase):
"item_code": item.get("item_code"),
"pending_qty": item.get("pending_qty"),
"sales_order_item": item.get("sales_order_item"),
- "bom": item.get("bom")
+ "bom": item.get("bom"),
+ "description": item.get("description")
})
so_item_name[item.get("sales_order_item")]= item.get("pending_qty")
make_work_orders(json.dumps({"items":po_items}), so.name, so.company)
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 c54430fd560..3e6ee86df00 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -54,8 +54,16 @@ erpnext.pos.PointOfSale = class PointOfSale {
this.prepare_menu();
this.set_online_status();
},
- () => this.setup_company(),
() => this.make_new_invoice(),
+ () => {
+ if(!this.frm.doc.company) {
+ this.setup_company()
+ .then((company) => {
+ this.frm.doc.company = company;
+ this.get_pos_profile();
+ });
+ }
+ },
() => {
frappe.dom.unfreeze();
},
@@ -63,6 +71,22 @@ erpnext.pos.PointOfSale = class PointOfSale {
]);
}
+ get_pos_profile() {
+ return frappe.xcall("erpnext.stock.get_item_details.get_pos_profile",
+ {'company': this.frm.doc.company})
+ .then((r) => {
+ if(r) {
+ this.frm.doc.pos_profile = r.name;
+ this.set_pos_profile_data()
+ .then(() => {
+ this.on_change_pos_profile();
+ });
+ } else {
+ this.raise_exception_for_pos_profile();
+ }
+ });
+ }
+
set_online_status() {
this.connection_status = false;
this.page.set_indicator(__("Offline"), "grey");
@@ -77,6 +101,11 @@ erpnext.pos.PointOfSale = class PointOfSale {
});
}
+ raise_exception_for_pos_profile() {
+ setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
+ frappe.throw(__("POS Profile is required to use Point-of-Sale"));
+ }
+
prepare_dom() {
this.wrapper.append(`
@@ -446,16 +475,15 @@ erpnext.pos.PointOfSale = class PointOfSale {
}
setup_company() {
- this.company = frappe.sys_defaults.company;
return new Promise(resolve => {
- if(!this.company) {
+ if(!this.frm.doc.company) {
frappe.prompt({fieldname:"company", options: "Company", fieldtype:"Link",
label: __("Select Company"), reqd: 1}, (data) => {
this.company = data.company;
resolve(this.company);
}, __("Select Company"));
} else {
- resolve(this.company);
+ resolve();
}
})
}
@@ -488,6 +516,10 @@ erpnext.pos.PointOfSale = class PointOfSale {
return new Promise(resolve => {
if (this.frm) {
this.frm = get_frm(this.frm);
+ if(this.company) {
+ this.frm.doc.company = this.company;
+ }
+
resolve();
} else {
frappe.model.with_doctype(doctype, () => {
@@ -504,12 +536,19 @@ erpnext.pos.PointOfSale = class PointOfSale {
frm.refresh(name);
frm.doc.items = [];
frm.doc.is_pos = 1;
+
return frm;
}
}
set_pos_profile_data() {
- this.frm.doc.company = this.company;
+ if (this.company) {
+ this.frm.doc.company = this.company;
+ }
+
+ if (!this.frm.doc.company) {
+ return;
+ }
return new Promise(resolve => {
return this.frm.call({
@@ -519,8 +558,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
if(!r.exc) {
if (!this.frm.doc.pos_profile) {
frappe.dom.unfreeze();
- setTimeout(() => frappe.set_route('List', 'POS Profile'), 2000);
- frappe.throw(__("POS Profile is required to use Point-of-Sale"));
+ this.raise_exception_for_pos_profile();
}
this.frm.script_manager.trigger("update_stock");
frappe.model.set_default_values(this.frm.doc);
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.py b/erpnext/selling/page/point_of_sale/point_of_sale.py
index 56d91518d8c..e088679917b 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.py
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.py
@@ -39,7 +39,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
if display_items_in_stock == 0:
- res = frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image,
+ res = frappe.db.sql("""select i.name as item_code, i.item_name, i.image as item_image, i.idx as idx,
i.is_stock_item, item_det.price_list_rate, item_det.currency
from `tabItem` i LEFT JOIN
(select item_code, price_list_rate, currency from
@@ -49,7 +49,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
where
i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
and i.item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt})
- and {condition} limit {start}, {page_length}""".format(start=start,page_length=page_length,lft=lft, rgt=rgt, condition=condition),
+ and {condition} order by idx desc limit {start}, {page_length}""".format(start=start,page_length=page_length,lft=lft, rgt=rgt, condition=condition),
{
'item_code': item_code,
'price_list': price_list
@@ -60,7 +60,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
}
elif display_items_in_stock == 1:
- query = """select i.name as item_code, i.item_name, i.image as item_image,
+ query = """select i.name as item_code, i.item_name, i.image as item_image, i.idx as idx,
i.is_stock_item, item_det.price_list_rate, item_det.currency
from `tabItem` i LEFT JOIN
(select item_code, price_list_rate, currency from
@@ -79,7 +79,7 @@ def get_items(start, page_length, price_list, item_group, search_value="", pos_p
where
i.disabled = 0 and i.has_variants = 0 and i.is_sales_item = 1
and i.item_group in (select name from `tabItem Group` where lft >= {lft} and rgt <= {rgt})
- and {condition} limit {start}, {page_length}""".format
+ and {condition} order by idx desc limit {start}, {page_length}""".format
(start=start,page_length=page_length,lft=lft, rgt=rgt, condition=condition),
{
'item_code': item_code,
diff --git a/erpnext/selling/report/address_and_contacts/address_and_contacts.py b/erpnext/selling/report/address_and_contacts/address_and_contacts.py
index eb242d0a737..a9e43034b48 100644
--- a/erpnext/selling/report/address_and_contacts/address_and_contacts.py
+++ b/erpnext/selling/report/address_and_contacts/address_and_contacts.py
@@ -102,8 +102,7 @@ def get_party_details(party_type, party_list, doctype, party_details):
records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True)
for d in records:
details = party_details.get(d[0])
- if details:
- details.setdefault(frappe.scrub(doctype), []).append(d[1:])
+ details.setdefault(frappe.scrub(doctype), []).append(d[1:])
return party_details
diff --git a/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py b/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py
index 1e45a736735..48494247595 100644
--- a/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py
+++ b/erpnext/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py
@@ -12,7 +12,7 @@ def execute(filters=None):
iwq_map = get_item_warehouse_quantity_map()
item_map = get_item_details()
- data = []
+ data = []
for sbom, warehouse in iwq_map.items():
total = 0
total_qty = 0
@@ -21,7 +21,7 @@ def execute(filters=None):
total += 1
row = [sbom, item_map.get(sbom).item_name, item_map.get(sbom).description,
item_map.get(sbom).stock_uom, wh]
- available_qty = min(item_qty.values())
+ available_qty = item_qty
total_qty += flt(available_qty)
row += [available_qty]
@@ -66,15 +66,30 @@ def get_item_warehouse_quantity():
return iwq_map
def get_item_warehouse_quantity_map():
+ query = """SELECT parent, warehouse, MIN(qty) AS qty
+ FROM (SELECT b.parent, bi.item_code, bi.warehouse,
+ sum(bi.projected_qty) / b.qty AS qty
+ FROM tabBin AS bi, (SELECT b.parent, b.item_code, b.qty, w.name
+ FROM `tabProduct Bundle Item` b, `tabWarehouse` w) AS b
+ WHERE bi.item_code = b.item_code
+ AND bi.warehouse = b.name
+ GROUP BY b.parent, b.item_code, bi.warehouse
+ UNION ALL
+ SELECT b.parent, b.item_code, b.name, 0 AS qty
+ FROM (SELECT b.parent, b.item_code, b.qty, w.name
+ FROM `tabProduct Bundle Item` b, `tabWarehouse` w) AS b
+ WHERE NOT EXISTS(SELECT *
+ FROM `tabBin` AS bi
+ WHERE bi.item_code = b.item_code
+ AND bi.warehouse = b.name)) AS r
+ GROUP BY parent, warehouse
+ HAVING MIN(qty) != 0"""
+ result = frappe.db.sql(query, as_dict=1)
+ last_sbom = ""
sbom_map = {}
- iwq_map = get_item_warehouse_quantity()
- sbom_item_map = get_product_bundle_items()
-
- for sbom, sbom_items in sbom_item_map.items():
- for item, child_qty in sbom_items.items():
- for wh, qty in iwq_map.get(item, {}).items():
- avail_qty = flt(qty) / flt(child_qty)
- sbom_map.setdefault(sbom, {}).setdefault(wh, {}) \
- .setdefault(item, avail_qty)
-
- return sbom_map
\ No newline at end of file
+ for line in result:
+ if line.get("parent") != last_sbom:
+ last_sbom = line.get("parent")
+ actual_dict = sbom_map.setdefault(last_sbom, {})
+ actual_dict.setdefault(line.get("warehouse"), line.get("qty"))
+ return sbom_map
diff --git a/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py
index 87216518c65..670b4e98bf3 100644
--- a/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py
+++ b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py
@@ -47,9 +47,8 @@ def get_columns():
},
{
"label": _("Material Request"),
- "options": "Material Request",
"fieldname": "material_request",
- "fieldtype": "Link",
+ "fieldtype": "Data",
"width": 140
},
{
@@ -116,33 +115,43 @@ def get_data():
{"sales_order_item": ("!=",""), "docstatus": 1},
["parent", "qty", "sales_order", "item_code"])
- grouped_records = {}
+ materials_request_dict = {}
for record in mr_records:
- grouped_records.setdefault(record.sales_order, []).append(record)
+ key = (record.sales_order, record.item_code)
+ if key not in materials_request_dict:
+ materials_request_dict.setdefault(key, {
+ 'qty': 0,
+ 'material_requests': [record.parent]
+ })
+
+ details = materials_request_dict.get(key)
+ details['qty'] += record.qty
+
+ if record.parent not in details.get('material_requests'):
+ details['material_requests'].append(record.parent)
pending_so=[]
for so in sales_order_entry:
# fetch all the material request records for a sales order item
- mr_list = grouped_records.get(so.name) or [{}]
- mr_item_record = ([mr for mr in mr_list if mr.get('item_code') == so.item_code] or [{}])
+ key = (so.name, so.item_code)
+ materials_request = materials_request_dict.get(key) or {}
- for mr in mr_item_record:
- # check for pending sales order
- if cint(so.net_qty) > cint(mr.get('qty')):
- so_record = {
- "item_code": so.item_code,
- "item_name": so.item_name,
- "description": so.description,
- "sales_order_no": so.name,
- "date": so.transaction_date,
- "material_request": cstr(mr.get('parent')),
- "customer": so.customer,
- "territory": so.territory,
- "so_qty": so.net_qty,
- "requested_qty": cint(mr.get('qty')),
- "pending_qty": so.net_qty - cint(mr.get('qty')),
- "company": so.company
- }
- pending_so.append(so_record)
+ # check for pending sales order
+ if cint(so.net_qty) > cint(materials_request.get('qty')):
+ so_record = {
+ "item_code": so.item_code,
+ "item_name": so.item_name,
+ "description": so.description,
+ "sales_order_no": so.name,
+ "date": so.transaction_date,
+ "material_request": ','.join(materials_request.get('material_requests', [])),
+ "customer": so.customer,
+ "territory": so.territory,
+ "so_qty": so.net_qty,
+ "requested_qty": cint(materials_request.get('qty')),
+ "pending_qty": so.net_qty - cint(materials_request.get('qty')),
+ "company": so.company
+ }
+ pending_so.append(so_record)
return pending_so
\ No newline at end of file
diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js
index 67051c8b5e5..b236151bad9 100644
--- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js
+++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js
@@ -33,7 +33,8 @@ frappe.query_reports["Sales Person-wise Transaction Summary"] = {
label: __("Company"),
fieldtype: "Link",
options: "Company",
- default: frappe.defaults.get_user_default("Company")
+ default: frappe.defaults.get_user_default("Company"),
+ reqd: 1
},
{
fieldname:"item_group",
diff --git a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
index db11ae95c2f..41c7f765175 100644
--- a/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
+++ b/erpnext/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py
@@ -15,7 +15,7 @@ def execute(filters=None):
item_details = get_item_details()
data = []
- company_currency = get_company_currency(filters["company"])
+ company_currency = get_company_currency(filters.get("company"))
for d in entries:
if d.stock_qty > 0 or filters.get('show_return_entries', 0):
diff --git a/erpnext/setup/doctype/brand/test_records.json b/erpnext/setup/doctype/brand/test_records.json
index d2a4ad4e238..e4f892eef50 100644
--- a/erpnext/setup/doctype/brand/test_records.json
+++ b/erpnext/setup/doctype/brand/test_records.json
@@ -1,6 +1,6 @@
[
{
- "brand": "_Test Brand",
+ "brand": "_Test Brand",
"doctype": "Brand"
}
]
\ No newline at end of file
diff --git a/erpnext/setup/doctype/company/company.js b/erpnext/setup/doctype/company/company.js
index 70e047a4e80..aff4baf9314 100644
--- a/erpnext/setup/doctype/company/company.js
+++ b/erpnext/setup/doctype/company/company.js
@@ -16,6 +16,12 @@ frappe.ui.form.on("Company", {
filters: {"is_additional_component": 1}
}
});
+
+ frm.set_query("parent_company", function() {
+ return {
+ filters: {"is_group": 1}
+ }
+ });
},
company_name: function(frm) {
@@ -28,6 +34,13 @@ frappe.ui.form.on("Company", {
}
},
+ parent_company: function(frm) {
+ var bool = frm.doc.parent_company ? true : false;
+ frm.set_value('create_chart_of_accounts_based_on', bool ? "Existing Company" : "");
+ frm.set_value('existing_company', bool ? frm.doc.parent_company : "");
+ disbale_coa_fields(frm, bool);
+ },
+
date_of_commencement: function(frm) {
if(frm.doc.date_of_commencement date_sub(curdate(), interval 1 year)
+ st.sales_person = %s and st.parent = dt.name and dt.transaction_date > date_sub(curdate(), interval 1 year)
group by dt.transaction_date ''', name)))
sales_invoice = dict(frappe.db.sql('''select
@@ -75,7 +76,7 @@ def get_timeline_data(doctype, name):
where
st.sales_person = %s and st.parent = dt.name and dt.posting_date > date_sub(curdate(), interval 1 year)
group by dt.posting_date ''', name))
-
+
for key in sales_invoice:
if out.get(key):
out[key] += sales_invoice[key]
@@ -97,5 +98,3 @@ def get_timeline_data(doctype, name):
out[key] = delivery_note[key]
return out
-
-
diff --git a/erpnext/setup/setup_wizard/operations/sample_data.py b/erpnext/setup/setup_wizard/operations/sample_data.py
index 3f787347393..e21c9bd1089 100644
--- a/erpnext/setup/setup_wizard/operations/sample_data.py
+++ b/erpnext/setup/setup_wizard/operations/sample_data.py
@@ -33,7 +33,7 @@ def make_sample_data(domains, make_dependent = False):
def make_opportunity(items, customer):
b = frappe.get_doc({
"doctype": "Opportunity",
- "enquiry_from": "Customer",
+ "opportunity_from": "Customer",
"customer": customer,
"opportunity_type": _("Sales"),
"with_items": 1
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index cc3205c7d70..efc128aa0c5 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -51,7 +51,9 @@ def get_cart_quotation(doc=None):
@frappe.whitelist()
def place_order():
quotation = _get_cart_quotation()
- quotation.company = frappe.db.get_value("Shopping Cart Settings", None, "company")
+ cart_settings = frappe.db.get_value("Shopping Cart Settings", None,
+ ["company", "allow_items_not_in_stock"], as_dict=1)
+ quotation.company = cart_settings.company
if not quotation.get("customer_address"):
throw(_("{0} is required").format(_(quotation.meta.get_label("customer_address"))))
@@ -64,14 +66,16 @@ def place_order():
from erpnext.selling.doctype.quotation.quotation import _make_sales_order
sales_order = frappe.get_doc(_make_sales_order(quotation.name, ignore_permissions=True))
- for item in sales_order.get("items"):
- item.reserved_warehouse, is_stock_item = frappe.db.get_value("Item",
- item.item_code, ["website_warehouse", "is_stock_item"])
- if is_stock_item:
- item_stock = get_qty_in_stock(item.item_code, "website_warehouse")
- if item.qty > item_stock.stock_qty[0][0]:
- throw(_("Only {0} in stock for item {1}").format(item_stock.stock_qty[0][0], item.item_code))
+ if not cart_settings.allow_items_not_in_stock:
+ for item in sales_order.get("items"):
+ item.reserved_warehouse, is_stock_item = frappe.db.get_value("Item",
+ item.item_code, ["website_warehouse", "is_stock_item"])
+
+ if is_stock_item:
+ item_stock = get_qty_in_stock(item.item_code, "website_warehouse")
+ if item.qty > item_stock.stock_qty[0][0]:
+ throw(_("Only {0} in stock for item {1}").format(item_stock.stock_qty[0][0], item.item_code))
sales_order.flags.ignore_permissions = True
sales_order.insert()
@@ -192,7 +196,7 @@ def _get_cart_quotation(party=None):
party = get_party()
quotation = frappe.get_all("Quotation", fields=["name"], filters=
- {party.doctype.lower(): party.name, "order_type": "Shopping Cart", "docstatus": 0},
+ {"party_name": party.name, "order_type": "Shopping Cart", "docstatus": 0},
order_by="modified desc", limit_page_length=1)
if quotation:
@@ -207,7 +211,7 @@ def _get_cart_quotation(party=None):
"status": "Draft",
"docstatus": 0,
"__islocal": 1,
- (party.doctype.lower()): party.name
+ "party_name": party.name
})
qdoc.contact_person = frappe.db.get_value("Contact", {"email_id": frappe.session.user})
@@ -287,9 +291,9 @@ def _set_price_list(quotation, cart_settings):
# check if customer price list exists
selling_price_list = None
- if quotation.customer:
+ if quotation.party_name:
from erpnext.accounts.party import get_default_price_list
- selling_price_list = get_default_price_list(frappe.get_doc("Customer", quotation.customer))
+ selling_price_list = get_default_price_list(frappe.get_doc("Customer", quotation.party_name))
# else check for territory based price list
if not selling_price_list:
@@ -301,9 +305,9 @@ def set_taxes(quotation, cart_settings):
"""set taxes based on billing territory"""
from erpnext.accounts.party import set_taxes
- customer_group = frappe.db.get_value("Customer", quotation.customer, "customer_group")
+ customer_group = frappe.db.get_value("Customer", quotation.party_name, "customer_group")
- quotation.taxes_and_charges = set_taxes(quotation.customer, "Customer", \
+ quotation.taxes_and_charges = set_taxes(quotation.party_name, "Customer", \
quotation.transaction_date, quotation.company, customer_group, None, \
quotation.customer_address, quotation.shipping_address_name, 1)
#
diff --git a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
index 724c1e9ba26..898a1c39be8 100644
--- a/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
+++ b/erpnext/shopping_cart/doctype/shopping_cart_settings/shopping_cart_settings.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -19,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "enabled",
"fieldtype": "Check",
"hidden": 0,
@@ -51,6 +53,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "display_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -84,6 +87,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "show_attachments",
"fieldtype": "Check",
"hidden": 0,
@@ -118,6 +122,7 @@
"columns": 0,
"depends_on": "eval:doc.enabled==0",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "show_price",
"fieldtype": "Check",
"hidden": 0,
@@ -150,6 +155,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"hidden": 0,
@@ -181,6 +187,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "show_stock_availability",
"fieldtype": "Check",
"hidden": 0,
@@ -214,6 +221,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "show_stock_availability",
+ "fetch_if_empty": 0,
"fieldname": "show_quantity_in_website",
"fieldtype": "Check",
"hidden": 0,
@@ -246,6 +254,40 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "allow_items_not_in_stock",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow items not in stock to be added to cart",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_2",
"fieldtype": "Section Break",
"hidden": 0,
@@ -276,6 +318,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -309,6 +352,7 @@
"collapsible": 0,
"columns": 0,
"description": "Prices will not be shown if Price List is not set",
+ "fetch_if_empty": 0,
"fieldname": "price_list",
"fieldtype": "Link",
"hidden": 0,
@@ -342,6 +386,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -373,6 +418,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "default_customer_group",
"fieldtype": "Link",
"hidden": 0,
@@ -405,6 +451,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "quotation_series",
"fieldtype": "Select",
"hidden": 0,
@@ -437,6 +484,7 @@
"collapsible": 1,
"collapsible_depends_on": "eval:doc.enable_checkout",
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"hidden": 0,
@@ -469,6 +517,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "enable_checkout",
"fieldtype": "Check",
"hidden": 0,
@@ -503,6 +552,7 @@
"columns": 0,
"default": "Orders",
"description": "After payment completion redirect user to selected page.",
+ "fetch_if_empty": 0,
"fieldname": "payment_success_url",
"fieldtype": "Select",
"hidden": 0,
@@ -536,6 +586,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"hidden": 0,
@@ -567,6 +618,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "payment_gateway_account",
"fieldtype": "Link",
"hidden": 0,
@@ -605,8 +657,8 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-05-31 03:11:58.911732",
- "modified_by": "sushant@digithinkit.com",
+ "modified": "2019-04-09 18:29:43.270862",
+ "modified_by": "Administrator",
"module": "Shopping Cart",
"name": "Shopping Cart Settings",
"owner": "Administrator",
@@ -637,5 +689,6 @@
"show_name_in_global_search": 0,
"sort_order": "ASC",
"track_changes": 0,
- "track_seen": 0
-}
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/shopping_cart/test_shopping_cart.py b/erpnext/shopping_cart/test_shopping_cart.py
index 7d6b41ef5fc..be08ec44445 100644
--- a/erpnext/shopping_cart/test_shopping_cart.py
+++ b/erpnext/shopping_cart/test_shopping_cart.py
@@ -33,7 +33,6 @@ class TestShoppingCart(unittest.TestCase):
self.assertEqual(quotation.quotation_to, "Customer")
self.assertEqual(quotation.contact_person,
frappe.db.get_value("Contact", dict(email_id="test_cart_user@example.com")))
- self.assertEqual(quotation.lead, None)
self.assertEqual(quotation.contact_email, frappe.session.user)
return quotation
@@ -44,8 +43,7 @@ class TestShoppingCart(unittest.TestCase):
# test if quotation with customer is fetched
quotation = _get_cart_quotation()
self.assertEqual(quotation.quotation_to, "Customer")
- self.assertEqual(quotation.customer, "_Test Customer")
- self.assertEqual(quotation.lead, None)
+ self.assertEqual(quotation.party_name, "_Test Customer")
self.assertEqual(quotation.contact_email, frappe.session.user)
return quotation
@@ -107,7 +105,7 @@ class TestShoppingCart(unittest.TestCase):
from erpnext.accounts.party import set_taxes
- tax_rule_master = set_taxes(quotation.customer, "Customer", \
+ tax_rule_master = set_taxes(quotation.party_name, "Customer", \
quotation.transaction_date, quotation.company, None, None, \
quotation.customer_address, quotation.shipping_address_name, 1)
self.assertEqual(quotation.taxes_and_charges, tax_rule_master)
@@ -122,7 +120,7 @@ class TestShoppingCart(unittest.TestCase):
"doctype": "Quotation",
"quotation_to": "Customer",
"order_type": "Shopping Cart",
- "customer": get_party(frappe.session.user).name,
+ "party_name": get_party(frappe.session.user).name,
"docstatus": 0,
"contact_email": frappe.session.user,
"selling_price_list": "_Test Price List Rest of the World",
diff --git a/erpnext/startup/boot.py b/erpnext/startup/boot.py
index 62c9e7b90c5..8a164f9d136 100644
--- a/erpnext/startup/boot.py
+++ b/erpnext/startup/boot.py
@@ -33,7 +33,7 @@ def boot_session(bootinfo):
tabCompany limit 1""") and 'Yes' or 'No'
bootinfo.docs += frappe.db.sql("""select name, default_currency, cost_center, default_terms,
- default_letter_head, default_bank_account, enable_perpetual_inventory from `tabCompany`""",
+ default_letter_head, default_bank_account, enable_perpetual_inventory, country from `tabCompany`""",
as_dict=1, update={"doctype":":Company"})
party_account_types = frappe.db.sql(""" select name, ifnull(account_type, '') from `tabParty Type`""")
diff --git a/erpnext/stock/__init__.py b/erpnext/stock/__init__.py
index ea3d1036d2d..32a03e7373c 100644
--- a/erpnext/stock/__init__.py
+++ b/erpnext/stock/__init__.py
@@ -8,16 +8,21 @@ install_docs = [
{"doctype":"Role", "role_name":"Stock User", "name":"Stock User"},
{"doctype":"Role", "role_name":"Quality Manager", "name":"Quality Manager"},
{"doctype":"Item Group", "item_group_name":"All Item Groups", "is_group": 1},
- {"doctype":"Item Group", "item_group_name":"Default",
+ {"doctype":"Item Group", "item_group_name":"Default",
"parent_item_group":"All Item Groups", "is_group": 0},
]
-def get_warehouse_account_map():
+def get_warehouse_account_map(company=None):
if not frappe.flags.warehouse_account_map or frappe.flags.in_test:
warehouse_account = frappe._dict()
+ filters = {}
+ if company:
+ filters['company'] = company
+
for d in frappe.get_all('Warehouse',
fields = ["name", "account", "parent_warehouse", "company"],
+ filters = filters,
order_by="lft, rgt"):
if not d.account:
d.account = get_warehouse_account(d, warehouse_account)
@@ -57,6 +62,6 @@ def get_warehouse_account(warehouse, warehouse_account=None):
frappe.throw(_("Please set Account in Warehouse {0} or Default Inventory Account in Company {1}")
.format(warehouse.name, warehouse.company))
return account
-
+
def get_company_default_inventory_account(company):
return frappe.get_cached_value('Company', company, 'default_inventory_account')
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index f8a34972b70..e8224eb458f 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -101,6 +101,29 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
refresh: function(doc, dt, dn) {
var me = this;
this._super();
+ if ((!doc.is_return) && (doc.status!="Closed" || this.frm.is_new())) {
+ if (this.frm.doc.docstatus===0) {
+ this.frm.add_custom_button(__('Sales Order'),
+ function() {
+ erpnext.utils.map_current_doc({
+ method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
+ source_doctype: "Sales Order",
+ target: me.frm,
+ setters: {
+ customer: me.frm.doc.customer || undefined,
+ },
+ get_query_filters: {
+ docstatus: 1,
+ status: ["!=", "Closed"],
+ per_delivered: ["<", 99.99],
+ company: me.frm.doc.company,
+ project: me.frm.doc.project || undefined,
+ }
+ })
+ }, __("Get items from"));
+ }
+ }
+
if (!doc.is_return && doc.status!="Closed") {
if(flt(doc.per_installed, 2) < 100 && doc.docstatus==1)
this.frm.add_custom_button(__('Installation Note'), function() {
@@ -127,27 +150,6 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
if (!doc.__islocal && doc.docstatus==1) {
this.frm.page.set_inner_btn_group_as_primary(__("Make"));
}
-
- if (this.frm.doc.docstatus===0) {
- this.frm.add_custom_button(__('Sales Order'),
- function() {
- erpnext.utils.map_current_doc({
- method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note",
- source_doctype: "Sales Order",
- target: me.frm,
- setters: {
- customer: me.frm.doc.customer || undefined,
- },
- get_query_filters: {
- docstatus: 1,
- status: ["!=", "Closed"],
- per_delivered: ["<", 99.99],
- company: me.frm.doc.company,
- project: me.frm.doc.project || undefined,
- }
- })
- }, __("Get items from"));
- }
}
if (doc.docstatus==1) {
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 1eb2b0985ac..184bf17aea8 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -391,19 +391,7 @@ def get_invoiced_qty_map(delivery_note):
return invoiced_qty_map
-def get_returned_qty_map_against_so(sales_orders):
- """returns a map: {so_detail: returned_qty}"""
- returned_qty_map = {}
-
- for name, returned_qty in frappe.get_all('Sales Order Item', fields = ["name", "returned_qty"],
- filters = {'parent': ('in', sales_orders), 'docstatus': 1}, as_list=1):
- if not returned_qty_map.get(name):
- returned_qty_map[name] = 0
- returned_qty_map[name] += returned_qty
-
- return returned_qty_map
-
-def get_returned_qty_map_against_dn(delivery_note):
+def get_returned_qty_map(delivery_note):
"""returns a map: {so_detail: returned_qty}"""
returned_qty_map = frappe._dict(frappe.db.sql("""select dn_item.item_code, sum(abs(dn_item.qty)) as qty
from `tabDelivery Note Item` dn_item, `tabDelivery Note` dn
@@ -419,9 +407,7 @@ def get_returned_qty_map_against_dn(delivery_note):
@frappe.whitelist()
def make_sales_invoice(source_name, target_doc=None):
doc = frappe.get_doc('Delivery Note', source_name)
- sales_orders = [d.against_sales_order for d in doc.items]
- returned_qty_map_against_so = get_returned_qty_map_against_so(sales_orders)
- returned_qty_map_against_dn = get_returned_qty_map_against_dn(source_name)
+ returned_qty_map = get_returned_qty_map(source_name)
invoiced_qty_map = get_invoiced_qty_map(source_name)
def set_missing_values(source, target):
@@ -442,17 +428,16 @@ def make_sales_invoice(source_name, target_doc=None):
def update_item(source_doc, target_doc, source_parent):
target_doc.qty, returned_qty = get_pending_qty(source_doc)
- if not source_doc.so_detail:
- returned_qty_map_against_dn[source_doc.item_code] = returned_qty
+ returned_qty_map[source_doc.item_code] = returned_qty
if source_doc.serial_no and source_parent.per_billed > 0:
target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code,
target_doc.qty, source_parent.name)
def get_pending_qty(item_row):
- pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) - returned_qty_map_against_so.get(item_row.so_detail, 0)
- returned_qty = flt(returned_qty_map_against_dn.get(item_row.item_code, 0))
- if not item_row.so_detail:
+ pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0)
+ returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
+ if returned_qty:
if returned_qty >= pending_qty:
pending_qty = 0
returned_qty -= pending_qty
@@ -461,7 +446,7 @@ def make_sales_invoice(source_name, target_doc=None):
returned_qty = 0
return pending_qty, returned_qty
- doc = get_mapped_doc("Delivery Note", source_name, {
+ doc = get_mapped_doc("Delivery Note", source_name, {
"Delivery Note": {
"doctype": "Sales Invoice",
"validation": {
@@ -479,7 +464,7 @@ def make_sales_invoice(source_name, target_doc=None):
"cost_center": "cost_center"
},
"postprocess": update_item,
- "filter": lambda d: get_pending_qty(d)[0]<=0
+ "filter": lambda d: get_pending_qty(d)[0] <= 0 if not doc.get("is_return") else get_pending_qty(d)[0] > 0
},
"Sales Taxes and Charges": {
"doctype": "Sales Taxes and Charges",
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 5c031213d8a..bc95c965bc5 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -655,7 +655,7 @@ class TestDeliveryNote(unittest.TestCase):
si = make_sales_invoice(dn.name)
self.assertEquals(si.items[0].qty, 1)
- def test_make_sales_invoice_from_dn_with_returned_qty_against_dn(self):
+ def test_make_sales_invoice_from_dn_with_returned_qty_duplicate_items(self):
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
dn = create_delivery_note(qty=8, do_not_submit=True)
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 58c907793a7..2d9f6e9acd9 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -23,6 +23,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "name_and_description_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -57,6 +58,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -91,6 +93,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "item_code",
"fieldtype": "Data",
"hidden": 0,
@@ -127,6 +130,7 @@
"columns": 0,
"depends_on": "variant_of",
"description": "If item is a variant of another item then description, image, pricing, taxes etc will be set from the template unless explicitly specified",
+ "fetch_if_empty": 0,
"fieldname": "variant_of",
"fieldtype": "Link",
"hidden": 0,
@@ -160,6 +164,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "item_name",
"fieldtype": "Data",
"hidden": 0,
@@ -195,6 +200,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "item_group",
"fieldtype": "Link",
"hidden": 0,
@@ -230,6 +236,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "is_item_from_hub",
"fieldtype": "Check",
"hidden": 0,
@@ -263,6 +270,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "stock_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -298,6 +306,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
@@ -329,6 +338,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "disabled",
"fieldtype": "Check",
"hidden": 0,
@@ -361,6 +371,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "allow_alternative_item",
"fieldtype": "Check",
"hidden": 0,
@@ -395,6 +406,7 @@
"columns": 0,
"default": "1",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "is_stock_item",
"fieldtype": "Check",
"hidden": 0,
@@ -431,6 +443,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "include_item_in_manufacturing",
"fieldtype": "Check",
"hidden": 0,
@@ -464,6 +477,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:(doc.__islocal&&doc.is_stock_item && !doc.has_serial_no && !doc.has_batch_no)",
+ "fetch_if_empty": 0,
"fieldname": "opening_stock",
"fieldtype": "Float",
"hidden": 0,
@@ -497,6 +511,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "valuation_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -530,6 +545,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.__islocal",
+ "fetch_if_empty": 0,
"fieldname": "standard_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -562,6 +578,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "is_fixed_asset",
"fieldtype": "Check",
"hidden": 0,
@@ -595,6 +612,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "is_fixed_asset",
+ "fetch_if_empty": 0,
"fieldname": "asset_category",
"fieldtype": "Link",
"hidden": 0,
@@ -629,6 +647,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "is_fixed_asset",
+ "fetch_if_empty": 0,
"fieldname": "asset_naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -663,6 +682,7 @@
"columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "tolerance",
"fieldtype": "Float",
"hidden": 0,
@@ -697,6 +717,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
@@ -730,6 +751,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"hidden": 0,
@@ -762,6 +784,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "brand",
"fieldtype": "Link",
"hidden": 0,
@@ -797,6 +820,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -831,6 +855,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sb_barcodes",
"fieldtype": "Section Break",
"hidden": 0,
@@ -863,6 +888,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "barcodes",
"fieldtype": "Table",
"hidden": 0,
@@ -898,6 +924,7 @@
"collapsible_depends_on": "is_stock_item",
"columns": 0,
"depends_on": "is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "inventory_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -932,6 +959,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "shelf_life_in_days",
"fieldtype": "Int",
"hidden": 0,
@@ -966,6 +994,7 @@
"columns": 0,
"default": "2099-12-31",
"depends_on": "is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "end_of_life",
"fieldtype": "Date",
"hidden": 0,
@@ -1001,6 +1030,7 @@
"collapsible": 0,
"columns": 0,
"default": "Purchase",
+ "fetch_if_empty": 0,
"fieldname": "default_material_request_type",
"fieldtype": "Select",
"hidden": 0,
@@ -1035,6 +1065,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "valuation_method",
"fieldtype": "Select",
"hidden": 0,
@@ -1069,6 +1100,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1103,6 +1135,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "warranty_period",
"fieldtype": "Data",
"hidden": 0,
@@ -1139,6 +1172,7 @@
"columns": 0,
"depends_on": "is_stock_item",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "weight_per_unit",
"fieldtype": "Float",
"hidden": 0,
@@ -1172,6 +1206,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "weight_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -1207,6 +1242,7 @@
"columns": 0,
"depends_on": "is_stock_item",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "reorder_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1242,6 +1278,7 @@
"columns": 0,
"depends_on": "",
"description": "Will also apply for variants unless overrridden",
+ "fetch_if_empty": 0,
"fieldname": "reorder_levels",
"fieldtype": "Table",
"hidden": 0,
@@ -1276,6 +1313,7 @@
"collapsible": 1,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "unit_of_measure_conversion",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1310,6 +1348,7 @@
"columns": 0,
"depends_on": "",
"description": "Will also apply for variants",
+ "fetch_if_empty": 0,
"fieldname": "uoms",
"fieldtype": "Table",
"hidden": 0,
@@ -1347,6 +1386,7 @@
"collapsible_depends_on": "eval:doc.has_batch_no || doc.has_serial_no || doc.is_fixed_asset",
"columns": 0,
"depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset",
+ "fetch_if_empty": 0,
"fieldname": "serial_nos_and_batches",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1381,6 +1421,7 @@
"columns": 0,
"default": "",
"depends_on": "eval:doc.is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "has_batch_no",
"fieldtype": "Check",
"hidden": 0,
@@ -1418,6 +1459,7 @@
"columns": 0,
"depends_on": "has_batch_no",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "create_new_batch",
"fieldtype": "Check",
"hidden": 0,
@@ -1452,6 +1494,7 @@
"columns": 0,
"depends_on": "eval:doc.has_batch_no==1 && doc.create_new_batch==1",
"description": "Example: ABCD.#####. If series is set and Batch No is not mentioned in transactions,then automatic batch number will be created based on this series. If you always want to explicitly mention Batch No for this item,leave this blank. Note: this setting will take priority over the Naming Series Prefix in Stock Settings.",
+ "fetch_if_empty": 0,
"fieldname": "batch_number_series",
"fieldtype": "Data",
"hidden": 0,
@@ -1485,6 +1528,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "has_batch_no",
+ "fetch_if_empty": 0,
"fieldname": "has_expiry_date",
"fieldtype": "Check",
"hidden": 0,
@@ -1518,6 +1562,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "has_batch_no",
+ "fetch_if_empty": 0,
"fieldname": "retain_sample",
"fieldtype": "Check",
"hidden": 0,
@@ -1552,6 +1597,7 @@
"columns": 0,
"depends_on": "eval: (doc.retain_sample && doc.has_batch_no)",
"description": "Maximum sample quantity that can be retained",
+ "fetch_if_empty": 0,
"fieldname": "sample_quantity",
"fieldtype": "Int",
"hidden": 0,
@@ -1584,6 +1630,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_37",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1618,6 +1665,7 @@
"default": "",
"depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "has_serial_no",
"fieldtype": "Check",
"hidden": 0,
@@ -1655,6 +1703,7 @@
"columns": 0,
"depends_on": "eval:doc.is_stock_item || doc.is_fixed_asset",
"description": "Example: ABCD.#####\nIf series is set and Serial No is not mentioned in transactions,then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.",
+ "fetch_if_empty": 0,
"fieldname": "serial_no_series",
"fieldtype": "Data",
"hidden": 0,
@@ -1689,6 +1738,7 @@
"collapsible_depends_on": "attributes",
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "variants_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1724,6 +1774,7 @@
"default": "0",
"depends_on": "eval:!doc.variant_of",
"description": "If this item has variants,then it cannot be selected in sales orders etc.",
+ "fetch_if_empty": 0,
"fieldname": "has_variants",
"fieldtype": "Check",
"hidden": 0,
@@ -1759,6 +1810,7 @@
"columns": 0,
"default": "Item Attribute",
"depends_on": "has_variants",
+ "fetch_if_empty": 0,
"fieldname": "variant_based_on",
"fieldtype": "Select",
"hidden": 0,
@@ -1781,7 +1833,7 @@
"report_hide": 0,
"reqd": 0,
"search_index": 0,
- "set_only_once": 1,
+ "set_only_once": 0,
"translatable": 0,
"unique": 0
},
@@ -1793,6 +1845,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:(doc.has_variants || doc.variant_of) && doc.variant_based_on==='Item Attribute'",
+ "fetch_if_empty": 0,
"fieldname": "attributes",
"fieldtype": "Table",
"hidden": 1,
@@ -1826,6 +1879,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "defaults",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1858,6 +1912,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "item_defaults",
"fieldtype": "Table",
"hidden": 0,
@@ -1891,6 +1946,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "purchase_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1926,6 +1982,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "is_purchase_item",
"fieldtype": "Check",
"hidden": 0,
@@ -1958,6 +2015,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "purchase_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -1994,6 +2052,7 @@
"default": "0.00",
"depends_on": "is_stock_item",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "min_order_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2028,6 +2087,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "safety_stock",
"fieldtype": "Float",
"hidden": 0,
@@ -2060,6 +2120,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "purchase_details_cb",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2094,6 +2155,7 @@
"columns": 0,
"depends_on": "",
"description": "Average time taken by the supplier to deliver",
+ "fetch_if_empty": 0,
"fieldname": "lead_time_days",
"fieldtype": "Int",
"hidden": 0,
@@ -2129,6 +2191,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "last_purchase_rate",
"fieldtype": "Float",
"hidden": 0,
@@ -2164,6 +2227,7 @@
"collapsible": 1,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "supplier_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2196,6 +2260,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "delivered_by_supplier",
"fieldtype": "Check",
"hidden": 0,
@@ -2229,6 +2294,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "manufacturer",
"fieldtype": "Link",
"hidden": 0,
@@ -2263,6 +2329,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "manufacturer_part_no",
"fieldtype": "Data",
"hidden": 0,
@@ -2296,6 +2363,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "column_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2331,6 +2399,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "supplier_items",
"fieldtype": "Table",
"hidden": 0,
@@ -2364,6 +2433,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "foreign_trade_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2396,6 +2466,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "country_of_origin",
"fieldtype": "Link",
"hidden": 0,
@@ -2429,6 +2500,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_59",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2460,6 +2532,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customs_tariff_number",
"fieldtype": "Link",
"hidden": 0,
@@ -2493,6 +2566,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sales_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2527,6 +2601,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "sales_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -2561,6 +2636,7 @@
"collapsible": 0,
"columns": 0,
"default": "1",
+ "fetch_if_empty": 0,
"fieldname": "is_sales_item",
"fieldtype": "Check",
"hidden": 0,
@@ -2594,6 +2670,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "column_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2629,6 +2706,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "max_discount",
"fieldtype": "Float",
"hidden": 0,
@@ -2663,6 +2741,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "deferred_revenue",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2696,6 +2775,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_revenue",
+ "fetch_if_empty": 0,
"fieldname": "deferred_revenue_account",
"fieldtype": "Link",
"hidden": 0,
@@ -2729,6 +2809,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "enable_deferred_revenue",
"fieldtype": "Check",
"hidden": 0,
@@ -2761,6 +2842,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_85",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2793,6 +2875,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_revenue",
+ "fetch_if_empty": 0,
"fieldname": "no_of_months",
"fieldtype": "Int",
"hidden": 0,
@@ -2825,6 +2908,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "deferred_expense_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2858,6 +2942,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_expense",
+ "fetch_if_empty": 0,
"fieldname": "deferred_expense_account",
"fieldtype": "Link",
"hidden": 0,
@@ -2891,6 +2976,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "enable_deferred_expense",
"fieldtype": "Check",
"hidden": 0,
@@ -2923,6 +3009,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_88",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2955,6 +3042,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "enable_deferred_expense",
+ "fetch_if_empty": 0,
"fieldname": "no_of_months_exp",
"fieldtype": "Int",
"hidden": 0,
@@ -2987,6 +3075,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3021,6 +3110,7 @@
"columns": 0,
"depends_on": "",
"description": "",
+ "fetch_if_empty": 0,
"fieldname": "customer_items",
"fieldtype": "Table",
"hidden": 0,
@@ -3054,6 +3144,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "item_tax_section_break",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3089,6 +3180,7 @@
"collapsible": 0,
"columns": 0,
"description": "Will also apply for variants",
+ "fetch_if_empty": 0,
"fieldname": "taxes",
"fieldtype": "Table",
"hidden": 0,
@@ -3124,6 +3216,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "inspection_criteria",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3159,6 +3252,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "inspection_required_before_purchase",
"fieldtype": "Check",
"hidden": 0,
@@ -3194,6 +3288,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "inspection_required_before_delivery",
"fieldtype": "Check",
"hidden": 0,
@@ -3227,6 +3322,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:(doc.inspection_required_before_purchase || doc.inspection_required_before_delivery)",
+ "fetch_if_empty": 0,
"fieldname": "quality_inspection_template",
"fieldtype": "Link",
"hidden": 0,
@@ -3261,6 +3357,7 @@
"collapsible": 1,
"columns": 0,
"depends_on": "is_stock_item",
+ "fetch_if_empty": 0,
"fieldname": "manufacturing",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3296,6 +3393,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "default_bom",
"fieldtype": "Link",
"hidden": 0,
@@ -3333,6 +3431,7 @@
"columns": 0,
"default": "",
"description": "If subcontracted to a vendor",
+ "fetch_if_empty": 0,
"fieldname": "is_sub_contracted_item",
"fieldtype": "Check",
"hidden": 0,
@@ -3368,6 +3467,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_74",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3399,6 +3499,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_code",
"fieldtype": "Data",
"hidden": 1,
@@ -3431,6 +3532,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "website_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3465,6 +3567,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.variant_of",
+ "fetch_if_empty": 0,
"fieldname": "show_in_website",
"fieldtype": "Check",
"hidden": 0,
@@ -3498,6 +3601,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "variant_of",
+ "fetch_if_empty": 0,
"fieldname": "show_variant_in_website",
"fieldtype": "Check",
"hidden": 0,
@@ -3531,6 +3635,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
+ "fetch_if_empty": 0,
"fieldname": "route",
"fieldtype": "Small Text",
"hidden": 0,
@@ -3565,6 +3670,7 @@
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
"description": "Items with higher weightage will be shown higher",
+ "fetch_if_empty": 0,
"fieldname": "weightage",
"fieldtype": "Int",
"hidden": 0,
@@ -3599,6 +3705,7 @@
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
"description": "Show a slideshow at the top of the page",
+ "fetch_if_empty": 0,
"fieldname": "slideshow",
"fieldtype": "Link",
"hidden": 0,
@@ -3634,6 +3741,7 @@
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
"description": "Item Image (if not slideshow)",
+ "fetch_if_empty": 0,
"fieldname": "website_image",
"fieldtype": "Attach",
"hidden": 0,
@@ -3667,6 +3775,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "thumbnail",
"fieldtype": "Data",
"hidden": 0,
@@ -3699,6 +3808,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "cb72",
"fieldtype": "Column Break",
"hidden": 0,
@@ -3732,6 +3842,7 @@
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
"description": "Show \"In Stock\" or \"Not in Stock\" based on stock available in this warehouse.",
+ "fetch_if_empty": 0,
"fieldname": "website_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -3767,6 +3878,7 @@
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
"description": "List this Item in multiple groups on the website.",
+ "fetch_if_empty": 0,
"fieldname": "website_item_groups",
"fieldtype": "Table",
"hidden": 0,
@@ -3802,6 +3914,7 @@
"collapsible_depends_on": "website_specifications",
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
+ "fetch_if_empty": 0,
"fieldname": "sb72",
"fieldtype": "Section Break",
"hidden": 0,
@@ -3835,6 +3948,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
+ "fetch_if_empty": 0,
"fieldname": "copy_from_item_group",
"fieldtype": "Button",
"hidden": 0,
@@ -3868,6 +3982,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
+ "fetch_if_empty": 0,
"fieldname": "website_specifications",
"fieldtype": "Table",
"hidden": 0,
@@ -3902,6 +4017,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval: doc.show_in_website || doc.show_variant_in_website",
+ "fetch_if_empty": 0,
"fieldname": "web_long_description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -3934,6 +4050,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "total_projected_qty",
"fieldtype": "Float",
"hidden": 1,
@@ -3967,6 +4084,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:(!doc.is_item_from_hub)",
+ "fetch_if_empty": 0,
"fieldname": "hub_publishing_sb",
"fieldtype": "Section Break",
"hidden": 0,
@@ -4001,6 +4119,7 @@
"columns": 0,
"default": "0",
"description": "Publish Item to hub.erpnext.com",
+ "fetch_if_empty": 0,
"fieldname": "publish_in_hub",
"fieldtype": "Check",
"hidden": 0,
@@ -4033,6 +4152,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "hub_category_to_publish",
"fieldtype": "Data",
"hidden": 0,
@@ -4067,6 +4187,7 @@
"collapsible": 0,
"columns": 0,
"description": "Publish \"In Stock\" or \"Not in Stock\" on Hub based on stock available in this warehouse.",
+ "fetch_if_empty": 0,
"fieldname": "hub_warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -4101,6 +4222,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
+ "fetch_if_empty": 0,
"fieldname": "synced_with_hub",
"fieldtype": "Check",
"hidden": 0,
@@ -4139,7 +4261,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 1,
- "modified": "2019-02-16 17:43:56.039611",
+ "modified": "2019-04-05 12:03:24.530849",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index bd06688caa2..8f93c3f7ff2 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -9,11 +9,11 @@ import erpnext
import frappe
import copy
from erpnext.controllers.item_variant import (ItemVariantExistsError,
- copy_attributes_to_variant, get_variant, make_variant_item_code, validate_item_variant_attributes)
+ copy_attributes_to_variant, get_variant, make_variant_item_code, validate_item_variant_attributes)
from erpnext.setup.doctype.item_group.item_group import (get_parent_item_groups, invalidate_cache_for)
from frappe import _, msgprint
from frappe.utils import (cint, cstr, flt, formatdate, get_timestamp, getdate,
- now_datetime, random_string, strip)
+ now_datetime, random_string, strip)
from frappe.utils.html_utils import clean_html
from frappe.website.doctype.website_slideshow.website_slideshow import \
get_slideshow
@@ -49,9 +49,6 @@ class Item(WebsiteGenerator):
self.set_onload('stock_exists', self.stock_ledger_created())
self.set_asset_naming_series()
- if self.is_fixed_asset:
- asset = self.asset_exists()
- self.set_onload("asset_exists", True if asset else False)
def set_asset_naming_series(self):
if not hasattr(self, '_asset_naming_series'):
@@ -118,9 +115,9 @@ class Item(WebsiteGenerator):
self.validate_has_variants()
self.validate_stock_exists_for_template_item()
- self.validate_asset_exists_for_serialized_asset()
self.validate_attributes()
self.validate_variant_attributes()
+ self.validate_variant_based_on_change()
self.validate_website_image()
self.make_thumbnail()
self.validate_fixed_asset()
@@ -128,6 +125,7 @@ class Item(WebsiteGenerator):
self.validate_uom_conversion_factor()
self.validate_item_defaults()
self.update_defaults_from_item_group()
+ self.validate_stock_for_has_batch_and_has_serial()
if not self.get("__islocal"):
self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")
@@ -151,7 +149,7 @@ class Item(WebsiteGenerator):
'''Add a new price'''
if not price_list:
price_list = (frappe.db.get_single_value('Selling Settings', 'selling_price_list')
- or frappe.db.get_value('Price List', _('Standard Selling')))
+ or frappe.db.get_value('Price List', _('Standard Selling')))
if price_list:
item_price = frappe.get_doc({
"doctype": "Item Price",
@@ -190,7 +188,7 @@ class Item(WebsiteGenerator):
def make_route(self):
if not self.route:
return cstr(frappe.db.get_value('Item Group', self.item_group,
- 'route')) + '/' + self.scrub((self.item_name if self.item_name else self.item_code) + '-' + random_string(5))
+ 'route')) + '/' + self.scrub((self.item_name if self.item_name else self.item_code) + '-' + random_string(5))
def validate_website_image(self):
"""Validate if the website image is a public file"""
@@ -213,7 +211,7 @@ class Item(WebsiteGenerator):
if not file_doc:
if not auto_set_website_image:
frappe.msgprint(_("Website Image {0} attached to Item {1} cannot be found")
- .format(self.website_image, self.name))
+ .format(self.website_image, self.name))
self.website_image = None
@@ -314,8 +312,8 @@ class Item(WebsiteGenerator):
# load variants
# also used in set_attribute_context
context.variants = frappe.get_all("Item",
- filters={"variant_of": self.name, "show_variant_in_website": 1},
- order_by="name asc")
+ filters={"variant_of": self.name, "show_variant_in_website": 1},
+ order_by="name asc")
variant = frappe.form_dict.variant
if not variant and context.variants:
@@ -326,7 +324,7 @@ class Item(WebsiteGenerator):
context.variant = frappe.get_doc("Item", variant)
for fieldname in ("website_image", "web_long_description", "description",
- "website_specifications"):
+ "website_specifications"):
if context.variant.get(fieldname):
value = context.variant.get(fieldname)
if isinstance(value, list):
@@ -349,7 +347,7 @@ class Item(WebsiteGenerator):
# load attributes
for v in context.variants:
v.attributes = frappe.get_all("Item Variant Attribute",
- fields=["attribute", "attribute_value"],
+ fields=["attribute", "attribute_value"],
filters={"parent": v.name})
for attr in v.attributes:
@@ -530,7 +528,7 @@ class Item(WebsiteGenerator):
warehouse += [d.get("warehouse")]
else:
frappe.throw(_("Row {0}: An Reorder entry already exists for this warehouse {1}")
- .format(d.idx, d.warehouse), DuplicateReorderRows)
+ .format(d.idx, d.warehouse), DuplicateReorderRows)
if d.warehouse_reorder_level and not d.warehouse_reorder_qty:
frappe.throw(_("Row #{0}: Please set reorder quantity").format(d.idx))
@@ -550,7 +548,7 @@ class Item(WebsiteGenerator):
def update_item_price(self):
frappe.db.sql("""update `tabItem Price` set item_name=%s,
item_description=%s, brand=%s where item_code=%s""",
- (self.item_name, self.description, self.brand, self.name))
+ (self.item_name, self.description, self.brand, self.name))
def on_trash(self):
super(Item, self).on_trash()
@@ -572,7 +570,7 @@ class Item(WebsiteGenerator):
new_properties = [cstr(d) for d in frappe.db.get_value("Item", new_name, field_list)]
if new_properties != [cstr(self.get(fld)) for fld in field_list]:
frappe.throw(_("To merge, following properties must be same for both items")
- + ": \n" + ", ".join([self.meta.get_label(fld) for fld in field_list]))
+ + ": \n" + ", ".join([self.meta.get_label(fld) for fld in field_list]))
def after_rename(self, old_name, new_name, merge):
if self.route:
@@ -595,7 +593,7 @@ class Item(WebsiteGenerator):
item_wise_tax_detail.pop(old_name)
frappe.db.set_value(dt, d.name, "item_wise_tax_detail",
- json.dumps(item_wise_tax_detail), update_modified=False)
+ json.dumps(item_wise_tax_detail), update_modified=False)
def set_last_purchase_rate(self, new_name):
last_purchase_rate = get_last_purchase_details(new_name).get("base_rate", 0)
@@ -623,7 +621,7 @@ class Item(WebsiteGenerator):
self.set("website_specifications", [])
if self.item_group:
for label, desc in frappe.db.get_values("Item Website Specification",
- {"parent": self.item_group}, ["label", "description"]):
+ {"parent": self.item_group}, ["label", "description"]):
row = self.append("website_specifications")
row.label = label
row.description = desc
@@ -697,7 +695,7 @@ class Item(WebsiteGenerator):
def update_variants(self):
if self.flags.dont_update_variants or \
- frappe.db.get_single_value('Item Variant Settings', 'do_not_update_variants'):
+ frappe.db.get_single_value('Item Variant Settings', 'do_not_update_variants'):
return
if self.has_variants:
variants = frappe.db.get_all("Item", fields=["item_code"], filters={"variant_of": self.name})
@@ -726,17 +724,10 @@ class Item(WebsiteGenerator):
frappe.throw(
_('Cannot change Attributes after stock transaction. Make a new Item and transfer stock to the new Item'))
- def validate_asset_exists_for_serialized_asset(self):
- if (not self.get("__islocal") and self.asset_exists() and
- cint(self.has_serial_no) != cint(frappe.db.get_value('Item', self.name, 'has_serial_no'))):
- frappe.throw(_("Asset is already exists against the item {0}, you cannot change the has serial no value")
- .format(self.name))
-
- def asset_exists(self):
- if not hasattr(self, '_asset_created'):
- self._asset_created = frappe.db.get_all("Asset",
- filters={"item_code": self.name, "docstatus": 1}, limit=1)
- return self._asset_created
+ def validate_variant_based_on_change(self):
+ if not self.is_new() and (self.variant_of or (self.has_variants and frappe.get_all("Item", {"variant_of": self.name}))):
+ if self.variant_based_on != frappe.db.get_value("Item", self.name, "variant_based_on"):
+ frappe.throw(_("Variant Based On cannot be changed"))
def validate_uom(self):
if not self.get("__islocal"):
@@ -748,7 +739,7 @@ class Item(WebsiteGenerator):
template_uom = frappe.db.get_value("Item", self.variant_of, "stock_uom")
if template_uom != self.stock_uom:
frappe.throw(_("Default Unit of Measure for Variant '{0}' must be same as in Template '{1}'")
- .format(self.stock_uom, template_uom))
+ .format(self.stock_uom, template_uom))
def validate_uom_conversion_factor(self):
if self.uoms:
@@ -758,7 +749,13 @@ class Item(WebsiteGenerator):
d.conversion_factor = value
def validate_attributes(self):
- if (self.has_variants or self.variant_of) and self.variant_based_on == 'Item Attribute':
+ if not (self.has_variants or self.variant_of):
+ return
+
+ if not self.variant_based_on:
+ self.variant_based_on = 'Item Attribute'
+
+ if self.variant_based_on == 'Item Attribute':
attributes = []
if not self.attributes:
frappe.throw(_("Attribute table is mandatory"))
@@ -770,7 +767,7 @@ class Item(WebsiteGenerator):
attributes.append(d.attribute)
def validate_variant_attributes(self):
- if self.variant_of and self.variant_based_on == 'Item Attribute':
+ if self.is_new() and self.variant_of and self.variant_based_on == 'Item Attribute':
args = {}
for d in self.attributes:
if cstr(d.attribute_value).strip() == '':
@@ -780,10 +777,15 @@ class Item(WebsiteGenerator):
variant = get_variant(self.variant_of, args, self.name)
if variant:
frappe.throw(_("Item variant {0} exists with same attributes")
- .format(variant), ItemVariantExistsError)
+ .format(variant), ItemVariantExistsError)
validate_item_variant_attributes(self, args)
+ def validate_stock_for_has_batch_and_has_serial(self):
+ if self.stock_ledger_created():
+ for value in ["has_batch_no", "has_serial_no"]:
+ if frappe.db.get_value("Item", self.name, value) != self.get_value(value):
+ frappe.throw(_("Cannot change {0} as Stock Transaction for Item {1} exist.".format(value, self.name)))
def get_timeline_data(doctype, name):
'''returns timeline data based on stock ledger entry'''
@@ -863,18 +865,18 @@ def get_last_purchase_details(item_code, doc_name=None, conversion_rate=1.0):
limit 1""", (item_code, cstr(doc_name)), as_dict=1)
purchase_order_date = getdate(last_purchase_order and last_purchase_order[0].transaction_date
- or "1900-01-01")
+ or "1900-01-01")
purchase_receipt_date = getdate(last_purchase_receipt and
- last_purchase_receipt[0].posting_date or "1900-01-01")
+ last_purchase_receipt[0].posting_date or "1900-01-01")
if (purchase_order_date > purchase_receipt_date) or \
- (last_purchase_order and not last_purchase_receipt):
+ (last_purchase_order and not last_purchase_receipt):
# use purchase order
last_purchase = last_purchase_order[0]
purchase_date = purchase_order_date
elif (purchase_receipt_date > purchase_order_date) or \
- (last_purchase_receipt and not last_purchase_order):
+ (last_purchase_receipt and not last_purchase_order):
# use purchase receipt
last_purchase = last_purchase_receipt[0]
purchase_date = purchase_receipt_date
@@ -904,7 +906,7 @@ def invalidate_cache_for_item(doc):
invalidate_cache_for(doc, doc.item_group)
website_item_groups = list(set((doc.get("old_website_item_groups") or [])
- + [d.item_group for d in doc.get({"doctype": "Website Item Group"}) if d.item_group]))
+ + [d.item_group for d in doc.get({"doctype": "Website Item Group"}) if d.item_group]))
for item_group in website_item_groups:
invalidate_cache_for(doc, item_group)
@@ -919,7 +921,7 @@ def check_stock_uom_with_bin(item, stock_uom):
matched = True
ref_uom = frappe.db.get_value("Stock Ledger Entry",
- {"item_code": item}, "stock_uom")
+ {"item_code": item}, "stock_uom")
if ref_uom:
if cstr(ref_uom) != cstr(stock_uom):
@@ -928,7 +930,7 @@ def check_stock_uom_with_bin(item, stock_uom):
bin_list = frappe.db.sql("select * from tabBin where item_code=%s", item, as_dict=1)
for bin in bin_list:
if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0
- or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(stock_uom):
+ or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(stock_uom):
matched = False
break
@@ -1005,4 +1007,4 @@ def update_variants(variants, template, publish_progress=True):
variant.save()
count+=1
if publish_progress:
- frappe.publish_progress(count*100/len(variants), title = _("Updating Variants..."))
\ No newline at end of file
+ frappe.publish_progress(count*100/len(variants), title = _("Updating Variants..."))
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index d02559ebcb1..ac499e0965e 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -17,7 +17,7 @@ from erpnext.stock.get_item_details import get_item_details
from six import iteritems
test_ignore = ["BOM"]
-test_dependencies = ["Warehouse", "Item Group"]
+test_dependencies = ["Warehouse", "Item Group", "Brand"]
def make_item(item_code, properties=None):
if frappe.db.exists("Item", item_code):
@@ -393,3 +393,6 @@ def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None,
"company": "_Test Company"
})
item.save()
+ else:
+ item = frappe.get_doc("Item", item_code)
+ return item
diff --git a/erpnext/stock/doctype/item_attribute/test_records.json b/erpnext/stock/doctype/item_attribute/test_records.json
index 0208c176d32..d346979496f 100644
--- a/erpnext/stock/doctype/item_attribute/test_records.json
+++ b/erpnext/stock/doctype/item_attribute/test_records.json
@@ -6,7 +6,8 @@
"item_attribute_values": [
{"attribute_value": "Small", "abbr": "S"},
{"attribute_value": "Medium", "abbr": "M"},
- {"attribute_value": "Large", "abbr": "L"}
+ {"attribute_value": "Large", "abbr": "L"},
+ {"attribute_value": "Extra Small", "abbr": "XSL"}
]
},
{
diff --git a/erpnext/stock/doctype/item_price/item_price.json b/erpnext/stock/doctype/item_price/item_price.json
index 593f8b420d4..9e29ad08ee3 100644
--- a/erpnext/stock/doctype/item_price/item_price.json
+++ b/erpnext/stock/doctype/item_price/item_price.json
@@ -1,953 +1,981 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "",
- "beta": 0,
- "creation": "2013-05-02 16:29:48",
- "custom": 0,
- "description": "Multiple Item prices.",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "",
+ "beta": 0,
+ "creation": "2013-05-02 16:29:48",
+ "custom": 0,
+ "description": "Multiple Item prices.",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
+ "engine": "InnoDB",
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Item Code",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "price_list_name",
- "oldfieldtype": "Select",
- "options": "Item",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Item Code",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "price_list_name",
+ "oldfieldtype": "Select",
+ "options": "Item",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "uom",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "UOM",
- "length": 0,
- "no_copy": 0,
- "options": "UOM",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "uom",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "description": "Quantity that must be bought or sold per UOM",
- "fieldname": "packing_unit",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Packing Unit",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "description": "Quantity that must be bought or sold per UOM",
+ "fetch_if_empty": 0,
+ "fieldname": "packing_unit",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Packing Unit",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "fieldname": "min_qty",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Minimum Qty ",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fetch_if_empty": 0,
+ "fieldname": "min_qty",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Minimum Qty ",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_17",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_17",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_from": "item_code.brand",
- "fieldname": "brand",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Brand",
- "length": 0,
- "no_copy": 0,
- "options": "",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "item_code.brand",
+ "fetch_if_empty": 0,
+ "fieldname": "brand",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Brand",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_description",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Description",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "item_description",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item Description",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "price_list_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Price List",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-tags",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "price_list_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Price List",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-tags",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "price_list",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Price List",
- "length": 0,
- "no_copy": 0,
- "options": "Price List",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "price_list",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Price List",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Price List",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.selling == 1",
- "fieldname": "customer",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Customer",
- "length": 0,
- "no_copy": 0,
- "options": "Customer",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.selling == 1",
+ "fetch_if_empty": 0,
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Customer",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.buying == 1",
- "fieldname": "supplier",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Supplier",
- "length": 0,
- "no_copy": 0,
- "options": "Supplier",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.buying == 1",
+ "fetch_if_empty": 0,
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Supplier",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Supplier",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "buying",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Buying",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "buying",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Buying",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "selling",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Selling",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "selling",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Selling",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_details",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-tag",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "item_details",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-tag",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "currency",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Currency",
- "length": 0,
- "no_copy": 0,
- "options": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "currency",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "col_br_1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "col_br_1",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "price_list_rate",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Rate",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "ref_rate",
- "oldfieldtype": "Currency",
- "options": "currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "price_list_rate",
+ "fieldtype": "Currency",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 1,
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Rate",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "ref_rate",
+ "oldfieldtype": "Currency",
+ "options": "currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_15",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_15",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "valid_from",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Valid From ",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Today",
+ "fetch_if_empty": 0,
+ "fieldname": "valid_from",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Valid From ",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "0",
- "fieldname": "lead_time_days",
- "fieldtype": "Int",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Lead Time in days",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fetch_if_empty": 0,
+ "fieldname": "lead_time_days",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Lead Time in days",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_18",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "column_break_18",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "valid_upto",
- "fieldtype": "Date",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Valid Upto ",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "valid_upto",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Valid Upto ",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_24",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "section_break_24",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "note",
- "fieldtype": "Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Note",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "note",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Note",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "reference",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Reference",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_if_empty": 0,
+ "fieldname": "reference",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Reference",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-flag",
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-29 06:27:16.102833",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Item Price",
- "name_case": "Title Case",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "fa fa-flag",
+ "idx": 1,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2019-04-12 12:33:54.621527",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Item Price",
+ "name_case": "Title Case",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Sales Master Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Sales Master Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Purchase Master Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Purchase Master Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
}
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_order": "ASC",
- "title_field": "item_code",
- "track_changes": 1,
- "track_seen": 0,
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_order": "ASC",
+ "title_field": "item_code",
+ "track_changes": 1,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/item_price/test_item_price.py b/erpnext/stock/doctype/item_price/test_item_price.py
index 455dff4e154..3782f540cf2 100644
--- a/erpnext/stock/doctype/item_price/test_item_price.py
+++ b/erpnext/stock/doctype/item_price/test_item_price.py
@@ -11,7 +11,7 @@ from erpnext.stock.doctype.item_price.item_price import ItemPriceDuplicateItem
class TestItemPrice(unittest.TestCase):
def setUp(self):
- frappe.db.sql("delete from `tabItem Price`")
+ frappe.db.sql("delete from `tabItem Price`")
make_test_records_for_doctype("Item Price", force=True)
def test_duplicate_item(self):
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index cb51e220b83..d09f24a965f 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -13,7 +13,7 @@ from erpnext.controllers.buying_controller import BuyingController
from erpnext.accounts.utils import get_account_currency
from frappe.desk.notifications import clear_doctype_notifications
from erpnext.buying.utils import check_for_closed_status
-from erpnext.assets.doctype.asset.asset import get_asset_account
+from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_disabled
from six import iteritems
form_grid_templates = {
@@ -31,7 +31,7 @@ class PurchaseReceipt(BuyingController):
'target_parent_dt': 'Purchase Order',
'target_parent_field': 'per_received',
'target_ref_field': 'qty',
- 'source_field': 'qty',
+ 'source_field': 'received_qty',
'percent_join_field': 'purchase_order',
'overflow_type': 'receipt'
},
@@ -258,7 +258,8 @@ class PurchaseReceipt(BuyingController):
d.rejected_warehouse not in warehouse_with_no_account:
warehouse_with_no_account.append(d.warehouse)
- self.get_asset_gl_entry(gl_entries)
+ if not is_cwip_accounting_disabled():
+ self.get_asset_gl_entry(gl_entries)
# Cost center-wise amount breakup for other charges included for valuation
valuation_tax = {}
for tax in self.get("taxes"):
@@ -406,10 +407,7 @@ def update_billed_amount_based_on_po(po_detail, update_modified=True):
def make_purchase_invoice(source_name, target_doc=None):
from frappe.model.mapper import get_mapped_doc
doc = frappe.get_doc('Purchase Receipt', source_name)
- purchase_orders = [d.purchase_order for d in doc.items]
- returned_qty_map_against_po = get_returned_qty_map_against_po(purchase_orders)
- returned_qty_map_against_pr = get_returned_qty_map_against_pr(source_name)
-
+ returned_qty_map = get_returned_qty_map(source_name)
invoiced_qty_map = get_invoiced_qty_map(source_name)
def set_missing_values(source, target):
@@ -418,19 +416,18 @@ def make_purchase_invoice(source_name, target_doc=None):
doc = frappe.get_doc(target)
doc.ignore_pricing_rule = 1
+ doc.run_method("onload")
doc.run_method("set_missing_values")
doc.run_method("calculate_taxes_and_totals")
def update_item(source_doc, target_doc, source_parent):
target_doc.qty, returned_qty = get_pending_qty(source_doc)
- if not source_doc.purchase_order_item:
- returned_qty_map_against_pr[source_doc.item_code] = returned_qty
+ returned_qty_map[source_doc.item_code] = returned_qty
def get_pending_qty(item_row):
- pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0) \
- - returned_qty_map_against_po.get(item_row.purchase_order_item, 0)
- returned_qty = flt(returned_qty_map_against_pr.get(item_row.item_code, 0))
- if not item_row.purchase_order_item:
+ pending_qty = item_row.qty - invoiced_qty_map.get(item_row.name, 0)
+ returned_qty = flt(returned_qty_map.get(item_row.item_code, 0))
+ if returned_qty:
if returned_qty >= pending_qty:
pending_qty = 0
returned_qty -= pending_qty
@@ -461,7 +458,7 @@ def make_purchase_invoice(source_name, target_doc=None):
"asset": "asset",
},
"postprocess": update_item,
- "filter": lambda d: get_pending_qty(d)[0]<=0
+ "filter": lambda d: get_pending_qty(d)[0] <= 0 if not doc.get("is_return") else get_pending_qty(d)[0] > 0
},
"Purchase Taxes and Charges": {
"doctype": "Purchase Taxes and Charges",
@@ -483,19 +480,7 @@ def get_invoiced_qty_map(purchase_receipt):
return invoiced_qty_map
-def get_returned_qty_map_against_po(purchase_orders):
- """returns a map: {so_detail: returned_qty}"""
- returned_qty_map = {}
-
- for name, returned_qty in frappe.get_all('Purchase Order Item', fields = ["name", "returned_qty"],
- filters = {'parent': ('in', purchase_orders), 'docstatus': 1}, as_list=1):
- if not returned_qty_map.get(name):
- returned_qty_map[name] = 0
- returned_qty_map[name] += returned_qty
-
- return returned_qty_map
-
-def get_returned_qty_map_against_pr(purchase_receipt):
+def get_returned_qty_map(purchase_receipt):
"""returns a map: {so_detail: returned_qty}"""
returned_qty_map = frappe._dict(frappe.db.sql("""select pr_item.item_code, sum(abs(pr_item.qty)) as qty
from `tabPurchase Receipt Item` pr_item, `tabPurchase Receipt` pr
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index c5ae838c8f0..d124ae4747d 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -418,7 +418,7 @@ class TestPurchaseReceipt(unittest.TestCase):
pi = make_purchase_invoice(pr.name)
self.assertEquals(pi.items[0].qty, 3)
- def test_make_purchase_invoice_from_dn_with_returned_qty_against_dn(self):
+ def test_make_purchase_invoice_from_pr_with_returned_qty_duplicate_items(self):
pr1 = make_purchase_receipt(qty=8, do_not_submit=True)
pr1.append("items", {
"item_code": "_Test Item",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 3a5253019af..dc9c4fc3fe8 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -802,7 +802,7 @@ class StockEntry(StockController):
# item dict = { item_code: {qty, description, stock_uom} }
item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=qty,
- fetch_exploded = self.use_multi_level_bom)
+ fetch_exploded = self.use_multi_level_bom, fetch_qty_in_stock_uom=False)
used_alternative_items = get_used_alternative_items(work_order = self.work_order)
for item in itervalues(item_dict):
@@ -1031,7 +1031,7 @@ class StockEntry(StockController):
se_child.item_code = item_dict[d].get('item_code') or cstr(d)
se_child.item_name = item_dict[d]["item_name"]
se_child.description = item_dict[d]["description"]
- se_child.uom = stock_uom
+ se_child.uom = item_dict[d]["uom"] if item_dict[d].get("uom") else stock_uom
se_child.stock_uom = stock_uom
se_child.qty = flt(item_dict[d]["qty"], se_child.precision("qty"))
se_child.expense_account = item_dict[d].get("expense_account") or expense_account
@@ -1049,8 +1049,9 @@ class StockEntry(StockController):
se_child.t_warehouse = self.to_warehouse
# in stock uom
- se_child.transfer_qty = flt(item_dict[d]["qty"], se_child.precision("qty"))
- se_child.conversion_factor = 1.00
+ se_child.conversion_factor = flt(item_dict[d].get("conversion_factor")) or 1
+ se_child.transfer_qty = flt(item_dict[d]["qty"]*se_child.conversion_factor, se_child.precision("qty"))
+
# to be assigned for finished item
se_child.bom_no = bom_no
diff --git a/erpnext/stock/doctype/warehouse/warehouse.json b/erpnext/stock/doctype/warehouse/warehouse.json
index 0d60a5ca384..63e374f6d78 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.json
+++ b/erpnext/stock/doctype/warehouse/warehouse.json
@@ -51,6 +51,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "description": "If blank, parent Warehouse Account or company default will be considered",
"fieldname": "warehouse_name",
"fieldtype": "Data",
"hidden": 0,
@@ -870,7 +871,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-29 06:26:48.647225",
+ "modified": "2018-08-29 06:26:49.647225",
"modified_by": "Administrator",
"module": "Stock",
"name": "Warehouse",
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 74f35953e2a..1c614dffab9 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -431,7 +431,7 @@ def insert_item_price(args):
def get_item_price(args, item_code, ignore_party=False):
"""
Get name, price_list_rate from Item Price based on conditions
- Check if the Derised qty is within the increment of the packing list.
+ Check if the desired qty is within the increment of the packing list.
:param args: dict (or frappe._dict) with mandatory fields price_list, uom
optional fields min_qty, transaction_date, customer, supplier
:param item_code: str, Item Doctype field item_code
@@ -469,11 +469,11 @@ def get_price_list_rate_for(args, item_code):
for min_qty 9 and min_qty 20. It returns Item Price Rate for qty 9 as
the best fit in the range of avaliable min_qtyies
- :param customer: link to Customer DocType
- :param supplier: link to Supplier DocType
+ :param customer: link to Customer DocType
+ :param supplier: link to Supplier DocType
:param price_list: str (Standard Buying or Standard Selling)
:param item_code: str, Item Doctype field item_code
- :param qty: Derised Qty
+ :param qty: Desired Qty
:param transaction_date: Date of the price
"""
item_price_args = {
@@ -490,7 +490,7 @@ def get_price_list_rate_for(args, item_code):
price_list_rate = get_item_price(item_price_args, item_code)
if price_list_rate:
desired_qty = args.get("qty")
- if check_packing_list(price_list_rate[0][0], desired_qty, item_code):
+ if desired_qty and check_packing_list(price_list_rate[0][0], desired_qty, item_code):
item_price_data = price_list_rate
else:
for field in ["customer", "supplier", "min_qty"]:
@@ -498,7 +498,7 @@ def get_price_list_rate_for(args, item_code):
general_price_list_rate = get_item_price(item_price_args, item_code, ignore_party=args.get("ignore_party"))
if not general_price_list_rate and args.get("uom") != args.get("stock_uom"):
- item_price_args["args"] = args.get("stock_uom")
+ item_price_args["uom"] = args.get("stock_uom")
general_price_list_rate = get_item_price(item_price_args, item_code, ignore_party=args.get("ignore_party"))
if general_price_list_rate:
@@ -514,19 +514,22 @@ def get_price_list_rate_for(args, item_code):
def check_packing_list(price_list_rate_name, desired_qty, item_code):
"""
- Check if the Derised qty is within the increment of the packing list.
+ Check if the desired qty is within the increment of the packing list.
:param price_list_rate_name: Name of Item Price
- :param desired_qty: Derised Qt
+ :param desired_qty: Desired Qt
:param item_code: str, Item Doctype field item_code
- :param qty: Derised Qt
+ :param qty: Desired Qt
"""
+ flag = True
item_price = frappe.get_doc("Item Price", price_list_rate_name)
- if desired_qty and item_price.packing_unit:
+ if item_price.packing_unit:
packing_increment = desired_qty % item_price.packing_unit
- if packing_increment == 0:
- return True
+ if packing_increment != 0:
+ flag = False
+
+ return flag
def validate_price_list(args):
if args.get("price_list"):
@@ -603,28 +606,39 @@ def get_pos_profile_item_details(company, args, pos_profile=None, update_data=Fa
@frappe.whitelist()
def get_pos_profile(company, pos_profile=None, user=None):
- if pos_profile:
- return frappe.get_cached_doc('POS Profile', pos_profile)
+ if pos_profile: return frappe.get_cached_doc('POS Profile', pos_profile)
if not user:
user = frappe.session['user']
+ condition = "pfu.user = %(user)s AND pfu.default=1"
+ if user and company:
+ condition = "pfu.user = %(user)s AND pf.company = %(company)s AND pfu.default=1"
+
pos_profile = frappe.db.sql("""SELECT pf.*
FROM
`tabPOS Profile` pf LEFT JOIN `tabPOS Profile User` pfu
ON
pf.name = pfu.parent
WHERE
- (
- (pfu.user = %(user)s AND pf.company = %(company)s AND pfu.default=1)
- OR (pfu.user = %(user)s AND pfu.default=1)
- OR (ifnull(pfu.user, '') = '' AND pf.company = %(company)s)
- ) AND pf.disabled = 0
- """, {
+ {cond} AND pf.disabled = 0
+ """.format(cond = condition), {
'user': user,
'company': company
}, as_dict=1)
+ if not pos_profile and company:
+ pos_profile = frappe.db.sql("""SELECT pf.*
+ FROM
+ `tabPOS Profile` pf LEFT JOIN `tabPOS Profile User` pfu
+ ON
+ pf.name = pfu.parent
+ WHERE
+ pf.company = %(company)s AND pf.disabled = 0
+ """, {
+ 'company': company
+ }, as_dict=1)
+
return pos_profile and pos_profile[0] or None
def get_serial_nos_by_fifo(args, sales_order=None):
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index ef9fbe41c02..af5e5e9f0a0 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -22,12 +22,8 @@ def execute(filters=None):
for sle in sl_entries:
item_detail = item_details[sle.item_code]
- data.append([sle.date, sle.item_code, item_detail.item_name, item_detail.item_group,
- item_detail.brand, item_detail.description, sle.warehouse,
- item_detail.stock_uom, sle.actual_qty, sle.qty_after_transaction,
- (sle.incoming_rate if sle.actual_qty > 0 else 0.0),
- sle.valuation_rate, sle.stock_value, sle.voucher_type, sle.voucher_no,
- sle.batch_no, sle.serial_no, sle.project, sle.company])
+ sle.update(item_detail)
+ data.append(sle)
if include_uom:
conversion_factors.append(item_detail.conversion_factor)
@@ -155,10 +151,10 @@ def get_opening_balance(filters, columns):
"posting_date": filters.from_date,
"posting_time": "00:00:00"
})
- row = [""]*len(columns)
- row[1] = _("'Opening'")
- for i, v in ((9, 'qty_after_transaction'), (11, 'valuation_rate'), (12, 'stock_value')):
- row[i] = last_entry.get(v, 0)
+ row = {}
+ row["item_code"] = _("'Opening'")
+ for dummy, v in ((9, 'qty_after_transaction'), (11, 'valuation_rate'), (12, 'stock_value')):
+ row[v] = last_entry.get(v, 0)
return row
diff --git a/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py b/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
index 2a02b469fb0..6a86889aa3d 100644
--- a/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
+++ b/erpnext/stock/report/supplier_wise_sales_analytics/supplier_wise_sales_analytics.py
@@ -94,9 +94,13 @@ def get_suppliers_details(filters):
item_supplier_map.setdefault(d.item_code, []).append(d.supplier)
if supplier:
+ invalid_items = []
for item_code, suppliers in iteritems(item_supplier_map):
if supplier not in suppliers:
- del item_supplier_map[item_code]
+ invalid_items.append(item_code)
+
+ for item_code in invalid_items:
+ del item_supplier_map[item_code]
return item_supplier_map
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 223a603004c..b7461c485f6 100644
--- a/erpnext/stock/report/total_stock_summary/total_stock_summary.js
+++ b/erpnext/stock/report/total_stock_summary/total_stock_summary.js
@@ -18,7 +18,9 @@ frappe.query_reports["Total Stock Summary"] = {
"label": __("Company"),
"fieldtype": "Link",
"width": "80",
- "options": "Company"
+ "options": "Company",
+ "default": frappe.defaults.get_user_default("Company"),
+ "reqd": 1
},
]
}
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 21cf2f78486..a95d9ee959e 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
@@ -20,6 +21,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "subject_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -53,6 +55,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
+ "fetch_if_empty": 0,
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
@@ -85,6 +88,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "subject",
"fieldtype": "Data",
"hidden": 0,
@@ -93,7 +97,7 @@
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
- "in_standard_filter": 0,
+ "in_standard_filter": 1,
"label": "Subject",
"length": 0,
"no_copy": 0,
@@ -116,6 +120,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "issue_type",
"fieldtype": "Link",
"hidden": 0,
@@ -149,6 +154,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "cb00",
"fieldtype": "Column Break",
"hidden": 0,
@@ -180,6 +186,7 @@
"collapsible": 0,
"columns": 0,
"default": "Open",
+ "fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
@@ -215,6 +222,7 @@
"collapsible": 0,
"columns": 0,
"default": "Medium",
+ "fetch_if_empty": 0,
"fieldname": "priority",
"fieldtype": "Select",
"hidden": 0,
@@ -249,6 +257,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.__islocal",
+ "fetch_if_empty": 0,
"fieldname": "raised_by",
"fieldtype": "Data",
"hidden": 0,
@@ -283,6 +292,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "email_account",
"fieldtype": "Link",
"hidden": 0,
@@ -316,6 +326,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer",
"fieldtype": "Link",
"hidden": 0,
@@ -350,6 +361,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_7",
"fieldtype": "Section Break",
"hidden": 0,
@@ -383,6 +395,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
+ "fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -416,6 +429,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "response",
"fieldtype": "Section Break",
"hidden": 0,
@@ -448,6 +462,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "mins_to_first_response",
"fieldtype": "Float",
"hidden": 0,
@@ -480,6 +495,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "first_responded_on",
"fieldtype": "Datetime",
"hidden": 0,
@@ -511,6 +527,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "additional_info",
"fieldtype": "Section Break",
"hidden": 0,
@@ -543,6 +560,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "lead",
"fieldtype": "Link",
"hidden": 0,
@@ -575,6 +593,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "contact",
"fieldtype": "Link",
"hidden": 0,
@@ -607,6 +626,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "column_break_16",
"fieldtype": "Column Break",
"hidden": 0,
@@ -638,6 +658,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "customer_name",
"fieldtype": "Data",
"hidden": 0,
@@ -671,6 +692,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "project",
"fieldtype": "Link",
"hidden": 0,
@@ -704,6 +726,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -736,6 +759,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "section_break_19",
"fieldtype": "Section Break",
"hidden": 0,
@@ -769,6 +793,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
+ "fetch_if_empty": 0,
"fieldname": "resolution_details",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -803,6 +828,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
+ "fetch_if_empty": 0,
"fieldname": "column_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -835,6 +861,7 @@
"collapsible": 0,
"columns": 0,
"default": "Today",
+ "fetch_if_empty": 0,
"fieldname": "opening_date",
"fieldtype": "Date",
"hidden": 0,
@@ -868,6 +895,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "opening_time",
"fieldtype": "Time",
"hidden": 0,
@@ -902,6 +930,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:!doc.__islocal",
+ "fetch_if_empty": 0,
"fieldname": "resolution_date",
"fieldtype": "Datetime",
"hidden": 0,
@@ -935,6 +964,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "content_type",
"fieldtype": "Data",
"hidden": 1,
@@ -966,6 +996,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "attachment",
"fieldtype": "Attach",
"hidden": 1,
@@ -998,6 +1029,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fetch_if_empty": 0,
"fieldname": "via_customer_portal",
"fieldtype": "Check",
"hidden": 0,
@@ -1035,7 +1067,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-21 14:44:27.615004",
+ "modified": "2019-04-24 23:09:48.711076",
"modified_by": "Administrator",
"module": "Support",
"name": "Issue",
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 0b5eb539c8d..2e74b997f61 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -9,6 +9,7 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import now
from frappe.utils.user import is_website_user
+from frappe.email.inbox import link_communication_to_document
sender_field = "raised_by"
@@ -160,3 +161,20 @@ def has_website_permission(doc, ptype, user, verbose=False):
def update_issue(contact, method):
"""Called when Contact is deleted"""
frappe.db.sql("""UPDATE `tabIssue` set contact='' where contact=%s""", contact.name)
+
+@frappe.whitelist()
+def make_issue_from_communication(communication, ignore_communication_links=False):
+ """ raise a issue from email """
+
+ doc = frappe.get_doc("Communication", communication)
+ issue = frappe.get_doc({
+ "doctype": "Issue",
+ "subject": doc.subject,
+ "communication_medium": doc.communication_medium,
+ "raised_by": doc.sender or "",
+ "raised_by_phone": doc.phone_no or ""
+ }).insert(ignore_permissions=True)
+
+ link_communication_to_document(doc, "Issue", issue.name, ignore_communication_links)
+
+ return issue.name
\ No newline at end of file
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
index ef69e200d9c..af98fc7987a 100644
--- a/erpnext/templates/includes/product_page.js
+++ b/erpnext/templates/includes/product_page.js
@@ -14,7 +14,9 @@ frappe.ready(function() {
callback: function(r) {
if(r.message) {
if(r.message.cart_settings.enabled) {
- $(".item-cart, .item-price, .item-stock").toggleClass("hide", (!!!r.message.product_info.price || !!!r.message.product_info.in_stock));
+ let hide_add_to_cart = !r.message.product_info.price
+ || (!r.message.product_info.in_stock && !r.message.cart_settings.allow_items_not_in_stock);
+ $(".item-cart, .item-price, .item-stock").toggleClass('hide', hide_add_to_cart);
}
if(r.message.cart_settings.show_price) {
$(".item-price").toggleClass("hide", false);
diff --git a/erpnext/templates/pages/cart.html b/erpnext/templates/pages/cart.html
index fb0c05fcddb..04d737f0557 100644
--- a/erpnext/templates/pages/cart.html
+++ b/erpnext/templates/pages/cart.html
@@ -60,7 +60,7 @@
{{doc.terms}}
{% endif %}
diff --git a/erpnext/templates/pages/regional/india/update-gstin.html b/erpnext/templates/pages/regional/india/update-gstin.html
index 3d9ab5d1253..d738fb4993e 100644
--- a/erpnext/templates/pages/regional/india/update-gstin.html
+++ b/erpnext/templates/pages/regional/india/update-gstin.html
@@ -32,7 +32,7 @@
Please update your GSTIN for us to issue correct tax invoice