resolved merge conflicts
diff --git a/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py b/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py
index cb95bd1..9e3388b 100644
--- a/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py
+++ b/erpnext/accounts/doctype/account/chart_of_accounts/import_from_openerp.py
@@ -4,7 +4,7 @@
"""
Import chart of accounts from OpenERP sources
"""
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import os, json
import ast
@@ -229,7 +229,7 @@
filename = src["id"][5:] + "_" + chart_id
- print "building " + filename
+ print("building " + filename)
chart = {}
chart["name"] = src["name"]
chart["country_code"] = src["id"][5:]
diff --git a/erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js b/erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js
new file mode 100644
index 0000000..f52f6fb
--- /dev/null
+++ b/erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js
@@ -0,0 +1,22 @@
+QUnit.module('Account');
+
+QUnit.test("test Bank Reconciliation", function(assert) {
+ assert.expect(0);
+ let done = assert.async();
+ frappe.run_serially([
+ () => frappe.set_route('Form', 'Bank Reconciliation'),
+ () => cur_frm.set_value('bank_account','Cash - FT'),
+ () => frappe.click_button('Get Payment Entries'),
+ () => {
+ for(var i=0;i<=cur_frm.doc.payment_entries.length-1;i++){
+ cur_frm.doc.payment_entries[i].clearance_date = frappe.datetime.add_days(frappe.datetime.now_date(), 2);
+ }
+ },
+ () => {cur_frm.refresh_fields('payment_entries');},
+ () => frappe.click_button('Update Clearance Date'),
+ () => frappe.timeout(0.5),
+ () => frappe.click_button('Close'),
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.js b/erpnext/accounts/doctype/journal_entry/test_journal_entry.js
new file mode 100644
index 0000000..28ccd95
--- /dev/null
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.js
@@ -0,0 +1,39 @@
+QUnit.module('Journal Entry');
+
+QUnit.test("test journal entry", function(assert) {
+ assert.expect(2);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Journal Entry', [
+ {posting_date:frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
+ {accounts: [
+ [
+ {'account':'Debtors - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+ {'party_type':'Customer'},
+ {'party':'Test Customer 1'},
+ {'credit_in_account_currency':1000},
+ {'is_advance':'Yes'},
+ ],
+ [
+ {'account':'HDFC - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+ {'debit_in_account_currency':1000},
+ ]
+ ]},
+ {cheque_no:1234},
+ {cheque_date: frappe.datetime.add_days(frappe.datetime.nowdate(), -1)},
+ {user_remark: 'Test'},
+ ]);
+ },
+ () => cur_frm.save(),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.total_debit==1000, "total debit correct");
+ assert.ok(cur_frm.doc.total_credit==1000, "total credit correct");
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 7bb9a52..9832c05 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -393,7 +393,7 @@
if self.payment_type=="Receive":
against_account = self.paid_to
else:
- against_account = self.paid_from
+ against_account = self.paid_from
party_gl_dict = self.get_gl_dict({
diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js
new file mode 100644
index 0000000..a4ef0ca
--- /dev/null
+++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js
@@ -0,0 +1,29 @@
+QUnit.module('Accounts');
+
+QUnit.test("test payment entry", function(assert) {
+ assert.expect(1);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Payment Entry', [
+ {payment_type:'Receive'},
+ {mode_of_payment:'Cash'},
+ {party_type:'Customer'},
+ {party:'Test Customer 3'},
+ {paid_amount:675},
+ {reference_no:123},
+ {reference_date: frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
+ ]);
+ },
+ () => cur_frm.save(),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.total_allocated_amount==675, "Allocated AmountCorrect");
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 96d617e..780edd8 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -109,7 +109,7 @@
if not self.recurring_id:
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
- self.company, self.base_grand_total, self)
+ self.company, self.base_grand_total, self)
self.check_prev_docstatus()
diff --git a/erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js b/erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js
new file mode 100644
index 0000000..7abfb41
--- /dev/null
+++ b/erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js
@@ -0,0 +1,52 @@
+QUnit.module('Sales Invoice');
+
+QUnit.test("test sales Invoice with payment request", function(assert) {
+ assert.expect(4);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Sales Invoice', [
+ {customer: 'Test Customer 1'},
+ {items: [
+ [
+ {'qty': 5},
+ {'item_code': 'Test Product 1'},
+ ]
+ ]},
+ {update_stock:1},
+ {customer_address: 'Test1-Billing'},
+ {shipping_address_name: 'Test1-Shipping'},
+ {contact_person: 'Contact 1-Test Customer 1'},
+ {taxes_and_charges: 'TEST In State GST'},
+ {tc_name: 'Test Term 1'},
+ {terms: 'This is Test'}
+ ]);
+ },
+ () => cur_frm.save(),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+ // get tax details
+ assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
+ // grand_total Calculated
+ assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
+
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(2),
+ () => frappe.tests.click_button('Close'),
+ () => frappe.tests.click_button('Make'),
+ () => frappe.tests.click_link('Payment Request'),
+ () => frappe.timeout(0.2),
+ () => { cur_frm.set_value('print_format','GST Tax Invoice');},
+ () => { cur_frm.set_value('email_to','test@gmail.com');},
+ () => cur_frm.save(),
+ () => {
+ // get payment details
+ assert.ok(cur_frm.doc.grand_total==590, "grand total Correct");
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
index 7faaf11..a47df2d 100644
--- a/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
+++ b/erpnext/accounts/doctype/shipping_rule/shipping_rule.py
@@ -54,13 +54,15 @@
d.idx = i + 1
def validate_overlapping_shipping_rule_conditions(self):
- def overlap_exists_between((x1, x2), (y1, y2)):
+ def overlap_exists_between(num_range1, num_range2):
"""
- (x1, x2) and (y1, y2) are two ranges
- if condition x = 100 to 300
- then condition y can only be like 50 to 99 or 301 to 400
+ num_range1 and num_range2 are two ranges
+ ranges are represented as a tuple e.g. range 100 to 300 is represented as (100, 300)
+ if condition num_range1 = 100 to 300
+ then condition num_range2 can only be like 50 to 99 or 301 to 400
hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
"""
+ (x1, x2), (y1, y2) = num_range1, num_range2
separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2)
return (not separate)
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
index 853b805..8fafce6 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html
@@ -10,15 +10,15 @@
<thead>
<tr>
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
- <th style="width: 15%">{%= __("Date") %}</th>
- <th style="width: 15%">{%= __("Ref") %}</th>
- <th style="width: 40%">{%= __("Party") %}</th>
- <th style="width: 15%">{%= __("Invoiced Amount") %}</th>
- <th style="width: 15%">{%= __("Paid Amount") %}</th>
- <th style="width: 15%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
- <th style="width: 15%">{%= __("Outstanding Amount") %}</th>
+ <th style="width: 14%">{%= __("Date") %}</th>
+ <th style="width: 16%">{%= __("Ref") %}</th>
+ <th style="width: 30%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
+ <th style="width: 10%">{%= __("Invoiced Amount") %}</th>
+ <th style="width: 10%">{%= __("Paid Amount") %}</th>
+ <th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
+ <th style="width: 10%">{%= __("Outstanding Amount") %}</th>
{% } else { %}
- <th style="width: 40%">{%= __("Party") %}</th>
+ <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>
@@ -34,8 +34,12 @@
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
<td>{%= data[i][__("Voucher Type")] %}
<br>{%= data[i][__("Voucher No")] %}</td>
- <td>{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}
- <br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
+ <td>
+ {% if(!(filters.customer || filters.supplier)) { %}
+ {%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}<br>{%= __("Remarks") %}:
+ {% } %}
+ {%= data[i][__("Remarks")] %}
+ </td>
<td style="text-align: right">
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
<td style="text-align: right">
@@ -59,8 +63,13 @@
{% } else { %}
{% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %}
{% if((data[i][__("Customer")] || data[i][__("Supplier")]) != __("'Total'")) { %}
- <td>{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
- <br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
+ <td>
+ {% if(!(filters.customer || filters.supplier)) { %}
+ {%= data[i][__("Customer")] || data[i][__("Supplier")] %}
+ <br>{%= __("Remarks") %}:
+ {% } %}
+ {%= data[i][__("Remarks")] %}
+ </td>
{% } else { %}
<td><b>{%= __("Total") %}</b></td>
{% } %}
diff --git a/erpnext/controllers/website_list_for_contact.py b/erpnext/controllers/website_list_for_contact.py
index 73badc2..65360ec 100644
--- a/erpnext/controllers/website_list_for_contact.py
+++ b/erpnext/controllers/website_list_for_contact.py
@@ -68,8 +68,8 @@
if txt:
if meta.get_field('items'):
if meta.get_field('items').options:
- child_doctype = meta.get_field('items').options
- for item in frappe.get_all(child_doctype, {"item_name": ['like', "%" + txt + "%"]}):
+ child_doctype = meta.get_field('items').options
+ for item in frappe.get_all(child_doctype, {"item_name": ['like', "%" + txt + "%"]}):
child = frappe.get_doc(child_doctype, item.name)
or_filters.append([doctype, "name", "=", child.parent])
diff --git a/erpnext/crm/doctype/lead/lead.json b/erpnext/crm/doctype/lead/lead.json
index e7c2d33..c9d04ac 100644
--- a/erpnext/crm/doctype/lead/lead.json
+++ b/erpnext/crm/doctype/lead/lead.json
@@ -80,36 +80,6 @@
"bold": 0,
"collapsible": 0,
"columns": 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,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "lead_name",
"fieldtype": "Data",
"hidden": 0,
@@ -141,21 +111,21 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "gender",
- "fieldtype": "Link",
+ "fieldname": "company_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_list_view": 1,
"in_standard_filter": 0,
- "label": "Gender",
+ "label": "Organization Name",
"length": 0,
"no_copy": 0,
- "options": "Gender",
+ "oldfieldname": "company_name",
+ "oldfieldtype": "Data",
"permlevel": 0,
- "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@@ -266,6 +236,37 @@
"bold": 0,
"collapsible": 0,
"columns": 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,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "source",
"fieldtype": "Link",
@@ -299,36 +300,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "company_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": "Organization Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "company_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": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "eval:doc.source == 'Existing Customer'",
"fieldname": "customer",
"fieldtype": "Link",
@@ -435,6 +406,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
+ "label": "Follow Up",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -514,11 +486,12 @@
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
- "bold": 0,
+ "bold": 1,
"collapsible": 0,
"columns": 0,
- "fieldname": "contact_by",
- "fieldtype": "Link",
+ "description": "",
+ "fieldname": "contact_date",
+ "fieldtype": "Datetime",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -526,12 +499,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Next Contact By",
+ "label": "Next Contact Date",
"length": 0,
- "no_copy": 0,
- "oldfieldname": "contact_by",
- "oldfieldtype": "Link",
- "options": "User",
+ "no_copy": 1,
+ "oldfieldname": "contact_date",
+ "oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -550,9 +522,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "Add to calendar on this date",
- "fieldname": "contact_date",
- "fieldtype": "Datetime",
+ "fieldname": "contact_by",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -560,11 +531,12 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Next Contact Date",
+ "label": "Next Contact By",
"length": 0,
- "no_copy": 1,
- "oldfieldname": "contact_date",
- "oldfieldtype": "Date",
+ "no_copy": 0,
+ "oldfieldname": "contact_by",
+ "oldfieldtype": "Link",
+ "options": "User",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -732,6 +704,37 @@
"bold": 0,
"collapsible": 0,
"columns": 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,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "mobile_no",
"fieldtype": "Data",
"hidden": 0,
@@ -1144,7 +1147,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-06-22 14:29:12.700000",
+ "modified": "2017-08-21 02:28:21.581948",
"modified_by": "Administrator",
"module": "CRM",
"name": "Lead",
diff --git a/erpnext/crm/doctype/opportunity/opportunity.json b/erpnext/crm/doctype/opportunity/opportunity.json
index dc8b3e7..89eb191 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.json
+++ b/erpnext/crm/doctype/opportunity/opportunity.json
@@ -423,6 +423,164 @@
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
+ "collapsible": 1,
+ "collapsible_depends_on": "contact_by",
+ "columns": 0,
+ "fieldname": "next_contact",
+ "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": "Follow Up",
+ "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,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "contact_by",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Next Contact By",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "contact_by",
+ "oldfieldtype": "Link",
+ "options": "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,
+ "unique": 0,
+ "width": "75px"
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "contact_date",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Next Contact Date",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "contact_date",
+ "oldfieldtype": "Date",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
+ "width": "50%"
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "to_discuss",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "To Discuss",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "to_discuss",
+ "oldfieldtype": "Small Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "with_items",
@@ -435,7 +593,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "",
+ "label": "Items",
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
@@ -990,164 +1148,6 @@
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 1,
- "collapsible_depends_on": "contact_by",
- "columns": 0,
- "fieldname": "next_contact",
- "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": "Next Contact",
- "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,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Your sales person who will contact the customer in future",
- "fieldname": "contact_by",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Next Contact By",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "contact_by",
- "oldfieldtype": "Link",
- "options": "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,
- "unique": 0,
- "width": "75px"
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Your sales person will get a reminder on this date to contact the customer",
- "fieldname": "contact_date",
- "fieldtype": "Datetime",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Next Contact Date",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "contact_date",
- "oldfieldtype": "Date",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0,
- "width": "50%"
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "to_discuss",
- "fieldtype": "Small Text",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "To Discuss",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "to_discuss",
- "oldfieldtype": "Small Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
@@ -1189,7 +1189,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-08-07 21:25:10.836517",
+ "modified": "2017-08-21 02:07:46.486433",
"modified_by": "Administrator",
"module": "CRM",
"name": "Opportunity",
diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py
index ae792ac..cec425c 100644
--- a/erpnext/demo/setup/setup_data.py
+++ b/erpnext/demo/setup/setup_data.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import random, json
import frappe, erpnext
@@ -42,7 +42,7 @@
frappe.clear_cache()
def complete_setup(domain='Manufacturing'):
- print "Complete Setup..."
+ print("Complete Setup...")
from frappe.desk.page.setup_wizard.setup_wizard import setup_complete
if not frappe.get_all('Company', limit=1):
diff --git a/erpnext/demo/user/stock.py b/erpnext/demo/user/stock.py
index 1b12db8..43668fe 100644
--- a/erpnext/demo/user/stock.py
+++ b/erpnext/demo/user/stock.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe, random
from frappe.desk import query_report
@@ -36,7 +36,7 @@
try:
pr.submit()
except NegativeStockError:
- print 'Negative stock for {0}'.format(po)
+ print('Negative stock for {0}'.format(po))
pass
frappe.db.commit()
diff --git a/erpnext/hr/doctype/appraisal/test_appraisal.js b/erpnext/hr/doctype/appraisal/test_appraisal.js
new file mode 100644
index 0000000..91da7d3
--- /dev/null
+++ b/erpnext/hr/doctype/appraisal/test_appraisal.js
@@ -0,0 +1,58 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Expense Claim [HR]", function (assert) {
+ assert.expect(3);
+ let done = assert.async();
+ let employee_name;
+
+ frappe.run_serially([
+ // Creating Appraisal
+ () => frappe.set_route('List','Appraisal','List'),
+ () => frappe.timeout(0.3),
+ () => frappe.click_button('Make a new Appraisal'),
+ () => {
+ cur_frm.set_value('kra_template','Test Appraisal 1'),
+ cur_frm.set_value('start_date','2017-08-21'),
+ cur_frm.set_value('end_date','2017-09-21');
+ },
+ () => frappe.timeout(1),
+ () => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 1','score',4),
+ () => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 1','score_earned',2),
+ () => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 2','score',4),
+ () => frappe.model.set_value('Appraisal Goal','New Appraisal Goal 2','score_earned',2),
+ () => frappe.timeout(1),
+ () => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+ (r) => {
+ employee_name = r.message.name;
+ },
+
+ () => frappe.timeout(1),
+ () => cur_frm.set_value('employee',employee_name),
+ () => cur_frm.set_value('employee_name','Test Employee 1'),
+ () => cur_frm.set_value('company','Test Company'),
+ () => frappe.click_button('Calculate Total Score'),
+ () => frappe.timeout(1),
+ () => cur_frm.save(),
+ () => frappe.timeout(1),
+ () => cur_frm.save(),
+
+ // Submitting the Appraisal
+ () => frappe.click_button('Submit'),
+ () => frappe.click_button('Yes'),
+ () => frappe.timeout(3),
+
+ // Checking if the appraisal is correctly set for the employee
+ () => {
+ assert.equal('Submitted',cur_frm.get_field('status').value,
+ 'Appraisal is submitted');
+
+ assert.equal('Test Employee 1',cur_frm.get_field('employee_name').value,
+ 'Appraisal is created for correct employee');
+
+ assert.equal(4,cur_frm.get_field('total_score').value,
+ 'Total score is correctly calculated');
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/hr/doctype/appraisal_template/test_appraisal_template.js b/erpnext/hr/doctype/appraisal_template/test_appraisal_template.js
new file mode 100644
index 0000000..4e245c7
--- /dev/null
+++ b/erpnext/hr/doctype/appraisal_template/test_appraisal_template.js
@@ -0,0 +1,30 @@
+QUnit.module('hr');
+QUnit.test("Test: Appraisal Template [HR]", function (assert) {
+ assert.expect(1);
+ let done = assert.async();
+ frappe.run_serially([
+ // Job Opening creation
+ () => {
+ frappe.tests.make('Appraisal Template', [
+ { kra_title: 'Test Appraisal 1'},
+ { description: 'This is just a test'},
+ { goals: [
+ [
+ { kra: 'Design'},
+ { per_weightage: 50}
+ ],
+ [
+ { kra: 'Code creation'},
+ { per_weightage: 50}
+ ]
+ ]},
+ ]);
+ },
+ () => frappe.timeout(5),
+ () => {
+ assert.equal('Test Appraisal 1',cur_frm.doc.kra_title, 'Appraisal name correctly set');
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/hr/doctype/employee_loan/test_employee_loan.js b/erpnext/hr/doctype/employee_loan/test_employee_loan.js
new file mode 100644
index 0000000..9039339
--- /dev/null
+++ b/erpnext/hr/doctype/employee_loan/test_employee_loan.js
@@ -0,0 +1,79 @@
+
+QUnit.test("Test Loan [HR]", function(assert) {
+ assert.expect(8);
+ let done = assert.async();
+ let employee_name;
+
+ // To create a loan and check principal,interest and balance amount
+ let loan_creation = (ename,lname) => {
+ return frappe.run_serially([
+ () => frappe.db.get_value('Employee', {'employee_name': ename}, 'name'),
+ (r) => {
+ employee_name = r.message.name;
+ },
+ () => frappe.db.get_value('Employee Loan Application', {'loan_type': lname}, 'name'),
+ (r) => {
+ // Creating loan for an employee
+ return frappe.tests.make('Employee Loan', [
+ { company: 'Test Company'},
+ { posting_date: '2017-08-26'},
+ { employee: employee_name},
+ { employee_loan_application: r.message.name},
+ { disbursement_date: '2018-08-26'},
+ { mode_of_payment: 'Cash'},
+ { employee_loan_account: 'Temporary Opening - TC'},
+ { interest_income_account: 'Service - TC'}
+ ]);
+ },
+ () => frappe.timeout(3),
+ () => frappe.click_button('Submit'),
+ () => frappe.timeout(1),
+ () => frappe.click_button('Yes'),
+ () => frappe.timeout(3),
+
+ // Checking if all the amounts are correctly calculated
+ () => {
+ assert.ok(cur_frm.get_field('employee_name').value=='Test Employee 1'&&
+ (cur_frm.get_field('status').value=='Sanctioned'),
+ 'Loan Sanctioned for correct employee');
+
+ assert.equal(7270,
+ cur_frm.get_doc('repayment_schedule').repayment_schedule[0].principal_amount,
+ 'Principal amount for first instalment is correctly calculated');
+
+ assert.equal(2333,
+ cur_frm.get_doc('repayment_schedule').repayment_schedule[0].interest_amount,
+ 'Interest amount for first instalment is correctly calculated');
+
+ assert.equal(192730,
+ cur_frm.get_doc('repayment_schedule').repayment_schedule[0].balance_loan_amount,
+ 'Balance amount after first instalment is correctly calculated');
+
+ assert.equal(9479,
+ cur_frm.get_doc('repayment_schedule').repayment_schedule[23].principal_amount,
+ 'Principal amount for last instalment is correctly calculated');
+
+ assert.equal(111,
+ cur_frm.get_doc('repayment_schedule').repayment_schedule[23].interest_amount,
+ 'Interest amount for last instalment is correctly calculated');
+
+ assert.equal(0,
+ cur_frm.get_doc('repayment_schedule').repayment_schedule[23].balance_loan_amount,
+ 'Balance amount after last instalment is correctly calculated');
+
+ },
+ () => frappe.set_route('List','Employee Loan','List'),
+ () => frappe.timeout(2),
+
+ // Checking the submission of Loan
+ () => {
+ assert.ok(cur_list.data[0].docstatus==1,'Loan sanctioned and submitted successfully');
+ },
+ ]);
+ };
+ frappe.run_serially([
+ // Creating loan
+ () => loan_creation('Test Employee 1','Test Loan'),
+ () => done()
+ ]);
+});
diff --git a/erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js b/erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js
new file mode 100644
index 0000000..72ad915
--- /dev/null
+++ b/erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js
@@ -0,0 +1,68 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Employee Loan Application [HR]", function (assert) {
+ assert.expect(8);
+ let done = assert.async();
+ let employee_name;
+
+ frappe.run_serially([
+ // Creation of Loan Application
+ () => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+ (r) => {
+ employee_name = r.message.name;
+ },
+ () => {
+ frappe.tests.make('Employee Loan Application', [
+ { company: 'Test Company'},
+ { employee: employee_name},
+ { employee_name: 'Test Employee 1'},
+ { status: 'Approved'},
+ { loan_type: 'Test Loan '},
+ { loan_amount: 200000},
+ { description: 'This is just a test'},
+ { repayment_method: 'Repay Over Number of Periods'},
+ { repayment_periods: 24},
+ { rate_of_interest: 14}
+ ]);
+ },
+ () => frappe.timeout(6),
+ () => frappe.click_button('Submit'),
+ () => frappe.timeout(1),
+ () => frappe.click_button('Yes'),
+ () => frappe.timeout(2),
+ () => {
+ // To check if all the amounts are correctly calculated
+
+ assert.ok(cur_frm.get_field('employee_name').value == 'Test Employee 1',
+ 'Application created successfully');
+
+ assert.ok(cur_frm.get_field('status').value=='Approved',
+ 'Status of application is correctly set');
+
+ assert.ok(cur_frm.get_field('loan_type').value=='Test Loan',
+ 'Application is created for correct Loan Type');
+
+ assert.ok(cur_frm.get_field('status').value=='Approved',
+ 'Status of application is correctly set');
+
+ assert.ok(cur_frm.get_field('repayment_amount').value==9603,
+ 'Repayment amount is correctly calculated');
+
+ assert.ok(cur_frm.get_field('total_payable_interest').value==30459,
+ 'Interest amount is correctly calculated');
+
+ assert.ok(cur_frm.get_field('total_payable_amount').value==230459,
+ 'Total payable amount is correctly calculated');
+ },
+
+ () => frappe.set_route('List','Employee Loan Application','List'),
+ () => frappe.timeout(2),
+
+ // Checking the submission of Loan Application
+ () => {
+ assert.ok(cur_list.data[0].docstatus==1,'Loan Application submitted successfully');
+ },
+ () => frappe.timeout(1),
+ () => done()
+ ]);
+});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/expense_claim/test_expense_claim.js b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
new file mode 100644
index 0000000..c7c764c
--- /dev/null
+++ b/erpnext/hr/doctype/expense_claim/test_expense_claim.js
@@ -0,0 +1,59 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Expense Claim [HR]", function (assert) {
+ assert.expect(3);
+ let done = assert.async();
+ let employee_name;
+ let d;
+ frappe.run_serially([
+ // Creating Expense Claim
+ () => frappe.set_route('List','Expense Claim','List'),
+ () => frappe.timeout(0.3),
+ () => frappe.click_button('Make a new Expense Claim'),
+ () => {
+ cur_frm.set_value('exp_approver','Administrator'),
+ cur_frm.set_value('is_paid',1),
+ cur_frm.set_value('expenses',[]),
+ d = frappe.model.add_child(cur_frm.doc,'Expense Claim Detail','expenses'),
+ d.expense_date = '2017-08-01',
+ d.expense_type = 'Test Expense Type 1',
+ d.description = 'This is just to test Expense Claim',
+ d.claim_amount = 2000,
+ d.sanctioned_amount=2000,
+ refresh_field('expenses');
+ },
+ () => frappe.timeout(2),
+ () => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+ (r) => {
+ employee_name = r.message.name;
+ },
+ () => frappe.timeout(1),
+ () => cur_frm.set_value('employee',employee_name),
+ () => cur_frm.set_value('employee_name','Test Employee 1'),
+ () => cur_frm.set_value('company','Test Company'),
+ () => cur_frm.set_value('payable_account','Creditors - TC'),
+ () => cur_frm.set_value('cost_center','Main - TC'),
+ () => cur_frm.set_value('mode_of_payment','Cash'),
+ () => cur_frm.save(),
+ () => frappe.timeout(1),
+ () => cur_frm.set_value('approval_status','Approved'),
+ () => frappe.timeout(1),
+ () => cur_frm.save(),
+ // Submitting the Expense Claim
+ () => frappe.click_button('Submit'),
+ () => frappe.click_button('Yes'),
+ () => frappe.timeout(3),
+
+ // Checking if the amount is correctly reimbursed for the employee
+ () => {
+ assert.equal(employee_name,cur_frm.get_field('employee').value,
+ 'Expense Claim is created for correct employee');
+ assert.equal(1,cur_frm.get_field('is_paid').value,
+ 'Expense is paid as required');
+ assert.equal(2000,cur_frm.get_field('total_amount_reimbursed').value,
+ 'Amount is reimbursed correctly');
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js b/erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js
new file mode 100644
index 0000000..595454f
--- /dev/null
+++ b/erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js
@@ -0,0 +1,30 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Expense Claim Type [HR]", function (assert) {
+ assert.expect(1);
+ let done = assert.async();
+ frappe.run_serially([
+ // Creating a Expense Claim Type
+ () => {
+ frappe.tests.make('Expense Claim Type', [
+ { expense_type: 'Test Expense Type 1'},
+ { description:'This is just a test'},
+ { accounts: [
+ [
+ { company: 'Test Company'},
+ { default_account: 'Round Off - TC'}
+ ]
+ ]},
+ ]);
+ },
+ () => frappe.timeout(5),
+
+ // Checking if the created type is present in the list
+ () => {
+ assert.equal('Test Expense Type 1', cur_frm.doc.expense_type,
+ 'Expense Claim Type created successfully');
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/hr/doctype/leave_application/test_leave_application.js b/erpnext/hr/doctype/leave_application/test_leave_application.js
index 51e8ed6..6028405 100644
--- a/erpnext/hr/doctype/leave_application/test_leave_application.js
+++ b/erpnext/hr/doctype/leave_application/test_leave_application.js
@@ -1,7 +1,7 @@
QUnit.module('hr');
QUnit.test("Test: Leave application [HR]", function (assert) {
- assert.expect(5);
+ assert.expect(4);
let done = assert.async();
let today_date = frappe.datetime.nowdate();
let leave_date = frappe.datetime.add_days(today_date, 1); // leave for tomorrow
@@ -22,8 +22,6 @@
},
() => frappe.timeout(1),
// check calculated total leave days
- () => assert.equal("0.5", cur_frm.doc.total_leave_days,
- "leave application for half day"),
() => assert.ok(!cur_frm.doc.docstatus,
"leave application not submitted with status as open"),
() => cur_frm.set_value("status", "Approved"), // approve the application [as administrator]
diff --git a/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py b/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py
index 42b26e3..210b8b7 100644
--- a/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py
+++ b/erpnext/hr/doctype/leave_block_list/test_leave_block_list.py
@@ -10,7 +10,7 @@
class TestLeaveBlockList(unittest.TestCase):
def tearDown(self):
- frappe.set_user("Administrator")
+ frappe.set_user("Administrator")
def test_get_applicable_block_dates(self):
frappe.set_user("test@example.com")
diff --git a/erpnext/hr/doctype/loan_type/test_loan_type.js b/erpnext/hr/doctype/loan_type/test_loan_type.js
new file mode 100644
index 0000000..8b5032b
--- /dev/null
+++ b/erpnext/hr/doctype/loan_type/test_loan_type.js
@@ -0,0 +1,31 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Loan Type [HR]", function (assert) {
+ assert.expect(3);
+ let done = assert.async();
+
+ frappe.run_serially([
+ // Loan Type creation
+ () => {
+ frappe.tests.make('Loan Type', [
+ { loan_name: 'Test Loan'},
+ { maximum_loan_amount: 400000},
+ { rate_of_interest: 14},
+ { description:
+ 'This is just a test.'}
+ ]);
+ },
+ () => frappe.timeout(3),
+ () => frappe.set_route('List','Loan Type','List'),
+ () => frappe.timeout(2),
+
+ // Checking if the fields are correctly set
+ () => {
+ assert.ok(cur_list.data.length==1, 'Loan Type created successfully');
+ assert.ok(cur_list.data[0].name=='Test Loan', 'Loan title Correctly set');
+ assert.ok(cur_list.data[0].disabled==0, 'Loan enabled');
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/hr/doctype/training_event/test_training_event.js b/erpnext/hr/doctype/training_event/test_training_event.js
new file mode 100644
index 0000000..a359af3
--- /dev/null
+++ b/erpnext/hr/doctype/training_event/test_training_event.js
@@ -0,0 +1,55 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Training Event [HR]", function (assert) {
+ assert.expect(4);
+ let done = assert.async();
+ let employee_name;
+
+ frappe.run_serially([
+ // Creation of Training Event
+ () => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+ (r) => {
+ employee_name = r.message.name;
+ },
+ () => {
+ frappe.tests.make('Training Event', [
+ { event_name: 'Test Training Event 1'},
+ { location: 'Mumbai'},
+ { start_time: '2017-09-01 11:00:0'},
+ { end_time: '2017-09-01 17:00:0'},
+ { introduction: 'This is just a test'},
+ { employees: [
+ [
+ {employee: employee_name},
+ {employee_name: 'Test Employee 1'}
+ ]
+ ]},
+ ]);
+ },
+ () => frappe.timeout(7),
+ () => frappe.click_button('Submit'),
+ () => frappe.timeout(1),
+ () => frappe.click_button('Yes'),
+ () => frappe.timeout(8),
+ () => {
+ // To check if the fields are correctly set
+ assert.ok(cur_frm.get_field('event_name').value == 'Test Training Event 1',
+ 'Event created successfully');
+
+ assert.ok(cur_frm.get_field('event_status').value=='Scheduled',
+ 'Status of event is correctly set');
+
+ assert.ok(cur_frm.doc.employees[0].employee_name=='Test Employee 1',
+ 'Attendee Employee is correctly set');
+ },
+
+ () => frappe.set_route('List','Training Event','List'),
+ () => frappe.timeout(2),
+ // Checking the submission of Training Event
+ () => {
+ assert.ok(cur_list.data[0].docstatus==1,'Training Event Submitted successfully');
+ },
+ () => frappe.timeout(2),
+ () => done()
+ ]);
+});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/training_feedback/test_training_feedback.js b/erpnext/hr/doctype/training_feedback/test_training_feedback.js
new file mode 100644
index 0000000..9daa51f
--- /dev/null
+++ b/erpnext/hr/doctype/training_feedback/test_training_feedback.js
@@ -0,0 +1,52 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Training Feedback [HR]", function (assert) {
+ assert.expect(3);
+ let done = assert.async();
+ let employee_name;
+
+ frappe.run_serially([
+ // Creating Training Feedback
+ () => frappe.set_route('List','Training Feedback','List'),
+ () => frappe.timeout(0.3),
+ () => frappe.click_button('Make a new Training Feedback'),
+ () => frappe.timeout(1),
+ () => frappe.db.get_value('Employee', {'employee_name': 'Test Employee 1'}, 'name'),
+ (r) => {
+ employee_name = r.message.name;
+ },
+ () => cur_frm.set_value('employee',employee_name),
+ () => cur_frm.set_value('employee_name','Test Employee 1'),
+ () => cur_frm.set_value('training_event','Test Training Event 1'),
+ () => cur_frm.set_value('event_name','Test Training Event 1'),
+ () => cur_frm.set_value('feedback','Great Experience. This is just a test.'),
+ () => frappe.timeout(1),
+ () => cur_frm.save(),
+ () => frappe.timeout(1),
+ () => cur_frm.save(),
+
+ // Submitting the feedback
+ () => frappe.click_button('Submit'),
+ () => frappe.click_button('Yes'),
+ () => frappe.timeout(3),
+
+ // Checking if the feedback is given by correct employee
+ () => {
+ assert.equal('Test Employee 1',cur_frm.get_field('employee_name').value,
+ 'Feedback is given by correct employee');
+
+ assert.equal('Test Training Event 1',cur_frm.get_field('training_event').value,
+ 'Feedback is given for correct event');
+ },
+
+ () => frappe.set_route('List','Training Feedback','List'),
+ () => frappe.timeout(2),
+
+ // Checking the submission of Training Result
+ () => {
+ assert.ok(cur_list.data[0].docstatus==1,'Training Feedback Submitted successfully');
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/hr/doctype/training_result_employee/test_training_result.js b/erpnext/hr/doctype/training_result_employee/test_training_result.js
new file mode 100644
index 0000000..2ebf896
--- /dev/null
+++ b/erpnext/hr/doctype/training_result_employee/test_training_result.js
@@ -0,0 +1,53 @@
+QUnit.module('hr');
+
+QUnit.test("Test: Training Result [HR]", function (assert) {
+ assert.expect(5);
+ let done = assert.async();
+ frappe.run_serially([
+ // Creating Training Result
+ () => frappe.set_route('List','Training Result','List'),
+ () => frappe.timeout(0.3),
+ () => frappe.click_button('Make a new Training Result'),
+ () => {
+ cur_frm.set_value('training_event','Test Training Event 1');
+ },
+ () => frappe.timeout(1),
+ () => frappe.model.set_value('Training Result Employee','New Training Result Employee 1','hours',4),
+ () => frappe.model.set_value('Training Result Employee','New Training Result Employee 1','grade','A'),
+ () => frappe.model.set_value('Training Result Employee','New Training Result Employee 1','comments','Nice Seminar'),
+ () => frappe.timeout(1),
+ () => cur_frm.save(),
+ () => frappe.timeout(1),
+ () => cur_frm.save(),
+
+ // Submitting the Training Result
+ () => frappe.click_button('Submit'),
+ () => frappe.click_button('Yes'),
+ () => frappe.timeout(4),
+
+ // Checking if the fields are correctly set
+ () => {
+ assert.equal('Test Training Event 1',cur_frm.get_field('training_event').value,
+ 'Training Result is created');
+
+ assert.equal('Test Employee 1',cur_frm.doc.employees[0].employee_name,
+ 'Training Result is created for correct employee');
+
+ assert.equal(4,cur_frm.doc.employees[0].hours,
+ 'Hours field is correctly calculated');
+
+ assert.equal('A',cur_frm.doc.employees[0].grade,
+ 'Grade field is correctly set');
+ },
+
+ () => frappe.set_route('List','Training Result','List'),
+ () => frappe.timeout(2),
+
+ // Checking the submission of Training Result
+ () => {
+ assert.ok(cur_list.data[0].docstatus==1,'Training Result Submitted successfully');
+ },
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 71ff43f..e48a002 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -259,15 +259,15 @@
def update_stock_qty(self):
- for m in self.get('items'):
+ for m in self.get('items'):
if not m.conversion_factor:
m.conversion_factor = flt(get_conversion_factor(m.item_code, m.uom)['conversion_factor'])
- if m.uom and m.qty:
- m.stock_qty = flt(m.conversion_factor)*flt(m.qty)
- if not m.uom and m.stock_uom:
- m.uom = m.stock_uom
- m.qty = m.stock_qty
+ if m.uom and m.qty:
+ m.stock_qty = flt(m.conversion_factor)*flt(m.qty)
+ if not m.uom and m.stock_uom:
+ m.uom = m.stock_uom
+ m.qty = m.stock_qty
def set_conversion_rate(self):
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 35530fd..7ec2753 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -433,4 +433,5 @@
erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
erpnext.patches.v8_5.remove_project_type_property_setter
erpnext.patches.v8_7.add_more_gst_fields
-erpnext.patches.v8_7.fix_purchase_receipt_status
\ No newline at end of file
+erpnext.patches.v8_7.fix_purchase_receipt_status
+erpnext.patches.v8_6.rename_bom_update_tool
\ No newline at end of file
diff --git a/erpnext/patches/v4_0/new_address_template.py b/erpnext/patches/v4_0/new_address_template.py
index f644a5a..fa66027 100644
--- a/erpnext/patches/v4_0/new_address_template.py
+++ b/erpnext/patches/v4_0/new_address_template.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
@@ -10,5 +10,5 @@
frappe.db.get_value("Global Defaults", "Global Defaults", "country")})
d.insert()
except:
- print frappe.get_traceback()
+ print(frappe.get_traceback())
diff --git a/erpnext/patches/v4_0/reset_permissions_for_masters.py b/erpnext/patches/v4_0/reset_permissions_for_masters.py
index b2f1fcd..bc1b438 100644
--- a/erpnext/patches/v4_0/reset_permissions_for_masters.py
+++ b/erpnext/patches/v4_0/reset_permissions_for_masters.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
from frappe.permissions import reset_perms
def execute():
@@ -16,5 +16,5 @@
try:
reset_perms(doctype)
except:
- print "Error resetting perms for", doctype
+ print("Error resetting perms for", doctype)
raise
diff --git a/erpnext/patches/v4_0/set_naming_series_property_setter.py b/erpnext/patches/v4_0/set_naming_series_property_setter.py
index 9d12f14..e61a596 100644
--- a/erpnext/patches/v4_0/set_naming_series_property_setter.py
+++ b/erpnext/patches/v4_0/set_naming_series_property_setter.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
@@ -91,7 +91,7 @@
(new_series, new_series))
if not (default_series and default_series[0][0]):
- print "[Skipping] Cannot guess which naming series to use for", doctype
+ print("[Skipping] Cannot guess which naming series to use for", doctype)
return
return default_series[0][0]
diff --git a/erpnext/patches/v4_0/split_email_settings.py b/erpnext/patches/v4_0/split_email_settings.py
index 21dc050..5d1dea6 100644
--- a/erpnext/patches/v4_0/split_email_settings.py
+++ b/erpnext/patches/v4_0/split_email_settings.py
@@ -1,11 +1,11 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
- print "WARNING!!!! Email Settings not migrated. Please setup your email again."
+ print("WARNING!!!! Email Settings not migrated. Please setup your email again.")
# this will happen if you are migrating very old accounts
# comment out this line below and remember to create new Email Accounts
diff --git a/erpnext/patches/v4_0/update_account_root_type.py b/erpnext/patches/v4_0/update_account_root_type.py
index e3edee9..15ddf03 100644
--- a/erpnext/patches/v4_0/update_account_root_type.py
+++ b/erpnext/patches/v4_0/update_account_root_type.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
@@ -31,4 +31,4 @@
frappe.db.sql("""UPDATE tabAccount SET root_type=%s WHERE lft>%s and rgt<%s""",
(root.root_type, root.lft, root.rgt))
else:
- print b"Root type not found for {0}".format(root.name.encode("utf-8"))
+ print(b"Root type not found for {0}".format(root.name.encode("utf-8")))
diff --git a/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py b/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py
index 0df5801..16932af 100644
--- a/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py
+++ b/erpnext/patches/v4_2/fix_gl_entries_for_stock_transactions.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe.utils import flt
@@ -37,7 +37,7 @@
if stock_bal and account_bal and abs(flt(stock_bal[0][0]) - flt(account_bal[0][0])) > 0.1:
try:
- print voucher_type, voucher_no, stock_bal[0][0], account_bal[0][0]
+ print(voucher_type, voucher_no, stock_bal[0][0], account_bal[0][0])
frappe.db.sql("""delete from `tabGL Entry`
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
@@ -45,10 +45,10 @@
voucher = frappe.get_doc(voucher_type, voucher_no)
voucher.make_gl_entries(repost_future_gle=False)
frappe.db.commit()
- except Exception, e:
- print frappe.get_traceback()
+ except Exception as e:
+ print(frappe.get_traceback())
rejected.append([voucher_type, voucher_no])
frappe.db.rollback()
- print "Failed to repost: "
- print rejected
+ print("Failed to repost: ")
+ print(rejected)
diff --git a/erpnext/patches/v4_2/party_model.py b/erpnext/patches/v4_2/party_model.py
index 8f4fc33..6f93352 100644
--- a/erpnext/patches/v4_2/party_model.py
+++ b/erpnext/patches/v4_2/party_model.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
@@ -109,7 +109,7 @@
and exists(select gle.name from `tabGL Entry` gle where gle.account = tabAccount.name)""")
if accounts_not_deleted:
- print "Accounts not deleted: " + "\n".join(accounts_not_deleted)
+ print("Accounts not deleted: " + "\n".join(accounts_not_deleted))
def remove_customer_supplier_account_report():
diff --git a/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py b/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
index 44bec00..1356129 100644
--- a/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
+++ b/erpnext/patches/v4_2/repost_sle_for_si_with_no_warehouse.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from erpnext.stock.stock_ledger import NegativeStockError
@@ -28,7 +28,7 @@
frappe.local.stockledger_exceptions = None
frappe.db.rollback()
- print "Failed to repost: ", failed_list
+ print("Failed to repost: ", failed_list)
\ No newline at end of file
diff --git a/erpnext/patches/v4_2/set_company_country.py b/erpnext/patches/v4_2/set_company_country.py
index 929f6c5..89f07f2 100644
--- a/erpnext/patches/v4_2/set_company_country.py
+++ b/erpnext/patches/v4_2/set_company_country.py
@@ -1,13 +1,13 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
country = frappe.db.get_single_value("Global Defaults", "country")
if not country:
- print "Country not specified in Global Defaults"
+ print("Country not specified in Global Defaults")
return
for company in frappe.db.sql_list("""select name from `tabCompany`
diff --git a/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py b/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py
index da58ae2..76efdcc 100644
--- a/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py
+++ b/erpnext/patches/v5_0/repost_gle_for_jv_with_multiple_party.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
@@ -21,6 +21,6 @@
je.make_gl_entries()
if je_list:
- print je_list
+ print(je_list)
\ No newline at end of file
diff --git a/erpnext/patches/v5_4/fix_missing_item_images.py b/erpnext/patches/v5_4/fix_missing_item_images.py
index 1891d2d..c0a2513 100644
--- a/erpnext/patches/v5_4/fix_missing_item_images.py
+++ b/erpnext/patches/v5_4/fix_missing_item_images.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
import os
from frappe.utils import get_files_path
@@ -45,7 +45,7 @@
try:
file_data.save()
except IOError:
- print "File {0} does not exist".format(new_file_url)
+ print("File {0} does not exist".format(new_file_url))
# marking fix to prevent further errors
fixed_files.append(file_url)
diff --git a/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py b/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py
index 125b84f..ba31122 100644
--- a/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py
+++ b/erpnext/patches/v5_4/notify_system_managers_regarding_wrong_tax_calculation.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe.email import sendmail_to_system_managers
from frappe.utils import get_link_to_form
@@ -36,6 +36,6 @@
except:
pass
- print "="*50
- print content
- print "="*50
\ No newline at end of file
+ print("="*50)
+ print(content)
+ print("="*50)
\ No newline at end of file
diff --git a/erpnext/patches/v5_7/item_template_attributes.py b/erpnext/patches/v5_7/item_template_attributes.py
index 9f141b5..22b15d3 100644
--- a/erpnext/patches/v5_7/item_template_attributes.py
+++ b/erpnext/patches/v5_7/item_template_attributes.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
import MySQLdb
@@ -32,7 +32,7 @@
migrate_item_variants()
except MySQLdb.ProgrammingError:
- print "`tabItem Variant` not found"
+ print("`tabItem Variant` not found")
def rename_and_reload_doctypes():
if "tabVariant Attribute" in frappe.db.get_tables():
diff --git a/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py b/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py
index dc0df0f..fb5eab4 100644
--- a/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py
+++ b/erpnext/patches/v6_12/repost_entries_with_target_warehouse.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
"""
@@ -38,19 +38,19 @@
si_list = get_affected_sales_invoice()
if so_list or dn_list or si_list:
- print "Entries with Target Warehouse:"
+ print("Entries with Target Warehouse:")
if so_list:
- print "Sales Order"
- print so_list
+ print("Sales Order")
+ print(so_list)
if dn_list:
- print "Delivery Notes"
- print [d.name for d in dn_list]
+ print("Delivery Notes")
+ print([d.name for d in dn_list])
if si_list:
- print "Sales Invoice"
- print [d.name for d in si_list]
+ print("Sales Invoice")
+ print([d.name for d in si_list])
def repost():
@@ -61,34 +61,34 @@
frappe.db.commit()
if dn_failed_list:
- print "-"*40
- print "Delivery Note Failed to Repost"
- print dn_failed_list
+ print("-"*40)
+ print("Delivery Note Failed to Repost")
+ print(dn_failed_list)
if si_failed_list:
- print "-"*40
- print "Sales Invoice Failed to Repost"
- print si_failed_list
- print
+ print("-"*40)
+ print("Sales Invoice Failed to Repost")
+ print(si_failed_list)
+ print()
- print """
+ print("""
If above Delivery Notes / Sales Invoice failed due to negative stock, follow these steps:
- Ensure that stock is available for those items in the mentioned warehouse on the date mentioned in the error
- Run this patch again
-"""
+""")
def repost_dn(dn_failed_list):
dn_list = get_affected_delivery_notes()
if dn_list:
- print "-"*40
- print "Reposting Delivery Notes"
+ print("-"*40)
+ print("Reposting Delivery Notes")
for dn in dn_list:
if dn.docstatus == 0:
continue
- print dn.name
+ print(dn.name)
try:
dn_doc = frappe.get_doc("Delivery Note", dn.name)
@@ -107,7 +107,7 @@
except Exception:
dn_failed_list.append(dn.name)
frappe.local.stockledger_exceptions = None
- print frappe.get_traceback()
+ print(frappe.get_traceback())
frappe.db.rollback()
frappe.db.sql("update `tabDelivery Note Item` set target_warehouse='' where docstatus=0")
@@ -116,14 +116,14 @@
si_list = get_affected_sales_invoice()
if si_list:
- print "-"*40
- print "Reposting Sales Invoice"
+ print("-"*40)
+ print("Reposting Sales Invoice")
for si in si_list:
if si.docstatus == 0:
continue
- print si.name
+ print(si.name)
try:
si_doc = frappe.get_doc("Sales Invoice", si.name)
@@ -141,7 +141,7 @@
except Exception:
si_failed_list.append(si.name)
frappe.local.stockledger_exceptions = None
- print frappe.get_traceback()
+ print(frappe.get_traceback())
frappe.db.rollback()
frappe.db.sql("update `tabSales Invoice Item` set target_warehouse='' where docstatus=0")
@@ -152,8 +152,8 @@
frappe.db.sql("update `tabSales Order Item` set target_warehouse=''")
if so_list:
- print "-"*40
- print "Sales Order reposted"
+ print("-"*40)
+ print("Sales Order reposted")
def get_affected_delivery_notes():
diff --git a/erpnext/patches/v6_4/fix_expense_included_in_valuation.py b/erpnext/patches/v6_4/fix_expense_included_in_valuation.py
index 436dd02..7ed15ab 100644
--- a/erpnext/patches/v6_4/fix_expense_included_in_valuation.py
+++ b/erpnext/patches/v6_4/fix_expense_included_in_valuation.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe.utils import cstr
@@ -33,7 +33,7 @@
(pi.name, company.expenses_included_in_valuation))
if gle_for_expenses_included_in_valuation:
- print pi.name
+ print(pi.name)
frappe.db.sql("""delete from `tabGL Entry`
where voucher_type='Purchase Invoice' and voucher_no=%s""", pi.name)
diff --git a/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py b/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
index b1464d5..b53412d 100644
--- a/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
+++ b/erpnext/patches/v6_4/fix_journal_entries_due_to_reconciliation.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
@@ -44,7 +44,7 @@
where name=%s""", d.name)
for d in journal_entries:
- print d
+ print(d)
# delete existing gle
frappe.db.sql("delete from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s", d)
diff --git a/erpnext/patches/v6_4/make_image_thumbnail.py b/erpnext/patches/v6_4/make_image_thumbnail.py
index 702148a..3315acc 100644
--- a/erpnext/patches/v6_4/make_image_thumbnail.py
+++ b/erpnext/patches/v6_4/make_image_thumbnail.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
import frappe
def execute():
@@ -11,4 +12,4 @@
if item_doc.thumbnail:
item_doc.db_set("thumbnail", item_doc.thumbnail, update_modified=False)
except Exception:
- print "Unable to make thumbnail for {0}".format(item.website_image.encode("utf-8"))
+ print("Unable to make thumbnail for {0}".format(item.website_image.encode("utf-8")))
diff --git a/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py b/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py
index e0268c4..1319b53 100644
--- a/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py
+++ b/erpnext/patches/v6_4/repost_gle_for_journal_entries_where_reference_name_missing.py
@@ -1,7 +1,7 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
def execute():
@@ -13,7 +13,7 @@
and against_voucher=je.reference_name)""")
for d in je_list:
- print d
+ print(d)
# delete existing gle
frappe.db.sql("delete from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s", d)
diff --git a/erpnext/patches/v6_6/fix_website_image.py b/erpnext/patches/v6_6/fix_website_image.py
index b3b4cab..cc3e2d8 100644
--- a/erpnext/patches/v6_6/fix_website_image.py
+++ b/erpnext/patches/v6_6/fix_website_image.py
@@ -1,4 +1,4 @@
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe.utils import encode
@@ -25,7 +25,7 @@
try:
file.validate_file()
except IOError:
- print encode(item.website_image), "does not exist"
+ print(encode(item.website_image), "does not exist")
file.delete()
item.db_set("website_image", None, update_modified=False)
diff --git a/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py b/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py
index 58da059..2bc0971 100644
--- a/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py
+++ b/erpnext/patches/v7_0/fix_nonwarehouse_ledger_gl_entries_for_transactions.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe, erpnext
def execute():
@@ -35,11 +35,11 @@
voucher.make_gl_entries()
frappe.db.commit()
except Exception as e:
- print frappe.get_traceback()
+ print(frappe.get_traceback())
rejected.append([voucher_type, voucher_no])
frappe.db.rollback()
- print rejected
+ print(rejected)
def set_warehouse_for_stock_account(warehouse_account):
for account in warehouse_account:
diff --git a/erpnext/patches/v7_0/rename_salary_components.py b/erpnext/patches/v7_0/rename_salary_components.py
index 4e9ceb2..8409ca8 100644
--- a/erpnext/patches/v7_0/rename_salary_components.py
+++ b/erpnext/patches/v7_0/rename_salary_components.py
@@ -81,7 +81,7 @@
try:
frappe.db.sql("""INSERT INTO `tabSalary Component` ({0}) SELECT {1} FROM `tab{2}`"""
.format(target_cols, source_cols, doctype))
- except Exception, e:
+ except Exception as e:
if e.args[0]==1062:
pass
diff --git a/erpnext/schools/api.py b/erpnext/schools/api.py
index c613c8c..ff2da07 100644
--- a/erpnext/schools/api.py
+++ b/erpnext/schools/api.py
@@ -63,7 +63,7 @@
:param student_group: Student Group.
:param date: Date.
"""
-
+
present = json.loads(students_present)
absent = json.loads(students_absent)
diff --git a/erpnext/schools/doctype/course_schedule/test_course_schedule.py b/erpnext/schools/doctype/course_schedule/test_course_schedule.py
index 6a3456f..f131382 100644
--- a/erpnext/schools/doctype/course_schedule/test_course_schedule.py
+++ b/erpnext/schools/doctype/course_schedule/test_course_schedule.py
@@ -17,7 +17,7 @@
cs1 = make_course_schedule_test_record(simulate= True)
cs2 = make_course_schedule_test_record(schedule_date=cs1.schedule_date, from_time= cs1.from_time,
- to_time= cs1.to_time, instructor="_T-Instructor-00002", room="RM0002", do_not_save= 1)
+ to_time= cs1.to_time, instructor="_Test Instructor 2", room="RM0002", do_not_save= 1)
self.assertRaises(OverlapError, cs2.save)
def test_instructor_conflict(self):
@@ -31,14 +31,14 @@
cs1 = make_course_schedule_test_record(simulate= True)
cs2 = make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time,
- student_group="Course-TC101-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", do_not_save= 1)
+ student_group="Course-TC101-2014-2015 (_Test Academic Term)", instructor="_Test Instructor 2", do_not_save= 1)
self.assertRaises(OverlapError, cs2.save)
def test_no_conflict(self):
cs1 = make_course_schedule_test_record(simulate= True)
make_course_schedule_test_record(from_time= cs1.from_time, to_time= cs1.to_time,
- student_group="Course-TC102-2014-2015 (_Test Academic Term)", instructor="_T-Instructor-00002", room="RM0002")
+ student_group="Course-TC102-2014-2015 (_Test Academic Term)", instructor="_Test Instructor 2", room="RM0002")
def make_course_schedule_test_record(**args):
args = frappe._dict(args)
@@ -46,7 +46,7 @@
course_schedule = frappe.new_doc("Course Schedule")
course_schedule.student_group = args.student_group or "Course-TC101-2014-2015 (_Test Academic Term)"
course_schedule.course = args.course or "TC101"
- course_schedule.instructor = args.instructor or "_T-Instructor-00001"
+ course_schedule.instructor = args.instructor or "_Test Instructor"
course_schedule.room = args.room or "RM0001"
course_schedule.schedule_date = args.schedule_date or today()
diff --git a/erpnext/schools/doctype/instructor/instructor.json b/erpnext/schools/doctype/instructor/instructor.json
index a98fe69..cd0b4f1 100644
--- a/erpnext/schools/doctype/instructor/instructor.json
+++ b/erpnext/schools/doctype/instructor/instructor.json
@@ -208,7 +208,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-06-30 08:21:49.055531",
+ "modified": "2017-08-25 01:03:14.602994",
"modified_by": "Administrator",
"module": "Schools",
"name": "Instructor",
diff --git a/erpnext/schools/doctype/instructor/instructor.py b/erpnext/schools/doctype/instructor/instructor.py
index 4331b91..ba179f7 100644
--- a/erpnext/schools/doctype/instructor/instructor.py
+++ b/erpnext/schools/doctype/instructor/instructor.py
@@ -4,7 +4,21 @@
from __future__ import unicode_literals
import frappe
+from frappe import _
from frappe.model.document import Document
+from frappe.model.naming import make_autoname
class Instructor(Document):
- pass
+ def autoname(self):
+ naming_method = frappe.db.get_value("School Settings", None, "instructor_created_by")
+ if not naming_method:
+ frappe.throw(_("Please setup Instructor Naming System in School > School Settings"))
+ else:
+ if naming_method == 'Naming Series':
+ self.name = make_autoname(self.naming_series + '.####')
+ elif naming_method == 'Employee Number':
+ if not self.employee:
+ frappe.throw("Please select Employee")
+ self.name = self.employee
+ elif naming_method == 'Full Name':
+ self.name = self.instructor_name
diff --git a/erpnext/schools/doctype/school_settings/school_settings.json b/erpnext/schools/doctype/school_settings/school_settings.json
index 3b5aae6..b6d9890 100644
--- a/erpnext/schools/doctype/school_settings/school_settings.json
+++ b/erpnext/schools/doctype/school_settings/school_settings.json
@@ -194,6 +194,67 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_7",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Full Name",
+ "fieldname": "instructor_created_by",
+ "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": "Instructor Records to be created by",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Full Name\nNaming Series\nEmployee Number",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
}
],
"has_web_view": 0,
@@ -206,7 +267,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-06-30 08:21:50.339169",
+ "modified": "2017-08-25 02:36:48.744456",
"modified_by": "Administrator",
"module": "Schools",
"name": "School Settings",
diff --git a/erpnext/schools/doctype/school_settings/school_settings.py b/erpnext/schools/doctype/school_settings/school_settings.py
index 999014a..88235cf 100644
--- a/erpnext/schools/doctype/school_settings/school_settings.py
+++ b/erpnext/schools/doctype/school_settings/school_settings.py
@@ -26,3 +26,10 @@
def get_defaults(self):
return frappe.defaults.get_defaults()
+
+ def validate(self):
+ from frappe.custom.doctype.property_setter.property_setter import make_property_setter
+ if self.get('instructor_created_by')=='Naming Series':
+ make_property_setter('Instructor', "naming_series", "hidden", 0, "Check")
+ else:
+ make_property_setter('Instructor', "naming_series", "hidden", 1, "Check")
diff --git a/erpnext/schools/doctype/student/student.js b/erpnext/schools/doctype/student/student.js
index d3d248b..cadf272 100644
--- a/erpnext/schools/doctype/student/student.js
+++ b/erpnext/schools/doctype/student/student.js
@@ -3,6 +3,11 @@
frappe.ui.form.on('Student', {
setup: function(frm) {
+ frm.add_fetch("guardian", "guardian_name", "guardian_name");
+ frm.add_fetch("student", "title", "full_name");
+ frm.add_fetch("student", "gender", "gender");
+ frm.add_fetch("student", "date_of_birth", "date_of_birth");
+
frm.set_query("student", "siblings", function(doc, cdt, cdn) {
return {
"filters": {
@@ -11,18 +16,4 @@
};
})
}
-});
-
-frappe.ui.form.on("Student Guardian", {
- guardian: function(frm) {
- frm.add_fetch("guardian", "guardian_name", "guardian_name");
- }
-});
-
-frappe.ui.form.on('Student Sibling', {
- student: function(frm) {
- frm.add_fetch("student", "title", "full_name");
- frm.add_fetch("student", "gender", "gender");
- frm.add_fetch("student", "date_of_birth", "date_of_birth");
- }
-});
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.js b/erpnext/schools/doctype/student_applicant/student_applicant.js
index 9b08ee5..40a6ac3 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.js
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.js
@@ -39,15 +39,12 @@
method: "erpnext.schools.api.enroll_student",
frm: frm
})
- }
-});
+ },
-
-frappe.ui.form.on('Student Sibling', {
- student: function(frm) {
+ setup: function(frm) {
+ frm.add_fetch("guardian", "guardian_name", "guardian_name");
frm.add_fetch("student", "title", "full_name");
frm.add_fetch("student", "gender", "gender");
frm.add_fetch("student", "date_of_birth", "date_of_birth");
}
-});
-
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.json b/erpnext/schools/doctype/student_applicant/student_applicant.json
index 271f873..578f84c 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.json
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.json
@@ -881,7 +881,7 @@
"in_standard_filter": 0,
"label": "Guardians",
"length": 0,
- "no_copy": 1,
+ "no_copy": 0,
"options": "Student Guardian",
"permlevel": 0,
"precision": "",
@@ -1058,7 +1058,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-06-30 08:21:50.917086",
+ "modified": "2017-08-23 06:12:36.996978",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student Applicant",
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.py b/erpnext/schools/doctype/student_applicant/student_applicant.py
index 047c702..081fa06 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.py
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.py
@@ -2,7 +2,7 @@
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
@@ -13,7 +13,7 @@
if self.student_admission:
naming_series = frappe.db.get_value('Student Admission', self.student_admission,
'naming_series_for_student_applicant')
- print naming_series
+ print(naming_series)
if naming_series:
self.naming_series = naming_series
diff --git a/erpnext/schools/doctype/student_group/test_student_group.py b/erpnext/schools/doctype/student_group/test_student_group.py
index 18a6b14..e358c27 100644
--- a/erpnext/schools/doctype/student_group/test_student_group.py
+++ b/erpnext/schools/doctype/student_group/test_student_group.py
@@ -8,20 +8,20 @@
from frappe.utils.make_random import get_random
class TestStudentGroup(unittest.TestCase):
- def test_student_roll_no(self):
- doc = frappe.get_doc({
- "doctype": "Student Group",
- "student_group_name": "_Test Student Group R",
+ def test_student_roll_no(self):
+ doc = frappe.get_doc({
+ "doctype": "Student Group",
+ "student_group_name": "_Test Student Group R",
"group_based_on": "Activity"
- }).insert()
+ }).insert()
- student_list = []
- while len(student_list) < 3:
- s = get_random("Student")
- if s not in student_list:
- student_list.append(s)
+ student_list = []
+ while len(student_list) < 3:
+ s = get_random("Student")
+ if s not in student_list:
+ student_list.append(s)
- doc.extend("students", [{"student":d} for d in student_list])
- doc.save()
- self.assertEquals(max([d.group_roll_number for d in doc.students]), 3)
+ doc.extend("students", [{"student":d} for d in student_list])
+ doc.save()
+ self.assertEquals(max([d.group_roll_number for d in doc.students]), 3)
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index d797632..c12cd44 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -67,7 +67,7 @@
'''If Customer created from Lead, update lead status to "Converted"
update Customer link in Quotation, Opportunity'''
if self.lead_name:
- frappe.db.set_value('Lead', self.lead_name, 'status', 'Converted', update_modified=False)
+ frappe.db.set_value('Lead', self.lead_name, 'status', 'Converted', update_modified=False)
for doctype in ('Opportunity', 'Quotation'):
for d in frappe.get_all(doctype, {'lead': self.lead_name}):
diff --git a/erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js b/erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js
new file mode 100644
index 0000000..26a099e
--- /dev/null
+++ b/erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js
@@ -0,0 +1,41 @@
+QUnit.module('Quotation');
+
+QUnit.test("test quotation submit cancel amend", function(assert) {
+ assert.expect(2);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Quotation', [
+ {customer: 'Test Customer 1'},
+ {items: [
+ [
+ {'delivery_date': frappe.datetime.add_days(frappe.defaults.get_default("year_end_date"), 1)},
+ {'qty': 5},
+ {'item_code': 'Test Product 1'}
+ ]
+ ]},
+ {customer_address: 'Test1-Billing'},
+ {shipping_address_name: 'Test1-Shipping'},
+ {contact_person: 'Contact 1-Test Customer 1'}
+ ]);
+ },
+ () => cur_frm.save(),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+ // get uom details
+ assert.ok(cur_frm.doc.grand_total== 500, "Grand total correct ");
+
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(1),
+ () => frappe.tests.click_button('Close'),
+ () => frappe.tests.click_button('Cancel'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_button('Amend'),
+ () => cur_frm.save(),
+ () => done()
+ ]);
+});
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index 396b1c2..5f904c2 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -51,9 +51,9 @@
# validate p.o date v/s delivery date
if self.po_date:
for d in self.get("items"):
- if d.delivery_date and getdate(self.po_date) > getdate(d.delivery_date):
- frappe.throw(_("Row #{0}: Expected Delivery Date cannot be before Purchase Order Date")
- .format(d.idx))
+ if d.delivery_date and getdate(self.po_date) > getdate(d.delivery_date):
+ frappe.throw(_("Row #{0}: Expected Delivery Date cannot be before Purchase Order Date")
+ .format(d.idx))
if self.po_no and self.customer:
so = frappe.db.sql("select name from `tabSales Order` \
diff --git a/erpnext/setup/doctype/item_group/test_item_group.py b/erpnext/setup/doctype/item_group/test_item_group.py
index bc88132..c487c72 100644
--- a/erpnext/setup/doctype/item_group/test_item_group.py
+++ b/erpnext/setup/doctype/item_group/test_item_group.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import unittest
import frappe
from frappe.utils.nestedset import NestedSetRecursionError, NestedSetMultipleRootsError, \
@@ -112,7 +112,7 @@
def print_tree(self):
import json
- print json.dumps(frappe.db.sql("select name, lft, rgt from `tabItem Group` order by lft"), indent=1)
+ print(json.dumps(frappe.db.sql("select name, lft, rgt from `tabItem Group` order by lft"), indent=1))
def test_move_leaf_into_another_group(self):
# before move
diff --git a/erpnext/setup/doctype/naming_series/naming_series.js b/erpnext/setup/doctype/naming_series/naming_series.js
index e2584bf..7c76d9c 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.js
+++ b/erpnext/setup/doctype/naming_series/naming_series.js
@@ -1,47 +1,55 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
-cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
- cur_frm.disable_save();
- cur_frm.toolbar.print_icon.addClass("hide");
- return cur_frm.call({
- doc: cur_frm.doc,
- method: 'get_transactions',
- callback: function(r) {
- cur_frm.cscript.update_selects(r);
- cur_frm.cscript.select_doc_for_series(doc, cdt, cdn);
- }
- });
-}
+frappe.ui.form.on("Naming Series", {
+ onload: function(frm) {
+ frm.disable_save();
+ frm.events.get_doc_and_prefix(frm);
+ },
-cur_frm.cscript.update_selects = function(r) {
- set_field_options('select_doc_for_series', r.message.transactions);
- set_field_options('prefix', r.message.prefixes);
-}
+ get_doc_and_prefix: function(frm) {
+ frappe.call({
+ method: "get_transactions",
+ doc: frm.doc,
+ callback: function(r) {
+ frm.set_df_property("select_doc_for_series", "options", r.message.transactions);
+ frm.set_df_property("prefix", "options", r.message.prefixes);
+ }
+ });
+ },
-cur_frm.cscript.select_doc_for_series = function(doc, cdt, cdn) {
- cur_frm.set_value('user_must_always_select', 0);
- cur_frm.toggle_display(['help_html','set_options', 'user_must_always_select', 'update'],
- doc.select_doc_for_series);
+ select_doc_for_series: function(frm) {
+ frm.set_value("user_must_always_select", 0);
+ frappe.call({
+ method: "get_options",
+ doc: frm.doc,
+ callback: function(r) {
+ frm.set_value("set_options", r.message);
+ if(r.message && r.message.split('\n')[0]=='')
+ frm.set_value('user_must_always_select', 1);
+ frm.refresh();
+ }
+ });
+ },
- var callback = function(r, rt){
- locals[cdt][cdn].set_options = r.message;
- refresh_field('set_options');
- if(r.message && r.message.split('\n')[0]=='')
- cur_frm.set_value('user_must_always_select', 1);
+ prefix: function(frm) {
+ frappe.call({
+ method: "get_current",
+ doc: frm.doc,
+ callback: function(r) {
+ frm.refresh_field("current_value");
+ }
+ });
+ },
+
+ update: function(frm) {
+ frappe.call({
+ method: "update_series",
+ doc: frm.doc,
+ callback: function(r) {
+ frm.events.get_doc_and_prefix(frm);
+ }
+ });
}
-
- if(doc.select_doc_for_series)
- return $c_obj(doc,'get_options','',callback);
-}
-
-cur_frm.cscript.update = function() {
- return cur_frm.call_server('update_series', '', cur_frm.cscript.update_selects);
-}
-
-cur_frm.cscript.prefix = function(doc, dt, dn) {
- return cur_frm.call_server('get_current', '', function(r) {
- refresh_field('current_value');
- });
-}
+});
diff --git a/erpnext/setup/doctype/naming_series/naming_series.json b/erpnext/setup/doctype/naming_series/naming_series.json
index 0daf1a1..f936dcf 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.json
+++ b/erpnext/setup/doctype/naming_series/naming_series.json
@@ -1,29 +1,40 @@
{
"allow_copy": 0,
+ "allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
+ "beta": 0,
"creation": "2013-01-25 11:35:08",
"custom": 0,
"description": "Set prefix for numbering series on your transactions",
"docstatus": 0,
"doctype": "DocType",
+ "editable_grid": 0,
"fields": [
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Set prefix for numbering series on your transactions",
"fieldname": "setup_series",
"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": "Setup Series",
+ "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,
@@ -31,20 +42,28 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "select_doc_for_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": "Select Transaction",
+ "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,
@@ -52,21 +71,30 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "depends_on": "select_doc_for_series",
"fieldname": "help_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": "Help HTML",
+ "length": 0,
"no_copy": 0,
"options": "<div class=\"well\">\nEdit list of Series in the box below. Rules:\n<ul>\n<li>Each Series Prefix on a new line.</li>\n<li>Allowed special characters are \"/\" and \"-\"</li>\n<li>Optionally, set the number of digits in the series using dot (.) followed by hashes (#). For example, \".####\" means that the series will have four digits. Default is five digits.</li>\n</ul>\nExamples:<br>\nINV-<br>\nINV-10-<br>\nINVK-<br>\nINV-.####<br>\n</div>",
"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,
@@ -74,20 +102,29 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "depends_on": "select_doc_for_series",
"fieldname": "set_options",
"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": "Series List for this Transaction",
+ "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,
@@ -95,21 +132,30 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "depends_on": "select_doc_for_series",
"description": "Check this if you want to force the user to select a series before saving. There will be no default if you check this.",
"fieldname": "user_must_always_select",
"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": "User must always select",
+ "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,
@@ -117,20 +163,30 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "depends_on": "select_doc_for_series",
"fieldname": "update",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
+ "in_global_search": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Update",
+ "length": 0,
"no_copy": 0,
+ "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,
@@ -138,21 +194,29 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "Change the starting / current sequence number of an existing series.",
"fieldname": "update_series",
"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": "Update Series",
+ "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,
@@ -160,20 +224,28 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "prefix",
"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": "Prefix",
+ "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,
@@ -181,21 +253,29 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"description": "This is the number of the last created transaction with this prefix",
"fieldname": "current_value",
"fieldtype": "Int",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
+ "in_global_search": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Current Value",
+ "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,
@@ -203,21 +283,29 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "update_series_start",
"fieldtype": "Button",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
+ "in_global_search": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Update Series Number",
+ "length": 0,
"no_copy": 0,
"options": "update_series_start",
"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,
@@ -225,16 +313,18 @@
"unique": 0
}
],
+ "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 1,
"icon": "fa fa-sort-by-order",
"idx": 1,
+ "image_view": 0,
"in_create": 0,
- "in_dialog": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
- "modified": "2015-02-05 05:11:41.473793",
+ "max_attachments": 0,
+ "modified": "2017-08-17 03:41:37.685910",
"modified_by": "Administrator",
"module": "Setup",
"name": "Naming Series",
@@ -261,6 +351,10 @@
"write": 1
}
],
+ "quick_entry": 0,
"read_only": 1,
- "read_only_onload": 0
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "track_changes": 0,
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 536b72f..4534584 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -21,7 +21,6 @@
where fieldname='naming_series'""")))
doctypes = list(set(get_doctypes_with_read()) | set(doctypes))
-
prefixes = ""
for d in doctypes:
options = ""
@@ -34,9 +33,8 @@
if options:
prefixes = prefixes + "\n" + options
-
prefixes.replace("\n\n", "\n")
- prefixes = "\n".join(sorted(prefixes.split()))
+ prefixes = "\n".join(sorted(prefixes.split("\n")))
return {
"transactions": "\n".join([''] + sorted(doctypes)),
@@ -112,9 +110,7 @@
where dt.name = df.dt and df.fieldname='naming_series' and dt.name != %s""",
self.select_doc_for_series)
))
- sr = [[frappe.get_meta(p).get_field("naming_series").options, p]
- for p in parent]
-
+ sr = [[frappe.get_meta(p).get_field("naming_series").options, p] for p in parent]
dt = frappe.get_doc("DocType", self.select_doc_for_series)
options = self.scrub_options_list(self.set_options.split("\n"))
for series in options:
diff --git a/erpnext/setup/doctype/naming_series/test_naming_series.js b/erpnext/setup/doctype/naming_series/test_naming_series.js
new file mode 100644
index 0000000..22b664b
--- /dev/null
+++ b/erpnext/setup/doctype/naming_series/test_naming_series.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Naming Series", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Naming Series
+ () => frappe.tests.make('Naming Series', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 7b71675..9bf15ce 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe import _
@@ -19,10 +19,10 @@
def check_setup_wizard_not_completed():
if frappe.db.get_default('desktop:home_page') == 'desktop':
- print
- print "ERPNext can only be installed on a fresh site where the setup wizard is not completed"
- print "You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall"
- print
+ print()
+ print("ERPNext can only be installed on a fresh site where the setup wizard is not completed")
+ print("You can reinstall this site (after saving your data) using: bench --site [sitename] reinstall")
+ print()
return False
def set_single_defaults():
diff --git a/erpnext/stock/doctype/batch/test_batch.js b/erpnext/stock/doctype/batch/test_batch.js
new file mode 100644
index 0000000..af7f50f
--- /dev/null
+++ b/erpnext/stock/doctype/batch/test_batch.js
@@ -0,0 +1,23 @@
+QUnit.module('Stock');
+
+QUnit.test("test Batch", function(assert) {
+ assert.expect(1);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Batch', [
+ {batch_id:'TEST-BATCH-001'},
+ {item:'Test Product 4'},
+ {expiry_date:frappe.datetime.add_days(frappe.datetime.now_date(), 2)},
+ ]);
+ },
+ () => cur_frm.save(),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.batch_id=='TEST-BATCH-001', "Batch Id correct");
+ },
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 4477c1d..41f8b84 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -3113,7 +3113,7 @@
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
- "in_standard_filter": 1,
+ "in_standard_filter": 0,
"label": "Installation Status",
"length": 0,
"no_copy": 0,
@@ -3487,7 +3487,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-08-09 15:44:14.253457",
+ "modified": "2017-08-23 13:25:34.182268",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 82beff8..f5a99af 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -92,9 +92,9 @@
def so_required(self):
"""check in manage account if sales order required or not"""
if frappe.db.get_value("Selling Settings", None, 'so_required') == 'Yes':
- for d in self.get('items'):
- if not d.against_sales_order:
- frappe.throw(_("Sales Order required for Item {0}").format(d.item_code))
+ for d in self.get('items'):
+ if not d.against_sales_order:
+ frappe.throw(_("Sales Order required for Item {0}").format(d.item_code))
def validate(self):
self.validate_posting_time()
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
index d12c288..2d089c4 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -84,9 +84,9 @@
def po_required(self):
if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes':
- for d in self.get('items'):
- if not d.purchase_order:
- frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code))
+ for d in self.get('items'):
+ if not d.purchase_order:
+ frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code))
def get_already_received_qty(self, po, po_detail):
qty = frappe.db.sql("""select sum(qty) from `tabPurchase Receipt Item`
diff --git a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js
new file mode 100644
index 0000000..ffd0664
--- /dev/null
+++ b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js
@@ -0,0 +1,35 @@
+QUnit.module('Stock');
+
+QUnit.test("test material receipt", function(assert) {
+ assert.expect(2);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Stock Entry', [
+ {purpose:'Material Receipt'},
+ {to_warehouse:'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+ {items: [
+ [
+ {'item_code': 'Test Product 4'},
+ {'qty': 5},
+ {'batch_no':'TEST-BATCH-001'},
+ {'serial_no':'Test-Product-001\nTest-Product-002\nTest-Product-003\nTest-Product-004\nTest-Product-005'},
+ {'basic_rate':100},
+ ]
+ ]},
+ ]);
+ },
+ () => cur_frm.save(),
+ () => frappe.click_button('Update Rate and Availability'),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
+ assert.ok(cur_frm.doc.total_incoming_value==500, " Incoming Value correct");
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js
new file mode 100644
index 0000000..e8b2973
--- /dev/null
+++ b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js
@@ -0,0 +1,34 @@
+QUnit.module('Stock');
+
+QUnit.test("test material Transfer to manufacture", function(assert) {
+ assert.expect(3);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Stock Entry', [
+ {purpose:'Material Transfer for Manufacture'},
+ {from_warehouse:'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+ {to_warehouse:'Work In Progress - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+ {items: [
+ [
+ {'item_code': 'Test Product 1'},
+ {'qty': 1},
+ ]
+ ]},
+ ]);
+ },
+ () => cur_frm.save(),
+ () => frappe.click_button('Update Rate and Availability'),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+ assert.ok(cur_frm.doc.total_outgoing_value==100, " Outgoing Value correct");
+ assert.ok(cur_frm.doc.total_incoming_value==100, " Incoming Value correct");
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js
new file mode 100644
index 0000000..131d3ca
--- /dev/null
+++ b/erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js
@@ -0,0 +1,34 @@
+QUnit.module('Stock');
+
+QUnit.test("test material Transfer to manufacture", function(assert) {
+ assert.expect(3);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Stock Entry', [
+ {purpose:'Subcontract'},
+ {from_warehouse:'Work In Progress - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+ {to_warehouse:'Finished Goods - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
+ {items: [
+ [
+ {'item_code': 'Test Product 1'},
+ {'qty': 1},
+ ]
+ ]},
+ ]);
+ },
+ () => cur_frm.save(),
+ () => frappe.click_button('Update Rate and Availability'),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
+ assert.ok(cur_frm.doc.total_outgoing_value==100, " Outgoing Value correct");
+ assert.ok(cur_frm.doc.total_incoming_value==100, " Incoming Value correct");
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
+
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.py b/erpnext/stock/doctype/stock_settings/stock_settings.py
index d9d9568..186eaee 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.py
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.py
@@ -18,7 +18,7 @@
self.get("item_naming_by")=="Naming Series", hide_name_field=True)
stock_frozen_limit = 356
- submitted_stock_frozen = self.stock_frozen_upto_days
+ submitted_stock_frozen = self.stock_frozen_upto_days or 0
if submitted_stock_frozen > stock_frozen_limit:
self.stock_frozen_upto_days = stock_frozen_limit
frappe.msgprint (_("`Freeze Stocks Older Than` should be smaller than %d days.") %stock_frozen_limit)
diff --git a/erpnext/stock/stock_balance.py b/erpnext/stock/stock_balance.py
index 403d5cb..6a4ac43 100644
--- a/erpnext/stock/stock_balance.py
+++ b/erpnext/stock/stock_balance.py
@@ -1,7 +1,7 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
-from __future__ import unicode_literals
+from __future__ import print_function, unicode_literals
import frappe
from frappe.utils import flt, cstr, nowdate, nowtime
@@ -170,7 +170,7 @@
where item_code=%s and warehouse=%s and docstatus < 2""", (d[0], d[1]))
if serial_nos and flt(serial_nos[0][0]) != flt(d[2]):
- print d[0], d[1], d[2], serial_nos[0][0]
+ print(d[0], d[1], d[2], serial_nos[0][0])
sle = frappe.db.sql("""select valuation_rate, company from `tabStock Ledger Entry`
where item_code = %s and warehouse = %s and ifnull(is_cancelled, 'No') = 'No'
@@ -244,7 +244,7 @@
i = 0
for voucher_type, voucher_no in vouchers:
i+=1
- print i, "/", len(vouchers), voucher_type, voucher_no
+ print(i, "/", len(vouchers), voucher_type, voucher_no)
try:
for dt in ["Stock Ledger Entry", "GL Entry"]:
frappe.db.sql("""delete from `tab%s` where voucher_type=%s and voucher_no=%s"""%
@@ -259,9 +259,9 @@
doc.update_stock_ledger()
doc.make_gl_entries(repost_future_gle=False)
frappe.db.commit()
- except Exception, e:
- print frappe.get_traceback()
+ except Exception as e:
+ print(frappe.get_traceback())
rejected.append([voucher_type, voucher_no])
frappe.db.rollback()
- print rejected
+ print(rejected)
diff --git a/erpnext/support/doctype/issue/issue.js b/erpnext/support/doctype/issue/issue.js
index c1b76e5..306736f 100644
--- a/erpnext/support/doctype/issue/issue.js
+++ b/erpnext/support/doctype/issue/issue.js
@@ -24,7 +24,7 @@
frm.timeline.wrapper.find('.comment-header .asset-details .btn-add-to-kb').remove();
$('<button class="btn btn-xs btn-link btn-add-to-kb text-muted hidden-xs pull-right">'+
__('Help Article') + '</button>')
- .appendTo(frm.timeline.wrapper.find('.comment-header .asset-details'))
+ .appendTo(frm.timeline.wrapper.find('.comment-header .asset-details:not([data-communication-type="Comment"])'))
.on('click', function() {
var content = $(this).parents('.timeline-item:first').find('.timeline-item-content').html();
var doc = frappe.model.get_new_doc('Help Article');
diff --git a/erpnext/templates/includes/product_page.js b/erpnext/templates/includes/product_page.js
index 3905959..b2d5ad9 100644
--- a/erpnext/templates/includes/product_page.js
+++ b/erpnext/templates/includes/product_page.js
@@ -73,7 +73,7 @@
}
}
- if (window.location.search.indexOf(item_code)!==-1) {
+ if (window.location.search == ("?variant=" + item_code) || window.location.search.includes(item_code)) {
return;
}
diff --git a/erpnext/templates/utils.py b/erpnext/templates/utils.py
index e46fed6..6ebe411 100644
--- a/erpnext/templates/utils.py
+++ b/erpnext/templates/utils.py
@@ -36,11 +36,11 @@
))
if customer:
- opportunity.customer = customer[0][0]
+ opportunity.customer = customer[0][0]
elif lead:
- opportunity.lead = lead
+ opportunity.lead = lead
else:
- opportunity.lead = new_lead.name
+ opportunity.lead = new_lead.name
opportunity.insert(ignore_permissions=True)
diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt
index cb33c90..653aeec 100644
--- a/erpnext/tests/ui/tests.txt
+++ b/erpnext/tests/ui/tests.txt
@@ -66,12 +66,23 @@
erpnext/hr/doctype/job_opening/test_job_opening.js
erpnext/hr/doctype/job_applicant/test_job_applicant.js
erpnext/hr/doctype/offer_letter/test_offer_letter.js
+erpnext/hr/doctype/appraisal_template/test_appraisal_template.js
+erpnext/hr/doctype/appraisal/test_appraisal.js
+erpnext/hr/doctype/expense_claim_type/test_expense_claim_type.js
+erpnext/hr/doctype/expense_claim/test_expense_claim.js
+erpnext/hr/doctype/training_event/test_training_event.js
+erpnext/hr/doctype/training_result_employee/test_training_result.js
+erpnext/hr/doctype/training_feedback/test_training_feedback.js
+erpnext/hr/doctype/loan_type/test_loan_type.js
+erpnext/hr/doctype/employee_loan_application/test_employee_loan_application.js
+erpnext/hr/doctype/employee_loan/test_employee_loan.js
erpnext/buying/doctype/supplier/test_supplier.js
erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js
erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js
erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_taxes_and_charges.js
erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice.js
erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment.js
+erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_payment_request.js
erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.js
erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation_for_item_wise_discount.js
erpnext/buying/doctype/purchase_order/tests/test_purchase_order.js
@@ -102,4 +113,12 @@
erpnext/schools/doctype/assessment_plan/test_assessment_plan.js
erpnext/schools/doctype/assessment_result/test_assessment_result.js
erpnext/schools/doctype/assessment_result_tool/test_assessment_result_tool.js
+erpnext/accounts/doctype/journal_entry/test_journal_entry.js
erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.js
+erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js
+erpnext/selling/doctype/quotation/tests/test_quotation_submit_cancel_amend.js
+erpnext/stock/doctype/batch/test_batch.js
+erpnext/accounts/doctype/bank_reconciliation/test_bank_reconciliation.js
+erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt_for_serialize_item.js
+erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_for_manufacture.js
+erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js
diff --git a/erpnext/utilities/__init__.py b/erpnext/utilities/__init__.py
index 944f978..0f641b2 100644
--- a/erpnext/utilities/__init__.py
+++ b/erpnext/utilities/__init__.py
@@ -1,5 +1,5 @@
## temp utility
-
+from __future__ import print_function
import frappe
from erpnext.utilities.activation import get_level
from frappe.utils import cstr
@@ -12,7 +12,7 @@
for f in dt.fields:
if f.fieldname == d.fieldname and f.fieldtype in ("Text", "Small Text"):
- print f.parent, f.fieldname
+ print(f.parent, f.fieldname)
f.fieldtype = "Text Editor"
dt.save()
break