Merge branch 'master' into develop

This commit is contained in:
Nabin Hait 2018-01-05 13:17:00 +05:30
commit cb495fb33b
46 changed files with 505 additions and 166 deletions

View File

@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides from erpnext.hooks import regional_overrides
from frappe.utils import getdate from frappe.utils import getdate
__version__ = '10.0.5' __version__ = '10.0.6'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@ -53,14 +53,12 @@ class Account(NestedSet):
def set_root_and_report_type(self): def set_root_and_report_type(self):
if self.parent_account: if self.parent_account:
par = frappe.db.get_value("Account", self.parent_account, par = frappe.db.get_value("Account", self.parent_account,
["report_type", "root_type", "account_type"], as_dict=1) ["report_type", "root_type"], as_dict=1)
if par.report_type: if par.report_type:
self.report_type = par.report_type self.report_type = par.report_type
if par.root_type: if par.root_type:
self.root_type = par.root_type self.root_type = par.root_type
if par.account_type and not self.account_type:
self.account_type = par.account_type
if self.is_group: if self.is_group:
db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1) db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1)

View File

@ -130,7 +130,7 @@
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
"search_index": 0, "search_index": 0,
"set_only_once": 1, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{ {
@ -1476,7 +1476,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-12-11 17:30:45.198147", "modified": "2018-01-03 17:30:45.198147",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "POS Profile", "name": "POS Profile",

View File

@ -18,7 +18,7 @@ QUnit.test("test purchase invoice", function(assert) {
{update_stock:1}, {update_stock:1},
{supplier_address: 'Test1-Billing'}, {supplier_address: 'Test1-Billing'},
{contact_person: 'Contact 3-Test Supplier'}, {contact_person: 'Contact 3-Test Supplier'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'}, {terms: 'This is Test'},
{payment_terms_template: '_Test Payment Term Template UI'} {payment_terms_template: '_Test Payment Term Template UI'}
@ -29,7 +29,7 @@ QUnit.test("test purchase invoice", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// grand_total Calculated // grand_total Calculated

View File

@ -3,6 +3,7 @@
# License: GNU General Public License v3. See license.txt # License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe
from frappe.model.document import Document from frappe.model.document import Document
from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_charges_template \ from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_charges_template \
import valdiate_taxes_and_charges_template import valdiate_taxes_and_charges_template
@ -10,3 +11,8 @@ from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_taxes_and_c
class PurchaseTaxesandChargesTemplate(Document): class PurchaseTaxesandChargesTemplate(Document):
def validate(self): def validate(self):
valdiate_taxes_and_charges_template(self) valdiate_taxes_and_charges_template(self)
def autoname(self):
if self.company and self.title:
abbr = frappe.db.get_value('Company', self.company, 'abbr')
self.name = '{0} - {1}'.format(self.title, abbr)

View File

@ -1,7 +1,7 @@
QUnit.module('Sales Taxes and Charges Template'); QUnit.module('Sales Taxes and Charges Template');
QUnit.test("test sales taxes and charges template", function(assert) { QUnit.test("test sales taxes and charges template", function(assert) {
assert.expect(1); assert.expect(2);
let done = assert.async(); let done = assert.async();
frappe.run_serially([ frappe.run_serially([
() => { () => {
@ -19,7 +19,10 @@ QUnit.test("test sales taxes and charges template", function(assert) {
]} ]}
]); ]);
}, },
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');}, () => {
assert.ok(cur_frm.doc.title=='TEST In State GST');
assert.ok(cur_frm.doc.name=='TEST In State GST - FT');
},
() => done() () => done()
]); ]);
}); });

View File

@ -17,7 +17,7 @@ QUnit.test("test sales Invoice", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'}, {terms: 'This is Test'},
{payment_terms_template: '_Test Payment Term Template UI'} {payment_terms_template: '_Test Payment Term Template UI'}
@ -28,7 +28,7 @@ QUnit.test("test sales Invoice", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// grand_total Calculated // grand_total Calculated

View File

@ -17,7 +17,7 @@ QUnit.test("test sales Invoice", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'} {terms: 'This is Test'}
]); ]);
@ -27,7 +27,7 @@ QUnit.test("test sales Invoice", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// grand_total Calculated // grand_total Calculated

View File

@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with payment", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'}, {terms: 'This is Test'},
{payment_terms_template: '_Test Payment Term Template UI'} {payment_terms_template: '_Test Payment Term Template UI'}
@ -28,7 +28,7 @@ QUnit.test("test sales Invoice with payment", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// grand_total Calculated // grand_total Calculated
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct"); assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");

View File

@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with payment request", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'} {terms: 'This is Test'}
]); ]);
@ -27,7 +27,7 @@ QUnit.test("test sales Invoice with payment request", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// grand_total Calculated // grand_total Calculated
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct"); assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");

View File

@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with serialize item", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'} {terms: 'This is Test'}
]); ]);
@ -27,7 +27,7 @@ QUnit.test("test sales Invoice with serialize item", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// get batch number // get batch number

View File

@ -12,6 +12,11 @@ class SalesTaxesandChargesTemplate(Document):
def validate(self): def validate(self):
valdiate_taxes_and_charges_template(self) valdiate_taxes_and_charges_template(self)
def autoname(self):
if self.company and self.title:
abbr = frappe.db.get_value('Company', self.company, 'abbr')
self.name = '{0} - {1}'.format(self.title, abbr)
def set_missing_values(self): def set_missing_values(self):
for data in self.taxes: for data in self.taxes:
if data.charge_type == 'On Net Total' and flt(data.rate) == 0.0: if data.charge_type == 'On Net Total' and flt(data.rate) == 0.0:

View File

@ -1,7 +1,7 @@
QUnit.module('Sales Taxes and Charges Template'); QUnit.module('Sales Taxes and Charges Template');
QUnit.test("test sales taxes and charges template", function(assert) { QUnit.test("test sales taxes and charges template", function(assert) {
assert.expect(1); assert.expect(2);
let done = assert.async(); let done = assert.async();
frappe.run_serially([ frappe.run_serially([
() => { () => {
@ -19,7 +19,10 @@ QUnit.test("test sales taxes and charges template", function(assert) {
]} ]}
]); ]);
}, },
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');}, () => {
assert.ok(cur_frm.doc.title=='TEST In State GST');
assert.ok(cur_frm.doc.name=='TEST In State GST - FT');
},
() => done() () => done()
]); ]);
}); });

