Merge branch 'develop' of github.com:frappe/erpnext into employee-leave-balance-summary
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index ee37c8d..106384a 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '12.1.0'
+__version__ = '12.1.1'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
index 648cc68..bc07b6d 100644
--- a/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
+++ b/erpnext/accounts/dashboard_chart_source/account_balance_timeline/account_balance_timeline.py
@@ -12,11 +12,14 @@
@frappe.whitelist()
@cache_source
-def get(chart_name=None, from_date = None, to_date = None):
- chart = frappe.get_doc('Dashboard Chart', chart_name)
+def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_date = None):
+ if chart_name:
+ chart = frappe.get_doc('Dashboard Chart', chart_name)
+ else:
+ chart = frappe._dict(frappe.parse_json(chart))
timespan = chart.timespan
timegrain = chart.time_interval
- filters = json.loads(chart.filters_json)
+ filters = frappe.parse_json(chart.filters_json)
account = filters.get("account")
company = filters.get("company")
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json b/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json
index b042bcc..adfa9f8 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/verified/de_kontenplan_SKR04_with_account_number.json
@@ -406,7 +406,11 @@
"is_group": 1,
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
"account_number": "9960"
- },
+ },
+ "Debitoren": {
+ "is_group": 1,
+ "account_number": "10000"
+ },
"Forderungen aus Lieferungen und Leistungen": {
"account_number": "1200",
"account_type": "Receivable"
@@ -1077,7 +1081,7 @@
}
}
},
- "C - Verb.": {
+ "C - Verbindlichkeiten": {
"account_type": "Payable",
"1 - Anleihen": {
"is_group": 1,
@@ -1193,7 +1197,15 @@
"is_group": 1,
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
"account_number": "9964"
- },
+ },
+ "Kreditoren": {
+ "account_number": "70000",
+ "is_group": 1,
+ "Wareneingangs-Verrechnungskonto" : {
+ "account_number": "70001",
+ "account_type": "Stock Received But Not Billed"
+ }
+ },
"Verb. aus Lieferungen und Leistungen": {
"account_number": "3300",
"account_type": "Payable"
@@ -1682,90 +1694,6 @@
"account_type": "Income Account"
}
},
- "Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
- "is_group": 1,
- "Erl\u00f6sschm\u00e4lerungen": {
- "account_number": "4700"
- },
- "Erl\u00f6sschm\u00e4lerungen aus steuerfreien Ums\u00e4tzen \u00a7 4 Nr. 1a UStG": {
- "account_number": "4705"
- },
- "Erl\u00f6sschm\u00e4lerungen 7 % USt": {
- "account_number": "4710"
- },
- "Erl\u00f6sschm\u00e4lerungen 19 % USt": {
- "account_number": "4720"
- },
- "Erl\u00f6sschm\u00e4lerungen 16 % USt": {
- "account_number": "4723"
- },
- "Erl\u00f6sschm\u00e4lerungen aus steuerfreien innergem. Lieferungen": {
- "account_number": "4724"
- },
- "Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 7 % USt": {
- "account_number": "4725"
- },
- "Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 19 % USt": {
- "account_number": "4726"
- },
- "Erl\u00f6sschm\u00e4lerungen aus im anderen EU-Land steuerpfl. Lieferungen": {
- "account_number": "4727"
- },
- "Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 16 % USt": {
- "account_number": "4729"
- },
- "Gew\u00e4hrte Skonti (Gruppe)": {
- "is_group": 1,
- "Gew. Skonti": {
- "account_number": "4730"
- },
- "Gew. Skonti 7 % USt": {
- "account_number": "4731"
- },
- "Gew. Skonti 19 % USt": {
- "account_number": "4736"
- },
- "Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": {
- "account_number": "4738"
- },
- "Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": {
- "account_number": "4741"
- },
- "Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": {
- "account_number": "4742"
- },
- "Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": {
- "account_number": "4743"
- },
- "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": {
- "account_number": "4745"
- },
- "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": {
- "account_number": "4746"
- },
- "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": {
- "account_number": "4748"
- }
- },
- "Gew\u00e4hrte Boni 7 % USt": {
- "account_number": "4750"
- },
- "Gew\u00e4hrte Boni 19 % USt": {
- "account_number": "4760"
- },
- "Gew\u00e4hrte Boni": {
- "account_number": "4769"
- },
- "Gew\u00e4hrte Rabatte": {
- "account_number": "4770"
- },
- "Gew\u00e4hrte Rabatte 7 % USt": {
- "account_number": "4780"
- },
- "Gew\u00e4hrte Rabatte 19 % USt": {
- "account_number": "4790"
- }
- },
"Grundst\u00fccksertr\u00e4ge (Gruppe)": {
"is_group": 1,
"Grundst\u00fccksertr\u00e4ge": {
@@ -2049,48 +1977,6 @@
"Erh. Skonti aus Erwerb Waren als letzter Abnehmer innerh. Dreiecksgesch. 19% Vorst. u. 19% Ust.": {
"account_number": "5793"
}
- },
- "Erhaltene Boni (Gruppe)": {
- "is_group": 1,
- "Erhaltene Boni 7 % Vorsteuer": {
- "account_number": "5750"
- },
- "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
- "account_number": "5753"
- },
- "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
- "account_number": "5754"
- },
- "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
- "account_number": "5755"
- },
- "Erhaltene Boni 19 % Vorsteuer": {
- "account_number": "5760"
- },
- "Erhaltene Boni": {
- "account_number": "5769"
- }
- },
- "Erhaltene Rabatte (Gruppe)": {
- "is_group": 1,
- "Erhaltene Rabatte": {
- "account_number": "5770"
- },
- "Erhaltene Rabatte 7 % Vorsteuer": {
- "account_number": "5780"
- },
- "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
- "account_number": "5783"
- },
- "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
- "account_number": "5784"
- },
- "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
- "account_number": "5785"
- },
- "Erhaltene Rabatte 19 % Vorsteuer": {
- "account_number": "5790"
- }
}
},
"Bezugsnebenkosten (Gruppe)": {
@@ -2409,7 +2295,49 @@
},
"6 - sonstige betriebliche Ertr\u00e4ge": {
"root_type": "Income",
- "is_group": 1,
+ "is_group": 1,
+ "Erhaltene Boni (Gruppe)": {
+ "is_group": 1,
+ "Erhaltene Boni 7 % Vorsteuer": {
+ "account_number": "5750"
+ },
+ "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
+ "account_number": "5753"
+ },
+ "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
+ "account_number": "5754"
+ },
+ "Erhaltene Boni aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
+ "account_number": "5755"
+ },
+ "Erhaltene Boni 19 % Vorsteuer": {
+ "account_number": "5760"
+ },
+ "Erhaltene Boni": {
+ "account_number": "5769"
+ }
+ },
+ "Erhaltene Rabatte (Gruppe)": {
+ "is_group": 1,
+ "Erhaltene Rabatte": {
+ "account_number": "5770"
+ },
+ "Erhaltene Rabatte 7 % Vorsteuer": {
+ "account_number": "5780"
+ },
+ "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe": {
+ "account_number": "5783"
+ },
+ "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 7% Vorsteuer": {
+ "account_number": "5784"
+ },
+ "Erhaltene Rabatte aus Einkauf Roh-, Hilfs- und Betriebsstoffe 19% Vorsteuer": {
+ "account_number": "5785"
+ },
+ "Erhaltene Rabatte 19 % Vorsteuer": {
+ "account_number": "5790"
+ }
+ },
"Andere aktivierte Eigenleistungen": {
"account_number": "4820"
},
@@ -2732,7 +2660,91 @@
},
"7 - sonstige betriebliche Aufwendungen": {
"root_type": "Expense",
- "is_group": 1,
+ "is_group": 1,
+ "Erl\u00f6sschm\u00e4lerungen (Gruppe)": {
+ "is_group": 1,
+ "Erl\u00f6sschm\u00e4lerungen": {
+ "account_number": "4700"
+ },
+ "Erl\u00f6sschm\u00e4lerungen aus steuerfreien Ums\u00e4tzen \u00a7 4 Nr. 1a UStG": {
+ "account_number": "4705"
+ },
+ "Erl\u00f6sschm\u00e4lerungen 7 % USt": {
+ "account_number": "4710"
+ },
+ "Erl\u00f6sschm\u00e4lerungen 19 % USt": {
+ "account_number": "4720"
+ },
+ "Erl\u00f6sschm\u00e4lerungen 16 % USt": {
+ "account_number": "4723"
+ },
+ "Erl\u00f6sschm\u00e4lerungen aus steuerfreien innergem. Lieferungen": {
+ "account_number": "4724"
+ },
+ "Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 7 % USt": {
+ "account_number": "4725"
+ },
+ "Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 19 % USt": {
+ "account_number": "4726"
+ },
+ "Erl\u00f6sschm\u00e4lerungen aus im anderen EU-Land steuerpfl. Lieferungen": {
+ "account_number": "4727"
+ },
+ "Erl\u00f6sschm\u00e4lerungen aus im Inland steuerpfl. EU-Lieferungen 16 % USt": {
+ "account_number": "4729"
+ },
+ "Gew\u00e4hrte Skonti (Gruppe)": {
+ "is_group": 1,
+ "Gew. Skonti": {
+ "account_number": "4730"
+ },
+ "Gew. Skonti 7 % USt": {
+ "account_number": "4731"
+ },
+ "Gew. Skonti 19 % USt": {
+ "account_number": "4736"
+ },
+ "Gew. Skonti aus Lieferungen von Mobilfunkger./Schaltkr., f. die der Leistungsempf. die Ust. schuldet": {
+ "account_number": "4738"
+ },
+ "Gew. Skonti aus Leistungen, f. die der Leistungsempf. die Umsatzsteuer nach \u00a7 13b UStG schuldet": {
+ "account_number": "4741"
+ },
+ "Gew. Skonti aus Erl\u00f6sen aus im anderen EU-Land steuerpfl. Leistungen, f. die der Leistungsempf. die Ust. schuldet": {
+ "account_number": "4742"
+ },
+ "Gew. Skonti aus steuerfreien innergem. Lieferungen \u00a7 4 Nr. 1b UStG": {
+ "account_number": "4743"
+ },
+ "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen": {
+ "account_number": "4745"
+ },
+ "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 7% USt": {
+ "account_number": "4746"
+ },
+ "Gew. Skonti aus im Inland steuerpfl. EU-Lieferungen 19% USt": {
+ "account_number": "4748"
+ }
+ },
+ "Gew\u00e4hrte Boni 7 % USt": {
+ "account_number": "4750"
+ },
+ "Gew\u00e4hrte Boni 19 % USt": {
+ "account_number": "4760"
+ },
+ "Gew\u00e4hrte Boni": {
+ "account_number": "4769"
+ },
+ "Gew\u00e4hrte Rabatte": {
+ "account_number": "4770"
+ },
+ "Gew\u00e4hrte Rabatte 7 % USt": {
+ "account_number": "4780"
+ },
+ "Gew\u00e4hrte Rabatte 19 % USt": {
+ "account_number": "4790"
+ }
+ },
"Sonstige betriebliche Aufwendungen": {
"account_number": "6300"
},
@@ -3609,18 +3621,6 @@
"Ertr\u00e4ge aus der Aufl\u00f6sung von R\u00fcckstellungen f. sonstige Steuern": {
"account_number": "7694"
}
- },
- "Debitoren": {
- "root_type": "Asset",
- "is_group": 1
- },
- "Kreditoren": {
- "root_type": "Liability",
- "is_group": 1,
- "Wareneingangs-Verrechnungskonto" : {
- "account_number": "70001",
- "account_type": "Stock Received But Not Billed"
- }
}
}
}
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 95c5dd5..abbac77 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -304,8 +304,10 @@
from erpnext.selling.doctype.customer.customer import check_credit_limit
validate_against_credit_limit = False
- bypass_credit_limit_check_at_sales_order = cint(frappe.get_cached_value("Customer", self.customer,
- "bypass_credit_limit_check_at_sales_order"))
+ bypass_credit_limit_check_at_sales_order = frappe.db.get_value("Customer Credit Limit",
+ filters={'parent': self.customer, 'parenttype': 'Customer', 'company': self.company},
+ fieldname=["bypass_credit_limit_check"])
+
if bypass_credit_limit_check_at_sales_order:
validate_against_credit_limit = True
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index e42f4af..59936d5 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -292,8 +292,11 @@
party_account_currency = frappe.db.get_value("Account", account.account, "account_currency", cache=True)
existing_gle_currency = get_party_gle_currency(doc.doctype, doc.name, account.company)
- company_default_currency = frappe.get_cached_value('Company',
- frappe.db.get_default("Company"), "default_currency")
+ if frappe.db.get_default("Company"):
+ company_default_currency = frappe.get_cached_value('Company',
+ frappe.db.get_default("Company"), "default_currency")
+ else:
+ company_default_currency = frappe.db.get_value('Company', account.company, "default_currency")
if existing_gle_currency and party_account_currency != existing_gle_currency:
frappe.throw(_("Accounting entries have already been made in currency {0} for company {1}. Please select a receivable or payable account with currency {0}.").format(existing_gle_currency, account.company))
@@ -365,7 +368,7 @@
.format(formatdate(default_due_date)))
@frappe.whitelist()
-def get_address_tax_category(tax_category, billing_address=None, shipping_address=None):
+def get_address_tax_category(tax_category=None, billing_address=None, shipping_address=None):
addr_tax_category_from = frappe.db.get_single_value("Accounts Settings", "determine_address_tax_category_from")
if addr_tax_category_from == "Shipping Address":
if shipping_address:
@@ -607,4 +610,4 @@
.format(("credit") if party_type == "Customer" else "debit", cond) , party_type)
if data:
- return frappe._dict(data)
\ No newline at end of file
+ return frappe._dict(data)
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index d00bcf6..791f3f8 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -1,275 +1,269 @@
<style>
-.print-format {
- padding: 4mm;
- font-size: 8.0pt !important;
-}
-.print-format td {
- vertical-align:middle !important;
-}
-</style>
+ .print-format {
+ padding: 4mm;
+ font-size: 8.0pt !important;
+ }
+ .print-format td {
+ vertical-align:middle !important;
+ }
+ </style>
-<h2 class="text-center" style="margin-top:0">{%= __(report.report_name) %}</h2>
-<h4 class="text-center">
- {% if (filters.customer_name) { %}
- {%= filters.customer_name %}
- {% } else { %}
- {%= filters.customer || filters.supplier %}
- {% } %}
-</h4>
-<h6 class="text-center">
- {% if (filters.tax_id) { %}
- {%= __("Tax Id: ")%} {%= filters.tax_id %}
+ <h2 class="text-center" style="margin-top:0">{%= __(report.report_name) %}</h2>
+ <h4 class="text-center">
+ {% if (filters.customer_name) { %}
+ {%= filters.customer_name %}
+ {% } else { %}
+ {%= filters.customer || filters.supplier %}
{% } %}
-</h6>
-<h5 class="text-center">
- {%= __(filters.ageing_based_on) %}
- {%= __("Until") %}
- {%= frappe.datetime.str_to_user(filters.report_date) %}
-</h5>
+ </h4>
+ <h6 class="text-center">
+ {% if (filters.tax_id) { %}
+ {%= __("Tax Id: ")%} {%= filters.tax_id %}
+ {% } %}
+ </h6>
+ <h5 class="text-center">
+ {%= __(filters.ageing_based_on) %}
+ {%= __("Until") %}
+ {%= frappe.datetime.str_to_user(filters.report_date) %}
+ </h5>
-<div class="clearfix">
- <div class="pull-left">
- {% if(filters.payment_terms) { %}
- <strong>{%= __("Payment Terms") %}:</strong> {%= filters.payment_terms %}
- {% } %}
+ <div class="clearfix">
+ <div class="pull-left">
+ {% if(filters.payment_terms) { %}
+ <strong>{%= __("Payment Terms") %}:</strong> {%= filters.payment_terms %}
+ {% } %}
+ </div>
+ <div class="pull-right">
+ {% if(filters.credit_limit) { %}
+ <strong>{%= __("Credit Limit") %}:</strong> {%= format_currency(filters.credit_limit) %}
+ {% } %}
+ </div>
</div>
- <div class="pull-right">
- {% if(filters.credit_limit) { %}
- <strong>{%= __("Credit Limit") %}:</strong> {%= format_currency(filters.credit_limit) %}
+
+ {% if(filters.show_future_payments) { %}
+ {% var balance_row = data.slice(-1).pop();
+ var range1 = report.columns[11].label;
+ var range2 = report.columns[12].label;
+ var range3 = report.columns[13].label;
+ var range4 = report.columns[14].label;
+ var range5 = report.columns[15].label;
+ %}
+ {% if(balance_row) { %}
+ <table class="table table-bordered table-condensed">
+ <caption class="text-right">(Amount in {%= data[0]["currency"] || "" %})</caption>
+ <colgroup>
+ <col style="width: 30mm;">
+ <col style="width: 18mm;">
+ <col style="width: 18mm;">
+ <col style="width: 18mm;">
+ <col style="width: 18mm;">
+ <col style="width: 18mm;">
+ <col style="width: 18mm;">
+ <col style="width: 18mm;">
+ </colgroup>
+
+ <thead>
+ <tr>
+ <th>{%= __(" ") %}</th>
+ <th>{%= __(range1) %}</th>
+ <th>{%= __(range2) %}</th>
+ <th>{%= __(range3) %}</th>
+ <th>{%= __(range4) %}</th>
+ <th>{%= __(range5) %}</th>
+ <th>{%= __("Total") %}</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{%= __("Total Outstanding") %}</td>
+ <td class="text-right">{%= format_number(balance_row["range1"], null, 2) %}</td>
+ <td class="text-right">{%= format_currency(balance_row["range2"]) %}</td>
+ <td class="text-right">{%= format_currency(balance_row["range3"]) %}</td>
+ <td class="text-right">{%= format_currency(balance_row["range4"]) %}</td>
+ <td class="text-right">{%= format_currency(balance_row["range5"]) %}</td>
+ <td class="text-right">
+ {%= format_currency(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) %}
+ </td>
+ </tr>
+ <td>{%= __("Future Payments") %}</td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ <td class="text-right">
+ {%= format_currency(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) %}
+ </td>
+ <tr class="cvs-footer">
+ <th class="text-left">{%= __("Cheques Required") %}</th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th class="text-right">
+ {%= format_currency(flt(balance_row["outstanding"] - balance_row[("future_amount")]), data[data.length-1]["currency"]) %}</th>
+ </tr>
+ </tbody>
+
+ </table>
+ {% } %}
{% } %}
- </div>
-</div>
-
-{% if(filters.show_future_payments) { %}
- {% var balance_row = data.slice(-1).pop();
- var range1 = report.columns[11].label;
- var range2 = report.columns[12].label;
- var range3 = report.columns[13].label;
- var range4 = report.columns[14].label;
- var range5 = report.columns[15].label;
- var range6 = report.columns[16].label;
- %}
- {% if(balance_row) { %}
- <table class="table table-bordered table-condensed">
- <caption class="text-right">(Amount in {%= data[0][__("currency")] || "" %})</caption>
- <colgroup>
- <col style="width: 30mm;">
- <col style="width: 18mm;">
- <col style="width: 18mm;">
- <col style="width: 18mm;">
- <col style="width: 18mm;">
- <col style="width: 18mm;">
- <col style="width: 18mm;">
- <col style="width: 18mm;">
- <col style="width: 18mm;">
- </colgroup>
-
+ <table class="table table-bordered">
<thead>
<tr>
- <th>{%= __(" ") %}</th>
- <th>{%= __(range1) %}</th>
- <th>{%= __(range2) %}</th>
- <th>{%= __(range3) %}</th>
- <th>{%= __(range4) %}</th>
- <th>{%= __(range5) %}</th>
- <th>{%= __(range6) %}</th>
- <th>{%= __("Total") %}</th>
+ {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
+ <th style="width: 10%">{%= __("Date") %}</th>
+ <th style="width: 4%">{%= __("Age (Days)") %}</th>
+
+ {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
+ <th style="width: 14%">{%= __("Reference") %}</th>
+ <th style="width: 10%">{%= __("Sales Person") %}</th>
+ {% } else { %}
+ <th style="width: 24%">{%= __("Reference") %}</th>
+ {% } %}
+ {% if(!filters.show_future_payments) { %}
+ <th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
+ {% } %}
+ <th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
+ {% if(!filters.show_future_payments) { %}
+ <th style="width: 10%; text-align: right">{%= __("Paid Amount") %}</th>
+ <th style="width: 10%; text-align: right">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
+ {% } %}
+ <th style="width: 10%; text-align: right">{%= __("Outstanding Amount") %}</th>
+ {% if(filters.show_future_payments) { %}
+ {% if(report.report_name === "Accounts Receivable") { %}
+ <th style="width: 12%">{%= __("Customer LPO No.") %}</th>
+ {% } %}
+ <th style="width: 10%">{%= __("Future Payment Ref") %}</th>
+ <th style="width: 10%">{%= __("Future Payment Amount") %}</th>
+ <th style="width: 10%">{%= __("Remaining Balance") %}</th>
+ {% } %}
+ {% } else { %}
+ <th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
+ <th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
+ <th style="width: 15%">{%= __("Total Paid Amount") %}</th>
+ <th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
+ <th style="width: 15%">{%= __("Total Outstanding Amount") %}</th>
+ {% } %}
</tr>
</thead>
<tbody>
- <tr>
- <td>{%= __("Total Outstanding") %}</td>
- <td class="text-right">{%= format_number(balance_row[range1], null, 2) %}</td>
- <td class="text-right">{%= format_currency(balance_row[range2]) %}</td>
- <td class="text-right">{%= format_currency(balance_row[range3]) %}</td>
- <td class="text-right">{%= format_currency(balance_row[range4]) %}</td>
- <td class="text-right">{%= format_currency(balance_row[range5]) %}</td>
- <td class="text-right">{%= format_currency(balance_row[range6]) %}</td>
- <td class="text-right">
- {%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %}
- </td>
- </tr>
- <td>{%= __("PDC/LC") %}</td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td></td>
- <td class="text-right">
- {%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}
- </td>
- <tr class="cvs-footer">
- <th class="text-left">{%= __("Cheques Required") %}</th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- <th></th>
- <th class="text-right">
- {%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}</th>
- </tr>
- </tbody>
-
- </table>
- {% } %}
-{% } %}
-<table class="table table-bordered">
- <thead>
- <tr>
- {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
- <th style="width: 10%">{%= __("Date") %}</th>
- <th style="width: 4%">{%= __("Age (Days)") %}</th>
-
- {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
- <th style="width: 14%">{%= __("Reference") %}</th>
- <th style="width: 10%">{%= __("Sales Person") %}</th>
- {% } else { %}
- <th style="width: 24%">{%= __("Reference") %}</th>
- {% } %}
- {% if(!filters.show_future_payments) { %}
- <th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
- {% } %}
- <th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
- {% if(!filters.show_future_payments) { %}
- <th style="width: 10%; text-align: right">{%= __("Paid Amount") %}</th>
- <th style="width: 10%; text-align: right">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
- {% } %}
- <th style="width: 10%; text-align: right">{%= __("Outstanding Amount") %}</th>
- {% if(filters.show_future_payments) { %}
- {% if(report.report_name === "Accounts Receivable") { %}
- <th style="width: 12%">{%= __("Customer LPO No.") %}</th>
- {% } %}
- <th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
- <th style="width: 10%">{%= __("PDC/LC Amount") %}</th>
- <th style="width: 10%">{%= __("Remaining Balance") %}</th>
- {% } %}
- {% } else { %}
- <th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
- <th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
- <th style="width: 15%">{%= __("Total Paid Amount") %}</th>
- <th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
- <th style="width: 15%">{%= __("Total Outstanding Amount") %}</th>
- {% } %}
- </tr>
- </thead>
- <tbody>
- {% for(var i=0, l=data.length; i<l; i++) { %}
- <tr>
- {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
- {% if(data[i][__("Customer")] || data[i][__("Supplier")]) { %}
- <td>{%= frappe.datetime.str_to_user(data[i]["posting_date"]) %}</td>
- <td style="text-align: right">{%= data[i][__("Age (Days)")] %}</td>
- <td>
- {% if(!filters.show_future_payments) { %}
- {%= data[i]["voucher_type"] %}
- <br>
- {% } %}
- {%= data[i]["voucher_no"] %}
- </td>
-
- {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
- <td>{%= data[i]["sales_person"] %}</td>
- {% } %}
-
- {% if(!filters.show_future_payments) { %}
- <td>
- {% if(!(filters.customer || filters.supplier)) { %}
- {%= data[i][__("Customer")] || data[i][__("Supplier")] %}
- {% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
- <br> {%= data[i][__("Customer Name")] %}
- {% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
- <br> {%= data[i][__("Supplier Name")] %}
+ {% for(var i=0, l=data.length; i<l; i++) { %}
+ <tr>
+ {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
+ {% if(data[i]["party"]) { %}
+ <td>{%= frappe.datetime.str_to_user(data[i]["posting_date"]) %}</td>
+ <td style="text-align: right">{%= data[i]["age"] %}</td>
+ <td>
+ {% if(!filters.show_future_payments) { %}
+ {%= data[i]["voucher_type"] %}
+ <br>
{% } %}
+ {%= data[i]["voucher_no"] %}
+ </td>
+
+ {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
+ <td>{%= data[i]["sales_person"] %}</td>
{% } %}
- <div>
- {% if data[i][__("Remarks")] %}
- {%= __("Remarks") %}:
- {%= data[i][__("Remarks")] %}
- {% } %}
- </div>
- </td>
- {% } %}
- <td style="text-align: right">
- {%= format_currency(data[i]["invoiced_amount"], data[i]["currency"]) %}</td>
-
- {% if(!filters.show_future_payments) { %}
- <td style="text-align: right">
- {%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
- <td style="text-align: right">
- {%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %}</td>
- {% } %}
- <td style="text-align: right">
- {%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
-
- {% if(filters.show_future_payments) { %}
- {% if(report.report_name === "Accounts Receivable") { %}
- <td style="text-align: right">
- {%= data[i]["po_no"] %}</td>
- {% } %}
- <td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
- <td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
- {% } %}
- {% } else { %}
- <td></td>
- {% if(!filters.show_future_payments) { %}
- <td></td>
- {% } %}
- {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
- <td></td>
- {% } %}
- <td></td>
- <td style="text-align: right"><b>{%= __("Total") %}</b></td>
- <td style="text-align: right">
- {%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %}</td>
-
- {% if(!filters.show_future_payments) { %}
- <td style="text-align: right">
- {%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %} </td>
- {% } %}
- <td style="text-align: right">
- {%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
-
- {% if(filters.show_future_payments) { %}
- {% if(report.report_name === "Accounts Receivable") { %}
- <td style="text-align: right">
- {%= data[i][__("Customer LPO")] %}</td>
- {% } %}
- <td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
- <td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
- {% } %}
- {% } %}
- {% } else { %}
- {% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %}
- {% if((data[i][__("Customer")] || data[i][__("Supplier")]) != __("'Total'")) { %}
+ {% if(!filters.show_future_payments) { %}
<td>
{% if(!(filters.customer || filters.supplier)) { %}
- {%= data[i][__("Customer")] || data[i][__("Supplier")] %}
- {% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
- <br> {%= data[i][__("Customer Name")] %}
- {% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
- <br> {%= data[i][__("Supplier Name")] %}
+ {%= data[i]["party"] %}
+ {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
+ <br> {%= data[i]["customer_name"] %}
+ {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %}
+ <br> {%= data[i]["supplier_name"] %}
{% } %}
{% } %}
- <br>{%= __("Remarks") %}:
- {%= data[i][__("Remarks")] %}
+ <div>
+ {% if data[i]["remarks"] %}
+ {%= __("Remarks") %}:
+ {%= data[i]["remarks"] %}
+ {% } %}
+ </div>
</td>
+ {% } %}
+
+ <td style="text-align: right">
+ {%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}</td>
+
+ {% if(!filters.show_future_payments) { %}
+ <td style="text-align: right">
+ {%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
+ <td style="text-align: right">
+ {%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}</td>
+ {% } %}
+ <td style="text-align: right">
+ {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
+
+ {% if(filters.show_future_payments) { %}
+ {% if(report.report_name === "Accounts Receivable") { %}
+ <td style="text-align: right">
+ {%= data[i]["po_no"] %}</td>
+ {% } %}
+ <td style="text-align: right">{%= data[i]["future_ref"] %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}</td>
+ {% } %}
{% } else { %}
- <td><b>{%= __("Total") %}</b></td>
+ <td></td>
+ {% if(!filters.show_future_payments) { %}
+ <td></td>
+ {% } %}
+ {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
+ <td></td>
+ {% } %}
+ <td></td>
+ <td style="text-align: right"><b>{%= __("Total") %}</b></td>
+ <td style="text-align: right">
+ {%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %}</td>
+
+ {% if(!filters.show_future_payments) { %}
+ <td style="text-align: right">
+ {%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} </td>
+ {% } %}
+ <td style="text-align: right">
+ {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
+
+ {% if(filters.show_future_payments) { %}
+ {% if(report.report_name === "Accounts Receivable") { %}
+ <td style="text-align: right">
+ {%= data[i]["po_no"] %}</td>
+ {% } %}
+ <td style="text-align: right">{%= data[i]["future_ref"] %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}</td>
+ {% } %}
{% } %}
- <td style="text-align: right">{%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("credit_note_amt")], data[i]["currency"]) : format_currency(data[i][__("debit_note_amt")], data[i]["currency"]) %}</td>
- <td style="text-align: right">{%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %}</td>
+ {% } else { %}
+ {% if(data[i]["party"]|| " ") { %}
+ {% if((data[i]["party"]) != __("'Total'")) { %}
+ <td>
+ {% if(!(filters.customer || filters.supplier)) { %}
+ {%= data[i]["party"] %}
+ {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
+ <br> {%= data[i]["customer_name"] %}
+ {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %}
+ <br> {%= data[i]["supplier_name"] %}
+ {% } %}
+ {% } %}
+ <br>{%= __("Remarks") %}:
+ {%= data[i]["remarks"] %}
+ </td>
+ {% } else { %}
+ <td><b>{%= __("Total") %}</b></td>
+ {% } %}
+ <td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}</td>
+ <td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
+ {% } %}
{% } %}
+ </tr>
{% } %}
- </tr>
- {% } %}
- </tbody>
-</table>
-<p class="text-right text-muted">{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
+ </tbody>
+ </table>
+ <p class="text-right text-muted">{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_list.js b/erpnext/buying/doctype/purchase_order/purchase_order_list.js
index a67d69d..8413eb6 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order_list.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order_list.js
@@ -16,9 +16,9 @@
return [__("To Receive"), "orange",
"per_received,<,100|per_billed,=,100|status,!=,Closed"];
}
- } else if (flt(doc.per_received, 2) == 100 && flt(doc.per_billed, 2) < 100 && doc.status !== "Closed") {
+ } else if (flt(doc.per_received, 2) >= 100 && flt(doc.per_billed, 2) < 100 && doc.status !== "Closed") {
return [__("To Bill"), "orange", "per_received,=,100|per_billed,<,100|status,!=,Closed"];
- } else if (flt(doc.per_received, 2) == 100 && flt(doc.per_billed, 2) == 100 && doc.status !== "Closed") {
+ } else if (flt(doc.per_received, 2) >= 100 && flt(doc.per_billed, 2) == 100 && doc.status !== "Closed") {
return [__("Completed"), "green", "per_received,=,100|per_billed,=,100|status,!=,Closed"];
}
},
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index b2057ca..64d49b4 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -57,9 +57,9 @@
"Purchase Order": [
["Draft", None],
["To Receive and Bill", "eval:self.per_received < 100 and self.per_billed < 100 and self.docstatus == 1"],
- ["To Bill", "eval:self.per_received == 100 and self.per_billed < 100 and self.docstatus == 1"],
+ ["To Bill", "eval:self.per_received >= 100 and self.per_billed < 100 and self.docstatus == 1"],
["To Receive", "eval:self.per_received < 100 and self.per_billed == 100 and self.docstatus == 1"],
- ["Completed", "eval:self.per_received == 100 and self.per_billed == 100 and self.docstatus == 1"],
+ ["Completed", "eval:self.per_received >= 100 and self.per_billed == 100 and self.docstatus == 1"],
["Delivered", "eval:self.status=='Delivered'"],
["Cancelled", "eval:self.docstatus==2"],
["On Hold", "eval:self.status=='On Hold'"],
diff --git a/erpnext/controllers/trends.py b/erpnext/controllers/trends.py
index 28a8fdd..0404a1e 100644
--- a/erpnext/controllers/trends.py
+++ b/erpnext/controllers/trends.py
@@ -39,7 +39,6 @@
frappe.throw(_("'Based On' and 'Group By' can not be same"))
def get_data(filters, conditions):
-
data = []
inc, cond= '',''
query_details = conditions["based_on_select"] + conditions["period_wise_select"]
@@ -47,10 +46,11 @@
posting_date = 't1.transaction_date'
if conditions.get('trans') in ['Sales Invoice', 'Purchase Invoice', 'Purchase Receipt', 'Delivery Note']:
posting_date = 't1.posting_date'
+ if filters.period_based_on:
+ posting_date = 't1.'+filters.period_based_on
if conditions["based_on_select"] in ["t1.project,", "t2.project,"]:
cond = ' and '+ conditions["based_on_select"][:-1] +' IS Not NULL'
-
if conditions.get('trans') in ['Sales Order', 'Purchase Order']:
cond += " and t1.status != 'Closed'"
diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py
index da25880..705c6e4 100644
--- a/erpnext/education/doctype/student/student.py
+++ b/erpnext/education/doctype/student/student.py
@@ -54,6 +54,7 @@
'send_welcome_email': 1,
'user_type': 'Website User'
})
+ student_user.flags.ignore_permissions = True
student_user.add_roles("Student")
student_user.save()
update_password_link = student_user.reset_password()
diff --git a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
index ed9eae3..ad32e94 100644
--- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
+++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py
@@ -69,33 +69,10 @@
def get_practitioner_list(doctype, txt, searchfield, start, page_len, filters=None):
fields = ["name", "first_name", "mobile_phone"]
- match_conditions = build_match_conditions("Healthcare Practitioner")
- match_conditions = "and {}".format(match_conditions) if match_conditions else ""
- if filters:
- filter_conditions = get_filters_cond(doctype, filters, [])
- match_conditions += "{}".format(filter_conditions)
+ filters = {
+ 'name': ("like", "%%%s%%" % txt)
+ }
- return frappe.db.sql("""select %s from `tabHealthcare Practitioner` where docstatus < 2
- and (%s like %s or first_name like %s)
- and active = 1
- {match_conditions}
- order by
- case when name like %s then 0 else 1 end,
- case when first_name like %s then 0 else 1 end,
- name, first_name limit %s, %s""".format(
- match_conditions=match_conditions) %
- (
- ", ".join(fields),
- frappe.db.escape(searchfield),
- "%s", "%s", "%s", "%s", "%s", "%s"
- ),
- (
- "%%%s%%" % frappe.db.escape(txt),
- "%%%s%%" % frappe.db.escape(txt),
- "%%%s%%" % frappe.db.escape(txt),
- "%%%s%%" % frappe.db.escape(txt),
- start,
- page_len
- )
- )
+ return frappe.get_all("Healthcare Practitioner", fields = fields,
+ filters = filters, start=start, page_length=page_len, order_by="name, first_name", as_list=1)
diff --git a/erpnext/healthcare/doctype/patient/patient.py b/erpnext/healthcare/doctype/patient/patient.py
index bf15cad..e3eea96 100644
--- a/erpnext/healthcare/doctype/patient/patient.py
+++ b/erpnext/healthcare/doctype/patient/patient.py
@@ -6,7 +6,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
-from frappe.utils import cint, cstr, getdate
+from frappe.utils import cint, cstr, getdate, flt
import dateutil
from frappe.model.naming import set_name_by_naming_series
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account,send_registration_sms
@@ -64,7 +64,7 @@
def invoice_patient_registration(self):
frappe.db.set_value("Patient", self.name, "disabled", 0)
send_registration_sms(self)
- if(frappe.get_value("Healthcare Settings", None, "registration_fee")>0):
+ if(flt(frappe.get_value("Healthcare Settings", None, "registration_fee"))>0):
company = frappe.defaults.get_user_default('company')
if not company:
company = frappe.db.get_value("Global Defaults", None, "default_company")
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index 5202218..ee0b2a2 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -7,6 +7,7 @@
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 1,
+ "engine": "InnoDB",
"field_order": [
"basic_information",
"employee",
@@ -54,6 +55,7 @@
"column_break_44",
"holiday_list",
"default_shift",
+ "leave_approver",
"salary_information",
"salary_mode",
"bank_name",
@@ -767,12 +769,18 @@
"fieldtype": "Link",
"label": "Default Shift",
"options": "Shift Type"
+ },
+ {
+ "fieldname": "leave_approver",
+ "fieldtype": "Link",
+ "label": "Leave Approver",
+ "options": "User"
}
],
"icon": "fa fa-user",
"idx": 24,
"image_field": "image",
- "modified": "2019-06-01 16:05:55.132180",
+ "modified": "2019-09-06 15:54:36.735147",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",
diff --git a/erpnext/hr/doctype/employee_checkin/employee_checkin.py b/erpnext/hr/doctype/employee_checkin/employee_checkin.py
index d7d6706..8670512 100644
--- a/erpnext/hr/doctype/employee_checkin/employee_checkin.py
+++ b/erpnext/hr/doctype/employee_checkin/employee_checkin.py
@@ -142,8 +142,10 @@
elif check_in_out_type == 'Strictly based on Log Type in Employee Checkin':
if working_hours_calc_type == 'First Check-in and Last Check-out':
- first_in_log = logs[find_index_in_dict(logs, 'log_type', 'IN')]
- last_out_log = logs[len(logs)-1-find_index_in_dict(reversed(logs), 'log_type', 'OUT')]
+ first_in_log_index = find_index_in_dict(logs, 'log_type', 'IN')
+ first_in_log = logs[first_in_log_index] if first_in_log_index or first_in_log_index == 0 else None
+ last_out_log_index = find_index_in_dict(reversed(logs), 'log_type', 'OUT')
+ last_out_log = logs[len(logs)-1-last_out_log_index] if last_out_log_index or last_out_log_index == 0 else None
if first_in_log and last_out_log:
in_time, out_time = first_in_log.time, last_out_log.time
total_hours = time_diff_in_hours(in_time, out_time)
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 0aa8849..d4da9c1 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -745,10 +745,12 @@
return leave_days
@frappe.whitelist()
-def get_leave_approver(employee, department=None):
- if not department:
- department = frappe.db.get_value('Employee', employee, 'department')
+def get_leave_approver(employee):
+ leave_approver, department = frappe.db.get_value("Employee",
+ employee, ["leave_approver", "department"])
- if department:
- return frappe.db.get_value('Department Approver', {'parent': department,
- 'parentfield': 'leave_approvers', 'idx': 1}, 'approver')
\ No newline at end of file
+ if not leave_approver and department:
+ leave_approver = frappe.db.get_value('Department Approver', {'parent': department,
+ 'parentfield': 'leave_approvers', 'idx': 1}, 'approver')
+
+ return leave_approver
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
deleted file mode 100644
index 6793062..0000000
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ /dev/null
@@ -1,648 +0,0 @@
-# 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
-import json
-from six import text_type
-from frappe import _
-from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
-from frappe.model.document import Document
-from erpnext.manufacturing.doctype.bom.bom import validate_bom_no, get_bom_items_as_dict
-from dateutil.relativedelta import relativedelta
-from erpnext.stock.doctype.item.item import validate_end_of_life
-from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
-from erpnext.projects.doctype.timesheet.timesheet import OverlapError
-from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs
-from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
-from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
-from frappe.utils.csvutils import getlink
-from erpnext.stock.utils import get_bin, validate_warehouse_company, get_latest_stock_qty
-from erpnext.utilities.transaction_base import validate_uom_is_integer
-
-class OverProductionError(frappe.ValidationError): pass
-class StockOverProductionError(frappe.ValidationError): pass
-class OperationTooLongError(frappe.ValidationError): pass
-class ItemHasVariantError(frappe.ValidationError): pass
-
-form_grid_templates = {
- "operations": "templates/form_grid/production_order_grid.html"
-}
-
-class ProductionOrder(Document):
- def validate(self):
- self.validate_production_item()
- if self.bom_no:
- validate_bom_no(self.production_item, self.bom_no)
-
- self.validate_sales_order()
- self.set_default_warehouse()
- self.validate_warehouse_belongs_to_company()
- self.calculate_operating_cost()
- self.validate_qty()
- self.validate_operation_time()
- self.status = self.get_status()
-
- validate_uom_is_integer(self, "stock_uom", ["qty", "produced_qty"])
-
- self.set_required_items(reset_only_qty = len(self.get("required_items")))
-
- def validate_sales_order(self):
- if self.sales_order:
- so = frappe.db.sql("""
- select so.name, so_item.delivery_date, so.project
- from `tabSales Order` so
- inner join `tabSales Order Item` so_item on so_item.parent = so.name
- left join `tabProduct Bundle Item` pk_item on so_item.item_code = pk_item.parent
- where so.name=%s and so.docstatus = 1 and (
- so_item.item_code=%s or
- pk_item.item_code=%s )
- """, (self.sales_order, self.production_item, self.production_item), as_dict=1)
-
- if not so:
- so = frappe.db.sql("""
- select
- so.name, so_item.delivery_date, so.project
- from
- `tabSales Order` so, `tabSales Order Item` so_item, `tabPacked Item` packed_item
- where so.name=%s
- and so.name=so_item.parent
- and so.name=packed_item.parent
- and so_item.item_code = packed_item.parent_item
- and so.docstatus = 1 and packed_item.item_code=%s
- """, (self.sales_order, self.production_item), as_dict=1)
-
- if len(so):
- if not self.expected_delivery_date:
- self.expected_delivery_date = so[0].delivery_date
-
- if so[0].project:
- self.project = so[0].project
-
- if not self.material_request:
- self.validate_production_order_against_so()
- else:
- frappe.throw(_("Sales Order {0} is not valid").format(self.sales_order))
-
- def set_default_warehouse(self):
- if not self.wip_warehouse:
- self.wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
- if not self.fg_warehouse:
- self.fg_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_fg_warehouse")
-
- def validate_warehouse_belongs_to_company(self):
- warehouses = [self.fg_warehouse, self.wip_warehouse]
- for d in self.get("required_items"):
- if d.source_warehouse not in warehouses:
- warehouses.append(d.source_warehouse)
-
- for wh in warehouses:
- validate_warehouse_company(wh, self.company)
-
- def calculate_operating_cost(self):
- self.planned_operating_cost, self.actual_operating_cost = 0.0, 0.0
- for d in self.get("operations"):
- d.planned_operating_cost = flt(d.hour_rate) * (flt(d.time_in_mins) / 60.0)
- d.actual_operating_cost = flt(d.hour_rate) * (flt(d.actual_operation_time) / 60.0)
-
- self.planned_operating_cost += flt(d.planned_operating_cost)
- self.actual_operating_cost += flt(d.actual_operating_cost)
-
- variable_cost = self.actual_operating_cost if self.actual_operating_cost \
- else self.planned_operating_cost
- self.total_operating_cost = flt(self.additional_operating_cost) + flt(variable_cost)
-
- def validate_production_order_against_so(self):
- # already ordered qty
- ordered_qty_against_so = frappe.db.sql("""select sum(qty) from `tabProduction Order`
- where production_item = %s and sales_order = %s and docstatus < 2 and name != %s""",
- (self.production_item, self.sales_order, self.name))[0][0]
-
- total_qty = flt(ordered_qty_against_so) + flt(self.qty)
-
- # get qty from Sales Order Item table
- so_item_qty = frappe.db.sql("""select sum(stock_qty) from `tabSales Order Item`
- where parent = %s and item_code = %s""",
- (self.sales_order, self.production_item))[0][0]
- # get qty from Packing Item table
- dnpi_qty = frappe.db.sql("""select sum(qty) from `tabPacked Item`
- where parent = %s and parenttype = 'Sales Order' and item_code = %s""",
- (self.sales_order, self.production_item))[0][0]
- # total qty in SO
- so_qty = flt(so_item_qty) + flt(dnpi_qty)
-
- allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings",
- "over_production_allowance_percentage"))
-
- if total_qty > so_qty + (allowance_percentage/100 * so_qty):
- frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}")
- .format(self.production_item, so_qty), OverProductionError)
-
- def update_status(self, status=None):
- '''Update status of production order if unknown'''
- if status != "Stopped":
- status = self.get_status(status)
-
- if status != self.status:
- self.db_set("status", status)
-
- self.update_required_items()
-
- return status
-
- def get_status(self, status=None):
- '''Return the status based on stock entries against this production order'''
- if not status:
- status = self.status
-
- if self.docstatus==0:
- status = 'Draft'
- elif self.docstatus==1:
- if status != 'Stopped':
- stock_entries = frappe._dict(frappe.db.sql("""select purpose, sum(fg_completed_qty)
- from `tabStock Entry` where production_order=%s and docstatus=1
- group by purpose""", self.name))
-
- status = "Not Started"
- if stock_entries:
- status = "In Process"
- produced_qty = stock_entries.get("Manufacture")
- if flt(produced_qty) == flt(self.qty):
- status = "Completed"
- else:
- status = 'Cancelled'
-
- return status
-
- def update_production_order_qty(self):
- """Update **Manufactured Qty** and **Material Transferred for Qty** in Production Order
- based on Stock Entry"""
-
- for purpose, fieldname in (("Manufacture", "produced_qty"),
- ("Material Transfer for Manufacture", "material_transferred_for_manufacturing")):
- qty = flt(frappe.db.sql("""select sum(fg_completed_qty)
- from `tabStock Entry` where production_order=%s and docstatus=1
- and purpose=%s""", (self.name, purpose))[0][0])
-
- if qty > self.qty:
- frappe.throw(_("{0} ({1}) cannot be greater than planned quanitity ({2}) in Production Order {3}").format(\
- self.meta.get_label(fieldname), qty, self.qty, self.name), StockOverProductionError)
-
- self.db_set(fieldname, qty)
-
- def before_submit(self):
- self.make_time_logs()
-
- def on_submit(self):
- if not self.wip_warehouse:
- frappe.throw(_("Work-in-Progress Warehouse is required before Submit"))
- if not self.fg_warehouse:
- frappe.throw(_("For Warehouse is required before Submit"))
-
- self.update_reserved_qty_for_production()
- self.update_completed_qty_in_material_request()
- self.update_planned_qty()
-
- def on_cancel(self):
- self.validate_cancel()
-
- frappe.db.set(self,'status', 'Cancelled')
- self.delete_timesheet()
- self.update_completed_qty_in_material_request()
- self.update_planned_qty()
- self.update_reserved_qty_for_production()
-
- def validate_cancel(self):
- if self.status == "Stopped":
- frappe.throw(_("Stopped Production Order cannot be cancelled, Unstop it first to cancel"))
-
- # Check whether any stock entry exists against this Production Order
- stock_entry = frappe.db.sql("""select name from `tabStock Entry`
- where production_order = %s and docstatus = 1""", self.name)
- if stock_entry:
- frappe.throw(_("Cannot cancel because submitted Stock Entry {0} exists").format(stock_entry[0][0]))
-
- def update_planned_qty(self):
- update_bin_qty(self.production_item, self.fg_warehouse, {
- "planned_qty": get_planned_qty(self.production_item, self.fg_warehouse)
- })
-
- if self.material_request:
- mr_obj = frappe.get_doc("Material Request", self.material_request)
- mr_obj.update_requested_qty([self.material_request_item])
-
- def update_completed_qty_in_material_request(self):
- if self.material_request:
- frappe.get_doc("Material Request", self.material_request).update_completed_qty([self.material_request_item])
-
- def set_production_order_operations(self):
- """Fetch operations from BOM and set in 'Production Order'"""
- self.set('operations', [])
-
- if not self.bom_no \
- or cint(frappe.db.get_single_value("Manufacturing Settings", "disable_capacity_planning")):
- return
-
- if self.use_multi_level_bom:
- bom_list = frappe.get_doc("BOM", self.bom_no).traverse_tree()
- else:
- bom_list = [self.bom_no]
-
- operations = frappe.db.sql("""
- select
- operation, description, workstation, idx,
- base_hour_rate as hour_rate, time_in_mins,
- "Pending" as status, parent as bom
- from
- `tabBOM Operation`
- where
- parent in (%s) order by idx
- """ % ", ".join(["%s"]*len(bom_list)), tuple(bom_list), as_dict=1)
-
- self.set('operations', operations)
- self.calculate_time()
-
- def calculate_time(self):
- bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
-
- for d in self.get("operations"):
- d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * flt(self.qty)
-
- self.calculate_operating_cost()
-
- def get_holidays(self, workstation):
- holiday_list = frappe.db.get_value("Workstation", workstation, "holiday_list")
-
- holidays = {}
-
- if holiday_list not in holidays:
- holiday_list_days = [getdate(d[0]) for d in frappe.get_all("Holiday", fields=["holiday_date"],
- filters={"parent": holiday_list}, order_by="holiday_date", limit_page_length=0, as_list=1)]
-
- holidays[holiday_list] = holiday_list_days
-
- return holidays[holiday_list]
-
- def make_time_logs(self, open_new=False):
- """Capacity Planning. Plan time logs based on earliest availablity of workstation after
- Planned Start Date. Time logs will be created and remain in Draft mode and must be submitted
- before manufacturing entry can be made."""
-
- if not self.operations:
- return
-
- timesheets = []
- plan_days = frappe.db.get_single_value("Manufacturing Settings", "capacity_planning_for_days") or 30
-
- timesheet = make_timesheet(self.name, self.company)
- timesheet.set('time_logs', [])
-
- for i, d in enumerate(self.operations):
-
- if d.status != 'Completed':
- self.set_start_end_time_for_workstation(d, i)
-
- args = self.get_operations_data(d)
-
- add_timesheet_detail(timesheet, args)
- original_start_time = d.planned_start_time
-
- # validate operating hours if workstation [not mandatory] is specified
- try:
- timesheet.validate_time_logs()
- except OverlapError:
- if frappe.message_log: frappe.message_log.pop()
- timesheet.schedule_for_production_order(d.idx)
- except WorkstationHolidayError:
- if frappe.message_log: frappe.message_log.pop()
- timesheet.schedule_for_production_order(d.idx)
-
- from_time, to_time = self.get_start_end_time(timesheet, d.name)
-
- if date_diff(from_time, original_start_time) > cint(plan_days):
- frappe.throw(_("Unable to find Time Slot in the next {0} days for Operation {1}").format(plan_days, d.operation))
- break
-
- d.planned_start_time = from_time
- d.planned_end_time = to_time
- d.db_update()
-
- if timesheet and open_new:
- return timesheet
-
- if timesheet and timesheet.get("time_logs"):
- timesheet.save()
- timesheets.append(getlink("Timesheet", timesheet.name))
-
- self.planned_end_date = self.operations[-1].planned_end_time
- if timesheets:
- frappe.local.message_log = []
- frappe.msgprint(_("Timesheet created:") + "\n" + "\n".join(timesheets))
-
- def get_operations_data(self, data):
- return {
- 'from_time': get_datetime(data.planned_start_time),
- 'hours': data.time_in_mins / 60.0,
- 'to_time': get_datetime(data.planned_end_time),
- 'project': self.project,
- 'operation': data.operation,
- 'operation_id': data.name,
- 'workstation': data.workstation,
- 'completed_qty': flt(self.qty) - flt(data.completed_qty)
- }
-
- def set_start_end_time_for_workstation(self, data, index):
- """Set start and end time for given operation. If first operation, set start as
- `planned_start_date`, else add time diff to end time of earlier operation."""
-
- if index == 0:
- data.planned_start_time = self.planned_start_date
- else:
- data.planned_start_time = get_datetime(self.operations[index-1].planned_end_time)\
- + get_mins_between_operations()
-
- data.planned_end_time = get_datetime(data.planned_start_time) + relativedelta(minutes = data.time_in_mins)
-
- if data.planned_start_time == data.planned_end_time:
- frappe.throw(_("Capacity Planning Error"))
-
- def get_start_end_time(self, timesheet, operation_id):
- for data in timesheet.time_logs:
- if data.operation_id == operation_id:
- return data.from_time, data.to_time
-
- def check_operation_fits_in_working_hours(self, d):
- """Raises expection if operation is longer than working hours in the given workstation."""
- from erpnext.manufacturing.doctype.workstation.workstation import check_if_within_operating_hours
- check_if_within_operating_hours(d.workstation, d.operation, d.planned_start_time, d.planned_end_time)
-
- def update_operation_status(self):
- for d in self.get("operations"):
- if not d.completed_qty:
- d.status = "Pending"
- elif flt(d.completed_qty) < flt(self.qty):
- d.status = "Work in Progress"
- elif flt(d.completed_qty) == flt(self.qty):
- d.status = "Completed"
- else:
- frappe.throw(_("Completed Qty can not be greater than 'Qty to Manufacture'"))
-
- def set_actual_dates(self):
- self.actual_start_date = None
- self.actual_end_date = None
- if self.get("operations"):
- actual_start_dates = [d.actual_start_time for d in self.get("operations") if d.actual_start_time]
- if actual_start_dates:
- self.actual_start_date = min(actual_start_dates)
-
- actual_end_dates = [d.actual_end_time for d in self.get("operations") if d.actual_end_time]
- if actual_end_dates:
- self.actual_end_date = max(actual_end_dates)
-
- def delete_timesheet(self):
- for timesheet in frappe.get_all("Timesheet", ["name"], {"production_order": self.name}):
- frappe.delete_doc("Timesheet", timesheet.name)
-
- def validate_production_item(self):
- if frappe.db.get_value("Item", self.production_item, "has_variants"):
- frappe.throw(_("Production Order cannot be raised against a Item Template"), ItemHasVariantError)
-
- if self.production_item:
- validate_end_of_life(self.production_item)
-
- def validate_qty(self):
- if not self.qty > 0:
- frappe.throw(_("Quantity to Manufacture must be greater than 0."))
-
- def validate_operation_time(self):
- for d in self.operations:
- if not d.time_in_mins > 0:
- frappe.throw(_("Operation Time must be greater than 0 for Operation {0}".format(d.operation)))
-
- def update_required_items(self):
- '''
- update bin reserved_qty_for_production
- called from Stock Entry for production, after submit, cancel
- '''
- if self.docstatus==1:
- # calculate transferred qty based on submitted stock entries
- self.update_transaferred_qty_for_required_items()
-
- # update in bin
- self.update_reserved_qty_for_production()
-
- def update_reserved_qty_for_production(self, items=None):
- '''update reserved_qty_for_production in bins'''
- for d in self.required_items:
- if d.source_warehouse:
- stock_bin = get_bin(d.item_code, d.source_warehouse)
- stock_bin.update_reserved_qty_for_production()
-
- def get_items_and_operations_from_bom(self):
- self.set_required_items()
- self.set_production_order_operations()
-
- return check_if_scrap_warehouse_mandatory(self.bom_no)
-
- def set_available_qty(self):
- for d in self.get("required_items"):
- if d.source_warehouse:
- d.available_qty_at_source_warehouse = get_latest_stock_qty(d.item_code, d.source_warehouse)
-
- if self.wip_warehouse:
- d.available_qty_at_wip_warehouse = get_latest_stock_qty(d.item_code, self.wip_warehouse)
-
- def set_required_items(self, reset_only_qty=False):
- '''set required_items for production to keep track of reserved qty'''
- if not reset_only_qty:
- self.required_items = []
-
- if self.bom_no and self.qty:
- item_dict = get_bom_items_as_dict(self.bom_no, self.company, qty=self.qty,
- fetch_exploded = self.use_multi_level_bom)
-
- if reset_only_qty:
- for d in self.get("required_items"):
- if item_dict.get(d.item_code):
- d.required_qty = item_dict.get(d.item_code).get("qty")
- else:
- for item in sorted(item_dict.values(), key=lambda d: d['idx']):
- self.append('required_items', {
- 'item_code': item.item_code,
- 'item_name': item.item_name,
- 'description': item.description,
- 'required_qty': item.qty,
- 'source_warehouse': item.source_warehouse or item.default_warehouse
- })
-
- self.set_available_qty()
-
- def update_transaferred_qty_for_required_items(self):
- '''update transferred qty from submitted stock entries for that item against
- the production order'''
-
- for d in self.required_items:
- transferred_qty = frappe.db.sql('''select sum(qty)
- from `tabStock Entry` entry, `tabStock Entry Detail` detail
- where
- entry.production_order = %s
- and entry.purpose = "Material Transfer for Manufacture"
- and entry.docstatus = 1
- and detail.parent = entry.name
- and detail.item_code = %s''', (self.name, d.item_code))[0][0]
-
- d.db_set('transferred_qty', flt(transferred_qty), update_modified = False)
-
-
-@frappe.whitelist()
-def get_item_details(item, project = None):
- res = frappe.db.sql("""
- select stock_uom, description
- from `tabItem`
- where disabled=0
- and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)
- and name=%s
- """, (nowdate(), item), as_dict=1)
-
- if not res:
- return {}
-
- res = res[0]
-
- filters = {"item": item, "is_default": 1}
-
- if project:
- filters = {"item": item, "project": project}
-
- res["bom_no"] = frappe.db.get_value("BOM", filters = filters)
-
- if not res["bom_no"]:
- variant_of= frappe.db.get_value("Item", item, "variant_of")
-
- if variant_of:
- res["bom_no"] = frappe.db.get_value("BOM", filters={"item": variant_of, "is_default": 1})
-
- if not res["bom_no"]:
- if project:
- res = get_item_details(item)
- frappe.msgprint(_("Default BOM not found for Item {0} and Project {1}").format(item, project), alert=1)
- else:
- frappe.throw(_("Default BOM for {0} not found").format(item))
-
- res['project'] = project or frappe.db.get_value('BOM', res['bom_no'], 'project')
- res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
-
- return res
-
-@frappe.whitelist()
-def check_if_scrap_warehouse_mandatory(bom_no):
- res = {"set_scrap_wh_mandatory": False }
- if bom_no:
- bom = frappe.get_doc("BOM", bom_no)
-
- if len(bom.scrap_items) > 0:
- res["set_scrap_wh_mandatory"] = True
-
- return res
-
-@frappe.whitelist()
-def set_production_order_ops(name):
- po = frappe.get_doc('Production Order', name)
- po.set_production_order_operations()
- po.save()
-
-@frappe.whitelist()
-def make_stock_entry(production_order_id, purpose, qty=None):
- production_order = frappe.get_doc("Production Order", production_order_id)
- if not frappe.db.get_value("Warehouse", production_order.wip_warehouse, "is_group") \
- and not production_order.skip_transfer:
- wip_warehouse = production_order.wip_warehouse
- else:
- wip_warehouse = None
-
- stock_entry = frappe.new_doc("Stock Entry")
- stock_entry.purpose = purpose
- stock_entry.production_order = production_order_id
- stock_entry.company = production_order.company
- stock_entry.from_bom = 1
- stock_entry.bom_no = production_order.bom_no
- stock_entry.use_multi_level_bom = production_order.use_multi_level_bom
- stock_entry.fg_completed_qty = qty or (flt(production_order.qty) - flt(production_order.produced_qty))
- stock_entry.set_stock_entry_type()
-
- if purpose=="Material Transfer for Manufacture":
- stock_entry.to_warehouse = wip_warehouse
- stock_entry.project = production_order.project
- else:
- stock_entry.from_warehouse = wip_warehouse
- stock_entry.to_warehouse = production_order.fg_warehouse
- additional_costs = get_additional_costs(production_order, fg_qty=stock_entry.fg_completed_qty)
- stock_entry.project = production_order.project
- stock_entry.set("additional_costs", additional_costs)
-
- stock_entry.get_items()
- return stock_entry.as_dict()
-
-@frappe.whitelist()
-def make_timesheet(production_order, company):
- timesheet = frappe.new_doc("Timesheet")
- timesheet.employee = ""
- timesheet.production_order = production_order
- timesheet.company = company
- return timesheet
-
-@frappe.whitelist()
-def add_timesheet_detail(timesheet, args):
- if isinstance(timesheet, text_type):
- timesheet = frappe.get_doc('Timesheet', timesheet)
-
- if isinstance(args, text_type):
- args = json.loads(args)
-
- timesheet.append('time_logs', args)
- return timesheet
-
-@frappe.whitelist()
-def get_default_warehouse():
- wip_warehouse = frappe.db.get_single_value("Manufacturing Settings",
- "default_wip_warehouse")
- fg_warehouse = frappe.db.get_single_value("Manufacturing Settings",
- "default_fg_warehouse")
- return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse}
-
-@frappe.whitelist()
-def make_new_timesheet(source_name, target_doc=None):
- po = frappe.get_doc('Production Order', source_name)
- ts = po.make_time_logs(open_new=True)
-
- if not ts or not ts.get('time_logs'):
- frappe.throw(_("Already completed"))
-
- return ts
-
-@frappe.whitelist()
-def stop_unstop(production_order, status):
- """ Called from client side on Stop/Unstop event"""
-
- if not frappe.has_permission("Production Order", "write"):
- frappe.throw(_("Not permitted"), frappe.PermissionError)
-
- pro_order = frappe.get_doc("Production Order", production_order)
- pro_order.update_status(status)
- pro_order.update_planned_qty()
- frappe.msgprint(_("Production Order has been {0}").format(status))
- pro_order.notify_update()
-
- return pro_order.status
-
-@frappe.whitelist()
-def query_sales_order(production_item):
- out = frappe.db.sql_list("""
- select distinct so.name from `tabSales Order` so, `tabSales Order Item` so_item
- where so_item.parent=so.name and so_item.item_code=%s and so.docstatus=1
- union
- select distinct so.name from `tabSales Order` so, `tabPacked Item` pi_item
- where pi_item.parent=so.name and pi_item.item_code=%s and so.docstatus=1
- """, (production_item, production_item))
-
- return out
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 650ab13..048ce0d 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -99,7 +99,7 @@
self.get_mr_items()
def get_so_items(self):
- so_list = [d.sales_order for d in self.sales_orders if d.sales_order]
+ so_list = [d.sales_order for d in self.get("sales_orders", []) if d.sales_order]
if not so_list:
msgprint(_("Please enter Sales Orders in the above table"))
return []
@@ -134,7 +134,7 @@
self.calculate_total_planned_qty()
def get_mr_items(self):
- mr_list = [d.material_request for d in self.material_requests if d.material_request]
+ mr_list = [d.material_request for d in self.get("material_requests", []) if d.material_request]
if not mr_list:
msgprint(_("Please enter Material Requests in the above table"))
return []
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 07b8ee6..2af1269 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -632,3 +632,4 @@
erpnext.patches.v12_0.add_default_dashboards
erpnext.patches.v12_0.remove_bank_remittance_custom_fields
erpnext.patches.v12_0.generate_leave_ledger_entries
+erpnext.patches.v12_0.move_credit_limit_to_customer_credit_limit
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/move_credit_limit_to_customer_credit_limit.py b/erpnext/patches/v12_0/move_credit_limit_to_customer_credit_limit.py
new file mode 100644
index 0000000..c9293b9
--- /dev/null
+++ b/erpnext/patches/v12_0/move_credit_limit_to_customer_credit_limit.py
@@ -0,0 +1,46 @@
+# Copyright (c) 2019, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ ''' Move credit limit and bypass credit limit to the child table of customer credit limit '''
+ frappe.reload_doc("Selling", "doctype", "Customer Credit Limit")
+ frappe.reload_doc("Selling", "doctype", "Customer")
+ frappe.reload_doc("Setup", "doctype", "Customer Group")
+
+ if frappe.db.a_row_exists("Customer Credit Limit"):
+ return
+
+ move_credit_limit_to_child_table()
+
+def move_credit_limit_to_child_table():
+ ''' maps data from old field to the new field in the child table '''
+
+ companies = frappe.get_all("Company", 'name')
+ for doctype in ("Customer", "Customer Group"):
+ fields = ""
+ if doctype == "Customer" \
+ and frappe.db.has_column('Customer', 'bypass_credit_limit_check_at_sales_order'):
+ fields = ", bypass_credit_limit_check_at_sales_order"
+
+ credit_limit_records = frappe.db.sql('''
+ SELECT name, credit_limit {0}
+ FROM `tab{1}` where credit_limit > 0
+ '''.format(fields, doctype), as_dict=1) #nosec
+
+ for record in credit_limit_records:
+ doc = frappe.get_doc(doctype, record.name)
+ for company in companies:
+ row = frappe._dict({
+ 'credit_limit': record.credit_limit,
+ 'company': company.name
+ })
+ if doctype == "Customer":
+ row.bypass_credit_limit_check = record.bypass_credit_limit_check_at_sales_order
+
+ doc.append("credit_limits", row)
+
+ for row in doc.credit_limits:
+ row.db_insert()
diff --git a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
index 02203d2..9f4c445 100644
--- a/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
+++ b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py
@@ -82,7 +82,7 @@
account_name = " - ".join(parts[:-1])
company = frappe.db.get_value("Company", filters={"abbr": parts[-1]})
parent_account = frappe.db.get_value("Account",
- filters={"account_type": "Tax", "root_type": "Liability", "is_group": 0}, fieldname="parent_account")
+ filters={"account_type": "Tax", "root_type": "Liability", "is_group": 0, "company": company}, fieldname="parent_account")
frappe.get_doc({
"doctype": "Account",
diff --git a/erpnext/projects/doctype/timesheet/timesheet.js b/erpnext/projects/doctype/timesheet/timesheet.js
index 101d903..3eea390 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.js
+++ b/erpnext/projects/doctype/timesheet/timesheet.js
@@ -147,6 +147,15 @@
calculate_time_and_amount(frm);
},
+ task: (frm, cdt, cdn) => {
+ let row = frm.selected_doc;
+ if (row.task) {
+ frappe.db.get_value("Task", row.task, "project", (r) => {
+ frappe.model.set_value(cdt, cdn, "project", r.project);
+ });
+ }
+ },
+
from_time: function(frm, cdt, cdn) {
calculate_end_time(frm, cdt, cdn);
},
@@ -200,9 +209,6 @@
},
activity_type: function(frm, cdt, cdn) {
- frm.script_manager.copy_from_first_row('time_logs', frm.selected_doc,
- 'project');
-
frappe.call({
method: "erpnext.projects.doctype.timesheet.timesheet.get_activity_cost",
args: {
diff --git a/erpnext/projects/doctype/timesheet/timesheet.py b/erpnext/projects/doctype/timesheet/timesheet.py
index 3c71922..9ee2927 100644
--- a/erpnext/projects/doctype/timesheet/timesheet.py
+++ b/erpnext/projects/doctype/timesheet/timesheet.py
@@ -145,12 +145,17 @@
def validate_time_logs(self):
for data in self.get('time_logs'):
self.validate_overlap(data)
+ self.validate_task_project()
def validate_overlap(self, data):
settings = frappe.get_single('Projects Settings')
self.validate_overlap_for("user", data, self.user, settings.ignore_user_time_overlap)
self.validate_overlap_for("employee", data, self.employee, settings.ignore_employee_time_overlap)
+ def validate_task_project(self):
+ for log in self.time_logs:
+ log.project = log.project or frappe.db.get_value("Task", log.task, "project")
+
def validate_overlap_for(self, fieldname, args, value, ignore_validation=False):
if not value or ignore_validation:
return
diff --git a/erpnext/public/js/purchase_trends_filters.js b/erpnext/public/js/purchase_trends_filters.js
index 595a138..cd767f5 100644
--- a/erpnext/public/js/purchase_trends_filters.js
+++ b/erpnext/public/js/purchase_trends_filters.js
@@ -4,6 +4,14 @@
erpnext.get_purchase_trends_filters = function() {
return [
{
+ "fieldname":"company",
+ "label": __("Company"),
+ "fieldtype": "Link",
+ "options": "Company",
+ "reqd": 1,
+ "default": frappe.defaults.get_user_default("Company")
+ },
+ {
"fieldname":"period",
"label": __("Period"),
"fieldtype": "Select",
@@ -16,6 +24,23 @@
"default": "Monthly"
},
{
+ "fieldname":"fiscal_year",
+ "label": __("Fiscal Year"),
+ "fieldtype": "Link",
+ "options":'Fiscal Year',
+ "default": frappe.sys_defaults.fiscal_year
+ },
+ {
+ "fieldname":"period_based_on",
+ "label": __("Period based On"),
+ "fieldtype": "Select",
+ "options": [
+ { "value": "posting_date", "label": __("Posting Date") },
+ { "value": "bill_date", "label": __("Billing Date") },
+ ],
+ "default": "posting_date"
+ },
+ {
"fieldname":"based_on",
"label": __("Based On"),
"fieldtype": "Select",
@@ -39,19 +64,5 @@
],
"default": ""
},
- {
- "fieldname":"fiscal_year",
- "label": __("Fiscal Year"),
- "fieldtype": "Link",
- "options":'Fiscal Year',
- "default": frappe.sys_defaults.fiscal_year
- },
- {
- "fieldname":"company",
- "label": __("Company"),
- "fieldtype": "Link",
- "options": "Company",
- "default": frappe.defaults.get_user_default("Company")
- },
];
}
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
index 4d3c522..b4de03e 100644
--- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
@@ -52,7 +52,19 @@
def get_children(doctype, parent=None, parent_quality_procedure=None, is_root=False):
if parent is None or parent == "All Quality Procedures":
parent = ""
- return frappe.get_all(doctype, fields=["name as value", "is_group as expandable"], filters={"parent_quality_procedure": parent})
+
+ return frappe.db.sql("""
+ select
+ name as value,
+ is_group as expandable
+ from
+ `tab{doctype}`
+ where
+ ifnull(parent_quality_procedure, "")={parent}
+ """.format(
+ doctype = doctype,
+ parent=frappe.db.escape(parent)
+ ), as_dict=1)
@frappe.whitelist()
def add_node():
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
index 8fd785f..dbdbbab 100644
--- a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
@@ -1,5 +1,3 @@
-frappe.provide("frappe.treeview_settings");
-
frappe.treeview_settings["Quality Procedure"] = {
ignore_fields:["parent_quality_procedure"],
get_tree_nodes: 'erpnext.quality_management.doctype.quality_procedure.quality_procedure.get_children',
@@ -19,7 +17,7 @@
],
breadcrumb: "Setup",
root_label: "All Quality Procedures",
- get_tree_root: true,
+ get_tree_root: false,
menu_items: [
{
label: __("New Quality Procedure"),
diff --git a/erpnext/selling/doctype/customer/customer.json b/erpnext/selling/doctype/customer/customer.json
index 8c30528..c2c8c19 100644
--- a/erpnext/selling/doctype/customer/customer.json
+++ b/erpnext/selling/doctype/customer/customer.json
@@ -1,2036 +1,475 @@
{
- "allow_copy": 0,
"allow_events_in_timeline": 1,
- "allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "naming_series:",
- "beta": 0,
"creation": "2013-06-11 14:26:44",
- "custom": 0,
"description": "Buyer of Goods and Services.",
- "docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
- "editable_grid": 0,
"engine": "InnoDB",
+ "field_order": [
+ "basic_info",
+ "naming_series",
+ "salutation",
+ "customer_name",
+ "gender",
+ "customer_type",
+ "default_bank_account",
+ "lead_name",
+ "image",
+ "column_break0",
+ "account_manager",
+ "customer_group",
+ "territory",
+ "tax_id",
+ "tax_category",
+ "disabled",
+ "is_internal_customer",
+ "represents_company",
+ "allowed_to_transact_section",
+ "companies",
+ "currency_and_price_list",
+ "default_currency",
+ "default_price_list",
+ "column_break_14",
+ "language",
+ "address_contacts",
+ "address_html",
+ "website",
+ "column_break1",
+ "contact_html",
+ "primary_address_and_contact_detail",
+ "customer_primary_contact",
+ "mobile_no",
+ "email_id",
+ "column_break_26",
+ "customer_primary_address",
+ "primary_address",
+ "default_receivable_accounts",
+ "accounts",
+ "credit_limit_section",
+ "payment_terms",
+ "credit_limits",
+ "more_info",
+ "customer_details",
+ "column_break_45",
+ "market_segment",
+ "industry",
+ "is_frozen",
+ "column_break_38",
+ "loyalty_program",
+ "loyalty_program_tier",
+ "sales_team_section_break",
+ "default_sales_partner",
+ "default_commission_rate",
+ "sales_team_section",
+ "sales_team",
+ "customer_pos_id"
+ ],
"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": "basic_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": "Name and Type",
- "length": 0,
- "no_copy": 0,
"oldfieldtype": "Section Break",
- "options": "fa fa-user",
- "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
+ "options": "fa fa-user"
},
{
- "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": 1,
"options": "CUST-.YYYY.-",
- "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": 1,
- "translatable": 0,
- "unique": 0
+ "set_only_once": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "eval:doc.customer_type!='Company'",
- "fetch_if_empty": 0,
"fieldname": "salutation",
"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": "Salutation",
- "length": 0,
- "no_copy": 0,
- "options": "Salutation",
- "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
+ "options": "Salutation"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
"bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "customer_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": "Full Name",
- "length": 0,
"no_copy": 1,
"oldfieldname": "customer_name",
"oldfieldtype": "Data",
- "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
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "eval:doc.customer_type != 'Company'",
- "fetch_if_empty": 0,
"fieldname": "gender",
"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": "Gender",
- "length": 0,
- "no_copy": 0,
- "options": "Gender",
- "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
+ "options": "Gender"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"default": "Company",
- "fetch_if_empty": 0,
"fieldname": "customer_type",
"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": "Type",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "customer_type",
"oldfieldtype": "Select",
"options": "Company\nIndividual",
- "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
+ "reqd": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "default_bank_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": "Default Bank Account",
- "length": 0,
- "no_copy": 0,
- "options": "Bank 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
+ "options": "Bank Account"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "lead_name",
"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": "From Lead",
- "length": 0,
"no_copy": 1,
"oldfieldname": "lead_name",
"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": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "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": 0,
- "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
+ "print_hide": 1
},
{
- "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_break0",
"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,
- "fetch_if_empty": 0,
"fieldname": "account_manager",
"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": "Account Manager",
- "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
+ "options": "User"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
- "fetch_if_empty": 0,
"fieldname": "customer_group",
"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": 1,
"label": "Customer Group",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "customer_group",
"oldfieldtype": "Link",
"options": "Customer Group",
- "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
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
- "fetch_if_empty": 0,
"fieldname": "territory",
"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": 1,
"label": "Territory",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "territory",
"oldfieldtype": "Link",
"options": "Territory",
- "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": 0,
- "translatable": 0,
- "unique": 0
+ "reqd": 1
},
{
- "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_id",
"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": "Tax ID",
- "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
+ "label": "Tax ID"
},
{
- "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_category",
"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 Category",
- "length": 0,
- "no_copy": 0,
- "options": "Tax Category",
- "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
+ "options": "Tax Category"
},
{
- "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": "disabled",
"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": "Disabled",
- "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
+ "label": "Disabled"
},
{
- "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": "is_internal_customer",
"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 Internal Customer",
- "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
+ "label": "Is Internal Customer"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "is_internal_customer",
- "fetch_if_empty": 0,
"fieldname": "represents_company",
"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": "Represents 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": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "represents_company",
- "fetch_if_empty": 0,
"fieldname": "allowed_to_transact_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": "Allowed To Transact With",
- "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
+ "label": "Allowed To Transact With"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "represents_company",
- "fetch_if_empty": 0,
"fieldname": "companies",
"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": "Allowed To Transact With",
- "length": 0,
- "no_copy": 0,
- "options": "Allowed To Transact With",
- "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
+ "options": "Allowed To Transact With"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "currency_and_price_list",
"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": "Currency and Price List",
- "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
+ "label": "Currency and Price List"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "default_currency",
"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": "Billing Currency",
- "length": 0,
"no_copy": 1,
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Currency"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "default_price_list",
"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": "Default 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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Price List"
},
{
- "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
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "language",
"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": "Print Language",
- "length": 0,
- "no_copy": 0,
- "options": "Language",
- "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
+ "options": "Language"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "eval:!doc.__islocal",
- "fetch_if_empty": 0,
"fieldname": "address_contacts",
"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": "Address and Contact",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-map-marker",
- "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
+ "options": "fa fa-map-marker"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "address_html",
"fieldtype": "HTML",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Address HTML",
- "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
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "website",
"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": "Website",
- "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
+ "label": "Website"
},
{
- "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,
- "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,
- "fetch_if_empty": 0,
"fieldname": "contact_html",
"fieldtype": "HTML",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "Contact HTML",
- "length": 0,
- "no_copy": 0,
"oldfieldtype": "HTML",
- "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
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Select, to make the customer searchable with these fields",
- "fetch_if_empty": 0,
"fieldname": "primary_address_and_contact_detail",
"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": "Primary Address and Contact Detail",
- "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
+ "label": "Primary Address and Contact Detail"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Reselect, if the chosen contact is edited after save",
- "fetch_if_empty": 0,
"fieldname": "customer_primary_contact",
"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 Primary Contact",
- "length": 0,
- "no_copy": 0,
- "options": "Contact",
- "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
+ "options": "Contact"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "customer_primary_contact.mobile_no",
- "fetch_if_empty": 0,
"fieldname": "mobile_no",
"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": "Mobile No",
- "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
+ "label": "Mobile No"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fetch_from": "customer_primary_contact.email_id",
- "fetch_if_empty": 0,
"fieldname": "email_id",
"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": "Email Id",
- "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
+ "label": "Email Id"
},
{
- "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_26",
- "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
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Reselect, if the chosen address is edited after save",
- "fetch_if_empty": 0,
"fieldname": "customer_primary_address",
"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 Primary Address",
- "length": 0,
- "no_copy": 0,
- "options": "Address",
- "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
+ "options": "Address"
},
{
- "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": "primary_address",
"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": "Primary Address",
- "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
+ "label": "Primary Address"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
- "collapsible_depends_on": "",
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "default_receivable_accounts",
"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",
- "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
+ "label": "Accounting"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
"description": "Mention if non-standard receivable account",
- "fetch_if_empty": 0,
"fieldname": "accounts",
"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": "Accounts",
- "length": 0,
- "no_copy": 0,
- "options": "Party Account",
- "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
+ "options": "Party Account"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
- "collapsible_depends_on": "",
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "credit_limit_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": "Credit Limit and Payment Terms",
- "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": ""
+ "label": "Credit Limit and Payment Terms"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
- "fieldname": "credit_limit",
- "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": "Credit Limit",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "credit_limit",
- "oldfieldtype": "Currency",
- "options": "",
- "permlevel": 1,
- "print_hide": 0,
- "print_hide_if_no_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",
- "fetch_if_empty": 0,
- "fieldname": "bypass_credit_limit_check_at_sales_order",
- "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": "Bypass credit limit check at Sales Order",
- "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_34",
- "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,
- "depends_on": "",
- "fetch_if_empty": 0,
"fieldname": "payment_terms",
"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": "Default Payment Terms Template",
- "length": 0,
- "no_copy": 0,
- "options": "Payment Terms Template",
- "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
+ "options": "Payment Terms Template"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
"collapsible_depends_on": "customer_details",
- "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,
"oldfieldtype": "Section Break",
- "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
+ "options": "fa fa-file-text"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"description": "Additional information regarding the customer.",
- "fetch_if_empty": 0,
"fieldname": "customer_details",
"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": "Customer Details",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "customer_details",
- "oldfieldtype": "Code",
- "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
+ "oldfieldtype": "Code"
},
{
- "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_45",
- "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
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "market_segment",
"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": "Market Segment",
- "length": 0,
- "no_copy": 0,
- "options": "Market Segment",
- "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
+ "options": "Market Segment"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "industry",
"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": "Industry",
- "length": 0,
- "no_copy": 0,
- "options": "Industry Type",
- "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
+ "options": "Industry Type"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
+ "default": "0",
"fieldname": "is_frozen",
"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 Frozen",
- "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
+ "label": "Is Frozen"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "column_break_38",
"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": "Loyalty Points",
- "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
+ "label": "Loyalty Points"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "loyalty_program",
"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": "Loyalty Program",
- "length": 0,
"no_copy": 1,
- "options": "Loyalty Program",
- "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
+ "options": "Loyalty Program"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "loyalty_program_tier",
"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": "Loyalty Program Tier",
- "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
+ "read_only": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
"collapsible_depends_on": "default_sales_partner",
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "sales_team_section_break",
"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": "Sales Partner and Commission",
- "length": 0,
- "no_copy": 0,
"oldfieldtype": "Section Break",
- "options": "fa fa-group",
- "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
+ "options": "fa fa-group"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "default_sales_partner",
"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": "Sales Partner",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "default_sales_partner",
"oldfieldtype": "Link",
- "options": "Sales Partner",
- "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
+ "options": "Sales Partner"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "default_commission_rate",
"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": "Commission Rate",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "default_commission_rate",
- "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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "oldfieldtype": "Currency"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 1,
"collapsible_depends_on": "sales_team",
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "sales_team_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": "Sales Team",
- "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
+ "label": "Sales Team"
},
{
- "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_team",
"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": "Sales Team Details",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "sales_team",
"oldfieldtype": "Table",
- "options": "Sales Team",
- "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
+ "options": "Sales Team"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fetch_if_empty": 0,
"fieldname": "customer_pos_id",
"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": "Customer POS id",
- "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": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "credit_limits",
+ "fieldtype": "Table",
+ "label": "Credit Limit",
+ "options": "Customer Credit Limit"
}
],
- "has_web_view": 0,
- "hide_toolbar": 0,
"icon": "fa fa-user",
"idx": 363,
"image_field": "image",
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "menu_index": 0,
- "modified": "2019-04-12 08:45:39.357491",
+ "modified": "2019-09-06 12:40:31.801424",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer",
@@ -2038,184 +477,81 @@
"owner": "Administrator",
"permissions": [
{
- "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": "Sales User",
- "set_user_permissions": 0,
"share": 1,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
"permlevel": 1,
- "print": 0,
"read": 1,
- "report": 0,
- "role": "Sales User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Sales User"
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Sales Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Sales Manager"
},
{
- "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": 1,
"share": 1,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
"permlevel": 1,
- "print": 0,
"read": 1,
- "report": 0,
"role": "Sales Master Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Stock User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Stock User"
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Stock Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Stock Manager"
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Accounts User"
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Accounts Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Accounts Manager"
}
],
"quick_entry": 1,
- "read_only": 0,
"search_fields": "customer_name,customer_group,territory, mobile_no,primary_address",
"show_name_in_global_search": 1,
+ "sort_field": "modified",
"sort_order": "ASC",
"title_field": "customer_name",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ "track_changes": 1
}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 3c9c3cc..4ca5af5 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -167,13 +167,18 @@
frappe.throw(_("A Customer Group exists with same name please change the Customer name or rename the Customer Group"), frappe.NameError)
def validate_credit_limit_on_change(self):
- if self.get("__islocal") or not self.credit_limit \
- or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"):
+ if self.get("__islocal") or not self.credit_limits:
return
- for company in frappe.get_all("Company"):
- outstanding_amt = get_customer_outstanding(self.name, company.name)
- if flt(self.credit_limit) < outstanding_amt:
+ company_record = []
+ for limit in self.credit_limits:
+ if limit.company in company_record:
+ frappe.throw(_("Credit limit is already defined for the Company {0}").format(limit.company, self.name))
+ else:
+ company_record.append(limit.company)
+
+ outstanding_amt = get_customer_outstanding(self.name, limit.company)
+ if flt(limit.credit_limit) < outstanding_amt:
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
def on_trash(self):
@@ -322,11 +327,13 @@
credit_limit = None
if customer:
- credit_limit, customer_group = frappe.get_cached_value("Customer",
- customer, ["credit_limit", "customer_group"])
+ credit_limit = frappe.db.get_value("Customer Credit Limit",
+ {'parent': customer, 'parenttype': 'Customer', 'company': company}, 'credit_limit')
if not credit_limit:
- credit_limit = frappe.get_cached_value("Customer Group", customer_group, "credit_limit")
+ customer_group = frappe.get_cached_value("Customer", customer, 'customer_group')
+ credit_limit = frappe.db.get_value("Customer Credit Limit",
+ {'parent': customer_group, 'parenttype': 'Customer Group', 'company': company}, 'credit_limit')
if not credit_limit:
credit_limit = frappe.get_cached_value('Company', company, "credit_limit")
diff --git a/erpnext/selling/doctype/customer/customer_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py
index 8e790bf..654dd48 100644
--- a/erpnext/selling/doctype/customer/customer_dashboard.py
+++ b/erpnext/selling/doctype/customer/customer_dashboard.py
@@ -9,7 +9,7 @@
'heatmap_message': _('This is based on transactions against this Customer. See timeline below for details'),
'fieldname': 'customer',
'non_standard_fieldnames': {
- 'Payment Entry': 'party_name',
+ 'Payment Entry': 'party',
'Quotation': 'party_name',
'Opportunity': 'party_name'
},
diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py
index f261ef3..87fdaa3 100644
--- a/erpnext/selling/doctype/customer/test_customer.py
+++ b/erpnext/selling/doctype/customer/test_customer.py
@@ -25,7 +25,7 @@
make_test_records('Item')
def tearDown(self):
- frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', 0.0)
+ set_credit_limit('_Test Customer', '_Test Company', 0)
def test_party_details(self):
from erpnext.accounts.party import get_party_details
@@ -225,8 +225,8 @@
item_qty = int((abs(outstanding_amt) + 200)/100)
make_sales_order(qty=item_qty)
- if credit_limit == 0.0:
- frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', outstanding_amt - 50.0)
+ if not credit_limit:
+ set_credit_limit('_Test Customer', '_Test Company', outstanding_amt - 50)
# Sales Order
so = make_sales_order(do_not_submit=True)
@@ -241,7 +241,7 @@
self.assertRaises(frappe.ValidationError, si.submit)
if credit_limit > outstanding_amt:
- frappe.db.set_value("Customer", '_Test Customer', 'credit_limit', credit_limit)
+ set_credit_limit('_Test Customer', '_Test Company', credit_limit)
# Makes Sales invoice from Sales Order
so.save(ignore_permissions=True)
@@ -252,7 +252,10 @@
def test_customer_credit_limit_on_change(self):
outstanding_amt = self.get_customer_outstanding_amount()
customer = frappe.get_doc("Customer", '_Test Customer')
- customer.credit_limit = flt(outstanding_amt - 100)
+ customer.append('credit_limits', {'credit_limit': flt(outstanding_amt - 100), 'company': '_Test Company'})
+
+ ''' define new credit limit for same company '''
+ customer.append('credit_limits', {'credit_limit': flt(outstanding_amt - 100), 'company': '_Test Company'})
self.assertRaises(frappe.ValidationError, customer.save)
def test_customer_payment_terms(self):
@@ -292,3 +295,20 @@
"doctype": "Customer",
"territory": "_Test Territory"
}
+
+def set_credit_limit(customer, company, credit_limit):
+ customer = frappe.get_doc("Customer", customer)
+ existing_row = None
+ for d in customer.credit_limits:
+ if d.company == company:
+ existing_row = d
+ d.credit_limit = credit_limit
+ d.db_update()
+ break
+
+ if not existing_row:
+ customer.append('credit_limits', {
+ 'company': company,
+ 'credit_limit': credit_limit
+ })
+ customer.credit_limits[-1].db_insert()
diff --git a/erpnext/selling/doctype/customer_credit_limit/__init__.py b/erpnext/selling/doctype/customer_credit_limit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/selling/doctype/customer_credit_limit/__init__.py
diff --git a/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.json b/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.json
new file mode 100644
index 0000000..e26f798
--- /dev/null
+++ b/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.json
@@ -0,0 +1,50 @@
+{
+ "creation": "2019-08-28 17:29:42.115592",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "company",
+ "column_break_2",
+ "credit_limit",
+ "bypass_credit_limit_check"
+ ],
+ "fields": [
+ {
+ "columns": 4,
+ "fieldname": "credit_limit",
+ "fieldtype": "Currency",
+ "in_list_view": 1,
+ "label": "Credit Limit"
+ },
+ {
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break"
+ },
+ {
+ "columns": 4,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Company",
+ "options": "Company"
+ },
+ {
+ "default": "0",
+ "fieldname": "bypass_credit_limit_check",
+ "fieldtype": "Check",
+ "in_list_view": 1,
+ "label": "Bypass credit limit_check"
+ }
+ ],
+ "istable": 1,
+ "modified": "2019-08-29 20:46:36.073953",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Customer Credit Limit",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.py b/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.py
new file mode 100644
index 0000000..60a4a9a
--- /dev/null
+++ b/erpnext/selling/doctype/customer_credit_limit/customer_credit_limit.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class CustomerCreditLimit(Document):
+ pass
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index c9aaab4..12b9a8e 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -208,7 +208,9 @@
def check_credit_limit(self):
# if bypass credit limit check is set to true (1) at sales order level,
# then we need not to check credit limit and vise versa
- if not cint(frappe.get_cached_value("Customer", self.customer, "bypass_credit_limit_check_at_sales_order")):
+ if not cint(frappe.db.get_value("Customer Credit Limit",
+ {'parent': self.customer, 'parenttype': 'Customer', 'company': self.company},
+ "bypass_credit_limit_check")):
check_credit_limit(self.customer, self.company)
def check_nextdoc_docstatus(self):
@@ -518,7 +520,7 @@
"doctype": "Material Request Item",
"field_map": {
"parent": "sales_order",
- "stock_uom": "uom"
+ "uom": "stock_uom"
},
"postprocess": update_item
},
diff --git a/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_bypass_credit_limit_check.js b/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_bypass_credit_limit_check.js
index dbd58c1..79d798b 100644
--- a/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_bypass_credit_limit_check.js
+++ b/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_bypass_credit_limit_check.js
@@ -1,7 +1,7 @@
QUnit.module('Sales Order');
QUnit.test("test_sales_order_with_bypass_credit_limit_check", function(assert) {
-//#PR : 10861, Author : ashish-greycube & jigneshpshah, Email:mr.ashish.shah@gmail.com
+//#PR : 10861, Author : ashish-greycube & jigneshpshah, Email:mr.ashish.shah@gmail.com
assert.expect(2);
let done = assert.async();
frappe.run_serially([
@@ -10,8 +10,10 @@
() => frappe.quick_entry.dialog.$wrapper.find('.edit-full').click(),
() => frappe.timeout(1),
() => cur_frm.set_value("customer_name", "Test Customer 10"),
- () => cur_frm.set_value("credit_limit", 100.00),
- () => cur_frm.set_value("bypass_credit_limit_check_at_sales_order", 1),
+ () => cur_frm.add_child('credit_limits', {
+ 'company': cur_frm.doc.company || '_Test Company'
+ 'credit_limit': 1000,
+ 'bypass_credit_limit_check': 1}),
// save form
() => cur_frm.save(),
() => frappe.timeout(1),
@@ -22,10 +24,10 @@
() => frappe.timeout(1),
() => cur_frm.set_value("item_code", "Test Product 10"),
() => cur_frm.set_value("item_group", "Products"),
- () => cur_frm.set_value("standard_rate", 100),
+ () => cur_frm.set_value("standard_rate", 100),
// save form
() => cur_frm.save(),
- () => frappe.timeout(1),
+ () => frappe.timeout(1),
() => {
return frappe.tests.make('Sales Order', [
@@ -46,11 +48,11 @@
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(3),
() => {
-
+
assert.ok(cur_frm.doc.status=="To Deliver and Bill", "It is submited. Credit limit is NOT checked for sales order");
- },
+ },
() => done()
]);
});
diff --git a/erpnext/selling/doctype/sales_order/tests/test_sales_order_without_bypass_credit_limit_check.js b/erpnext/selling/doctype/sales_order/tests/test_sales_order_without_bypass_credit_limit_check.js
index 4e81fb0..8de39f9 100644
--- a/erpnext/selling/doctype/sales_order/tests/test_sales_order_without_bypass_credit_limit_check.js
+++ b/erpnext/selling/doctype/sales_order/tests/test_sales_order_without_bypass_credit_limit_check.js
@@ -1,7 +1,7 @@
QUnit.module('Sales Order');
QUnit.test("test_sales_order_without_bypass_credit_limit_check", function(assert) {
-//#PR : 10861, Author : ashish-greycube & jigneshpshah, Email:mr.ashish.shah@gmail.com
+//#PR : 10861, Author : ashish-greycube & jigneshpshah, Email:mr.ashish.shah@gmail.com
assert.expect(2);
let done = assert.async();
frappe.run_serially([
@@ -10,8 +10,10 @@
() => frappe.quick_entry.dialog.$wrapper.find('.edit-full').click(),
() => frappe.timeout(1),
() => cur_frm.set_value("customer_name", "Test Customer 11"),
- () => cur_frm.set_value("credit_limit", 100.00),
- () => cur_frm.set_value("bypass_credit_limit_check_at_sales_order", 0),
+ () => cur_frm.add_child('credit_limits', {
+ 'credit_limit': 1000,
+ 'company': '_Test Company',
+ 'bypass_credit_limit_check': 1}),
// save form
() => cur_frm.save(),
() => frappe.timeout(1),
@@ -21,10 +23,10 @@
() => frappe.click_link('Edit in full page'),
() => cur_frm.set_value("item_code", "Test Product 11"),
() => cur_frm.set_value("item_group", "Products"),
- () => cur_frm.set_value("standard_rate", 100),
+ () => cur_frm.set_value("standard_rate", 100),
// save form
() => cur_frm.save(),
- () => frappe.timeout(1),
+ () => frappe.timeout(1),
() => {
return frappe.tests.make('Sales Order', [
@@ -45,14 +47,14 @@
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(3),
() => {
-
- if (cur_dialog.body.innerText.match(/^Credit limit has been crossed for customer.*$/))
- {
+
+ if (cur_dialog.body.innerText.match(/^Credit limit has been crossed for customer.*$/))
+ {
/*Match found */
assert.ok(true, "Credit Limit crossed message received");
}
-
-
+
+
},
() => cur_dialog.cancel(),
() => done()
diff --git a/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py b/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py
index ee0d72b..cd50568 100644
--- a/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py
+++ b/erpnext/selling/report/customer_credit_balance/customer_credit_balance.py
@@ -29,7 +29,7 @@
if customer_naming_type == "Naming Series":
row = [d.name, d.customer_name, credit_limit, outstanding_amt, bal,
- d.bypass_credit_limit_check_at_sales_order, d.is_frozen,
+ d.bypass_credit_limit_check, d.is_frozen,
d.disabled]
else:
row = [d.name, credit_limit, outstanding_amt, bal,
@@ -60,9 +60,15 @@
conditions = ""
if filters.get("customer"):
- conditions += " where name = %(customer)s"
+ conditions += " AND c.name = " + filters.get("customer")
- return frappe.db.sql("""select name, customer_name,
- bypass_credit_limit_check_at_sales_order, is_frozen, disabled from `tabCustomer` %s
- """ % conditions, filters, as_dict=1)
-
+ return frappe.db.sql("""SELECT
+ c.name, c.customer_name,
+ ccl.bypass_credit_limit_check,
+ c.is_frozen, c.disabled
+ FROM `tabCustomer` c, `tabCustomer Credit Limit` ccl
+ WHERE
+ c.name = ccl.parent
+ AND ccl.company = %s
+ {0}
+ """.format(conditions), (filters.get("company")), as_dict=1) #nosec
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 670b4e9..14d8031 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
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
-from frappe.utils import cint,cstr
+from frappe.utils import flt
def execute(filters=None):
columns = get_columns()
@@ -100,7 +100,7 @@
so.transaction_date,
so.customer,
so.territory,
- sum(so_item.qty) as net_qty,
+ sum(so_item.qty) as total_qty,
so.company
FROM `tabSales Order` so, `tabSales Order Item` so_item
WHERE
@@ -111,10 +111,15 @@
so.name,so_item.item_code
""", as_dict = 1)
+ sales_orders = [row.name for row in sales_order_entry]
mr_records = frappe.get_all("Material Request Item",
- {"sales_order_item": ("!=",""), "docstatus": 1},
+ {"sales_order": ("in", sales_orders), "docstatus": 1},
["parent", "qty", "sales_order", "item_code"])
+ bundled_item_map = get_packed_items(sales_orders)
+
+ item_with_product_bundle = get_items_with_product_bundle([row.item_code for row in sales_order_entry])
+
materials_request_dict = {}
for record in mr_records:
@@ -131,27 +136,64 @@
if record.parent not in details.get('material_requests'):
details['material_requests'].append(record.parent)
- pending_so=[]
+ pending_so = []
for so in sales_order_entry:
- # fetch all the material request records for a sales order item
- key = (so.name, so.item_code)
- materials_request = materials_request_dict.get(key) or {}
+ if so.item_code not in item_with_product_bundle:
+ material_requests_against_so = materials_request_dict.get((so.name, so.item_code)) or {}
+ # check for pending sales order
+ if flt(so.total_qty) > flt(material_requests_against_so.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(material_requests_against_so.get('material_requests', [])),
+ "customer": so.customer,
+ "territory": so.territory,
+ "so_qty": so.total_qty,
+ "requested_qty": material_requests_against_so.get('qty'),
+ "pending_qty": so.total_qty - flt(material_requests_against_so.get('qty')),
+ "company": so.company
+ }
+ pending_so.append(so_record)
+ else:
+ for item in bundled_item_map.get((so.name, so.item_code)):
+ material_requests_against_so = materials_request_dict.get((so.name, item.item_code)) or {}
+ if flt(item.qty) > flt(material_requests_against_so.get('qty')):
+ so_record = {
+ "item_code": item.item_code,
+ "item_name": item.item_name,
+ "description": item.description,
+ "sales_order_no": so.name,
+ "date": so.transaction_date,
+ "material_request": ','.join(material_requests_against_so.get('material_requests', [])),
+ "customer": so.customer,
+ "territory": so.territory,
+ "so_qty": item.qty,
+ "requested_qty": material_requests_against_so.get('qty', 0),
+ "pending_qty": item.qty - flt(material_requests_against_so.get('qty', 0)),
+ "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
+
+ return pending_so
+
+def get_items_with_product_bundle(item_list):
+ bundled_items = frappe.get_all("Product Bundle", filters = [
+ ("new_item_code", "IN", item_list)
+ ], fields = ["new_item_code"])
+
+ return [d.new_item_code for d in bundled_items]
+
+def get_packed_items(sales_order_list):
+ packed_items = frappe.get_all("Packed Item", filters = [
+ ("parent", "IN", sales_order_list)
+ ], fields = ["parent_item", "item_code", "qty", "item_name", "description", "parent"])
+
+ bundled_item_map = frappe._dict()
+ for d in packed_items:
+ bundled_item_map.setdefault((d.parent, d.parent_item), []).append(d)
+
+ return bundled_item_map
diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py
index 8a5e50a..72767f0 100644
--- a/erpnext/selling/report/sales_analytics/sales_analytics.py
+++ b/erpnext/selling/report/sales_analytics/sales_analytics.py
@@ -40,6 +40,16 @@
"fieldtype": "Data",
"width": 140
})
+
+ if self.filters.tree_type == "Item":
+ self.columns.append({
+ "label": _("UOM"),
+ "fieldname": 'stock_uom',
+ "fieldtype": "Link",
+ "options": "UOM",
+ "width": 100
+ })
+
for end_date in self.periodic_daterange:
period = self.get_period(end_date)
self.columns.append({
@@ -129,7 +139,7 @@
value_field = 'qty'
self.entries = frappe.db.sql("""
- select i.item_code as entity, i.item_name as entity_name, i.{value_field} as value_field, s.{date_field}
+ select i.item_code as entity, i.item_name as entity_name, i.stock_uom, i.{value_field} as value_field, s.{date_field}
from `tab{doctype} Item` i , `tab{doctype}` s
where s.name = i.parent and i.docstatus = 1 and s.company = %s
and s.{date_field} between %s and %s
@@ -198,6 +208,10 @@
total += amount
row["total"] = total
+
+ if self.filters.tree_type == "Item":
+ row["stock_uom"] = period_data.get("stock_uom")
+
self.data.append(row)
def get_rows_by_group(self):
@@ -232,6 +246,9 @@
self.entity_periodic_data.setdefault(d.entity, frappe._dict()).setdefault(period, 0.0)
self.entity_periodic_data[d.entity][period] += flt(d.value_field)
+ if self.filters.tree_type == "Item":
+ self.entity_periodic_data[d.entity]['stock_uom'] = d.stock_uom
+
def get_period(self, posting_date):
if self.filters.range == 'Weekly':
period = "Week " + str(posting_date.isocalendar()[1]) + " " + str(posting_date.year)
diff --git a/erpnext/setup/doctype/customer_group/customer_group.json b/erpnext/setup/doctype/customer_group/customer_group.json
index c130e79..3565b4b 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.json
+++ b/erpnext/setup/doctype/customer_group/customer_group.json
@@ -1,553 +1,194 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
+ "_comments": "[]",
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:customer_group_name",
- "beta": 0,
"creation": "2013-01-10 16:34:23",
- "custom": 0,
- "docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
- "editable_grid": 0,
+ "field_order": [
+ "customer_group_name",
+ "parent_customer_group",
+ "is_group",
+ "cb0",
+ "default_price_list",
+ "payment_terms",
+ "lft",
+ "rgt",
+ "old_parent",
+ "default_receivable_account",
+ "accounts",
+ "credit_limit_section",
+ "credit_limits"
+ ],
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "customer_group_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": "Customer Group Name",
- "length": 0,
"no_copy": 1,
"oldfieldname": "customer_group_name",
"oldfieldtype": "Data",
- "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": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
"bold": 1,
- "collapsible": 0,
- "columns": 0,
- "description": "",
"fieldname": "parent_customer_group",
"fieldtype": "Link",
- "hidden": 0,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
"in_list_view": 1,
- "in_standard_filter": 0,
"label": "Parent Customer Group",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "parent_customer_group",
"oldfieldtype": "Link",
- "options": "Customer Group",
- "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
+ "options": "Customer Group"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
"bold": 1,
- "collapsible": 0,
- "columns": 0,
+ "default": "0",
"description": "Only leaf nodes are allowed in transaction",
"fieldname": "is_group",
"fieldtype": "Check",
- "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": "Is Group",
- "length": 0,
- "no_copy": 0,
"oldfieldname": "is_group",
- "oldfieldtype": "Select",
- "options": "",
- "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
+ "oldfieldtype": "Select"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "cb0",
- "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
+ "fieldtype": "Column Break"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "default_price_list",
"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": "Default 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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "options": "Price List"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
"fieldname": "payment_terms",
"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": "Default Payment Terms Template",
- "length": 0,
- "no_copy": 0,
- "options": "Payment Terms Template",
- "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
+ "options": "Payment Terms Template"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "credit_limit",
- "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": "Credit Limit",
- "length": 0,
- "no_copy": 0,
- "permlevel": 1,
- "print_hide": 0,
- "print_hide_if_no_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": "lft",
"fieldtype": "Int",
"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": "lft",
- "length": 0,
"no_copy": 1,
"oldfieldname": "lft",
"oldfieldtype": "Int",
- "permlevel": 0,
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
"report_hide": 1,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "rgt",
"fieldtype": "Int",
"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": "rgt",
- "length": 0,
"no_copy": 1,
"oldfieldname": "rgt",
"oldfieldtype": "Int",
- "permlevel": 0,
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
"report_hide": 1,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "search_index": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
"fieldname": "old_parent",
"fieldtype": "Link",
"hidden": 1,
"ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
"label": "old_parent",
- "length": 0,
"no_copy": 1,
"oldfieldname": "old_parent",
"oldfieldtype": "Data",
"options": "Customer Group",
- "permlevel": 0,
"print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 1,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
+ "report_hide": 1
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "default_receivable_account",
"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": "Default Receivable Account",
- "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
+ "label": "Default Receivable Account"
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "eval:!doc.__islocal",
"description": "Mention if non-standard receivable account applicable",
"fieldname": "accounts",
"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": "Accounts",
- "length": 0,
- "no_copy": 0,
- "options": "Party Account",
- "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
+ "options": "Party Account"
+ },
+ {
+ "fieldname": "credit_limit_section",
+ "fieldtype": "Section Break",
+ "label": "Credit Limits"
+ },
+ {
+ "fieldname": "credit_limits",
+ "fieldtype": "Table",
+ "label": "Credit Limit",
+ "options": "Customer Credit Limit"
}
],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
"icon": "fa fa-sitemap",
"idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2018-08-29 06:26:05.935871",
+ "modified": "2019-09-06 12:40:14.954697",
"modified_by": "Administrator",
"module": "Setup",
"name": "Customer Group",
"owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Sales Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Sales Manager"
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
"email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Sales User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Sales User"
},
{
- "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": 1,
"share": 1,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
"permlevel": 1,
- "print": 0,
"read": 1,
- "report": 0,
"role": "Sales Master Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
"write": 1
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
"permlevel": 1,
- "print": 0,
"read": 1,
- "report": 0,
- "role": "Sales User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Sales User"
},
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
"permlevel": 1,
- "print": 0,
"read": 1,
- "report": 0,
- "role": "Sales Manager",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
+ "role": "Sales Manager"
}
],
"quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
"search_fields": "parent_customer_group",
"show_name_in_global_search": 1,
- "sort_order": "DESC",
- "track_changes": 0,
- "track_seen": 0,
- "track_views": 0
+ "sort_order": "DESC"
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index bb357d8..b309b50 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
import copy
+from frappe import _
from frappe.utils import nowdate, cint, cstr
from frappe.utils.nestedset import NestedSet
from frappe.website.website_generator import WebsiteGenerator
@@ -28,7 +29,8 @@
super(ItemGroup, self).validate()
if not self.parent_item_group and not frappe.flags.in_test:
- self.parent_item_group = 'All Item Groups'
+ if frappe.db.exists("Item Group", _('All Item Groups'), cache=True):
+ self.parent_item_group = _('All Item Groups')
self.make_route()
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index 0922f3d..db2c327 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -336,19 +336,20 @@
def _set_price_list(quotation, cart_settings):
"""Set price list based on customer or shopping cart default"""
- if quotation.selling_price_list:
- return
+ from erpnext.accounts.party import get_default_price_list
# check if customer price list exists
selling_price_list = None
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.party_name))
+ selling_price_list = frappe.db.get_value('Customer', quotation.party_name, 'default_price_list')
# else check for territory based price list
if not selling_price_list:
selling_price_list = cart_settings.price_list
+ if not selling_price_list and quotation.party_name:
+ selling_price_list = get_default_price_list(frappe.get_doc("Customer", quotation.party_name))
+
quotation.selling_price_list = selling_price_list
def set_taxes(quotation, cart_settings):
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index f79d127..bdb49e4 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -234,8 +234,10 @@
extra_amount = 0
validate_against_credit_limit = False
- bypass_credit_limit_check_at_sales_order = cint(frappe.db.get_value("Customer", self.customer,
- "bypass_credit_limit_check_at_sales_order"))
+ bypass_credit_limit_check_at_sales_order = cint(frappe.db.get_value("Customer Credit Limit",
+ filters={'parent': self.customer, 'parenttype': 'Customer', 'company': self.company},
+ fieldname="bypass_credit_limit_check"))
+
if bypass_credit_limit_check_at_sales_order:
validate_against_credit_limit = True
extra_amount = self.base_grand_total
diff --git a/erpnext/stock/doctype/delivery_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
index a253811..77d322e 100644
--- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py
+++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py
@@ -238,7 +238,7 @@
try:
directions = maps_client.directions(**directions_data)
except Exception as e:
- frappe.throw(_(e.message))
+ frappe.throw(_(e))
return directions[0] if directions else False
diff --git a/erpnext/stock/doctype/packing_slip/packing_slip.py b/erpnext/stock/doctype/packing_slip/packing_slip.py
index b99215c..4139a19 100644
--- a/erpnext/stock/doctype/packing_slip/packing_slip.py
+++ b/erpnext/stock/doctype/packing_slip/packing_slip.py
@@ -49,7 +49,7 @@
frappe.msgprint(_("Please specify a valid 'From Case No.'"), raise_exception=1)
elif not self.to_case_no:
self.to_case_no = self.from_case_no
- elif self.from_case_no > self.to_case_no:
+ elif cint(self.from_case_no) > cint(self.to_case_no):
frappe.msgprint(_("'To Case No.' cannot be less than 'From Case No.'"),
raise_exception=1)
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index bf5a818..35c0bb6 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -639,7 +639,7 @@
if not frappe.db.get_value("Price List",
{"name": args.price_list, args.transaction_type: 1, "enabled": 1}):
throw(_("Price List {0} is disabled or does not exist").format(args.price_list))
- elif not args.get("supplier"):
+ elif args.get("customer"):
throw(_("Price List not selected"))
def validate_conversion_rate(args, meta):
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index f7deac3..69a4b94 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -181,10 +181,7 @@
# rounding as per precision
self.stock_value = flt(self.stock_value, self.precision)
- if self.prev_stock_value < 0 and self.stock_value >= 0 and sle.voucher_type != 'Stock Reconciliation':
- stock_value_difference = sle.actual_qty * self.valuation_rate
- else:
- stock_value_difference = self.stock_value - self.prev_stock_value
+ stock_value_difference = self.stock_value - self.prev_stock_value
self.prev_stock_value = self.stock_value
diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py
index 6ea3228..aec37d4 100644
--- a/erpnext/stock/utils.py
+++ b/erpnext/stock/utils.py
@@ -15,7 +15,7 @@
values = {}
conditions = ""
if warehouse:
- conditions += """ and warehouse in (
+ conditions += """ and `tabBin`.warehouse in (
select w2.name from `tabWarehouse` w1
join `tabWarehouse` w2 on
w1.name = %(warehouse)s
@@ -25,11 +25,12 @@
values['warehouse'] = warehouse
if item_code:
- conditions += " and item_code = %(item_code)s"
+ conditions += " and `tabBin`.item_code = %(item_code)s"
values['item_code'] = item_code
- query = "select sum(stock_value) from `tabBin` where 1 = 1 %s" % conditions
+ query = """select sum(stock_value) from `tabBin`, `tabItem` where 1 = 1
+ and `tabItem`.name = `tabBin`.item_code and ifnull(`tabItem`.disabled, 0) = 0 %s""" % conditions
stock_value = frappe.db.sql(query, values)
diff --git a/erpnext/templates/includes/footer/footer_powered.html b/erpnext/templates/includes/footer/footer_powered.html
index 8d5523f..d4deaae 100644
--- a/erpnext/templates/includes/footer/footer_powered.html
+++ b/erpnext/templates/includes/footer/footer_powered.html
@@ -1,3 +1,3 @@
{% set domains = frappe.get_doc("Domain Settings").active_domains %}
-<a href="https://erpnext.com?source=website_footer" target="_blank" class="text-muted">Powered by ERPNext - {{ domains[0].domain if domains else 'Open Source' }} ERP Software</a>
+<a href="https://erpnext.com?source=website_footer" target="_blank" class="text-muted">Powered by ERPNext - ERP Software {{ ('for ' + domains[0].domain + ' Companies') if domains else '' }}</a>