Merge branch 'develop' into payment-terms
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 42f538d..0c7daad 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
import frappe
from erpnext.hooks import regional_overrides
-__version__ = '9.1.6'
+__version__ = '9.1.7'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index 04f7e1b..6856f62 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -88,7 +88,7 @@
doc.naming_series = pos_profile.get('naming_series') or 'SINV-'
doc.letter_head = pos_profile.get('letter_head') or company_data.default_letter_head
doc.ignore_pricing_rule = pos_profile.get('ignore_pricing_rule') or 0
- doc.apply_discount_on = pos_profile.get('apply_discount_on') or ''
+ doc.apply_discount_on = pos_profile.get('apply_discount_on') or 'Grand Total'
doc.customer_group = pos_profile.get('customer_group') or get_root('Customer Group')
doc.territory = pos_profile.get('territory') or get_root('Territory')
doc.terms = frappe.db.get_value('Terms and Conditions', pos_profile.get('tc_name'), 'terms') or doc.terms or ''
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 57a8a18..c442062 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -84,6 +84,7 @@
this.get_data_from_server(function () {
me.make_control();
me.create_new();
+ me.make();
});
},
@@ -382,7 +383,6 @@
},
setup: function () {
- this.make();
this.set_primary_action();
this.party_field.$input.attr('disabled', false);
if(this.selected_row) {
@@ -1341,6 +1341,12 @@
this.wrapper.find('input.discount-percentage').on("change", function () {
me.frm.doc.additional_discount_percentage = flt($(this).val(), precision("additional_discount_percentage"));
+
+ if(me.frm.doc.additional_discount_percentage && me.frm.doc.discount_amount) {
+ // Reset discount amount
+ me.frm.doc.discount_amount = 0;
+ }
+
var total = me.frm.doc.grand_total
if (me.frm.doc.apply_discount_on == 'Net Total') {
@@ -1348,15 +1354,15 @@
}
me.frm.doc.discount_amount = flt(total * flt(me.frm.doc.additional_discount_percentage) / 100, precision("discount_amount"));
- me.wrapper.find('input.discount-amount').val(me.frm.doc.discount_amount)
me.refresh();
+ me.wrapper.find('input.discount-amount').val(me.frm.doc.discount_amount)
});
this.wrapper.find('input.discount-amount').on("change", function () {
me.frm.doc.discount_amount = flt($(this).val(), precision("discount_amount"));
me.frm.doc.additional_discount_percentage = 0.0;
- me.wrapper.find('input.discount-percentage').val(0);
me.refresh();
+ me.wrapper.find('input.discount-percentage').val(0);
});
},
@@ -1517,6 +1523,8 @@
var me = this;
this.wrapper.find(".net-total").text(format_currency(me.frm.doc.total, me.frm.doc.currency));
this.wrapper.find(".grand-total").text(format_currency(me.frm.doc.grand_total, me.frm.doc.currency));
+ this.wrapper.find('input.discount-percentage').val(this.frm.doc.additional_discount_percentage);
+ this.wrapper.find('input.discount-amount').val(this.frm.doc.discount_amount);
},
set_primary_action: function () {
diff --git a/erpnext/buying/doctype/purchase_order/tests/test_purchase_order.js b/erpnext/buying/doctype/purchase_order/tests/test_purchase_order.js
index 6605a65..5d19687 100644
--- a/erpnext/buying/doctype/purchase_order/tests/test_purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/tests/test_purchase_order.js
@@ -1,7 +1,7 @@
QUnit.module('Buying');
QUnit.test("test: purchase order", function(assert) {
- assert.expect(11);
+ assert.expect(16);
let done = assert.async();
frappe.run_serially([
@@ -40,7 +40,6 @@
// Get supplier details
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Supplier name correct");
assert.ok(cur_frm.doc.schedule_date == frappe.datetime.add_days(frappe.datetime.now_date(), 1), "Schedule Date correct");
- assert.ok($('div.control-value.like-disabled-input.for-description').text().includes('Contact 3'), "Contact display correct");
assert.ok(cur_frm.doc.contact_email == 'test@supplier.com', "Contact email correct");
// Get item details
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item name correct");
@@ -53,7 +52,7 @@
assert.ok(cur_frm.doc.items[1].qty == 2, "Quantity correct");
assert.ok(cur_frm.doc.items[1].schedule_date == cur_frm.doc.schedule_date, "Schedule Date correct");
// Calculate total
- assert.ok(cur_frm.doc.total == 500, "Total correct");
+ assert.ok(cur_frm.doc.total == 700, "Total correct");
// Get terms
assert.ok(cur_frm.doc.terms == 'This is a term.', "Terms correct");
},
@@ -70,7 +69,7 @@
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
- () => frappe.timeout(0.3),
+ () => frappe.timeout(1),
() => {
assert.ok(cur_frm.doc.status == 'To Receive and Bill', "Submitted successfully");
diff --git a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js
index a4d68aa..1fcfe75 100644
--- a/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js
+++ b/erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js
@@ -27,6 +27,7 @@
{tc_name: 'Test Term 1'}
]);
},
+ () => frappe.timeout(3),
() => {
assert.ok(cur_frm.doc.transaction_date == date, "Date correct");
assert.ok(cur_frm.doc.company == cur_frm.doc.company, "Company correct");
@@ -38,7 +39,7 @@
assert.ok(cur_frm.doc.message_for_supplier == 'Please supply the specified items at the best possible rates', "Reply correct");
assert.ok(cur_frm.doc.tc_name == 'Test Term 1', "Term name correct");
},
- () => frappe.timeout(0.3),
+ () => frappe.timeout(3),
() => cur_frm.print_doc(),
() => frappe.timeout(1),
() => {
@@ -65,7 +66,7 @@
assert.ok(cur_frm.doc.docstatus == 1, "Quotation request submitted");
},
() => frappe.click_button('Send Supplier Emails'),
- () => frappe.timeout(4),
+ () => frappe.timeout(6),
() => {
assert.ok($('div.modal.fade.in > div.modal-dialog > div > div.modal-body.ui-front > div.msgprint').text().includes("Email sent to supplier Test Supplier"), "Send emails working");
},
diff --git a/erpnext/buying/doctype/supplier/test_supplier.js b/erpnext/buying/doctype/supplier/test_supplier.js
index 99a5bc6..05ea044 100644
--- a/erpnext/buying/doctype/supplier/test_supplier.js
+++ b/erpnext/buying/doctype/supplier/test_supplier.js
@@ -56,7 +56,8 @@
() => frappe.click_button('New Contact'),
() => {
return frappe.tests.set_form_values(cur_frm, [
- {first_name: "Contact 3"}
+ {first_name: "Contact 3"},
+ {email_id: "test@supplier.com"}
]);
},
() => cur_frm.save(),
diff --git a/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.js
deleted file mode 100644
index 7097a6d..0000000
--- a/erpnext/buying/doctype/supplier_quotation/test_supplier_quotation.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Supplier Quotation", function (assert) {
- let done = assert.async();
-
- // number of asserts
- assert.expect(1);
-
- frappe.run_serially('Supplier Quotation', [
- // insert a new Supplier Quotation
- () => frappe.tests.make([
- // values to be set
- {key: 'value'}
- ]),
- () => {
- assert.equal(cur_frm.doc.key, 'value');
- },
- () => done()
- ]);
-
-});
diff --git a/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js
index 76be06c..2d2b29c 100644
--- a/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js
+++ b/erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js
@@ -27,12 +27,13 @@
{terms: 'This is a term'}
]);
},
+ () => frappe.timeout(3),
() => {
// Get Supplier details
assert.ok(cur_frm.doc.supplier == 'Test Supplier', "Supplier correct");
assert.ok(cur_frm.doc.company == cur_frm.doc.company, "Company correct");
// Get Contact details
- assert.ok(cur_frm.doc.contact_display == 'Contact 3', "Conatct correct");
+ assert.ok(cur_frm.doc.contact_person == 'Contact 3-Test Supplier', "Conatct correct");
assert.ok(cur_frm.doc.contact_email == 'test@supplier.com', "Email correct");
// Get uom
assert.ok(cur_frm.doc.items[0].uom == 'Unit', "Multi uom correct");
diff --git a/erpnext/config/hr.py b/erpnext/config/hr.py
index 43f625a..ec281bb 100644
--- a/erpnext/config/hr.py
+++ b/erpnext/config/hr.py
@@ -178,6 +178,10 @@
"items": [
{
"type": "doctype",
+ "name": "Training Program"
+ },
+ {
+ "type": "doctype",
"name": "Training Event"
},
{
diff --git a/erpnext/docs/assets/img/human-resources/training_event.png b/erpnext/docs/assets/img/human-resources/training_event.png
index 04162eb..bd1d6dc 100644
--- a/erpnext/docs/assets/img/human-resources/training_event.png
+++ b/erpnext/docs/assets/img/human-resources/training_event.png
Binary files differ
diff --git a/erpnext/docs/assets/img/human-resources/training_program.png b/erpnext/docs/assets/img/human-resources/training_program.png
new file mode 100644
index 0000000..97bd2bf
--- /dev/null
+++ b/erpnext/docs/assets/img/human-resources/training_program.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/human-resources/training.md b/erpnext/docs/user/manual/en/human-resources/training.md
index 2aa0679..4d39bf1 100644
--- a/erpnext/docs/user/manual/en/human-resources/training.md
+++ b/erpnext/docs/user/manual/en/human-resources/training.md
@@ -1,8 +1,13 @@
# Training
+### Training Program
+
+Create Training Program and schedule Training Events under it. It has a dashboard linked to Training Event to view which event is under the Training Program.
+
+<img class="screenshot" alt="Employee" src="/docs/assets/img/human-resources/training_program.png">
### Training Event
-Schedule seminars, workshops, conferences etc using Training Event. You can also invite your employees to attend the event using this feature.
+Schedule seminars, workshops, conferences etc using Training Event linked to a Training Program. You can also invite your employees to attend the event using this feature.
<img class="screenshot" alt="Employee" src="/docs/assets/img/human-resources/training_event.png">
@@ -14,11 +19,11 @@
<img class="screenshot" alt="Employee" src="/docs/assets/img/human-resources/training_event_employee.png">
-When you submit the Training Event, a notifcation will be sent to the employee notifying that the Training has been scheduled. This is sent via Email Alert "Training Scheduled". You can modifiy this Email Alert to customize the message.
+When you submit the Training Event, a notification will be sent to the employee notifying that the Training has been scheduled. This is sent via Email Alert "Training Scheduled". You can modify this Email Alert to customize the message.
### Training Result
-After compleation of the training Employee-wise training results can be stored based on the Feedback received from the Trainer.
+After completion of the training Employee-wise training results can be stored based on the Feedback received from the Trainer.
<img class="screenshot" alt="Employee" src="/docs/assets/img/human-resources/training_result.png">
diff --git a/erpnext/hr/doctype/offer_letter/test_offer_letter.js b/erpnext/hr/doctype/offer_letter/test_offer_letter.js
index 2069532..5b61d64 100644
--- a/erpnext/hr/doctype/offer_letter/test_offer_letter.js
+++ b/erpnext/hr/doctype/offer_letter/test_offer_letter.js
@@ -27,7 +27,7 @@
]},
]);
},
- () => frappe.timeout(8),
+ () => frappe.timeout(12),
() => frappe.click_button('Submit'),
() => frappe.timeout(2),
() => frappe.click_button('Yes'),
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.js b/erpnext/hr/doctype/salary_slip/test_salary_slip.js
index a49c973..619e530 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.js
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.js
@@ -15,7 +15,7 @@
{ employee: employee_name}
]);
},
- () => frappe.timeout(1),
+ () => frappe.timeout(3),
() => {
// To check if all the calculations are correctly done
if(ename === 'Test Employee 1')
@@ -43,7 +43,7 @@
() => salary_slip('Test Employee 1'),
() => frappe.timeout(6),
() => salary_slip('Test Employee 3'),
- () => frappe.timeout(3),
+ () => frappe.timeout(5),
() => done()
]);
});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/salary_structure/test_salary_structure.js b/erpnext/hr/doctype/salary_structure/test_salary_structure.js
index 5e028cf..542fa50 100644
--- a/erpnext/hr/doctype/salary_structure/test_salary_structure.js
+++ b/erpnext/hr/doctype/salary_structure/test_salary_structure.js
@@ -1,5 +1,5 @@
QUnit.test("test Salary Structure", function(assert) {
- assert.expect(6);
+ assert.expect(7);
let done = assert.async();
let employee_name1;
@@ -9,6 +9,7 @@
employee_name1 = r.name;
}
),
+ () => frappe.timeout(5),
() => frappe.db.get_value('Employee', {'employee_name': "Test Employee 3"}, 'name',
(r) => {
// Creating Salary Structure for employees);
@@ -48,12 +49,14 @@
]);
}
),
- () => frappe.timeout(3),
+ () => frappe.timeout(15),
() => {
- // To check if all the fields are correctly set
- assert.ok(cur_frm.doc.employees[0].employee_name.includes('Test Employee 1') &&
- cur_frm.doc.employees[1].employee_name.includes('Test Employee 3'),
- 'Employee names are correctly set');
+ // To check if all the fields are correctly set
+ assert.ok(cur_frm.doc.employees[0].employee_name=='Test Employee 1',
+ 'Employee 1 name correctly set');
+
+ assert.ok(cur_frm.doc.employees[1].employee_name=='Test Employee 3',
+ 'Employee 2 name correctly set');
assert.ok(cur_frm.doc.employees[0].base==25000,
'Base value for first employee is correctly set');
diff --git a/erpnext/hr/doctype/training_event/test_training_event.py b/erpnext/hr/doctype/training_event/test_training_event.py
index 03416ee..57123e3 100644
--- a/erpnext/hr/doctype/training_event/test_training_event.py
+++ b/erpnext/hr/doctype/training_event/test_training_event.py
@@ -5,8 +5,38 @@
import frappe
import unittest
-
-# test_records = frappe.get_test_records('Training Event')
+from frappe.utils import today, add_days
+from erpnext.hr.doctype.salary_structure.test_salary_structure import make_employee
class TestTrainingEvent(unittest.TestCase):
- pass
+ def setUp(self):
+ create_training_program("Basic Training")
+ self.employee = make_employee("robert_loan@trainig.com")
+ self.employee2 = make_employee("suzie.tan@trainig.com")
+
+ def test_create_training_event(self):
+ if not frappe.db.get_value("Training Event", "Basic Training Event"):
+ frappe.get_doc({
+ "doctype": "Training Event",
+ "event_name": "Basic Training Event",
+ "training_program": "Basic Training",
+ "location": "Union Square",
+ "start_time": add_days(today(), 5),
+ "end_time": add_days(today(), 6),
+ "introduction": "Welcome to the Basic Training Event",
+ "employees": get_attendees(self.employee, self.employee2)
+ }).insert()
+
+def create_training_program(training_program):
+ if not frappe.db.get_value("Training Program", training_program):
+ frappe.get_doc({
+ "doctype": "Training Program",
+ "training_program": training_program,
+ "description": training_program
+ }).insert()
+
+def get_attendees(employee, employee2):
+ return [
+ {"employee": employee},
+ {"employee": employee2}
+ ]
\ No newline at end of file
diff --git a/erpnext/hr/doctype/training_event/training_event.json b/erpnext/hr/doctype/training_event/training_event.json
index cb8518b..4b812a9 100644
--- a/erpnext/hr/doctype/training_event/training_event.json
+++ b/erpnext/hr/doctype/training_event/training_event.json
@@ -44,6 +44,37 @@
},
{
"allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "training_program",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Training Program",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Training Program",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -778,7 +809,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-10-06 10:59:09.217283",
+ "modified": "2017-10-23 06:13:29.065781",
"modified_by": "Administrator",
"module": "HR",
"name": "Training Event",
@@ -806,7 +837,7 @@
"write": 1
}
],
- "quick_entry": 1,
+ "quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"search_fields": "event_name",
diff --git a/erpnext/hr/doctype/training_program/__init__.py b/erpnext/hr/doctype/training_program/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/hr/doctype/training_program/__init__.py
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.js b/erpnext/hr/doctype/training_program/test_training_program.js
similarity index 65%
rename from erpnext/buying/doctype/purchase_order/test_purchase_order.js
rename to erpnext/hr/doctype/training_program/test_training_program.js
index e9db270..3a62b2f 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.js
+++ b/erpnext/hr/doctype/training_program/test_training_program.js
@@ -2,15 +2,15 @@
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
-QUnit.test("test: Purchase Order", function (assert) {
+QUnit.test("test: Training Program", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(1);
- frappe.run_serially('Purchase Order', [
- // insert a new Purchase Order
- () => frappe.tests.make([
+ frappe.run_serially([
+ // insert a new Training Program
+ () => frappe.tests.make('Training Program', [
// values to be set
{key: 'value'}
]),
diff --git a/erpnext/hr/doctype/training_program/test_training_program.py b/erpnext/hr/doctype/training_program/test_training_program.py
new file mode 100644
index 0000000..9d5b286
--- /dev/null
+++ b/erpnext/hr/doctype/training_program/test_training_program.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestTrainingProgram(unittest.TestCase):
+ pass
diff --git a/erpnext/hr/doctype/training_program/training_program.js b/erpnext/hr/doctype/training_program/training_program.js
new file mode 100644
index 0000000..7d85cab
--- /dev/null
+++ b/erpnext/hr/doctype/training_program/training_program.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Training Program', {
+});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/training_program/training_program.json b/erpnext/hr/doctype/training_program/training_program.json
new file mode 100644
index 0000000..d9b33d5
--- /dev/null
+++ b/erpnext/hr/doctype/training_program/training_program.json
@@ -0,0 +1,454 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:training_program",
+ "beta": 0,
+ "creation": "2017-10-11 04:43:17.230065",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "training_program",
+ "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": "Training Program",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 1,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Scheduled",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Scheduled\nCompleted\nCancelled",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_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_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "trainer_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Trainer Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "trainer_email",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Trainer Email",
+ "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,
+ "fieldname": "column_break_8",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "supplier",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Supplier",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Supplier",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "contact_number",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Contact Number",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_11",
+ "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,
+ "fieldname": "description",
+ "fieldtype": "Text Editor",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Description",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Training Program",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-10-16 05:34:23.055153",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Training Program",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "training_program",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/training_program/training_program.py b/erpnext/hr/doctype/training_program/training_program.py
new file mode 100644
index 0000000..7a3720b
--- /dev/null
+++ b/erpnext/hr/doctype/training_program/training_program.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class TrainingProgram(Document):
+ pass
diff --git a/erpnext/hr/doctype/training_program/training_program_dashboard.py b/erpnext/hr/doctype/training_program/training_program_dashboard.py
new file mode 100644
index 0000000..b5d9f19
--- /dev/null
+++ b/erpnext/hr/doctype/training_program/training_program_dashboard.py
@@ -0,0 +1,12 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'training_program',
+ 'transactions': [
+ {
+ 'label': _('Training Event'),
+ 'items': ['Training Event']
+ },
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/hr/email_alert/training_scheduled/training_scheduled.json b/erpnext/hr/email_alert/training_scheduled/training_scheduled.json
index e1631f8..0782f0c 100644
--- a/erpnext/hr/email_alert/training_scheduled/training_scheduled.json
+++ b/erpnext/hr/email_alert/training_scheduled/training_scheduled.json
@@ -10,8 +10,8 @@
"idx": 0,
"is_standard": 1,
"message": "<h3>{{_(\"Training Event\")}}</h3>\n\n<p>{{ doc.introduction }}</p>\n\n<h4>{{_(\"Details\")}}</h4>\n{{_(\"Event Name\")}}: {{ frappe.utils.get_link_to_form(doc.doctype, doc.name) }}\n<br>{{_(\"Event Location\")}}: {{ doc.location }}\n<br>{{_(\"Start Time\")}}: {{ doc.start_time }}\n<br>{{_(\"End Time\")}}: {{ doc.end_time }}\n",
- "modified": "2017-08-13 22:49:42.338881",
- "modified_by": "Administrator",
+ "modified": "2017-08-13 22:49:42.338881",
+ "modified_by": "Administrator",
"module": "HR",
"name": "Training Scheduled",
"owner": "Administrator",
diff --git a/erpnext/manufacturing/doctype/operation/test_operation.js b/erpnext/manufacturing/doctype/operation/test_operation.js
index 5aafe42..42553ce 100644
--- a/erpnext/manufacturing/doctype/operation/test_operation.js
+++ b/erpnext/manufacturing/doctype/operation/test_operation.js
@@ -14,7 +14,7 @@
]
);
},
- () => frappe.timeout(1),
+ () => frappe.timeout(3),
() => {
assert.ok(cur_frm.docname.includes('Assemble Keyboard'),
'Assemble Keyboard created successfully');
@@ -31,7 +31,7 @@
]
);
},
- () => frappe.timeout(1),
+ () => frappe.timeout(3),
// Create a CPU operation
() => {
@@ -42,7 +42,7 @@
]
);
},
- () => frappe.timeout(1),
+ () => frappe.timeout(3),
() => done()
]);
diff --git a/erpnext/patches/v8_0/disable_instructor_role.py b/erpnext/patches/v8_0/disable_instructor_role.py
index 94ebd9c..4ba78d1 100644
--- a/erpnext/patches/v8_0/disable_instructor_role.py
+++ b/erpnext/patches/v8_0/disable_instructor_role.py
@@ -12,6 +12,7 @@
domains = frappe.db.sql_list("select domain from tabCompany")
if "Education" not in domains:
- role = frappe.get_doc("Role", "Instructor")
- role.disabled = 1
- role.save(ignore_permissions=True)
\ No newline at end of file
+ if frappe.db.exists("Role", "Instructor"):
+ role = frappe.get_doc("Role", "Instructor")
+ role.disabled = 1
+ role.save(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/restaurant/doctype/restaurant/test_restaurant.js b/erpnext/restaurant/doctype/restaurant/test_restaurant.js
index 1cc7c7f..f4a1343 100644
--- a/erpnext/restaurant/doctype/restaurant/test_restaurant.js
+++ b/erpnext/restaurant/doctype/restaurant/test_restaurant.js
@@ -15,9 +15,11 @@
// values to be set
{__newname: 'Test Restaurant 1'},
{company: 'Test Company'},
- {invoice_series_prefix: 'Test-Rest-1-Inv-'}
+ {invoice_series_prefix: 'Test-Rest-1-Inv-'},
+ {default_customer: 'Test Customer 1'}
])
},
+ () => frappe.timeout(3),
() => {
assert.equal(cur_frm.doc.company, 'Test Company');
},
@@ -26,9 +28,11 @@
// values to be set
{__newname: 'Test Restaurant 2'},
{company: 'Test Company'},
- {invoice_series_prefix: 'Test-Rest-3-Inv-'}
+ {invoice_series_prefix: 'Test-Rest-3-Inv-'},
+ {default_customer: 'Test Customer 2'}
]);
},
+ () => frappe.timeout(3),
() => {
assert.equal(cur_frm.doc.company, 'Test Company');
},
diff --git a/erpnext/restaurant/doctype/restaurant_menu/test_restaurant_menu.js b/erpnext/restaurant/doctype/restaurant_menu/test_restaurant_menu.js
index 25057d8..f5ab9f0 100644
--- a/erpnext/restaurant/doctype/restaurant_menu/test_restaurant_menu.js
+++ b/erpnext/restaurant/doctype/restaurant_menu/test_restaurant_menu.js
@@ -16,7 +16,7 @@
{item_group: "Products"},
{is_stock_item: 1},
],
- "Test Product 3": [
+ "Food Item 3": [
{item_code: "Food Item 3"},
{item_group: "Products"},
{is_stock_item: 1},
@@ -50,6 +50,7 @@
]}
]);
},
+ () => frappe.timeout(2),
() => {
return frappe.tests.make("Restaurant Menu", [
{__newname: 'Restaurant Menu 2'},
@@ -66,6 +67,7 @@
]}
]);
},
+ () => frappe.timeout(2),
() => frappe.set_route('Form', 'Restaurant', 'Test Restaurant 1'),
() => cur_frm.set_value('active_menu', 'Restaurant Menu 1'),
() => cur_frm.save(),
diff --git a/erpnext/schools/doctype/student_admission/test_student_admission.js b/erpnext/schools/doctype/student_admission/test_student_admission.js
index 3e997ca..767f237 100644
--- a/erpnext/schools/doctype/student_admission/test_student_admission.js
+++ b/erpnext/schools/doctype/student_admission/test_student_admission.js
@@ -2,7 +2,7 @@
QUnit.module('schools');
QUnit.test('Test: Student Admission', function(assert) {
- assert.expect(9);
+ assert.expect(10);
let done = assert.async();
frappe.run_serially([
() => {
diff --git a/erpnext/schools/doctype/student_applicant/student_applicant.py b/erpnext/schools/doctype/student_applicant/student_applicant.py
index 7fa44a6..465b4e4 100644
--- a/erpnext/schools/doctype/student_applicant/student_applicant.py
+++ b/erpnext/schools/doctype/student_applicant/student_applicant.py
@@ -41,9 +41,14 @@
def validation_from_student_admission(self):
student_admission = get_student_admission_data(self.student_admission, self.program)
if student_admission:
- if not (getdate(student_admission.minimum_age) >= getdate(self.date_of_birth) >=
- getdate(student_admission.maximum_age)):
- frappe.throw(_("Not eligible for the admission in this program as per DOB"))
+ if ((
+ student_admission.minimum_age
+ and getdate(student_admission.minimum_age) > getdate(self.date_of_birth)
+ ) or (
+ student_admission.maximum_age
+ and getdate(student_admission.maximum_age) < getdate(self.date_of_birth)
+ )):
+ frappe.throw(_("Not eligible for the admission in this program as per DOB"))
def on_payment_authorized(self, *args, **kwargs):
self.db_set('paid', 1)
diff --git a/erpnext/schools/doctype/student_group/test_student_group.js b/erpnext/schools/doctype/student_group/test_student_group.js
index 634ad18..bee5067 100644
--- a/erpnext/schools/doctype/student_group/test_student_group.js
+++ b/erpnext/schools/doctype/student_group/test_student_group.js
@@ -4,15 +4,10 @@
QUnit.test('Test: Student Group', function(assert){
assert.expect(2);
let done = assert.async();
- let instructor_code;
let group_based_on = ["test-batch-wise-group", "test-course-wise-group"];
let tasks = [];
frappe.run_serially([
- // Saving Instructor code beforehand
- () => frappe.db.get_value('Instructor', {'instructor_name': 'Instructor 1'}, 'name'),
- (instructor) => {instructor_code = instructor.message.name;},
-
// Creating a Batch and Course based group
() => {
return frappe.tests.make('Student Group', [
@@ -22,12 +17,7 @@
{group_based_on: 'Batch'},
{student_group_name: group_based_on[0]},
{max_strength: 10},
- {batch: 'A'},
- {instructors: [
- [
- {instructor: instructor_code}
- ]
- ]}
+ {batch: 'A'}
]);
},
() => {
@@ -40,11 +30,6 @@
{max_strength: 10},
{batch: 'A'},
{course: 'Test_Sub'},
- {instructors: [
- [
- {instructor: instructor_code}
- ]
- ]}
]);
},
diff --git a/erpnext/setup/doctype/customer_group/customer_group.py b/erpnext/setup/doctype/customer_group/customer_group.py
index 0f1ee81..7472c51 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.py
+++ b/erpnext/setup/doctype/customer_group/customer_group.py
@@ -17,11 +17,11 @@
def validate_name_with_customer(self):
if frappe.db.exists("Customer", self.name):
- frappe.msgprint(_("An Customer exists with same name"), raise_exception=1)
+ frappe.msgprint(_("A customer with the same name already exists"), raise_exception=1)
def get_parent_customer_groups(customer_group):
lft, rgt = frappe.db.get_value("Customer Group", customer_group, ['lft', 'rgt'])
return frappe.db.sql("""select name from `tabCustomer Group`
where lft <= %s and rgt >= %s
- order by lft asc""", (lft, rgt), as_dict=True)
\ No newline at end of file
+ order by lft asc""", (lft, rgt), as_dict=True)
diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt
index 4b3c2c5..38c138d 100644
--- a/erpnext/tests/ui/tests.txt
+++ b/erpnext/tests/ui/tests.txt
@@ -131,6 +131,6 @@
erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js
erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_last_purchase_rate.js
erpnext/restaurant/doctype/restaurant/test_restaurant.js
-erpnext/restaurant/doctype/test_restaurant_table/test_restaurant_table.js
+erpnext/restaurant/doctype/restaurant_table/test_restaurant_table.js
erpnext/restaurant/doctype/restaurant_menu/test_restaurant_menu.js
erpnext/restaurant/doctype/restaurant_order_entry/restaurant_order_entry.js