View File

@ -2,7 +2,7 @@
{ {
"doctype": "Tax Rule", "doctype": "Tax Rule",
"tax_type" : "Sales", "tax_type" : "Sales",
"sales_tax_template": "_Test Tax 1", "sales_tax_template": "_Test Tax 1 - _TC",
"use_for_shopping_cart": 1, "use_for_shopping_cart": 1,
"billing_city": "_Test City", "billing_city": "_Test City",
"billing_state": "Test State", "billing_state": "Test State",
@ -15,7 +15,7 @@
{ {
"doctype": "Tax Rule", "doctype": "Tax Rule",
"tax_type" : "Sales", "tax_type" : "Sales",
"sales_tax_template": "_Test Tax 2", "sales_tax_template": "_Test Tax 2 - _TC",
"use_for_shopping_cart": 0, "use_for_shopping_cart": 0,
"billing_city": "_Test City", "billing_city": "_Test City",
"billing_country": "India", "billing_country": "India",

View File

@ -18,40 +18,40 @@ class TestTaxRule(unittest.TestCase):
def test_conflict(self): def test_conflict(self):
tax_rule1 = make_tax_rule(customer= "_Test Customer", tax_rule1 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1)
tax_rule1.save() tax_rule1.save()
tax_rule2 = make_tax_rule(customer= "_Test Customer", tax_rule2 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1)
self.assertRaises(ConflictingTaxRule, tax_rule2.save) self.assertRaises(ConflictingTaxRule, tax_rule2.save)
def test_conflict_with_non_overlapping_dates(self): def test_conflict_with_non_overlapping_dates(self):
tax_rule1 = make_tax_rule(customer= "_Test Customer", tax_rule1 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01") sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01")
tax_rule1.save() tax_rule1.save()
tax_rule2 = make_tax_rule(customer= "_Test Customer", tax_rule2 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, to_date = "2013-01-01") sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, to_date = "2013-01-01")
tax_rule2.save() tax_rule2.save()
self.assertTrue(tax_rule2.name) self.assertTrue(tax_rule2.name)
def test_for_parent_customer_group(self): def test_for_parent_customer_group(self):
tax_rule1 = make_tax_rule(customer_group= "All Customer Groups", tax_rule1 = make_tax_rule(customer_group= "All Customer Groups",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01") sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01")
tax_rule1.save() tax_rule1.save()
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}), self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
"_Test Sales Taxes and Charges Template") "_Test Sales Taxes and Charges Template - _TC")
def test_conflict_with_overlapping_dates(self): def test_conflict_with_overlapping_dates(self):
tax_rule1 = make_tax_rule(customer= "_Test Customer", tax_rule1 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05") sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05")
tax_rule1.save() tax_rule1.save()
tax_rule2 = make_tax_rule(customer= "_Test Customer", tax_rule2 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-03", to_date = "2015-01-09") sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority = 1, from_date = "2015-01-03", to_date = "2015-01-09")
self.assertRaises(ConflictingTaxRule, tax_rule2.save) self.assertRaises(ConflictingTaxRule, tax_rule2.save)
@ -62,66 +62,66 @@ class TestTaxRule(unittest.TestCase):
def test_select_tax_rule_based_on_customer(self): def test_select_tax_rule_based_on_customer(self):
make_tax_rule(customer= "_Test Customer", make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
make_tax_rule(customer= "_Test Customer 1", make_tax_rule(customer= "_Test Customer 1",
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
make_tax_rule(customer= "_Test Customer 2", make_tax_rule(customer= "_Test Customer 2",
sales_tax_template = "_Test Sales Taxes and Charges Template 2", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template 2 - _TC", save=1)
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer 2"}), self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer 2"}),
"_Test Sales Taxes and Charges Template 2") "_Test Sales Taxes and Charges Template 2 - _TC")
def test_select_tax_rule_based_on_better_match(self): def test_select_tax_rule_based_on_better_match(self):
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", billing_state = "Test State", make_tax_rule(customer= "_Test Customer", billing_city = "Test City", billing_state = "Test State",
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
make_tax_rule(customer= "_Test Customer", billing_city = "Test City1", billing_state = "Test State", make_tax_rule(customer= "_Test Customer", billing_city = "Test City1", billing_state = "Test State",
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City", "billing_state": "Test State"}), self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City", "billing_state": "Test State"}),
"_Test Sales Taxes and Charges Template") "_Test Sales Taxes and Charges Template - _TC")
def test_select_tax_rule_based_on_state_match(self): def test_select_tax_rule_based_on_state_match(self):
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State", make_tax_rule(customer= "_Test Customer", shipping_state = "Test State",
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
make_tax_rule(customer= "_Test Customer", shipping_state = "Test State12", make_tax_rule(customer= "_Test Customer", shipping_state = "Test State12",
sales_tax_template = "_Test Sales Taxes and Charges Template 1", priority=2, save=1) sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "shipping_state": "Test State"}), self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "shipping_state": "Test State"}),
"_Test Sales Taxes and Charges Template") "_Test Sales Taxes and Charges Template - _TC")
def test_select_tax_rule_based_on_better_priority(self): def test_select_tax_rule_based_on_better_priority(self):
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority=1, save=1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", priority=1, save=1)
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
sales_tax_template = "_Test Sales Taxes and Charges Template 1", priority=2, save=1) sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", priority=2, save=1)
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City"}), self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City"}),
"_Test Sales Taxes and Charges Template 1") "_Test Sales Taxes and Charges Template 1 - _TC")
def test_select_tax_rule_based_cross_matching_keys(self): def test_select_tax_rule_based_cross_matching_keys(self):
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
make_tax_rule(customer= "_Test Customer 1", billing_city = "Test City 1", make_tax_rule(customer= "_Test Customer 1", billing_city = "Test City 1",
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}), self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
None) None)
def test_select_tax_rule_based_cross_partially_keys(self): def test_select_tax_rule_based_cross_partially_keys(self):
make_tax_rule(customer= "_Test Customer", billing_city = "Test City", make_tax_rule(customer= "_Test Customer", billing_city = "Test City",
sales_tax_template = "_Test Sales Taxes and Charges Template", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template - _TC", save=1)
make_tax_rule(billing_city = "Test City 1", make_tax_rule(billing_city = "Test City 1",
sales_tax_template = "_Test Sales Taxes and Charges Template 1", save=1) sales_tax_template = "_Test Sales Taxes and Charges Template 1 - _TC", save=1)
self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}), self.assertEquals(get_tax_template("2015-01-01", {"customer":"_Test Customer", "billing_city": "Test City 1"}),
"_Test Sales Taxes and Charges Template 1") "_Test Sales Taxes and Charges Template 1 - _TC")
def make_tax_rule(**args): def make_tax_rule(**args):

