diff --git a/erpnext/__init__.py b/erpnext/__init__.py index ee37c8d7801..106384ade06 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe 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/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 b042bcc4204..adfa9f89e23 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/bank/bank_dashboard.py b/erpnext/accounts/doctype/bank/bank_dashboard.py index 4a1dad89526..1e2383de5fd 100644 --- a/erpnext/accounts/doctype/bank/bank_dashboard.py +++ b/erpnext/accounts/doctype/bank/bank_dashboard.py @@ -8,7 +8,7 @@ def get_data(): 'fieldname': 'bank', 'transactions': [ { - 'label': _('Bank Deatils'), + 'label': _('Bank Details'), 'items': ['Bank Account', 'Bank Guarantee'] } ] diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js index 0e7301204af..2173e7dfb7b 100755 --- a/erpnext/accounts/page/pos/pos.js +++ b/erpnext/accounts/page/pos/pos.js @@ -1118,7 +1118,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ if (key) { return $.grep(this.items_list, function (item) { if (search_status) { - if (in_list(me.batch_no_data[item.item_code], me.search_item.$input.val())) { + if (me.batch_no_data[item.item_code] && + in_list(me.batch_no_data[item.item_code], me.search_item.$input.val())) { search_status = false; return me.item_batch_no[item.item_code] = me.search_item.$input.val() } else if (me.serial_no_data[item.item_code] @@ -1126,7 +1127,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({ search_status = false; me.item_serial_no[item.item_code] = [me.search_item.$input.val(), me.serial_no_data[item.item_code][me.search_item.$input.val()]] return true - } else if (in_list(me.barcode_data[item.item_code], me.search_item.$input.val())) { + } else if (me.barcode_data[item.item_code] && + in_list(me.barcode_data[item.item_code], me.search_item.$input.val())) { search_status = false; return true; } else if (reg.test(item.item_code.toLowerCase()) || (item.description && reg.test(item.description.toLowerCase())) || diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index e42f4af2a5d..59936d5116d 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -292,8 +292,11 @@ def validate_party_accounts(doc): 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 @@ def validate_due_date(posting_date, due_date, party_type, party, company=None, b .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 @@ def get_partywise_advanced_payment_amount(party_type, posting_date = None): .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 d00bcf643e7..791f3f8008b 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -1,275 +1,269 @@ + .print-format { + padding: 4mm; + font-size: 8.0pt !important; + } + .print-format td { + vertical-align:middle !important; + } + -
| {%= __(" ") %} | +{%= __(range1) %} | +{%= __(range2) %} | +{%= __(range3) %} | +{%= __(range4) %} | +{%= __(range5) %} | +{%= __("Total") %} | +
|---|---|---|---|---|---|---|
| {%= __("Total Outstanding") %} | +{%= format_number(balance_row["range1"], null, 2) %} | +{%= format_currency(balance_row["range2"]) %} | +{%= format_currency(balance_row["range3"]) %} | +{%= format_currency(balance_row["range4"]) %} | +{%= format_currency(balance_row["range5"]) %} | ++ {%= format_currency(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) %} + | +{%= __("Future Payments") %} | ++ | + | + | + | + | + {%= format_currency(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) %} + | +
| {%= __("Cheques Required") %} | ++ | + | + | + | + | + {%= format_currency(flt(balance_row["outstanding"] - balance_row[("future_amount")]), data[data.length-1]["currency"]) %} | +
| {%= __(" ") %} | -{%= __(range1) %} | -{%= __(range2) %} | -{%= __(range3) %} | -{%= __(range4) %} | -{%= __(range5) %} | -{%= __(range6) %} | -{%= __("Total") %} | + {% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %} +{%= __("Date") %} | +{%= __("Age (Days)") %} | + + {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} +{%= __("Reference") %} | +{%= __("Sales Person") %} | + {% } else { %} +{%= __("Reference") %} | + {% } %} + {% if(!filters.show_future_payments) { %} +{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %} | + {% } %} +{%= __("Invoiced Amount") %} | + {% if(!filters.show_future_payments) { %} +{%= __("Paid Amount") %} | +{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %} | + {% } %} +{%= __("Outstanding Amount") %} | + {% if(filters.show_future_payments) { %} + {% if(report.report_name === "Accounts Receivable") { %} +{%= __("Customer LPO No.") %} | + {% } %} +{%= __("Future Payment Ref") %} | +{%= __("Future Payment Amount") %} | +{%= __("Remaining Balance") %} | + {% } %} + {% } else { %} +{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %} | +{%= __("Total Invoiced Amount") %} | +{%= __("Total Paid Amount") %} | +{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %} | +{%= __("Total Outstanding Amount") %} | + {% } %}
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| {%= __("Total Outstanding") %} | -{%= format_number(balance_row[range1], null, 2) %} | -{%= format_currency(balance_row[range2]) %} | -{%= format_currency(balance_row[range3]) %} | -{%= format_currency(balance_row[range4]) %} | -{%= format_currency(balance_row[range5]) %} | -{%= format_currency(balance_row[range6]) %} | -- {%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %} - | -{%= __("PDC/LC") %} | -- | - | - | - | - | - | - {%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %} - | -|||||||||||
| {%= __("Cheques Required") %} | -- | - | - | - | - | - | - {%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %} | -
| {%= __("Date") %} | -{%= __("Age (Days)") %} | - - {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} -{%= __("Reference") %} | -{%= __("Sales Person") %} | - {% } else { %} -{%= __("Reference") %} | - {% } %} - {% if(!filters.show_future_payments) { %} -{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %} | - {% } %} -{%= __("Invoiced Amount") %} | - {% if(!filters.show_future_payments) { %} -{%= __("Paid Amount") %} | -{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %} | - {% } %} -{%= __("Outstanding Amount") %} | - {% if(filters.show_future_payments) { %} - {% if(report.report_name === "Accounts Receivable") { %} -{%= __("Customer LPO No.") %} | - {% } %} -{%= __("PDC/LC Ref") %} | -{%= __("PDC/LC Amount") %} | -{%= __("Remaining Balance") %} | - {% } %} - {% } else { %} -{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %} | -{%= __("Total Invoiced Amount") %} | -{%= __("Total Paid Amount") %} | -{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %} | -{%= __("Total Outstanding Amount") %} | - {% } %} -{%= frappe.datetime.str_to_user(data[i]["posting_date"]) %} | -{%= data[i][__("Age (Days)")] %} | -
- {% if(!filters.show_future_payments) { %}
- {%= data[i]["voucher_type"] %}
- - {% } %} - {%= data[i]["voucher_no"] %} - |
-
- {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
- {%= data[i]["sales_person"] %} | - {% } %} - - {% if(!filters.show_future_payments) { %} -
- {% if(!(filters.customer || filters.supplier)) { %}
- {%= data[i][__("Customer")] || data[i][__("Supplier")] %}
- {% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
- {%= data[i][__("Customer Name")] %} - {% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %} - {%= data[i][__("Supplier Name")] %} + {% for(var i=0, l=data.length; i {%= frappe.datetime.str_to_user(data[i]["posting_date"]) %} |
+ {%= data[i]["age"] %} |
+
+ {% if(!filters.show_future_payments) { %}
+ {%= data[i]["voucher_type"] %}
+ |
+
+ {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
+ {% } %} + {%= data[i]["voucher_no"] %} + {%= data[i]["sales_person"] %} |
{% } %}
-
- {% if data[i][__("Remarks")] %}
- {%= __("Remarks") %}:
- {%= data[i][__("Remarks")] %}
- {% } %}
-
- |
- {% } %}
- - {%= format_currency(data[i]["invoiced_amount"], data[i]["currency"]) %} | - - {% if(!filters.show_future_payments) { %} -- {%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %} | -- {%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %} | - {% } %} -- {%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %} | - - {% if(filters.show_future_payments) { %} - {% if(report.report_name === "Accounts Receivable") { %} -- {%= data[i]["po_no"] %} | - {% } %} -{%= data[i][("pdc/lc_ref")] %} | -{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %} | -{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %} | - {% } %} - {% } else { %} -- {% if(!filters.show_future_payments) { %} - | - {% } %} - {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} - | - {% } %} - | - | {%= __("Total") %} | -- {%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %} | - - {% if(!filters.show_future_payments) { %} -- {%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %} | -{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %} | - {% } %} -- {%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %} | - - {% if(filters.show_future_payments) { %} - {% if(report.report_name === "Accounts Receivable") { %} -- {%= data[i][__("Customer LPO")] %} | - {% } %} -{%= data[i][("pdc/lc_ref")] %} | -{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %} | -{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %} | - {% } %} - {% } %} - {% } else { %} - {% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %} - {% if((data[i][__("Customer")] || data[i][__("Supplier")]) != __("'Total'")) { %} + {% if(!filters.show_future_payments) { %}
{% if(!(filters.customer || filters.supplier)) { %}
- {%= data[i][__("Customer")] || data[i][__("Supplier")] %}
- {% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
- {%= data[i][__("Customer Name")] %} - {% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %} - {%= data[i][__("Supplier Name")] %} + {%= data[i]["party"] %} + {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %} + {%= data[i]["customer_name"] %} + {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %} + {%= data[i]["supplier_name"] %} {% } %} {% } %} - {%= __("Remarks") %}: - {%= data[i][__("Remarks")] %} +
+ {% if data[i]["remarks"] %}
+ {%= __("Remarks") %}:
+ {%= data[i]["remarks"] %}
+ {% } %}
+
|
+ {% } %}
+
+ + {%= format_currency(data[i]["invoiced"], data[i]["currency"]) %} | + + {% if(!filters.show_future_payments) { %} ++ {%= format_currency(data[i]["paid"], data[i]["currency"]) %} | ++ {%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} | + {% } %} ++ {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} | + + {% if(filters.show_future_payments) { %} + {% if(report.report_name === "Accounts Receivable") { %} ++ {%= data[i]["po_no"] %} | + {% } %} +{%= data[i]["future_ref"] %} | +{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %} | +{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %} | + {% } %} {% } else { %} -{%= __("Total") %} | ++ {% if(!filters.show_future_payments) { %} + | + {% } %} + {% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %} + | + {% } %} + | + | {%= __("Total") %} | ++ {%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %} | + + {% if(!filters.show_future_payments) { %} ++ {%= format_currency(data[i]["paid"], data[i]["currency"]) %} | +{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} | + {% } %} ++ {%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} | + + {% if(filters.show_future_payments) { %} + {% if(report.report_name === "Accounts Receivable") { %} ++ {%= data[i]["po_no"] %} | + {% } %} +{%= data[i]["future_ref"] %} | +{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %} | +{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %} | + {% } %} + {% } %} + {% } else { %} + {% if(data[i]["party"]|| " ") { %} + {% if((data[i]["party"]) != __("'Total'")) { %} +
+ {% if(!(filters.customer || filters.supplier)) { %}
+ {%= data[i]["party"] %}
+ {% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
+ {%= data[i]["customer_name"] %} + {% } else if(data[i]["supplier_name"] != data[i]["party"]) { %} + {%= data[i]["supplier_name"] %} + {% } %} + {% } %} + {%= __("Remarks") %}: + {%= data[i]["remarks"] %} + |
+ {% } else { %}
+ {%= __("Total") %} | + {% } %} +{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %} | +{%= format_currency(data[i]["paid"], data[i]["currency"]) %} | +{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} | +{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %} | {% } %} -{%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %} | -{%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %} | -{%= 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"]) %} | -{%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %} | {% } %} + {% } %} - - {% } %} -
|---|
{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}
+ +{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_list.js b/erpnext/buying/doctype/purchase_order/purchase_order_list.js index a67d69dc26b..8413eb65c3f 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 @@ frappe.listview_settings['Purchase Order'] = { 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/communication/doctype/call_log/call_log.py b/erpnext/communication/doctype/call_log/call_log.py index 35c31a0bf83..5343bef62ce 100644 --- a/erpnext/communication/doctype/call_log/call_log.py +++ b/erpnext/communication/doctype/call_log/call_log.py @@ -28,7 +28,7 @@ class CallLog(Document): self.trigger_call_popup() def trigger_call_popup(self): - scheduled_employees = get_scheduled_employees_for_popup(self.to) + scheduled_employees = get_scheduled_employees_for_popup(self.medium) employee_emails = get_employees_with_number(self.to) # check if employees with matched number are scheduled to receive popup diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index b2057ca40f9..64d49b45492 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -57,9 +57,9 @@ status_map = { "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/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py index ed9eae3529f..ad32e946312 100644 --- a/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py +++ b/erpnext/healthcare/doctype/healthcare_practitioner/healthcare_practitioner.py @@ -69,33 +69,10 @@ def validate_service_item(item, msg): 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 bf15cad5d52..e3eea96f859 100644 --- a/erpnext/healthcare/doctype/patient/patient.py +++ b/erpnext/healthcare/doctype/patient/patient.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals 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 @@ class Patient(Document): 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/additional_salary/additional_salary.py b/erpnext/hr/doctype/additional_salary/additional_salary.py index 82f2a22e81b..8498b3d277d 100644 --- a/erpnext/hr/doctype/additional_salary/additional_salary.py +++ b/erpnext/hr/doctype/additional_salary/additional_salary.py @@ -11,7 +11,7 @@ from frappe.utils import getdate, date_diff class AdditionalSalary(Document): def before_insert(self): if frappe.db.exists("Additional Salary", {"employee": self.employee, "salary_component": self.salary_component, - "amount": self.amount, "payroll_date": self.payroll_date, "company": self.company}): + "amount": self.amount, "payroll_date": self.payroll_date, "company": self.company, "docstatus": 1}): frappe.throw(_("Additional Salary Component Exists.")) diff --git a/erpnext/hr/doctype/employee_checkin/employee_checkin.py b/erpnext/hr/doctype/employee_checkin/employee_checkin.py index d7d67061406..86705121ac5 100644 --- a/erpnext/hr/doctype/employee_checkin/employee_checkin.py +++ b/erpnext/hr/doctype/employee_checkin/employee_checkin.py @@ -142,8 +142,10 @@ def calculate_working_hours(logs, check_in_out_type, working_hours_calc_type): 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/employee_incentive/employee_incentive.js b/erpnext/hr/doctype/employee_incentive/employee_incentive.js index d2ddfb67a84..db0f83aac9a 100644 --- a/erpnext/hr/doctype/employee_incentive/employee_incentive.js +++ b/erpnext/hr/doctype/employee_incentive/employee_incentive.js @@ -2,7 +2,21 @@ // For license information, please see license.txt frappe.ui.form.on('Employee Incentive', { - refresh: function(frm) { + setup: function(frm) { + frm.set_query("employee", function() { + return { + filters: { + "status": "Active" + } + }; + }); + frm.set_query("salary_component", function() { + return { + filters: { + "type": "Earning" + } + }; + }); } }); diff --git a/erpnext/hr/doctype/employee_incentive/employee_incentive.json b/erpnext/hr/doctype/employee_incentive/employee_incentive.json index 5ba1d636be6..3bc772cfa68 100644 --- a/erpnext/hr/doctype/employee_incentive/employee_incentive.json +++ b/erpnext/hr/doctype/employee_incentive/employee_incentive.json @@ -1,330 +1,130 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "HR-EINV-.YY.-.MM.-.#####", - "beta": 0, - "creation": "2018-04-13 16:13:43.404546", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "autoname": "HR-EINV-.YY.-.MM.-.#####", + "creation": "2018-04-13 16:13:43.404546", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "employee", + "incentive_amount", + "payroll_date", + "salary_component", + "amended_from", + "column_break_5", + "employee_name", + "department", + "additional_salary" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Employee", - "length": 0, - "no_copy": 0, - "options": "Employee", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "employee", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Employee", + "options": "Employee", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "incentive_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Incentive Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "incentive_amount", + "fieldtype": "Currency", + "label": "Incentive Amount", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "payroll_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Payroll Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "payroll_date", + "fieldtype": "Date", + "label": "Payroll Date", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Employee Incentive", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Employee Incentive", + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_5", - "fieldtype": "Column Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "column_break_5", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Employee Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fetch_from": "employee.employee_name", + "fieldname": "employee_name", + "fieldtype": "Data", + "label": "Employee Name", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.department", - "fieldname": "department", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Department", - "length": 0, - "no_copy": 0, - "options": "Department", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fetch_from": "employee.department", + "fieldname": "department", + "fieldtype": "Link", + "label": "Department", + "options": "Department", + "read_only": 1 + }, + { + "fieldname": "additional_salary", + "fieldtype": "Link", + "label": "Additional Salary", + "no_copy": 1, + "options": "Additional Salary", + "read_only": 1 + }, + { + "fieldname": "salary_component", + "fieldtype": "Link", + "label": "Salary Component", + "options": "Salary Component", + "reqd": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-21 16:15:51.811149", - "modified_by": "Administrator", - "module": "HR", - "name": "Employee Incentive", - "name_case": "", - "owner": "Administrator", + ], + "is_submittable": 1, + "modified": "2019-09-03 16:48:16.822252", + "modified_by": "Administrator", + "module": "HR", + "name": "Employee Incentive", + "owner": "Administrator", "permissions": [ { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Employee", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 0 - }, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Employee", + "share": 1 + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "create": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "share": 1, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "employee_name", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + ], + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "employee_name", + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/hr/doctype/employee_incentive/employee_incentive.py b/erpnext/hr/doctype/employee_incentive/employee_incentive.py index 6c9a315336e..2e138f8ef56 100644 --- a/erpnext/hr/doctype/employee_incentive/employee_incentive.py +++ b/erpnext/hr/doctype/employee_incentive/employee_incentive.py @@ -7,4 +7,39 @@ import frappe from frappe.model.document import Document class EmployeeIncentive(Document): - pass + def on_submit(self): + company = frappe.db.get_value('Employee', self.employee, 'company') + additional_salary = frappe.db.exists('Additional Salary', { + 'employee': self.employee, + 'salary_component': self.salary_component, + 'payroll_date': self.payroll_date, + 'company': company, + 'docstatus': 1 + }) + + if not additional_salary: + additional_salary = frappe.new_doc('Additional Salary') + additional_salary.employee = self.employee + additional_salary.salary_component = self.salary_component + additional_salary.amount = self.incentive_amount + additional_salary.payroll_date = self.payroll_date + additional_salary.company = company + additional_salary.submit() + self.db_set('additional_salary', additional_salary.name) + + else: + incentive_added = frappe.db.get_value('Additional Salary', additional_salary, 'amount') + self.incentive_amount + frappe.db.set_value('Additional Salary', additional_salary, 'amount', incentive_added) + self.db_set('additional_salary', additional_salary) + + def on_cancel(self): + if self.additional_salary: + incentive_removed = frappe.db.get_value('Additional Salary', self.additional_salary, 'amount') - self.incentive_amount + if incentive_removed == 0: + frappe.get_doc('Additional Salary', self.additional_salary).cancel() + else: + frappe.db.set_value('Additional Salary', self.additional_salary, 'amount', incentive_removed) + + self.db_set('additional_salary', '') + + diff --git a/erpnext/hr/doctype/retention_bonus/retention_bonus.js b/erpnext/hr/doctype/retention_bonus/retention_bonus.js index 58f6b536042..64e726db857 100644 --- a/erpnext/hr/doctype/retention_bonus/retention_bonus.js +++ b/erpnext/hr/doctype/retention_bonus/retention_bonus.js @@ -10,8 +10,13 @@ frappe.ui.form.on('Retention Bonus', { } }; }); - }, - refresh: function(frm) { + frm.set_query("salary_component", function() { + return { + filters: { + "type": "Earning" + } + }; + }); } }); diff --git a/erpnext/hr/doctype/retention_bonus/retention_bonus.json b/erpnext/hr/doctype/retention_bonus/retention_bonus.json index 5a92f07bd67..7781053e137 100644 --- a/erpnext/hr/doctype/retention_bonus/retention_bonus.json +++ b/erpnext/hr/doctype/retention_bonus/retention_bonus.json @@ -1,415 +1,165 @@ { - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 1, - "autoname": "HR-RTB-.YYYY.-.#####", - "beta": 0, - "creation": "2018-05-13 14:59:42.038964", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_import": 1, + "allow_rename": 1, + "autoname": "HR-RTB-.YYYY.-.#####", + "creation": "2018-05-13 14:59:42.038964", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "company", + "employee", + "bonus_payment_date", + "bonus_amount", + "salary_component", + "amended_from", + "column_break_6", + "employee_name", + "department", + "date_of_joining", + "additional_salary" + ], "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "company", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Company", - "length": 0, - "no_copy": 0, - "options": "Company", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "employee", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Employee", - "length": 0, - "no_copy": 0, - "options": "Employee", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "employee", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Employee", + "options": "Employee", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "bonus_payment_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Bonus Payment Date", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "bonus_payment_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Bonus Payment Date", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "bonus_amount", - "fieldtype": "Currency", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Bonus Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "bonus_amount", + "fieldtype": "Currency", + "label": "Bonus Amount", + "reqd": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "amended_from", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Amended From", - "length": 0, - "no_copy": 1, - "options": "Retention Bonus", - "permlevel": 0, - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fieldname": "amended_from", + "fieldtype": "Link", + "label": "Amended From", + "no_copy": 1, + "options": "Retention Bonus", + "print_hide": 1, + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_6", - "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 - }, + "fieldname": "column_break_6", + "fieldtype": "Column Break" + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.employee_name", - "fieldname": "employee_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Employee Name", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fetch_from": "employee.employee_name", + "fieldname": "employee_name", + "fieldtype": "Data", + "label": "Employee Name", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.department", - "fieldname": "department", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Department", - "length": 0, - "no_copy": 0, - "options": "Department", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, + "fetch_from": "employee.department", + "fieldname": "department", + "fieldtype": "Link", + "label": "Department", + "options": "Department", + "read_only": 1 + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "employee.date_of_joining", - "fieldname": "date_of_joining", - "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": "Date of Joining", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 + "fetch_from": "employee.date_of_joining", + "fieldname": "date_of_joining", + "fieldtype": "Data", + "label": "Date of Joining", + "read_only": 1 + }, + { + "fieldname": "additional_salary", + "fieldtype": "Link", + "label": "Additional Salary", + "no_copy": 1, + "options": "Additional Salary", + "read_only": 1 + }, + { + "fieldname": "salary_component", + "fieldtype": "Link", + "label": "Salary Component", + "options": "Salary Component", + "reqd": 1 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 1, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-08-21 16:15:38.710684", - "modified_by": "Administrator", - "module": "HR", - "name": "Retention Bonus", - "name_case": "", - "owner": "Administrator", + ], + "is_submittable": 1, + "modified": "2019-09-03 16:47:24.210422", + "modified_by": "Administrator", + "module": "HR", + "name": "Retention Bonus", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR Manager", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "HR User", - "set_user_permissions": 0, - "share": 1, - "submit": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "HR User", + "share": 1, + "submit": 1, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Employee", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 0 + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Employee", + "share": 1 } - ], - "quick_entry": 1, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1, - "track_seen": 0, - "track_views": 0 + ], + "quick_entry": 1, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/hr/doctype/retention_bonus/retention_bonus.py b/erpnext/hr/doctype/retention_bonus/retention_bonus.py index 20d4c13f197..48637a350cd 100644 --- a/erpnext/hr/doctype/retention_bonus/retention_bonus.py +++ b/erpnext/hr/doctype/retention_bonus/retention_bonus.py @@ -10,7 +10,42 @@ from frappe.utils import getdate class RetentionBonus(Document): def validate(self): - if frappe.get_value("Employee", self.employee, "status") == "Left": - frappe.throw(_("Cannot create Retention Bonus for left Employees")) + if frappe.get_value('Employee', self.employee, 'status') == 'Left': + frappe.throw(_('Cannot create Retention Bonus for left Employees')) if getdate(self.bonus_payment_date) < getdate(): - frappe.throw(_("Bonus Payment Date cannot be a past date")) + frappe.throw(_('Bonus Payment Date cannot be a past date')) + + def on_submit(self): + company = frappe.db.get_value('Employee', self.employee, 'company') + additional_salary = frappe.db.exists('Additional Salary', { + 'employee': self.employee, + 'salary_component': self.salary_component, + 'payroll_date': self.bonus_payment_date, + 'company': company, + 'docstatus': 1 + }) + + if not additional_salary: + additional_salary = frappe.new_doc('Additional Salary') + additional_salary.employee = self.employee + additional_salary.salary_component = self.salary_component + additional_salary.amount = self.bonus_amount + additional_salary.payroll_date = self.bonus_payment_date + additional_salary.company = company + additional_salary.submit() + self.db_set('additional_salary', additional_salary.name) + + else: + bonus_added = frappe.db.get_value('Additional Salary', additional_salary, 'amount') + self.bonus_amount + frappe.db.set_value('Additional Salary', additional_salary, 'amount', bonus_added) + self.db_set('additional_salary', additional_salary) + + def on_cancel(self): + if self.additional_salary: + bonus_removed = frappe.db.get_value('Additional Salary', self.additional_salary, 'amount') - self.bonus_amount + if bonus_removed == 0: + frappe.get_doc('Additional Salary', self.additional_salary).cancel() + else: + frappe.db.set_value('Additional Salary', self.additional_salary, 'amount', bonus_removed) + + self.db_set('additional_salary', '') \ No newline at end of file diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py index 650ab137a04..048ce0d6ef8 100644 --- a/erpnext/manufacturing/doctype/production_plan/production_plan.py +++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py @@ -99,7 +99,7 @@ class ProductionPlan(Document): 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 @@ class ProductionPlan(Document): 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/v12_0/move_item_tax_to_item_tax_template.py b/erpnext/patches/v12_0/move_item_tax_to_item_tax_template.py index 02203d29d40..9f4c4453651 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 @@ def get_item_tax_template(item_tax_templates, rename_template_to_untitled, item_ 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 101d903bed7..3eea390ff31 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.js +++ b/erpnext/projects/doctype/timesheet/timesheet.js @@ -147,6 +147,15 @@ frappe.ui.form.on("Timesheet Detail", { 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 @@ frappe.ui.form.on("Timesheet Detail", { }, 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 3c719227bda..9ee292796c3 100644 --- a/erpnext/projects/doctype/timesheet/timesheet.py +++ b/erpnext/projects/doctype/timesheet/timesheet.py @@ -145,12 +145,17 @@ class Timesheet(Document): 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/quality_management/doctype/quality_procedure/quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py index 4d3c5229563..b4de03e1e4f 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 @@ class QualityProcedure(NestedSet): 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 8fd785f2057..dbdbbab3925 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 @@ frappe.treeview_settings["Quality Procedure"] = { ], 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_dashboard.py b/erpnext/selling/doctype/customer/customer_dashboard.py index 8e790bf9ce3..654dd48c669 100644 --- a/erpnext/selling/doctype/customer/customer_dashboard.py +++ b/erpnext/selling/doctype/customer/customer_dashboard.py @@ -9,7 +9,7 @@ def get_data(): '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/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py index c9aaab4b21e..67fa0d43c8d 100755 --- a/erpnext/selling/doctype/sales_order/sales_order.py +++ b/erpnext/selling/doctype/sales_order/sales_order.py @@ -518,7 +518,7 @@ def make_material_request(source_name, target_doc=None): "doctype": "Material Request Item", "field_map": { "parent": "sales_order", - "stock_uom": "uom" + "uom": "stock_uom" }, "postprocess": update_item }, 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 670b4e98bf3..14d80315823 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 @@ def get_data(): 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 @@ def get_data(): 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 @@ def get_data(): 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 8a5e50a61e7..72767f06890 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.py +++ b/erpnext/selling/report/sales_analytics/sales_analytics.py @@ -40,6 +40,16 @@ class Analytics(object): "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 @@ class Analytics(object): 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 @@ class Analytics(object): 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 @@ class Analytics(object): 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/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py index 0922f3d1a07..db2c3277d0f 100644 --- a/erpnext/shopping_cart/cart.py +++ b/erpnext/shopping_cart/cart.py @@ -336,19 +336,20 @@ def set_price_list_and_rate(quotation, cart_settings): 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_trip/delivery_trip.py b/erpnext/stock/doctype/delivery_trip/delivery_trip.py index a253811b278..77d322ed28d 100644 --- a/erpnext/stock/doctype/delivery_trip/delivery_trip.py +++ b/erpnext/stock/doctype/delivery_trip/delivery_trip.py @@ -238,7 +238,7 @@ class DeliveryTrip(Document): 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 b99215c426a..4139a19abf4 100644 --- a/erpnext/stock/doctype/packing_slip/packing_slip.py +++ b/erpnext/stock/doctype/packing_slip/packing_slip.py @@ -49,7 +49,7 @@ class PackingSlip(Document): 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 bf5a8180bd4..35c0bb61658 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -639,7 +639,7 @@ def validate_price_list(args): 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 f7deac35911..69a4b94b4ea 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -181,10 +181,7 @@ class update_entries_after(object): # 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 6ea322872ef..aec37d4e945 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -15,7 +15,7 @@ def get_stock_value_from_bin(warehouse=None, item_code=None): 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 @@ def get_stock_value_from_bin(warehouse=None, item_code=None): 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)