Merge pull request #10293 from ashwinisave35/knowledge_base_button
Changed Text of Knowledge base button to Help Article
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 070c93f..64bfa0f 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
import frappe
from erpnext.hooks import regional_overrides
-__version__ = '8.7.0'
+__version__ = '8.7.2'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/account/account.js b/erpnext/accounts/doctype/account/account.js
index ed7e39a..ca46d6b0 100644
--- a/erpnext/accounts/doctype/account/account.js
+++ b/erpnext/accounts/doctype/account/account.js
@@ -68,7 +68,8 @@
}
});
});
- } else if (cint(frm.doc.is_group) == 0) {
+ } else if (cint(frm.doc.is_group) == 0
+ && frappe.boot.user.can_read.indexOf("GL Entry") !== -1) {
cur_frm.add_custom_button(__('Ledger'), function () {
frappe.route_options = {
"account": frm.doc.name,
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.json b/erpnext/accounts/doctype/gl_entry/gl_entry.json
index b1a4129..76e66d0 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.json
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.json
@@ -718,7 +718,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-04-27 13:18:06.617940",
+ "modified": "2017-08-03 12:40:09.611951",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GL Entry",
@@ -786,7 +786,7 @@
}
],
"quick_entry": 1,
- "read_only": 1,
+ "read_only": 0,
"read_only_onload": 0,
"search_fields": "voucher_no,account,posting_date,against_voucher",
"show_name_in_global_search": 0,
diff --git a/erpnext/accounts/doctype/gl_entry/test_gl_entry.js b/erpnext/accounts/doctype/gl_entry/test_gl_entry.js
new file mode 100644
index 0000000..2986e5e
--- /dev/null
+++ b/erpnext/accounts/doctype/gl_entry/test_gl_entry.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: GL Entry", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially('GL Entry', [
+ // insert a new GL Entry
+ () => frappe.tests.make([
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index e768c27..589bc40 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -510,7 +510,7 @@
i += 1
- if self.update_stock and valuation_tax:
+ if self.auto_accounting_for_stock and self.update_stock and valuation_tax:
for cost_center, amount in valuation_tax.items():
gl_entries.append(
self.get_gl_dict({
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 62d9a1e..806b489 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -5,6 +5,7 @@
import frappe
import unittest, copy
from frappe.utils import nowdate, add_days, flt
+from frappe.model.dynamic_links import get_dynamic_link_map
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
@@ -556,6 +557,12 @@
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 161.8)
+ link_data = get_dynamic_link_map().get('Sales Invoice', [])
+ link_doctypes = [d.parent for d in link_data]
+
+ # test case for dynamic link order
+ self.assertTrue(link_doctypes.index('GL Entry') > link_doctypes.index('Journal Entry Account'))
+
jv.cancel()
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 561.8)
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 0f8b92f..5cb04c5 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -15,7 +15,8 @@
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
from erpnext.accounts.utils import get_fiscal_year
-from erpnext import get_default_currency
+from erpnext import get_default_currency, get_company_currency
+
class DuplicatePartyAccountError(frappe.ValidationError): pass
@@ -43,6 +44,7 @@
frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)
party = frappe.get_doc(party_type, party)
+ currency = party.default_currency if party.default_currency else get_company_currency(company)
set_address_details(out, party, party_type, doctype, company)
set_contact_details(out, party, party_type)
diff --git a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
index b269cb8..2dd7b6c 100755
--- a/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
+++ b/erpnext/buying/doctype/purchase_order_item/purchase_order_item.json
@@ -14,6 +14,7 @@
"engine": "InnoDB",
"fields": [
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -45,6 +46,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -74,6 +76,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -104,6 +107,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -132,6 +136,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 1,
"collapsible": 0,
@@ -162,6 +167,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 1,
"collapsible": 0,
@@ -191,6 +197,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 1,
@@ -220,6 +227,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -252,6 +260,7 @@
"width": "300px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -279,6 +288,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -308,6 +318,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -338,6 +349,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -366,6 +378,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -398,6 +411,7 @@
"width": "60px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -431,6 +445,7 @@
"width": "100px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -458,6 +473,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -491,6 +507,7 @@
"width": "100px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -523,6 +540,7 @@
"width": "100px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -550,6 +568,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -579,6 +598,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -608,6 +628,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -635,6 +656,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -664,6 +686,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -691,6 +714,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -722,6 +746,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -753,6 +778,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -780,6 +806,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -814,6 +841,7 @@
"width": "100px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -845,6 +873,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -874,6 +903,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -902,6 +932,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -932,6 +963,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -962,6 +994,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -990,6 +1023,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1020,6 +1054,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1050,6 +1085,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1078,6 +1114,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1109,6 +1146,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1138,6 +1176,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1171,6 +1210,7 @@
"width": "120px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1201,6 +1241,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1231,6 +1272,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1260,6 +1302,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1289,6 +1332,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1318,6 +1362,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1347,6 +1392,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1374,6 +1420,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1406,6 +1453,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1437,6 +1485,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1467,6 +1516,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1499,6 +1549,7 @@
"width": "100px"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1529,6 +1580,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1559,6 +1611,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1588,6 +1641,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -1619,6 +1673,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@@ -1659,7 +1714,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-04-25 18:49:08.604055",
+ "modified": "2017-08-02 22:15:47.411235",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order Item",
diff --git a/erpnext/crm/doctype/item/test_item.js b/erpnext/crm/doctype/item/test_item.js
index b48f93a..58cf549 100644
--- a/erpnext/crm/doctype/item/test_item.js
+++ b/erpnext/crm/doctype/item/test_item.js
@@ -117,4 +117,4 @@
),
() => done()
]);
-});
+});
\ No newline at end of file
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index 287ce61..7575ee4 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -339,7 +339,12 @@
"debit_in_account_currency": total_salary_amount.rounded_total
})
journal_entry.set("accounts", account_amt_list)
- return journal_entry.as_dict()
+ return journal_entry.as_dict()
+ else:
+ frappe.msgprint(
+ _("There are no submitted Salary Slips to process."),
+ title="Error", indicator="red"
+ )
def update_salary_slip_status(self, jv_name = None):
ss_list = self.get_sal_slip_list(ss_status=1)
diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.js b/erpnext/manufacturing/doctype/production_order/test_production_order.js
index 57299db..0a7745e 100644
--- a/erpnext/manufacturing/doctype/production_order/test_production_order.js
+++ b/erpnext/manufacturing/doctype/production_order/test_production_order.js
@@ -1,8 +1,17 @@
QUnit.test("test: production order", function (assert) {
- assert.expect(2);
+ assert.expect(25);
let done = assert.async();
let laptop_quantity = 5;
- let single_laptop_cost = 1340; // Calculated in workstation (time * per_hour_cost) for every item
+ let items = ["Screen", "CPU", "Keyboard"];
+ let operation_items = ["CPU", "Keyboard", "Screen"];
+ let click_make = () => {
+ let element = $(`.btn-primary:contains("Make"):visible`);
+ if(!element.length) {
+ throw `did not find any button containing 'Make'`;
+ }
+ element.click();
+ return frappe.timeout(1);
+ };
frappe.run_serially([
// test production order
@@ -24,18 +33,106 @@
() => frappe.timeout(1),
() => cur_frm.set_value("fg_warehouse", "Finished Goods - RB"),
() => cur_frm.save(),
- () => frappe.timeout(1),
+ () => frappe.timeout(2),
() => {
- assert.equal(cur_frm.doc.planned_operating_cost, cur_frm.doc.total_operating_cost, "Total and Planned Cost is equal");
- assert.equal(cur_frm.doc.planned_operating_cost, laptop_quantity*single_laptop_cost, "Total cost is calculated correctly "+cur_frm.doc.planned_operating_cost);
+ assert.equal(cur_frm.doc.planned_operating_cost, cur_frm.doc.total_operating_cost,
+ "Total and Planned Cost is equal");
+ assert.equal(cur_frm.doc.planned_operating_cost, cur_frm.doc.total_operating_cost,
+ "Total and Planned Cost is equal");
+
+ items.forEach(function(item, index) {
+ assert.equal(item, cur_frm.doc.required_items[index].item_code, `Required item ${item} added`);
+ assert.equal("Stores - RB", cur_frm.doc.required_items[index].source_warehouse, `Item ${item} warhouse verified`);
+ assert.equal("5", cur_frm.doc.required_items[index].required_qty, `Item ${item} quantity verified`);
+ });
+
+ operation_items.forEach(function(operation_item, index) {
+ assert.equal(`Assemble ${operation_item}`, cur_frm.doc.operations[index].operation,
+ `Operation ${operation_item} added`);
+ assert.equal(`${operation_item} assembly workstation`, cur_frm.doc.operations[index].workstation,
+ `Workstation ${operation_item} linked`);
+ });
},
+ // Submit the production order
() => cur_frm.savesubmit(),
() => frappe.timeout(1),
() => frappe.click_button('Yes'),
() => frappe.timeout(1),
+ // Confirm the production order timesheet, save and submit it
+ () => frappe.click_link("TS-00"),
+ () => frappe.timeout(1),
+ () => frappe.click_button("Save"),
+ () => frappe.timeout(1),
+ () => frappe.click_button("Submit"),
+ () => frappe.timeout(1),
+ () => frappe.click_button("Yes"),
+ () => frappe.timeout(2),
+
+ // Start the production order process
+ () => frappe.set_route("List", "Production Order"),
+ () => frappe.timeout(2),
+ () => frappe.set_route("List", "Production Order"),
+ () => frappe.timeout(2),
+ () => frappe.click_link("Laptop"),
+ () => frappe.timeout(1),
+ () => frappe.click_button("Start"),
+ () => frappe.timeout(0.5),
+ () => click_make(),
+ () => frappe.click_button("Save"),
+ () => frappe.timeout(0.5),
+
+ () => {
+ assert.equal(cur_frm.doc.total_outgoing_value, cur_frm.doc.total_incoming_value,
+ "Total incoming and outgoing cost is equal");
+ assert.equal(cur_frm.doc.total_outgoing_value, "99000",
+ "Outgoing cost is correct"); // Price of each item x5
+ },
+ // Submit for production
+ () => frappe.click_button("Submit"),
+ () => frappe.timeout(0.5),
+ () => frappe.click_button("Yes"),
+ () => frappe.timeout(0.5),
+
+ // Finish the production order by sending for manufacturing
+ () => frappe.set_route("List", "Production Order"),
+ () => frappe.timeout(1),
+ () => frappe.click_link("Laptop"),
+ () => frappe.timeout(1),
+
+ () => {
+ assert.ok(frappe.tests.is_visible("5 items in progress", 'p'), "Production order initiated");
+ assert.ok(frappe.tests.is_visible("Finish"), "Finish button visible");
+ },
+
+ () => frappe.click_button("Finish"),
+ () => frappe.timeout(0.5),
+ () => click_make(),
+ () => {
+ assert.equal(cur_frm.doc.total_incoming_value, "105700",
+ "Incoming cost is correct"); // Price of each item x5, values are in USD
+ assert.equal(cur_frm.doc.total_outgoing_value, "99000",
+ "Outgoing cost is correct"); // Price of each item x5, values are in USD
+ assert.equal(cur_frm.doc.total_incoming_value - cur_frm.doc.total_outgoing_value, cur_frm.doc.value_difference,
+ "Value difference is correct"); // Price of each item x5, values are in USD
+ },
+ () => frappe.click_button("Save"),
+ () => frappe.timeout(1),
+ () => frappe.click_button("Submit"),
+ () => frappe.timeout(1),
+ () => frappe.click_button("Yes"),
+ () => frappe.timeout(1),
+
+ // Manufacturing finished
+ () => frappe.set_route("List", "Production Order"),
+ () => frappe.timeout(1),
+ () => frappe.click_link("Laptop"),
+ () => frappe.timeout(1),
+
+ () => assert.ok(frappe.tests.is_visible("5 items produced", 'p'), "Production order completed"),
+
() => done()
]);
-});
+});
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 64cf5d0..b6d29d8 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -429,4 +429,6 @@
erpnext.patches.v8_5.update_existing_data_in_project_type
erpnext.patches.v8_5.set_default_mode_of_payment
erpnext.patches.v8_5.update_customer_group_in_POS_profile
-erpnext.patches.v8_6.update_timesheet_company_from_PO
\ No newline at end of file
+erpnext.patches.v8_6.update_timesheet_company_from_PO
+erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
+erpnext.patches.v8_5.remove_project_type_property_setter
\ No newline at end of file
diff --git a/erpnext/patches/v8_0/set_sales_invoice_serial_number_from_delivery_note.py b/erpnext/patches/v8_0/set_sales_invoice_serial_number_from_delivery_note.py
index 2ae74cd..5dedc81 100644
--- a/erpnext/patches/v8_0/set_sales_invoice_serial_number_from_delivery_note.py
+++ b/erpnext/patches/v8_0/set_sales_invoice_serial_number_from_delivery_note.py
@@ -26,7 +26,7 @@
if not sales_invoice or not serial_nos:
continue
- serial_nos = ["'%s'"%no for no in serial_nos.split("\n")]
+ serial_nos = ["'%s'"%frappe.db.escape(no) for no in serial_nos.split("\n")]
frappe.db.sql("""
UPDATE
@@ -36,7 +36,7 @@
WHERE
name in ({serial_nos})
""".format(
- sales_invoice=sales_invoice,
+ sales_invoice=frappe.db.escape(sales_invoice),
serial_nos=",".join(serial_nos)
)
)
\ No newline at end of file
diff --git a/erpnext/patches/v8_5/remove_project_type_property_setter.py b/erpnext/patches/v8_5/remove_project_type_property_setter.py
new file mode 100644
index 0000000..03d128d
--- /dev/null
+++ b/erpnext/patches/v8_5/remove_project_type_property_setter.py
@@ -0,0 +1,17 @@
+import frappe
+
+def execute():
+ ps = frappe.db.get_value('Property Setter', dict(doc_type='Project', field_name='project_type',
+ property='options'))
+ if ps:
+ frappe.delete_doc('Property Setter', ps)
+
+ project_types = frappe.db.sql_list('select distinct project_type from tabProject')
+
+ for project_type in project_types:
+ if project_type and not frappe.db.exists("Project Type", project_type):
+ p_type = frappe.get_doc({
+ "doctype": "Project Type",
+ "project_type": project_type
+ })
+ p_type.insert()
\ No newline at end of file
diff --git a/erpnext/patches/v8_6/set_write_permission_for_quotation_for_sales_manager.py b/erpnext/patches/v8_6/set_write_permission_for_quotation_for_sales_manager.py
new file mode 100644
index 0000000..c2320ec
--- /dev/null
+++ b/erpnext/patches/v8_6/set_write_permission_for_quotation_for_sales_manager.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ # Set write permission to permlevel 1 for sales manager role in Quotation doctype
+ frappe.db.sql(""" update `tabCustom DocPerm` set `tabCustom DocPerm`.write = 1
+ where `tabCustom DocPerm`.parent = 'Quotation' and `tabCustom DocPerm`.role = 'Sales Manager'
+ and `tabCustom DocPerm`.permlevel = 1 """)
diff --git a/erpnext/schools/doctype/program/test_program.js b/erpnext/schools/doctype/program/test_program.js
index 16bc932..a14fe97 100644
--- a/erpnext/schools/doctype/program/test_program.js
+++ b/erpnext/schools/doctype/program/test_program.js
@@ -2,7 +2,7 @@
QUnit.module('schools');
QUnit.test('Test: Program', function(assert){
- assert.expect(11);
+ assert.expect(6);
let done = assert.async();
let fee_structure_code;
frappe.run_serially([
@@ -21,45 +21,6 @@
]);
},
- () => cur_frm.save(),
- // Setting up Fee Category to select in Program doctype
- () => {
- return frappe.tests.make('Fee Category', [
- {category_name: 'Reservation'},
- {description: 'Special Provision'}
- ]);
- },
- // Setting up Fee Structure to be selected in Program doctype
- () => {
- return frappe.tests.make('Fee Structure', [
- {program: 'Standard Test'},
- {academic_term: '2016-17 (Semester 1)'},
- {student_category: 'Reservation'},
- {components: [
- [
- {fees_category: 'Reservation'},
- {amount: 20000}
- ]
- ]}
- ]);
- },
- () => {fee_structure_code = frappe.get_route()[2];}, // Storing naming convention of Fee Structure entry
- () => frappe.set_route('Form', ('Program/Standard Test')), // Routing to our current Program doctype
-
- () => $('.shaded-section~ .visible-section+ .visible-section .grid-add-row').trigger('click'), // clicking on Add Row button
- // Storing data that were inter-dependent
- () => cur_frm.doc.fees[0].academic_term = '2016-17 (Semester 1)',
- () => cur_frm.doc.fees[0].student_category = 'Reservation',
- () => cur_frm.doc.fees[0].due_date = '2016-08-20',
- () => $('.error').trigger('click'),
- () => $('.bold.input-sm').trigger('focus'),
- () => frappe.timeout(1),
- () => $('.bold.input-sm').trigger('focus'),
- () => $('.bold.input-sm').val(fee_structure_code),
- () => $('.bold.input-sm').trigger('focus'),
- () => frappe.timeout(1),
- () => cur_frm.save(),
-
() => {
assert.ok(cur_frm.doc.program_name == 'Standard Test');
assert.ok(cur_frm.doc.program_code == 'Standard Test');
@@ -67,11 +28,6 @@
assert.ok(cur_frm.doc.program_abbreviation == 'Standard Test');
assert.ok(cur_frm.doc.courses[0].course == 'Test_Sub');
assert.ok(cur_frm.doc.courses[0].required == true);
- assert.ok(cur_frm.doc.fees[0].academic_term == '2016-17 (Semester 1)');
- assert.ok(cur_frm.doc.fees[0].fee_structure == fee_structure_code);
- assert.ok(cur_frm.doc.fees[0].student_category == 'Reservation');
- assert.ok(cur_frm.doc.fees[0].due_date == '2016-08-20');
- assert.ok(cur_frm.doc.fees[0].amount == 20000);
},
() => done()
]);
diff --git a/erpnext/schools/doctype/program_enrollment/program_enrollment.js b/erpnext/schools/doctype/program_enrollment/program_enrollment.js
index d1b703b..8418e85 100644
--- a/erpnext/schools/doctype/program_enrollment/program_enrollment.js
+++ b/erpnext/schools/doctype/program_enrollment/program_enrollment.js
@@ -43,6 +43,7 @@
},
program: function(frm) {
+ frm.events.get_courses(frm);
if (frm.doc.program) {
frappe.call({
method: "erpnext.schools.api.get_fee_schedule",
diff --git a/erpnext/schools/doctype/student_applicant/tests/test_student_applicant_dummy_data.js b/erpnext/schools/doctype/student_applicant/tests/test_student_applicant_dummy_data.js
new file mode 100644
index 0000000..26244ab
--- /dev/null
+++ b/erpnext/schools/doctype/student_applicant/tests/test_student_applicant_dummy_data.js
@@ -0,0 +1,87 @@
+QUnit.module('Admission');
+
+QUnit.test('Make Students', function(assert){
+ assert.expect(0);
+ let done = assert.async();
+ let tasks = [];
+ let loop = [1,2,3,4];
+ let fname;
+
+ frappe.run_serially([
+ // Making School House to be used in this test and later
+ () => frappe.set_route('Form', 'School House/New School House'),
+ () => frappe.timeout(0.5),
+ () => cur_frm.doc.house_name = 'Test_house',
+ () => cur_frm.save(),
+
+ // Making Student Applicant entries
+ () => {
+ loop.forEach(index => {
+ tasks.push(() => {
+ fname = "Fname" + index;
+
+ return frappe.tests.make('Student Applicant', [
+ {first_name: fname},
+ {middle_name: "Mname"},
+ {last_name: "Lname"},
+ {program: "Standard Test"},
+ {student_admission: "2016-17 Admissions"},
+ {date_of_birth: '1995-08-20'},
+ {student_email_id: ('test' + (index+3) + '@testmail.com')},
+ {gender: 'Male'},
+ {student_mobile_number: (9898980000 + index)},
+ {blood_group: 'O+'},
+ {address_line_1: 'Test appt, Test Society,'},
+ {address_line_2: 'Test district, Test city.'},
+ {city: 'Test'},
+ {state: 'Test'},
+ {pincode: '395007'}
+ ]);
+ });
+ });
+ return frappe.run_serially(tasks);
+ },
+
+ // Using Program Enrollment Tool to enroll all dummy student at once
+ () => frappe.set_route('Form', 'Program Enrollment Tool'),
+ () => {
+ cur_frm.set_value("get_students_from", "Student Applicants");
+ cur_frm.set_value("academic_year", "2016-17");
+ cur_frm.set_value("program", "Standard Test");
+ },
+ () => frappe.tests.click_button("Get Students"),
+ () => frappe.timeout(1),
+ () => frappe.tests.click_button("Enroll Students"),
+ () => frappe.timeout(1.5),
+ () => frappe.tests.click_button("Close"),
+
+ // Submitting required data for each enrolled Student
+ () => {
+ tasks = [];
+ loop.forEach(index => {
+ tasks.push(
+ () => {fname = "Fname" + index + " Mname Lname";},
+ () => frappe.set_route('List', 'Program Enrollment/List'),
+ () => frappe.timeout(0.6),
+ () => frappe.tests.click_link(fname),
+ () => frappe.timeout(0.4),
+ () => {
+ cur_frm.set_value('program', 'Standard Test');
+ cur_frm.set_value('student_category', 'Reservation');
+ cur_frm.set_value('student_batch_name', 'A');
+ cur_frm.set_value('academic_year', '2016-17');
+ cur_frm.set_value('academic_term', '2016-17 (Semester 1)');
+ cur_frm.set_value('school_house', 'Test_house');
+ },
+ () => cur_frm.save(),
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.5)
+ );
+ });
+ return frappe.run_serially(tasks);
+ },
+ () => done()
+ ]);
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js b/erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js
index 61f36e2..b983afd 100644
--- a/erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js
+++ b/erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js
@@ -2,14 +2,10 @@
QUnit.module('schools');
QUnit.test('test student applicant', function(assert){
- assert.expect(12);
+ assert.expect(11);
let done = assert.async();
let testing_status;
frappe.run_serially([
- () => frappe.set_route('Form', 'School House/New School House'),
- () => frappe.timeout(0.5),
- () => cur_frm.doc.house_name = 'Test_house',
- () => cur_frm.save(),
() => frappe.set_route('List', 'Student Applicant'),
() => frappe.timeout(0.5),
() => {$(`a:contains("Fname Mname Lname"):visible`)[0].click();},
@@ -97,26 +93,15 @@
cur_frm.set_value('academic_year', '2016-17');
cur_frm.set_value('academic_term', '2016-17 (Semester 1)');
cur_frm.set_value('school_house', 'Test_house');
- $('a:contains("Fees"):visible').click();
- },
- () => frappe.timeout(1),
- () => {
- cur_frm.doc.fees[0].student_category = "Reservation";
},
() => cur_frm.save(),
+
// Submitting Program Enrollment form for our Test Student
- () => frappe.timeout(0.5),
+ () => frappe.timeout(1),
() => frappe.tests.click_button('Submit'),
() => frappe.tests.click_button('Yes'),
() => {
- testing_status = $('.msgprint').text();
- assert.ok("Fee Records Created" == (testing_status.substring(0,19)), "Fee record created for enrolled student test");
- },
- () => frappe.timeout(0.5),
- () => frappe.tests.click_button('Close'),
- () => {
- testing_status = $('h1').text();
- assert.ok(testing_status.indexOf('Submitted') != -1, "Program enrollment successfully submitted"); // Checking if the program enrollment entry shows submitted or not
+ assert.ok(cur_frm.doc.docstatus == 1, "Program enrollment successfully submitted");
},
() => done()
]);
diff --git a/erpnext/schools/doctype/student_group/test_student_group.js b/erpnext/schools/doctype/student_group/test_student_group.js
new file mode 100644
index 0000000..842d0ba
--- /dev/null
+++ b/erpnext/schools/doctype/student_group/test_student_group.js
@@ -0,0 +1,62 @@
+// Testing Student Module in Schools
+QUnit.module('schools');
+
+QUnit.test('Test: Student Group', function(assert){
+ assert.expect(2);
+ let done = assert.async();
+ let instructor_code;
+ let loop = ["test-batch-wise-group", "test-course-wise-group"];
+ let tasks = [];
+
+ frappe.run_serially([
+ // Saving Instructor code beforehand
+ () => frappe.set_route('List', 'Instructor'),
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_link('Instructor 1'),
+ () => frappe.timeout(0.5),
+ () => {instructor_code = frappe.get_route()[2];},
+
+ // Creating a Batch and Course based group
+ () => {
+ loop.forEach(index => {
+ tasks.push(() => {
+ return frappe.tests.make('Student Group', [
+ {academic_year: '2016-17'},
+ {academic_term: '2016-17 (Semester 1)'},
+ {program: "Standard Test"},
+ {group_based_on: 'Batch'},
+ {student_group_name: index},
+ {max_strength: 10},
+ {batch: 'A'},
+ {instructors: [
+ [
+ {instructor: instructor_code}
+ ]
+ ]}
+ ]);
+ });
+ });
+ return frappe.run_serially(tasks);
+ },
+
+ // Populating the created group with Students
+ () => {
+ tasks = [];
+ loop.forEach(index => {
+ tasks.push(
+ () => frappe.timeout(0.3),
+ () => frappe.set_route("Form", ('Student Group/' + index)),
+ () => frappe.timeout(0.3),
+ () => frappe.tests.click_button('Get Students'),
+ () => frappe.timeout(0.2),
+ () => {
+ assert.equal(cur_frm.doc.students.length, 5, 'Successfully fetched list of students');
+ },
+ );
+ });
+ return frappe.run_serially(tasks);
+ },
+
+ () => done()
+ ]);
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js b/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js
index 146f11c..d0d7afd 100644
--- a/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js
+++ b/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.js
@@ -8,7 +8,7 @@
});
frappe.realtime.on("student_group_creation_progress", function(data) {
if(data.progress) {
- frappe.hide_frappe.msgprint(true);
+ frappe.hide_msgprint(true);
frappe.show_progress(__("Creating student groups"), data.progress[0],data.progress[1]);
}
});
diff --git a/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.py b/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.py
index a236508..4a4cec7 100644
--- a/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.py
+++ b/erpnext/schools/doctype/student_group_creation_tool/student_group_creation_tool.py
@@ -64,6 +64,7 @@
student_group.program = self.program
student_group.course = d.course
student_group.batch = d.batch
+ student_group.max_strength = d.max_strength
student_group.academic_term = self.academic_term
student_group.academic_year = self.academic_year
student_group.save()
diff --git a/erpnext/schools/doctype/student_group_creation_tool/test_student_group_creation_tool.js b/erpnext/schools/doctype/student_group_creation_tool/test_student_group_creation_tool.js
new file mode 100644
index 0000000..c0b4dc8
--- /dev/null
+++ b/erpnext/schools/doctype/student_group_creation_tool/test_student_group_creation_tool.js
@@ -0,0 +1,88 @@
+QUnit.module('schools');
+
+QUnit.test('Test: Student Group Creation Tool', function(assert){
+ assert.expect(5);
+ let done = assert.async();
+ let instructor_code;
+
+ frappe.run_serially([
+ // Saving Instructor code beforehand
+ () => frappe.set_route('List', 'Instructor'),
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_link('Instructor 1'),
+ () => frappe.timeout(0.5),
+ () => {instructor_code = frappe.get_route()[2];},
+
+ // Setting up the creation tool to generate and save Student Group
+ () => frappe.set_route('Form', 'Student Group Creation Tool'),
+ () => frappe.timeout(0.5),
+ () => {
+ cur_frm.set_value("academic_year", "2016-17");
+ cur_frm.set_value("academic_term", "2016-17 (Semester 1)");
+ cur_frm.set_value("program", "Standard Test");
+ frappe.tests.click_button('Get Courses');
+ },
+ () => frappe.timeout(0.5),
+ () => {
+ assert.equal(cur_frm.doc.courses.length, 4, 'Successfully created groups using the tool');
+ },
+
+ () => {
+ let d, grid, grid_row;
+
+ for(d = 0; d < cur_frm.doc.courses.length; d++)
+ {
+ grid = cur_frm.get_field("courses").grid;
+ grid_row = grid.get_row(d).toggle_view(true);
+ if(grid_row.doc.student_group_name == 'Standard Test/A/2016-17 (Semester 1)'){
+ grid_row.doc.max_strength = 10;
+ grid_row.doc.student_group_name = "test-batch-wise-group-2";
+ $(`.octicon.octicon-triangle-up`).click();
+ continue;
+ }
+ else if(grid_row.doc.student_group_name == 'Test_Sub/Standard Test/2016-17 (Semester 1)'){
+ grid_row.doc.max_strength = 10;
+ grid_row.doc.student_group_name = "test-course-wise-group-2";
+ $(`.octicon.octicon-triangle-up`).click();
+ continue;
+ }
+ }
+ },
+
+ // Generating Student Group
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_button("Create Student Groups"),
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_button("Close"),
+
+ // Goin to the generated group to set up student and instructor list
+ () => {
+ let loop = ['Student Group/test-batch-wise-group-2', 'Student Group/test-course-wise-group-2'];
+ let tasks = [];
+ loop.forEach(index => {
+ tasks.push(
+ () => frappe.timeout(1),
+ () => frappe.set_route("Form", index),
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_button("Get Students"),
+ () => frappe.timeout(0.5),
+ () => {
+ assert.equal(cur_frm.doc.students.length, 5, 'Successfully fetched list of students');
+ },
+ () => frappe.timeout(0.5),
+ () => {
+ d = cur_frm.add_child('instructors');
+ d.instructor = instructor_code;
+ cur_frm.save();
+ },
+ () => {
+ assert.equal(cur_frm.doc.instructors.length, 1, 'Instructor detail stored successfully');
+ },
+ );
+ });
+ return frappe.run_serially(tasks);
+ },
+
+ () => done()
+ ]);
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_log/test_student_log.js b/erpnext/schools/doctype/student_log/test_student_log.js
new file mode 100644
index 0000000..6e03976
--- /dev/null
+++ b/erpnext/schools/doctype/student_log/test_student_log.js
@@ -0,0 +1,38 @@
+// Testing Student Module in Schools
+QUnit.module('schools');
+
+QUnit.test('Test: Student Log', function(assert){
+ assert.expect(9);
+ let done = assert.async();
+ let student_code;
+ frappe.run_serially([
+ () => frappe.set_route("List", "Student"),
+ () => frappe.timeout(0.5),
+ () => frappe.tests.click_link('Fname Mname Lname'),
+ () => frappe.timeout(0.5),
+ () => {student_code = frappe.get_route()[2];},
+ () => {
+ return frappe.tests.make("Student Log", [
+ {student: student_code},
+ {academic_year: '2016-17'},
+ {academic_term: '2016-17 (Semester 1)'},
+ {program: "Standard Test"},
+ {date: '2017-07-31'},
+ {student_batch: 'A'},
+ {log: 'This is Test log.'}
+ ]);
+ },
+ () => {
+ assert.equal(cur_frm.doc.student, student_code, 'Student code was fetched properly');
+ assert.equal(cur_frm.doc.student_name, 'Fname Mname Lname', 'Student name was correctly auto-fetched');
+ assert.equal(cur_frm.doc.type, 'General', 'Default type selected');
+ assert.equal(cur_frm.doc.academic_year, '2016-17');
+ assert.equal(cur_frm.doc.academic_term, '2016-17 (Semester 1)');
+ assert.equal(cur_frm.doc.program, 'Standard Test', 'Program correctly selected');
+ assert.equal(cur_frm.doc.student_batch, 'A');
+ assert.equal(cur_frm.doc.date, '2017-07-31');
+ assert.equal(cur_frm.doc.log, 'This is Test log.');
+ },
+ () => done()
+ ]);
+});
\ No newline at end of file
diff --git a/erpnext/selling/doctype/quotation/quotation.json b/erpnext/selling/doctype/quotation/quotation.json
index 33eed19..16ea578 100644
--- a/erpnext/selling/doctype/quotation/quotation.json
+++ b/erpnext/selling/doctype/quotation/quotation.json
@@ -2602,7 +2602,7 @@
"istable": 0,
"max_attachments": 1,
"menu_index": 0,
- "modified": "2017-07-25 08:14:35.355019",
+ "modified": "2017-08-02 18:15:38.198698",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",
@@ -2668,7 +2668,7 @@
"set_user_permissions": 0,
"share": 0,
"submit": 0,
- "write": 0
+ "write": 1
},
{
"amend": 1,
diff --git a/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_pricing_rule.js b/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_pricing_rule.js
new file mode 100644
index 0000000..e91fb01
--- /dev/null
+++ b/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_pricing_rule.js
@@ -0,0 +1,34 @@
+QUnit.module('Sales Order');
+
+QUnit.test("test sales order with shipping rule", function(assert) {
+ assert.expect(2);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Sales Order', [
+ {customer: 'Test Customer 3'},
+ {items: [
+ [
+ {'delivery_date': frappe.datetime.add_days(frappe.defaults.get_default("year_end_date"), 1)},
+ {'qty': 5},
+ {'item_code': 'Test Product 2'},
+ ]
+ ]},
+ {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 2', "Item name correct");
+ // get grand_total details
+ assert.ok(cur_frm.doc.grand_total== 675, "Grand total correct ");
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
diff --git a/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_shipping_rule.js b/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_shipping_rule.js
new file mode 100644
index 0000000..7d1211f
--- /dev/null
+++ b/erpnext/selling/doctype/sales_order/tests/test_sales_order_with_shipping_rule.js
@@ -0,0 +1,35 @@
+QUnit.module('Sales Order');
+
+QUnit.test("test sales order with shipping rule", function(assert) {
+ assert.expect(2);
+ let done = assert.async();
+ frappe.run_serially([
+ () => {
+ return frappe.tests.make('Sales Order', [
+ {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 4'},
+ ]
+ ]},
+ {customer_address: 'Test1-Billing'},
+ {shipping_address_name: 'Test1-Shipping'},
+ {contact_person: 'Contact 1-Test Customer 1'},
+ {shipping_rule:'Next Day Shipping'}
+ ]);
+ },
+ () => cur_frm.save(),
+ () => {
+ // get_item_details
+ assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
+ // get grand_total details
+ assert.ok(cur_frm.doc.grand_total== 550, "Grand total correct ");
+ },
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(0.3),
+ () => done()
+ ]);
+});
diff --git a/erpnext/shopping_cart/product.py b/erpnext/shopping_cart/product.py
index 1999a4a..912467f 100644
--- a/erpnext/shopping_cart/product.py
+++ b/erpnext/shopping_cart/product.py
@@ -85,7 +85,7 @@
if pricing_rule:
if pricing_rule.pricing_rule_for == "Discount Percentage":
- price[0].price_list_rate = flt(price[0].price_list_rate * (1.0 - (pricing_rule.discount_percentage / 100.0)))
+ price[0].price_list_rate = flt(price[0].price_list_rate * (1.0 - (flt(pricing_rule.discount_percentage) / 100.0)))
if pricing_rule.pricing_rule_for == "Price":
price[0].price_list_rate = pricing_rule.price_list_rate
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
index 9df4ff7..dc9a322 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
@@ -452,6 +452,7 @@
"label": "Difference Amount",
"length": 0,
"no_copy": 0,
+ "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -477,7 +478,7 @@
"istable": 0,
"max_attachments": 1,
"menu_index": 0,
- "modified": "2017-06-16 17:35:54.811500",
+ "modified": "2017-08-02 23:54:28.516007",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reconciliation",
diff --git a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
index 4a19108..0fafe83 100644
--- a/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
+++ b/erpnext/stock/doctype/stock_reconciliation_item/stock_reconciliation_item.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@@ -12,6 +13,7 @@
"engine": "InnoDB",
"fields": [
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -41,6 +43,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -71,6 +74,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -100,6 +104,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -130,6 +135,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -158,6 +164,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -188,6 +195,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -205,6 +213,7 @@
"label": "Valuation Rate",
"length": 0,
"no_copy": 0,
+ "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -218,6 +227,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -234,6 +244,7 @@
"label": "Amount",
"length": 0,
"no_copy": 0,
+ "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -247,6 +258,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -276,6 +288,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -306,6 +319,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -334,6 +348,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -351,6 +366,7 @@
"label": "Current Valuation Rate",
"length": 0,
"no_copy": 0,
+ "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -364,6 +380,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -381,6 +398,7 @@
"label": "Current Amount",
"length": 0,
"no_copy": 0,
+ "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -394,6 +412,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -422,6 +441,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -451,6 +471,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -479,6 +500,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -495,6 +517,7 @@
"label": "Amount Difference",
"length": 0,
"no_copy": 0,
+ "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -508,18 +531,18 @@
"unique": 0
}
],
+ "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
- "in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-02-20 13:32:09.827878",
+ "modified": "2017-08-03 00:03:40.412071",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Reconciliation Item",
diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.js b/erpnext/stock/doctype/warehouse/test_warehouse.js
index 3763613..f13bc58 100644
--- a/erpnext/stock/doctype/warehouse/test_warehouse.js
+++ b/erpnext/stock/doctype/warehouse/test_warehouse.js
@@ -16,4 +16,4 @@
() => done()
]);
-});
+});
\ No newline at end of file
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index ec55cec..916adff 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -29,14 +29,28 @@
return columns, data
def get_columns():
- return [_("Date") + ":Datetime:95", _("Item") + ":Link/Item:130", _("Item Name") + "::100", _("Item Group") + ":Link/Item Group:100",
- _("Brand") + ":Link/Brand:100", _("Description") + "::200", _("Warehouse") + ":Link/Warehouse:100",
- _("Stock UOM") + ":Link/UOM:100", _("Qty") + ":Float:50", _("Balance Qty") + ":Float:100",
- _("Incoming Rate") + ":Currency:110", _("Valuation Rate") + ":Currency:110", _("Balance Value") + ":Currency:110",
- _("Voucher Type") + "::110", _("Voucher #") + ":Dynamic Link/"+_("Voucher Type")+":100", _("Batch") + ":Link/Batch:100",
- _("Serial #") + ":Link/Serial No:100", _("Company") + ":Link/Company:100"
+ columns = [
+ _("Date") + ":Datetime:95", _("Item") + ":Link/Item:130",
+ _("Item Name") + "::100", _("Item Group") + ":Link/Item Group:100",
+ _("Brand") + ":Link/Brand:100", _("Description") + "::200",
+ _("Warehouse") + ":Link/Warehouse:100", _("Stock UOM") + ":Link/UOM:100",
+ _("Qty") + ":Float:50", _("Balance Qty") + ":Float:100",
+ {"label": _("Incoming Rate"), "fieldtype": "Currency", "width": 110,
+ "options": "Company:company:default_currency"},
+ {"label": _("Valuation Rate"), "fieldtype": "Currency", "width": 110,
+ "options": "Company:company:default_currency"},
+ {"label": _("Balance Value"), "fieldtype": "Currency", "width": 110,
+ "options": "Company:company:default_currency"},
+ _("Voucher Type") + "::110",
+ _("Voucher #") + ":Dynamic Link/" + _("Voucher Type") + ":100",
+ _("Batch") + ":Link/Batch:100",
+ _("Serial #") + ":Link/Serial No:100",
+ {"label": _("Company"), "fieldtype": "Link", "width": 110,
+ "options": "company", "fieldname": "company"}
]
+ return columns
+
def get_stock_ledger_entries(filters):
return frappe.db.sql("""select concat_ws(" ", posting_date, posting_time) as date,
item_code, warehouse, actual_qty, qty_after_transaction, incoming_rate, valuation_rate,
diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt
index fb86b7c..4ce1675 100644
--- a/erpnext/tests/ui/tests.txt
+++ b/erpnext/tests/ui/tests.txt
@@ -16,6 +16,8 @@
erpnext/selling/doctype/sales_order/tests/test_sales_order_with_multi_uom.js
erpnext/selling/doctype/sales_order/tests/test_sales_order_with_discount_on_grand_total.js
erpnext/selling/doctype/sales_order/tests/test_sales_order_with_taxes_and_charges.js
+erpnext/selling/doctype/sales_order/tests/test_sales_order_with_shipping_rule.js
+erpnext/selling/doctype/sales_order/tests/test_sales_order_with_pricing_rule.js
erpnext/manufacturing/doctype/workstation/test_workstation.js
erpnext/manufacturing/doctype/operation/test_operation.js
erpnext/manufacturing/doctype/bom/test_bom.js
@@ -41,7 +43,7 @@
erpnext/schools/doctype/room/test_room.js
erpnext/schools/doctype/instructor/test_instructor.js
erpnext/stock/doctype/warehouse/test_warehouse.js
-erpnext/manufacturing/doctype/production_order/test_production_order.js
+erpnext/manufacturing/doctype/production_order/test_production_order.js #long
erpnext/accounts/page/pos/test_pos.js
erpnext/selling/doctype/product_bundle/test_product_bundle.js
erpnext/schools/doctype/grading_scale/test_grading_scale.js
@@ -51,5 +53,9 @@
erpnext/schools/doctype/program/test_program.js
erpnext/schools/doctype/guardian/test_guardian.js
erpnext/schools/doctype/student_admission/test_student_admission.js
+erpnext/schools/doctype/student_applicant/tests/test_student_applicant_dummy_data.js
erpnext/schools/doctype/student_applicant/tests/test_student_applicant.js
-erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js
\ No newline at end of file
+erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js
+erpnext/schools/doctype/student_log/test_student_log.js
+erpnext/schools/doctype/student_group/test_student_group.js
+erpnext/schools/doctype/student_group_creation_tool/test_student_group_creation_tool.js
\ No newline at end of file