View File

@ -6,6 +6,7 @@ import frappe, erpnext
from frappe import _ from frappe import _
from frappe.utils import flt from frappe.utils import flt
from frappe.model.meta import get_field_precision from frappe.model.meta import get_field_precision
from frappe.utils.xlsxutils import handle_html
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
def execute(filters=None): def execute(filters=None):
@ -188,10 +189,10 @@ def get_tax_accounts(item_list, columns, company_currency,
tuple([doctype] + invoice_item_row.keys())) tuple([doctype] + invoice_item_row.keys()))
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details: for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
description = handle_html(description)
if description not in tax_columns and tax_amount: if description not in tax_columns and tax_amount:
# as description is text editor earlier and markup can break the column convention in reports # as description is text editor earlier and markup can break the column convention in reports
from frappe.utils.xlsxutils import handle_html tax_columns.append(description)
tax_columns.append(handle_html(description))
if item_wise_tax_detail: if item_wise_tax_detail:
try: try:

View File

@ -66,12 +66,12 @@ def get_mode_of_payments(filters):
invoice_list = get_invoices(filters) invoice_list = get_invoices(filters)
invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list]) invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list])
if invoice_list: if invoice_list:
inv_mop = frappe.db.sql("""select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') inv_mop = frappe.db.sql("""select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') as mode_of_payment
from `tabSales Invoice` a, `tabSales Invoice Payment` b from `tabSales Invoice` a, `tabSales Invoice Payment` b
where a.name = b.parent where a.name = b.parent
and a.name in ({invoice_list_names}) and a.name in ({invoice_list_names})
union union
select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') select a.owner,a.posting_date, ifnull(b.mode_of_payment, '') as mode_of_payment
from `tabSales Invoice` a, `tabPayment Entry` b,`tabPayment Entry Reference` c from `tabSales Invoice` a, `tabPayment Entry` b,`tabPayment Entry Reference` c
where a.name = c.reference_name where a.name = c.reference_name
and b.name = c.parent and b.name = c.parent

View File

@ -24,7 +24,7 @@ QUnit.test("test: purchase order with taxes and charges", function(assert) {
] ]
]}, ]},
{taxes_and_charges: 'TEST In State GST'} {taxes_and_charges: 'TEST In State GST - FT'}
]); ]);
}, },

View File

@ -17,7 +17,7 @@ QUnit.test("test: supplier quotation with taxes and charges", function(assert) {
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))}, {"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
] ]
]}, ]},
{taxes_and_charges:'TEST In State GST'}, {taxes_and_charges:'TEST In State GST - FT'},
]); ]);
}, },
() => {supplier_quotation_name = cur_frm.doc.name;}, () => {supplier_quotation_name = cur_frm.doc.name;},

View File

@ -101,7 +101,7 @@ class Lead(SellingController):
def set_lead_name(self): def set_lead_name(self):
if not self.lead_name: if not self.lead_name:
frappe.db.set_value("Lead", self.name, "lead_name", self.organization_name) frappe.db.set_value("Lead", self.name, "lead_name", self.company_name)
@frappe.whitelist() @frappe.whitelist()
def make_customer(source_name, target_doc=None): def make_customer(source_name, target_doc=None):

View File

@ -29,7 +29,7 @@
"email_id": "test_lead4@example.com", "email_id": "test_lead4@example.com",
"organization_lead": 1, "organization_lead": 1,
"lead_name": "_Test Lead 4", "lead_name": "_Test Lead 4",
"organization_name": "_Test Lead 4", "company_name": "_Test Lead 4",
"status": "Open" "status": "Open"
} }
] ]

View File

@ -1,16 +1,21 @@
# Program Enrollment Tool # Program Enrollment Tool
The Program Enrollment tool allows the bulk enrollment of the **Student Applicants** in a Program. The Program Enrollment tool allows the bulk enrollment of the new and old students in a Program. If you are enrolling a new student, you can fetch the students from the **Student Applicant** or if you are promoting the older students you can fetch them from the **Program Enrollment** itself
> Note: Academic Term is optional in the Program Enrollment Tool
You can create the the Program Enrollment for : You can create the Program Enrollment for :
1. **Student Applicants** >> List of Student Applicants will be fetched for the selected **Program** and **Academic year**. 1. **Student Applicants**: List of Student Applicants will be fetched for the selected **Program**, **Academic year** and **Academic Term** (if provided).
<img class="screenshot" alt="Student Applicant Enrollment" src="/docs/assets/img/education/admission/program-enrollment-tool.gif"> <img class="screenshot" alt="Student Applicant Enrollment" src="/docs/assets/img/education/admission/program-enrollment-tool.gif">
2. **Program Enrollment** >> You can bulk update the **Program** for the students from one academic year to another in the same **Program** or a new **Program**. 2. **Program Enrollment**: List of students already enrolled in selected **Program** for the given **Academic Year**, **Academic Term** (if provided) and **Student Batch** will be fetched and can be used to enroll students from one academic year/term to another in the same **Program** or a new **Program**.
<img class="screenshot" alt="Student Applicant Enrollment" src="/docs/assets/img/education/admission/program-enrollment-tool01.gif"> <img class="screenshot" alt="Student Applicant Enrollment" src="/docs/assets/img/education/admission/program-enrollment-tool01.gif">
**New Student Batch**: This can be selected for the entire students fetched in the table. Priority will be given to the Batch selected in the table (for individual students).
For promoting the students, the new academic year, academic term and program can also be selected for the enrollment of the fetched students list.
{next} {next}

View File

@ -1,11 +1,19 @@
// Copyright (c) 2016, Frappe and contributors // Copyright (c) 2016, Frappe and contributors
// For license information, please see license.txt // For license information, please see license.txt
cur_frm.add_fetch("student", "title", "student_name");
cur_frm.add_fetch("student_applicant", "title", "student_name");
frappe.ui.form.on("Program Enrollment Tool", { frappe.ui.form.on("Program Enrollment Tool", {
setup: function(frm) {
frm.add_fetch("student", "title", "student_name");
frm.add_fetch("student_applicant", "title", "student_name");
},
"refresh": function(frm) { "refresh": function(frm) {
frm.disable_save(); frm.disable_save();
frm.fields_dict.enroll_students.$input.addClass(' btn btn-primary');
frappe.realtime.on("program_enrollment_tool", function(data) {
frappe.hide_msgprint(true);
frappe.show_progress(__("Enrolling students"), data.progress[0], data.progress[1]);
});
}, },
"get_students": function(frm) { "get_students": function(frm) {
@ -18,7 +26,7 @@ frappe.ui.form.on("Program Enrollment Tool", {
frm.set_value("students", r.message); frm.set_value("students", r.message);
} }
} }
}) });
}, },
"enroll_students": function(frm) { "enroll_students": function(frm) {
@ -27,7 +35,8 @@ frappe.ui.form.on("Program Enrollment Tool", {
doc:frm.doc, doc:frm.doc,
callback: function(r) { callback: function(r) {
frm.set_value("students", []); frm.set_value("students", []);
frappe.hide_msgprint(true);
} }
}) });
} }
}); });

View File

@ -29,7 +29,7 @@
"label": "Get Students From", "label": "Get Students From",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "\nStudent Applicants\nProgram Enrollments", "options": "\nStudent Applicant\nProgram Enrollment",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -73,6 +73,67 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.get_students_from==\"Program Enrollment\"",
"fieldname": "student_batch",
"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": "Student Batch",
"length": 0,
"no_copy": 0,
"options": "Student Batch Name",
"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_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@ -110,8 +171,8 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "get_students", "fieldname": "academic_term",
"fieldtype": "Button", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -119,9 +180,10 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Get Students", "label": "Academic Term",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Academic Term",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -163,6 +225,36 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "get_students",
"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": "Get Students",
"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_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@ -209,6 +301,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Enrollment Details",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -229,7 +322,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "eval:doc.get_students_from==\"Program Enrollments\"", "depends_on": "eval:doc.get_students_from==\"Program Enrollment\"",
"fieldname": "new_program", "fieldname": "new_program",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@ -261,8 +354,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "eval:doc.get_students_from==\"Program Enrollments\"", "fieldname": "new_student_batch",
"fieldname": "new_academic_year",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -271,10 +363,10 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "New Academic Year", "label": "New Student Batch",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Academic Year", "options": "Student Batch Name",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -316,6 +408,99 @@
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_12",
"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,
"depends_on": "eval:doc.get_students_from==\"Program Enrollment\"",
"fieldname": "new_academic_year",
"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": "New Academic Year",
"length": 0,
"no_copy": 0,
"options": "Academic Year",
"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": "eval:doc.get_students_from==\"Program Enrollment\"",
"fieldname": "new_academic_term",
"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": "New Academic Term",
"length": 0,
"no_copy": 0,
"options": "Academic Term",
"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, "has_web_view": 0,
@ -328,7 +513,7 @@
"issingle": 1, "issingle": 1,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-12-27 09:35:45.002469", "modified": "2018-01-02 11:59:40.230689",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Education", "module": "Education",
"name": "Program Enrollment Tool", "name": "Program Enrollment Tool",

View File

@ -17,14 +17,19 @@ class ProgramEnrollmentTool(Document):
elif not self.academic_year: elif not self.academic_year:
frappe.throw(_("Mandatory field - Academic Year")) frappe.throw(_("Mandatory field - Academic Year"))
else: else:
if self.get_students_from == "Student Applicants": condition = 'and academic_term=%(academic_term)s' if self.academic_term else " "
students = frappe.db.sql("select name as student_applicant, title as student_name from \ if self.get_students_from == "Student Applicant":
`tabStudent Applicant` where program = %s and academic_year = %s",(self.program, self.academic_year), as_dict=1) students = frappe.db.sql('''select name as student_applicant, title as student_name from `tabStudent Applicant`
else: where application_status="Approved" and program=%(program)s and academic_year=%(academic_year)s {0}'''
students = frappe.db.sql("select student, student_name, student_batch_name from \ .format(condition), self.as_dict(), as_dict=1)
`tabProgram Enrollment` where program = %s and academic_year = %s",(self.program, self.academic_year), as_dict=1) elif self.get_students_from == "Program Enrollment":
student_list = [d.student for d in students] condition2 = 'and student_batch_name=%(student_batch)s' if self.student_batch else " "
students = frappe.db.sql('''select student, student_name, student_batch_name from `tabProgram Enrollment`
where program=%(program)s and academic_year=%(academic_year)s {0} {1}'''
.format(condition, condition2), self.as_dict(), as_dict=1)
student_list = [d.student for d in students]
if student_list:
inactive_students = frappe.db.sql(''' inactive_students = frappe.db.sql('''
select name as student, title as student_name from `tabStudent` where name in (%s) and enabled = 0''' % select name as student, title as student_name from `tabStudent` where name in (%s) and enabled = 0''' %
', '.join(['%s']*len(student_list)), tuple(student_list), as_dict=1) ', '.join(['%s']*len(student_list)), tuple(student_list), as_dict=1)
@ -39,18 +44,22 @@ class ProgramEnrollmentTool(Document):
frappe.throw(_("No students Found")) frappe.throw(_("No students Found"))
def enroll_students(self): def enroll_students(self):
for stud in self.students: total = len(self.students)
for i, stud in enumerate(self.students):
frappe.publish_realtime("program_enrollment_tool", dict(progress=[i+1, total]), user=frappe.session.user)
if stud.student: if stud.student:
prog_enrollment = frappe.new_doc("Program Enrollment") prog_enrollment = frappe.new_doc("Program Enrollment")
prog_enrollment.student = stud.student prog_enrollment.student = stud.student
prog_enrollment.student_name = stud.student_name prog_enrollment.student_name = stud.student_name
prog_enrollment.student_batch_name = stud.student_batch_name
prog_enrollment.program = self.new_program prog_enrollment.program = self.new_program
prog_enrollment.academic_year = self.new_academic_year prog_enrollment.academic_year = self.new_academic_year
prog_enrollment.academic_term = self.new_academic_term
prog_enrollment.student_batch_name = stud.student_batch_name if stud.student_batch_name else self.new_student_batch
prog_enrollment.save() prog_enrollment.save()
elif stud.student_applicant: elif stud.student_applicant:
prog_enrollment = enroll_student(stud.student_applicant) prog_enrollment = enroll_student(stud.student_applicant)
prog_enrollment.academic_year = self.academic_year prog_enrollment.academic_year = self.academic_year
prog_enrollment.academic_term = self.academic_term
prog_enrollment.student_batch_name = stud.student_batch_name if stud.student_batch_name else self.new_student_batch
prog_enrollment.save() prog_enrollment.save()
frappe.msgprint("Students have been enrolled.") frappe.msgprint("{0} Students have been enrolled.".format(total))

View File

@ -133,6 +133,37 @@
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student_batch_name",
"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": "Student Batch Name",
"length": 0,
"no_copy": 0,
"options": "Student Batch Name",
"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, "has_web_view": 0,
@ -145,7 +176,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2017-11-10 19:09:59.530615", "modified": "2018-01-02 12:03:53.890741",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Education", "module": "Education",
"name": "Program Enrollment Tool Student", "name": "Program Enrollment Tool Student",

View File

@ -320,6 +320,37 @@
"set_only_once": 0, "set_only_once": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_term",
"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": "Academic Term",
"length": 0,
"no_copy": 0,
"options": "Academic Term",
"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_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@ -1058,7 +1089,7 @@
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"menu_index": 0, "menu_index": 0,
"modified": "2017-11-10 19:08:55.049625", "modified": "2018-01-02 11:47:14.944338",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Education", "module": "Education",
"name": "Student Applicant", "name": "Student Applicant",

View File

@ -262,13 +262,15 @@ frappe.ui.form.on("Expense Claim", {
}, },
get_advances: function(frm) { get_advances: function(frm) {
frappe.model.clear_table(frm.doc, "advances");
if (frm.doc.employee) {
return frappe.call({ return frappe.call({
method: "erpnext.hr.doctype.expense_claim.expense_claim.get_advances", method: "erpnext.hr.doctype.expense_claim.expense_claim.get_advances",
args: { args: {
employee: frm.doc.employee employee: frm.doc.employee
}, },
callback: function(r, rt) { callback: function(r, rt) {
frappe.model.clear_table(frm.doc, "advances");
if(r.message) { if(r.message) {
$.each(r.message, function(i, d) { $.each(r.message, function(i, d) {
var row = frappe.model.add_child(frm.doc, "Expense Claim Advance", "advances"); var row = frappe.model.add_child(frm.doc, "Expense Claim Advance", "advances");
@ -284,6 +286,7 @@ frappe.ui.form.on("Expense Claim", {
} }
}); });
} }
}
}); });
frappe.ui.form.on("Expense Claim Detail", { frappe.ui.form.on("Expense Claim Detail", {

View File

@ -236,7 +236,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges", var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
me.frm.doc.name); me.frm.doc.name);
if(taxes_and_charges_field) { if (!this.frm.doc.taxes_and_charges && this.frm.doc.taxes) {
return;
}
if (taxes_and_charges_field) {
return frappe.call({ return frappe.call({
method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges", method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges",
args: { args: {

View File

@ -17,7 +17,7 @@ QUnit.test("test quotation with taxes and charges", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'} {terms: 'This is Test'}
]); ]);
@ -27,7 +27,7 @@ QUnit.test("test quotation with taxes and charges", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");

View File

@ -17,7 +17,7 @@ QUnit.test("test sales order", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'}, {terms: 'This is Test'},
{payment_terms_template: '_Test Payment Term Template UI'} {payment_terms_template: '_Test Payment Term Template UI'}
@ -34,7 +34,7 @@ QUnit.test("test sales order", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 3', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 3', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
}, },

View File

@ -17,7 +17,7 @@ QUnit.test("test sales order with taxes and charges", function(assert) {
{customer_address: 'Test1-Billing'}, {customer_address: 'Test1-Billing'},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'} {terms: 'This is Test'}
]); ]);
@ -27,7 +27,7 @@ QUnit.test("test sales order with taxes and charges", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");

View File

@ -360,6 +360,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
fieldtype: 'Link', fieldtype: 'Link',
label: __('POS Profile'), label: __('POS Profile'),
options: 'POS Profile', options: 'POS Profile',
reqd: 1,
get_query: () => { get_query: () => {
return { return {
query: 'erpnext.accounts.doctype.pos_profile.pos_profile.pos_profile_query', query: 'erpnext.accounts.doctype.pos_profile.pos_profile.pos_profile_query',
@ -1211,6 +1212,7 @@ class POSItems {
return new Promise(res => { return new Promise(res => {
frappe.call({ frappe.call({
method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items", method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items",
freeze: true,
args: { args: {
start, start,
page_length, page_length,

View File

@ -34,24 +34,52 @@ frappe.ui.form.on("Company", {
frm.add_custom_button(__('Cost Centers'), function() { frm.add_custom_button(__('Cost Centers'), function() {
frappe.set_route('Tree', 'Cost Center', {'company': frm.doc.name}) frappe.set_route('Tree', 'Cost Center', {'company': frm.doc.name})
}) }, __("View"));
frm.add_custom_button(__('Chart of Accounts'), function() { frm.add_custom_button(__('Chart of Accounts'), function() {
frappe.set_route('Tree', 'Account', {'company': frm.doc.name}) frappe.set_route('Tree', 'Account', {'company': frm.doc.name})
}) }, __("View"));
frm.add_custom_button(__('Sales Tax Template'), function() {
frappe.set_route('List', 'Sales Taxes and Charges Template', {'company': frm.doc.name});
}, __("View"));
frm.add_custom_button(__('Purchase Tax Template'), function() {
frappe.set_route('List', 'Purchase Taxes and Charges Template', {'company': frm.doc.name});
}, __("View"));
frm.add_custom_button(__('Default Tax Template'), function() {
frm.trigger("make_default_tax_template");
}, __("Make"));
frm.page.set_inner_btn_group_as_primary(__("View"));
frm.page.set_inner_btn_group_as_primary(__("Make"));
} }
erpnext.company.set_chart_of_accounts_options(frm.doc); erpnext.company.set_chart_of_accounts_options(frm.doc);
}, },
make_default_tax_template: function(frm) {
frm.call({
method: "create_default_tax_template",
doc: frm.doc,
freeze: true,
callback: function() {
frappe.msgprint(__("Default tax templates for sales and purchase are created."));
}
})
},
onload_post_render: function(frm) { onload_post_render: function(frm) {
if(frm.get_field("delete_company_transactions").$input) if(frm.get_field("delete_company_transactions").$input)
frm.get_field("delete_company_transactions").$input.addClass("btn-danger"); frm.get_field("delete_company_transactions").$input.addClass("btn-danger");
}, },
country: function(frm) { country: function(frm) {
erpnext.company.set_chart_of_accounts_options(frm.doc); erpnext.company.set_chart_of_accounts_options(frm.doc);
}, },
delete_company_transactions: function(frm) { delete_company_transactions: function(frm) {
frappe.verify_password(function() { frappe.verify_password(function() {
var d = frappe.prompt({ var d = frappe.prompt({

View File

@ -50,6 +50,13 @@ class Company(Document):
if frappe.db.sql("select abbr from tabCompany where name!=%s and abbr=%s", (self.name, self.abbr)): if frappe.db.sql("select abbr from tabCompany where name!=%s and abbr=%s", (self.name, self.abbr)):
frappe.throw(_("Abbreviation already used for another company")) frappe.throw(_("Abbreviation already used for another company"))
def create_default_tax_template(self):
from erpnext.setup.setup_wizard.operations.taxes_setup import create_sales_tax
create_sales_tax({
'country': self.country,
'company_name': self.name
})
def validate_default_accounts(self): def validate_default_accounts(self):
for field in ["default_bank_account", "default_cash_account", for field in ["default_bank_account", "default_cash_account",
"default_receivable_account", "default_payable_account", "default_receivable_account", "default_payable_account",

View File

@ -82,7 +82,7 @@ def get_product_list_for_group(product_group=None, start=0, limit=10, search=Non
# base query # base query
query = """select I.name, I.item_name, I.item_code, I.route, I.image, I.website_image, I.thumbnail, I.item_group, query = """select I.name, I.item_name, I.item_code, I.route, I.image, I.website_image, I.thumbnail, I.item_group,
I.description, I.web_long_description as website_description, I.description, I.web_long_description as website_description, I.is_stock_item,
case when (S.actual_qty - S.reserved_qty) > 0 then 1 else 0 end as in_stock case when (S.actual_qty - S.reserved_qty) > 0 then 1 else 0 end as in_stock
from `tabItem` I from `tabItem` I
left join tabBin S on I.item_code = S.item_code and I.website_warehouse = S.warehouse left join tabBin S on I.item_code = S.item_code and I.website_warehouse = S.warehouse

View File

@ -16,7 +16,6 @@ def create_sales_tax(args):
tax_data.get('tax_rate'), sales_tax) tax_data.get('tax_rate'), sales_tax)
def make_tax_account_and_template(company, account_name, tax_rate, template_name=None): def make_tax_account_and_template(company, account_name, tax_rate, template_name=None):
try:
if not isinstance(account_name, (list, tuple)): if not isinstance(account_name, (list, tuple)):
account_name = [account_name] account_name = [account_name]
tax_rate = [tax_rate] tax_rate = [tax_rate]
@ -27,16 +26,18 @@ def make_tax_account_and_template(company, account_name, tax_rate, template_name
if tax_account: if tax_account:
accounts.append(tax_account) accounts.append(tax_account)
try:
if accounts: if accounts:
make_sales_and_purchase_tax_templates(accounts, template_name) make_sales_and_purchase_tax_templates(accounts, template_name)
except frappe.NameError: except frappe.NameError:
pass frappe.message_log.pop()
except RootNotEditable: except RootNotEditable:
pass pass
def make_tax_account(company, account_name, tax_rate): def make_tax_account(company, account_name, tax_rate):
tax_group = get_tax_account_group(company) tax_group = get_tax_account_group(company)
if tax_group: if tax_group:
try:
return frappe.get_doc({ return frappe.get_doc({
"doctype":"Account", "doctype":"Account",
"company": company, "company": company,
@ -48,6 +49,11 @@ def make_tax_account(company, account_name, tax_rate):
"account_type": "Tax", "account_type": "Tax",
"tax_rate": flt(tax_rate) if tax_rate else None "tax_rate": flt(tax_rate) if tax_rate else None
}).insert(ignore_permissions=True, ignore_mandatory=True) }).insert(ignore_permissions=True, ignore_mandatory=True)
except frappe.NameError:
frappe.message_log.pop()
abbr = frappe.db.get_value('Company', company, 'abbr')
account = '{0} - {1}'.format(account_name, abbr)
return frappe.get_doc('Account', account)
def make_sales_and_purchase_tax_templates(accounts, template_name=None): def make_sales_and_purchase_tax_templates(accounts, template_name=None):
if not template_name: if not template_name:
@ -62,7 +68,7 @@ def make_sales_and_purchase_tax_templates(accounts, template_name=None):
for account in accounts: for account in accounts:
sales_tax_template['taxes'].append({ sales_tax_template['taxes'].append({
"category": "Valuation and Total", "category": "Total",
"charge_type": "On Net Total", "charge_type": "On Net Total",
"account_head": account.name, "account_head": account.name,
"description": "{0} @ {1}".format(account.account_name, account.tax_rate), "description": "{0} @ {1}".format(account.account_name, account.tax_rate),

View File

@ -30,10 +30,10 @@ def get_product_info_for_website(item_code):
product_info = { product_info = {
"price": price, "price": price,
"stock_qty": stock_status.stock_qty, "stock_qty": stock_status.stock_qty,
"in_stock": stock_status.in_stock, "in_stock": stock_status.in_stock if stock_status.is_stock_item else 1,
"qty": 0, "qty": 0,
"uom": frappe.db.get_value("Item", item_code, "stock_uom"), "uom": frappe.db.get_value("Item", item_code, "stock_uom"),
"show_stock_qty": show_quantity_in_website() "show_stock_qty": show_quantity_in_website() if stock_status.is_stock_item else 0
} }
if product_info["price"]: if product_info["price"]:

View File

@ -128,7 +128,7 @@ class TestShoppingCart(unittest.TestCase):
"contact_email": frappe.session.user, "contact_email": frappe.session.user,
"selling_price_list": "_Test Price List Rest of the World", "selling_price_list": "_Test Price List Rest of the World",
"currency": "USD", "currency": "USD",
"taxes_and_charges" : "_Test Tax 1", "taxes_and_charges" : "_Test Tax 1 - _TC",
"conversion_rate":1, "conversion_rate":1,
"transaction_date" : nowdate(), "transaction_date" : nowdate(),
"valid_till" : add_months(nowdate(), 1), "valid_till" : add_months(nowdate(), 1),
@ -136,7 +136,7 @@ class TestShoppingCart(unittest.TestCase):
"item_code": "_Test Item", "item_code": "_Test Item",
"qty": 1 "qty": 1
}], }],
"taxes": frappe.get_doc("Sales Taxes and Charges Template", "_Test Tax 1").taxes, "taxes": frappe.get_doc("Sales Taxes and Charges Template", "_Test Tax 1 - _TC").taxes,
"company": "_Test Company" "company": "_Test Company"
} }

View File

@ -15,7 +15,7 @@ QUnit.test("test delivery note", function(assert) {
]}, ]},
{shipping_address_name: 'Test1-Shipping'}, {shipping_address_name: 'Test1-Shipping'},
{contact_person: 'Contact 1-Test Customer 1'}, {contact_person: 'Contact 1-Test Customer 1'},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{transporter_name:'TEST TRANSPORT'}, {transporter_name:'TEST TRANSPORT'},
{lr_no:'MH-04-FG 1111'} {lr_no:'MH-04-FG 1111'}

View File

@ -137,10 +137,10 @@ class PackingSlip(Document):
for d in self.get("items"): for d in self.get("items"):
res = frappe.db.get_value("Item", d.item_code, res = frappe.db.get_value("Item", d.item_code,
["net_weight", "weight_uom"], as_dict=True) ["weight_per_unit", "weight_uom"], as_dict=True)
if res and len(res)>0: if res and len(res)>0:
d.net_weight = res["net_weight"] d.net_weight = res["weight_per_unit"]
d.weight_uom = res["weight_uom"] d.weight_uom = res["weight_uom"]
def get_recommended_case_no(self): def get_recommended_case_no(self):

View File

@ -17,7 +17,7 @@ QUnit.test("test Purchase Receipt", function(assert) {
{'rejected_warehouse':'Work In Progress - '+frappe.get_abbr(frappe.defaults.get_default('Company'))}, {'rejected_warehouse':'Work In Progress - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
] ]
]}, ]},
{taxes_and_charges: 'TEST In State GST'}, {taxes_and_charges: 'TEST In State GST - FT'},
{tc_name: 'Test Term 1'}, {tc_name: 'Test Term 1'},
{terms: 'This is Test'} {terms: 'This is Test'}
]); ]);
@ -27,7 +27,7 @@ QUnit.test("test Purchase Receipt", function(assert) {
// get_item_details // get_item_details
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct"); assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
// get tax details // get tax details
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct"); assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
// get tax account head details // get tax account head details
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct"); assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
// grand_total Calculated // grand_total Calculated

View File

@ -37,9 +37,10 @@ def get_item_price_qty_data(filters):
from `tabItem Price` a left join `tabBin` b from `tabItem Price` a left join `tabBin` b
ON a.item_code = b.item_code ON a.item_code = b.item_code
{conditions}""" {conditions}"""
.format(conditions=conditions),filters,as_dict=1) .format(conditions=conditions), filters, as_dict=1)
price_list_names = ",".join(['"' + item['price_list_name'] + '"' for item in item_results]) price_list_names = ",".join(['"' + frappe.db.escape(item['price_list_name']) + '"'
for item in item_results])
buying_price_map = get_buying_price_map(price_list_names) buying_price_map = get_buying_price_map(price_list_names)
selling_price_map = get_selling_price_map(price_list_names) selling_price_map = get_selling_price_map(price_list_names)
@ -66,7 +67,8 @@ def get_buying_price_map(price_list_names):
`tabItem Price` `tabItem Price`
where where
name in ({price_list_names}) and buying=1 name in ({price_list_names}) and buying=1
""".format(price_list_names=price_list_names),as_dict=1) """.format(price_list_names=price_list_names), as_dict=1)
buying_price_map = {} buying_price_map = {}
for d in buying_price: for d in buying_price:
name = d["name"] name = d["name"]
@ -84,7 +86,8 @@ def get_selling_price_map(price_list_names):
`tabItem Price` `tabItem Price`
where where
name in ({price_list_names}) and selling=1 name in ({price_list_names}) and selling=1
""".format(price_list_names=price_list_names),as_dict=1) """.format(price_list_names=price_list_names), as_dict=1)
selling_price_map = {} selling_price_map = {}
for d in selling_price: for d in selling_price:
name = d["name"] name = d["name"]

View File

@ -64,7 +64,7 @@ frappe.ready(function() {
// then chose the closest available one // then chose the closest available one
var attribute = $(this).attr("data-attribute"); var attribute = $(this).attr("data-attribute");
var attribute_value = $(this).val() var attribute_value = $(this).val();
var item_code = find_closest_match(attribute, attribute_value); var item_code = find_closest_match(attribute, attribute_value);
if (!item_code) { if (!item_code) {

View File

@ -5,7 +5,7 @@
<div class="product-image-img"> <div class="product-image-img">
{{ product_image_square(thumbnail or website_image) }} {{ product_image_square(thumbnail or website_image) }}
<div class="product-text" itemprop="name">{{ item_name }}</div> <div class="product-text" itemprop="name">{{ item_name }}</div>
{% if in_stock %} {% if in_stock or not is_stock_item %}
<div style='color: green'> <i class='fa fa-check'></i> {{ _("In stock") }}</div> <div style='color: green'> <i class='fa fa-check'></i> {{ _("In stock") }}</div>
{% else %} {% else %}
<div style='color: red'> <i class='fa fa-close'></i> {{ _("Not in stock") }}</div> <div style='color: red'> <i class='fa fa-close'></i> {{ _("Not in stock") }}</div>

View File

@ -9,7 +9,7 @@ from erpnext.accounts.doctype.pricing_rule.pricing_rule import get_pricing_rule_
def get_qty_in_stock(item_code, item_warehouse_field): def get_qty_in_stock(item_code, item_warehouse_field):
in_stock, stock_qty = 0, '' in_stock, stock_qty = 0, ''
template_item_code = frappe.db.get_value("Item", item_code, "variant_of") template_item_code, is_stock_item = frappe.db.get_value("Item", item_code, ["variant_of", "is_stock_item"])
warehouse = frappe.db.get_value("Item", item_code, item_warehouse_field) warehouse = frappe.db.get_value("Item", item_code, item_warehouse_field)
if not warehouse and template_item_code and template_item_code != item_code: if not warehouse and template_item_code and template_item_code != item_code:
@ -21,7 +21,7 @@ def get_qty_in_stock(item_code, item_warehouse_field):
if stock_qty: if stock_qty:
in_stock = stock_qty[0][0] > 0 and 1 or 0 in_stock = stock_qty[0][0] > 0 and 1 or 0
return frappe._dict({"in_stock": in_stock, "stock_qty": stock_qty}) return frappe._dict({"in_stock": in_stock, "stock_qty": stock_qty, "is_stock_item": is_stock_item})
def get_price(item_code, price_list, customer_group, company, qty=1): def get_price(item_code, price_list, customer_group, company, qty=1):
template_item_code = frappe.db.get_value("Item", item_code, "variant_of") template_item_code = frappe.db.get_value("Item", item_code, "variant_of")