Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
471bc618b5 | ||
|
|
0b3b63a9af | ||
|
|
412e044e8f | ||
|
|
0f458b1260 | ||
|
|
da22167741 | ||
|
|
8b94f1b553 | ||
|
|
7fcc21bc8b | ||
|
|
bf4c114c58 | ||
|
|
44fa9a6d9d | ||
|
|
50b6d79758 | ||
|
|
3a972c4d85 | ||
|
|
745c2658eb | ||
|
|
4702cc0368 | ||
|
|
c98cfbdab4 | ||
|
|
28d0230e56 | ||
|
|
eac2e369cf | ||
|
|
a521efc990 | ||
|
|
171157f1b3 | ||
|
|
bc2c83ee3c | ||
|
|
3f784a7a49 | ||
|
|
1f39feb12f | ||
|
|
c5c6f82623 | ||
|
|
42688f0636 | ||
|
|
941d0af13a | ||
|
|
76625b359e | ||
|
|
e9b37abfca | ||
|
|
abf5fa6bbb | ||
|
|
650a1eeede | ||
|
|
96b264b314 | ||
|
|
2ac1835f7d | ||
|
|
15d53c7912 | ||
|
|
9579645ae1 | ||
|
|
a6b41e855b | ||
|
|
526b0bc4e9 | ||
|
|
2640c7eec5 | ||
|
|
da82674b47 | ||
|
|
07be33805d | ||
|
|
a84d38999c | ||
|
|
c9ed09440c | ||
|
|
fe22686a8f |
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '10.0.3'
|
||||
__version__ = '10.0.7'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -53,14 +53,12 @@ class Account(NestedSet):
|
||||
def set_root_and_report_type(self):
|
||||
if 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:
|
||||
self.report_type = par.report_type
|
||||
if 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:
|
||||
db_value = frappe.db.get_value("Account", self.name, ["report_type", "root_type"], as_dict=1)
|
||||
@@ -165,7 +163,7 @@ class Account(NestedSet):
|
||||
if self.check_gle_exists():
|
||||
throw(_("Account with existing transaction can not be deleted"))
|
||||
|
||||
super(Account, self).on_trash()
|
||||
super(Account, self).on_trash(True)
|
||||
|
||||
def before_rename(self, old, new, merge=False):
|
||||
# Add company abbr if not provided
|
||||
|
||||
@@ -79,15 +79,17 @@ frappe.treeview_settings["Account"] = {
|
||||
|
||||
},
|
||||
onrender: function(node) {
|
||||
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
||||
if (node.data && node.data.balance!==undefined) {
|
||||
$('<span class="balance-area pull-right text-muted small">'
|
||||
+ (node.data.balance_in_account_currency ?
|
||||
(format_currency(Math.abs(node.data.balance_in_account_currency),
|
||||
node.data.account_currency) + " / ") : "")
|
||||
+ format_currency(Math.abs(node.data.balance), node.data.company_currency)
|
||||
+ " " + dr_or_cr
|
||||
+ '</span>').insertBefore(node.$ul);
|
||||
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
|
||||
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr";
|
||||
if (node.data && node.data.balance!==undefined) {
|
||||
$('<span class="balance-area pull-right text-muted small">'
|
||||
+ (node.data.balance_in_account_currency ?
|
||||
(format_currency(Math.abs(node.data.balance_in_account_currency),
|
||||
node.data.account_currency) + " / ") : "")
|
||||
+ format_currency(Math.abs(node.data.balance), node.data.company_currency)
|
||||
+ " " + dr_or_cr
|
||||
+ '</span>').insertBefore(node.$ul);
|
||||
}
|
||||
}
|
||||
},
|
||||
toolbar: [
|
||||
|
||||
@@ -287,6 +287,95 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "print_settings",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Settings",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "show_inclusive_tax_in_print",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Show Inclusive Tax In Print",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_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,
|
||||
@@ -422,7 +511,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-25 13:28:05.067615",
|
||||
"modified": "2018-01-05 15:26:10.357085",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1476,7 +1476,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-11 17:30:45.198147",
|
||||
"modified": "2018-01-03 17:30:45.198147",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
||||
@@ -63,7 +63,11 @@ class POSProfile(Document):
|
||||
|
||||
if len(default_mode_of_payment) > 1:
|
||||
frappe.throw(_("Multiple default mode of payment is not allowed"))
|
||||
|
||||
def validate_customer_territory_group(self):
|
||||
if not frappe.db.get_single_value('POS Settings', 'use_pos_in_offline_mode'):
|
||||
return
|
||||
|
||||
if not self.territory:
|
||||
frappe.throw(_("Territory is Required in POS Profile"), title="Mandatory Field")
|
||||
|
||||
@@ -103,7 +107,7 @@ def get_item_groups(pos_profile):
|
||||
if pos_profile.get('item_groups'):
|
||||
# Get items based on the item groups defined in the POS profile
|
||||
for data in pos_profile.get('item_groups'):
|
||||
item_groups.extend(["'%s'"%d.name for d in get_child_nodes('Item Group', data.item_group)])
|
||||
item_groups.extend(["'%s'" % frappe.db.escape(d.name) for d in get_child_nodes('Item Group', data.item_group)])
|
||||
|
||||
return list(set(item_groups))
|
||||
|
||||
|
||||
@@ -277,6 +277,8 @@ class PurchaseInvoice(BuyingController):
|
||||
.format(item.purchase_receipt))
|
||||
|
||||
def on_submit(self):
|
||||
super(PurchaseInvoice, self).on_submit()
|
||||
|
||||
self.check_prev_docstatus()
|
||||
self.update_status_updater_args()
|
||||
|
||||
@@ -606,6 +608,8 @@ class PurchaseInvoice(BuyingController):
|
||||
))
|
||||
|
||||
def on_cancel(self):
|
||||
super(PurchaseInvoice, self).on_cancel()
|
||||
|
||||
self.check_for_closed_status()
|
||||
|
||||
self.update_status_updater_args()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
QUnit.module('Purchase Invoice');
|
||||
|
||||
QUnit.test("test purchase invoice", function(assert) {
|
||||
assert.expect(6);
|
||||
assert.expect(9);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
@@ -18,7 +18,7 @@ QUnit.test("test purchase invoice", function(assert) {
|
||||
{update_stock:1},
|
||||
{supplier_address: 'Test1-Billing'},
|
||||
{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'},
|
||||
{terms: 'This is Test'},
|
||||
{payment_terms_template: '_Test Payment Term Template UI'}
|
||||
@@ -29,7 +29,7 @@ QUnit.test("test purchase invoice", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||
// 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");
|
||||
// grand_total Calculated
|
||||
@@ -39,6 +39,33 @@ QUnit.test("test purchase invoice", function(assert) {
|
||||
assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty");
|
||||
|
||||
},
|
||||
() => {
|
||||
let date = cur_frm.doc.due_date;
|
||||
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||
frappe.timeout(0.5);
|
||||
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.tests.set_form_values(cur_frm, [{'payment_terms_schedule': ''}]),
|
||||
() => {
|
||||
let date = cur_frm.doc.due_date;
|
||||
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||
frappe.timeout(0.5);
|
||||
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.tests.set_form_values(cur_frm, [{'payment_schedule': []}]),
|
||||
() => {
|
||||
let date = cur_frm.doc.due_date;
|
||||
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||
frappe.timeout(0.5);
|
||||
assert.ok(!cur_dialog, 'Message is not shown');
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from erpnext.accounts.doctype.sales_taxes_and_charges_template.sales_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):
|
||||
def validate(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)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
QUnit.module('Sales Taxes and Charges Template');
|
||||
|
||||
QUnit.test("test sales taxes and charges template", function(assert) {
|
||||
assert.expect(1);
|
||||
assert.expect(2);
|
||||
let done = assert.async();
|
||||
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()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice", function(assert) {
|
||||
assert.expect(6);
|
||||
assert.expect(9);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'},
|
||||
{payment_terms_template: '_Test Payment Term Template UI'}
|
||||
@@ -28,7 +28,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||
// 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");
|
||||
// grand_total Calculated
|
||||
@@ -38,6 +38,33 @@ QUnit.test("test sales Invoice", function(assert) {
|
||||
assert.ok(cur_frm.doc.payment_schedule.length > 0, "Payment Term Schedule is not empty");
|
||||
|
||||
},
|
||||
() => {
|
||||
let date = cur_frm.doc.due_date;
|
||||
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||
frappe.timeout(0.5);
|
||||
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.tests.set_form_values(cur_frm, [{'payment_terms_schedule': ''}]),
|
||||
() => {
|
||||
let date = cur_frm.doc.due_date;
|
||||
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||
frappe.timeout(0.5);
|
||||
assert.ok(cur_dialog && cur_dialog.is_visible, 'Message is displayed to user');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.tests.set_form_values(cur_frm, [{'payment_schedule': []}]),
|
||||
() => {
|
||||
let date = cur_frm.doc.due_date;
|
||||
frappe.tests.set_control('due_date', frappe.datetime.add_days(date, 1));
|
||||
frappe.timeout(0.5);
|
||||
assert.ok(!cur_dialog, 'Message is not shown');
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
@@ -27,7 +27,7 @@ QUnit.test("test sales Invoice", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||
// 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");
|
||||
// grand_total Calculated
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with payment", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'},
|
||||
{payment_terms_template: '_Test Payment Term Template UI'}
|
||||
@@ -28,7 +28,7 @@ QUnit.test("test sales Invoice with payment", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with payment request", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
@@ -27,7 +27,7 @@ QUnit.test("test sales Invoice with payment request", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test sales Invoice with serialize item", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
@@ -27,7 +27,7 @@ QUnit.test("test sales Invoice with serialize item", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
|
||||
// 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
|
||||
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
|
||||
|
||||
@@ -11,7 +11,12 @@ from erpnext.controllers.accounts_controller import validate_taxes_and_charges,
|
||||
class SalesTaxesandChargesTemplate(Document):
|
||||
def validate(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):
|
||||
for data in self.taxes:
|
||||
if data.charge_type == 'On Net Total' and flt(data.rate) == 0.0:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
QUnit.module('Sales Taxes and Charges Template');
|
||||
|
||||
QUnit.test("test sales taxes and charges template", function(assert) {
|
||||
assert.expect(1);
|
||||
assert.expect(2);
|
||||
let done = assert.async();
|
||||
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()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"doctype": "Tax Rule",
|
||||
"tax_type" : "Sales",
|
||||
"sales_tax_template": "_Test Tax 1",
|
||||
"sales_tax_template": "_Test Tax 1 - _TC",
|
||||
"use_for_shopping_cart": 1,
|
||||
"billing_city": "_Test City",
|
||||
"billing_state": "Test State",
|
||||
@@ -15,7 +15,7 @@
|
||||
{
|
||||
"doctype": "Tax Rule",
|
||||
"tax_type" : "Sales",
|
||||
"sales_tax_template": "_Test Tax 2",
|
||||
"sales_tax_template": "_Test Tax 2 - _TC",
|
||||
"use_for_shopping_cart": 0,
|
||||
"billing_city": "_Test City",
|
||||
"billing_country": "India",
|
||||
|
||||
@@ -18,40 +18,40 @@ class TestTaxRule(unittest.TestCase):
|
||||
|
||||
def test_conflict(self):
|
||||
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_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)
|
||||
|
||||
def test_conflict_with_non_overlapping_dates(self):
|
||||
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_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()
|
||||
self.assertTrue(tax_rule2.name)
|
||||
|
||||
def test_for_parent_customer_group(self):
|
||||
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()
|
||||
|
||||
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):
|
||||
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_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)
|
||||
|
||||
@@ -62,66 +62,66 @@ class TestTaxRule(unittest.TestCase):
|
||||
|
||||
def test_select_tax_rule_based_on_customer(self):
|
||||
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",
|
||||
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",
|
||||
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"}),
|
||||
"_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):
|
||||
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",
|
||||
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"}),
|
||||
"_Test Sales Taxes and Charges Template")
|
||||
"_Test Sales Taxes and Charges Template - _TC")
|
||||
|
||||
def test_select_tax_rule_based_on_state_match(self):
|
||||
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",
|
||||
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"}),
|
||||
"_Test Sales Taxes and Charges Template")
|
||||
"_Test Sales Taxes and Charges Template - _TC")
|
||||
|
||||
def test_select_tax_rule_based_on_better_priority(self):
|
||||
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",
|
||||
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"}),
|
||||
"_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):
|
||||
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",
|
||||
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"}),
|
||||
None)
|
||||
|
||||
def test_select_tax_rule_based_cross_partially_keys(self):
|
||||
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",
|
||||
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"}),
|
||||
"_Test Sales Taxes and Charges Template 1")
|
||||
"_Test Sales Taxes and Charges Template 1 - _TC")
|
||||
|
||||
|
||||
def make_tax_rule(**args):
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"font": "Default",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||
"idx": 0,
|
||||
"line_breaks": 0,
|
||||
"modified": "2017-12-15 11:57:11.712191",
|
||||
"modified": "2018-01-05 17:25:59.181985",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GST POS Invoice",
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
{
|
||||
"align_labels_right": 0,
|
||||
"creation": "2011-12-21 11:08:55",
|
||||
"custom_format": 1,
|
||||
"disabled": 0,
|
||||
"doc_type": "Sales Invoice",
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n{% if doc.get(\"taxes\", filters={\"included_in_print_rate\": 1}) %}\n<hr>\n<p><b>Taxes Included:</b></p>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount_after_discount_amount\", doc) }}\n\t\t\t</td>\n\t\t<tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n{%- endif -%}\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{{ doc.select_print_heading or _(\"Invoice\") }}<br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t<b>{{ _(\"Customer\") }}:</b> {{ doc.customer_name }}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.get_formatted(\"rate\") }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t{% if doc.flags.show_inclusive_tax_in_print %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total Excl. Tax\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"net_total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% else %}\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ _(\"Total\") }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }}\n\t\t\t\t</td>\n\t\t\t{% endif %}\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t {%- if not row.included_in_print_rate or doc.flags.show_inclusive_tax_in_print -%}\n\t\t\t<tr>\n\t\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t\t{{ row.description }}\n\t\t\t\t</td>\n\t\t\t\t<td class=\"text-right\">\n\t\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t\t</td>\n\t\t\t<tr>\n\t\t {%- endif -%}\n\t\t{%- endfor -%}\n\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<hr>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||
"idx": 1,
|
||||
"modified": "2015-04-21 05:06:29.380856",
|
||||
"line_breaks": 0,
|
||||
"modified": "2018-01-05 17:23:40.403289",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Invoice",
|
||||
"owner": "Administrator",
|
||||
"print_format_builder": 0,
|
||||
"print_format_type": "Server",
|
||||
"show_section_headings": 0,
|
||||
"standard": "Yes"
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
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
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -188,10 +189,10 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
tuple([doctype] + invoice_item_row.keys()))
|
||||
|
||||
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:
|
||||
# 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(handle_html(description))
|
||||
tax_columns.append(description)
|
||||
|
||||
if item_wise_tax_detail:
|
||||
try:
|
||||
|
||||
@@ -66,12 +66,12 @@ def get_mode_of_payments(filters):
|
||||
invoice_list = get_invoices(filters)
|
||||
invoice_list_names = ",".join(['"' + invoice['name'] + '"' for invoice in invoice_list])
|
||||
if invoice_list:
|
||||
inv_mop = frappe.db.sql("""select a.owner,a.posting_date,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
|
||||
where a.name = b.parent
|
||||
and a.name in ({invoice_list_names})
|
||||
union
|
||||
select a.owner,a.posting_date,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
|
||||
where a.name = c.reference_name
|
||||
and b.name = c.parent
|
||||
|
||||
@@ -252,6 +252,9 @@ def add_ac(args=None):
|
||||
if not ac.parent_account:
|
||||
ac.parent_account = args.get("parent")
|
||||
|
||||
if ac.is_root:
|
||||
ac.parent_account=''
|
||||
|
||||
ac.old_parent = ""
|
||||
ac.freeze_account = "No"
|
||||
if cint(ac.get("is_root")):
|
||||
|
||||
@@ -25,7 +25,7 @@ erpnext.crop.update_item_rate_uom = function(frm, cdt, cdn) {
|
||||
let material_list = ['materials_required', 'produce', 'byproducts'];
|
||||
material_list.forEach((material) => {
|
||||
frm.doc[material].forEach((item, index) => {
|
||||
if (item.name == cdn){
|
||||
if (item.name == cdn && item.item_code){
|
||||
frappe.call({
|
||||
method:'erpnext.agriculture.doctype.crop.crop.get_item_details',
|
||||
args: {
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2015-08-25 04:55:06.052342",
|
||||
"modified": "2017-12-27 15:20:06.052342",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Buying Settings",
|
||||
|
||||
@@ -21,22 +21,17 @@ frappe.ui.form.on("Purchase Order", {
|
||||
return erpnext.queries.warehouse(frm.doc);
|
||||
});
|
||||
|
||||
frappe.db.get_value('Buying Settings', {name: 'Buying Settings'}, 'disable_fetch_last_purchase_rate', (r) => {
|
||||
value = r && cint(r.disable_fetch_last_purchase_rate);
|
||||
frm.toggle_display('get_last_purchase_rate', !value);
|
||||
});
|
||||
|
||||
frm.set_indicator_formatter('item_code',
|
||||
function(doc) { return (doc.qty<=doc.received_qty) ? "green" : "orange" })
|
||||
},
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Purchase Order Item", {
|
||||
item_code: function(frm) {
|
||||
frappe.call({
|
||||
method: "get_last_purchase_rate",
|
||||
doc: frm.doc,
|
||||
callback: function(r, rt) {
|
||||
frm.trigger('calculate_taxes_and_totals');
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
schedule_date: function(frm, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
if (row.schedule_date) {
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "{supplier_name}",
|
||||
@@ -292,40 +292,40 @@
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fieldname": "schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reqd By Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"fieldname": "schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reqd By Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1238,6 +1238,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
|
||||
"fieldname": "get_last_purchase_rate",
|
||||
"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 last purchase rate",
|
||||
"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,
|
||||
@@ -3260,9 +3291,9 @@
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-19 14:53:03.986840",
|
||||
"modified_by": "nabinhait@gmail.com",
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-21 14:45:34.140128",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
"owner": "Administrator",
|
||||
|
||||
@@ -11,8 +11,7 @@ from erpnext.controllers.buying_controller import BuyingController
|
||||
from erpnext.stock.doctype.item.item import get_last_purchase_details
|
||||
from erpnext.stock.stock_balance import update_bin_qty, get_ordered_qty
|
||||
from frappe.desk.notifications import clear_doctype_notifications
|
||||
from erpnext.buying.utils import (validate_for_items, check_for_closed_status,
|
||||
update_last_purchase_rate)
|
||||
from erpnext.buying.utils import validate_for_items, check_for_closed_status
|
||||
|
||||
|
||||
form_grid_templates = {
|
||||
@@ -112,27 +111,26 @@ class PurchaseOrder(BuyingController):
|
||||
|
||||
def get_last_purchase_rate(self):
|
||||
"""get last purchase rates for all items"""
|
||||
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||
|
||||
if not cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")):
|
||||
conversion_rate = flt(self.get('conversion_rate')) or 1.0
|
||||
conversion_rate = flt(self.get('conversion_rate')) or 1.0
|
||||
for d in self.get("items"):
|
||||
if d.item_code:
|
||||
last_purchase_details = get_last_purchase_details(d.item_code, self.name)
|
||||
if last_purchase_details:
|
||||
d.base_price_list_rate = (last_purchase_details['base_price_list_rate'] *
|
||||
(flt(d.conversion_factor) or 1.0))
|
||||
d.discount_percentage = last_purchase_details['discount_percentage']
|
||||
d.base_rate = last_purchase_details['base_rate'] * (flt(d.conversion_factor) or 1.0)
|
||||
d.price_list_rate = d.base_price_list_rate / conversion_rate
|
||||
d.rate = d.base_rate / conversion_rate
|
||||
d.last_purchase_rate = d.rate
|
||||
else:
|
||||
|
||||
for d in self.get("items"):
|
||||
if d.item_code:
|
||||
last_purchase_details = get_last_purchase_details(d.item_code, self.name)
|
||||
|
||||
if last_purchase_details:
|
||||
d.base_price_list_rate = (last_purchase_details['base_price_list_rate'] *
|
||||
(flt(d.conversion_factor) or 1.0))
|
||||
d.discount_percentage = last_purchase_details['discount_percentage']
|
||||
d.base_rate = last_purchase_details['base_rate'] * (flt(d.conversion_factor) or 1.0)
|
||||
d.price_list_rate = d.base_price_list_rate / conversion_rate
|
||||
d.last_purchase_rate = d.base_rate / conversion_rate
|
||||
else:
|
||||
|
||||
item_last_purchase_rate = frappe.db.get_value("Item", d.item_code, "last_purchase_rate")
|
||||
if item_last_purchase_rate:
|
||||
d.base_price_list_rate = d.base_rate = d.price_list_rate \
|
||||
= d.last_purchase_rate = item_last_purchase_rate
|
||||
item_last_purchase_rate = frappe.db.get_value("Item", d.item_code, "last_purchase_rate")
|
||||
if item_last_purchase_rate:
|
||||
d.base_price_list_rate = d.base_rate = d.price_list_rate \
|
||||
= d.rate = d.last_purchase_rate = item_last_purchase_rate
|
||||
|
||||
# Check for Closed status
|
||||
def check_for_closed_status(self):
|
||||
@@ -189,6 +187,8 @@ class PurchaseOrder(BuyingController):
|
||||
clear_doctype_notifications(self)
|
||||
|
||||
def on_submit(self):
|
||||
super(PurchaseOrder, self).on_submit()
|
||||
|
||||
if self.is_against_so():
|
||||
self.update_status_updater()
|
||||
|
||||
@@ -199,9 +199,9 @@ class PurchaseOrder(BuyingController):
|
||||
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||
self.company, self.base_grand_total)
|
||||
|
||||
update_last_purchase_rate(self, is_submit = 1)
|
||||
|
||||
def on_cancel(self):
|
||||
super(PurchaseOrder, self).on_cancel()
|
||||
|
||||
if self.is_against_so():
|
||||
self.update_status_updater()
|
||||
|
||||
@@ -218,8 +218,6 @@ class PurchaseOrder(BuyingController):
|
||||
self.update_requested_qty()
|
||||
self.update_ordered_qty()
|
||||
|
||||
update_last_purchase_rate(self, is_submit = 0)
|
||||
|
||||
def on_update(self):
|
||||
pass
|
||||
|
||||
@@ -257,6 +255,21 @@ class PurchaseOrder(BuyingController):
|
||||
if item.delivered_by_supplier == 1:
|
||||
item.received_qty = item.qty
|
||||
|
||||
def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0):
|
||||
"""get last purchase rate for an item"""
|
||||
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||
|
||||
conversion_rate = flt(conversion_rate) or 1.0
|
||||
|
||||
last_purchase_details = get_last_purchase_details(item_code, name)
|
||||
if last_purchase_details:
|
||||
last_purchase_rate = (last_purchase_details['base_rate'] * (flt(conversion_factor) or 1.0)) / conversion_rate
|
||||
return last_purchase_rate
|
||||
else:
|
||||
item_last_purchase_rate = frappe.db.get_value("Item", item_code, "last_purchase_rate")
|
||||
if item_last_purchase_rate:
|
||||
return item_last_purchase_rate
|
||||
|
||||
@frappe.whitelist()
|
||||
def close_or_unclose_purchase_orders(names, status):
|
||||
if not frappe.has_permission("Purchase Order", "write"):
|
||||
|
||||
@@ -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'}
|
||||
]);
|
||||
},
|
||||
|
||||
|
||||
@@ -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'))},
|
||||
]
|
||||
]},
|
||||
{taxes_and_charges:'TEST In State GST'},
|
||||
{taxes_and_charges:'TEST In State GST - FT'},
|
||||
]);
|
||||
},
|
||||
() => {supplier_quotation_name = cur_frm.doc.name;},
|
||||
|
||||
@@ -375,6 +375,17 @@ class AccountsController(TransactionBase):
|
||||
|
||||
return res
|
||||
|
||||
def is_inclusive_tax(self):
|
||||
is_inclusive = cint(frappe.db.get_single_value("Accounts Settings",
|
||||
"show_inclusive_tax_in_print"))
|
||||
|
||||
if is_inclusive:
|
||||
is_inclusive = 0
|
||||
if self.get("taxes", filters={"included_in_print_rate": 1}):
|
||||
is_inclusive = 1
|
||||
|
||||
return is_inclusive
|
||||
|
||||
def validate_advance_entries(self):
|
||||
order_field = "sales_order" if self.doctype == "Sales Invoice" else "purchase_order"
|
||||
order_list = list(set([d.get(order_field)
|
||||
|
||||
@@ -8,7 +8,7 @@ from frappe.utils import flt,cint, cstr, getdate
|
||||
|
||||
from erpnext.accounts.party import get_party_details
|
||||
from erpnext.stock.get_item_details import get_conversion_factor
|
||||
from erpnext.buying.utils import validate_for_items
|
||||
from erpnext.buying.utils import validate_for_items, update_last_purchase_rate
|
||||
from erpnext.stock.stock_ledger import get_valuation_rate
|
||||
|
||||
from erpnext.controllers.stock_controller import StockController
|
||||
@@ -18,7 +18,10 @@ class BuyingController(StockController):
|
||||
if hasattr(self, "taxes"):
|
||||
self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
|
||||
"print_taxes_with_zero_amount"))
|
||||
self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax()
|
||||
|
||||
self.print_templates = {
|
||||
"total": "templates/print_formats/includes/total.html",
|
||||
"taxes": "templates/print_formats/includes/taxes.html"
|
||||
}
|
||||
|
||||
@@ -409,6 +412,18 @@ class BuyingController(StockController):
|
||||
"actual_qty": -1*flt(d.consumed_qty),
|
||||
}))
|
||||
|
||||
def on_submit(self):
|
||||
if self.get('is_return'):
|
||||
return
|
||||
|
||||
update_last_purchase_rate(self, is_submit = 1)
|
||||
|
||||
def on_cancel(self):
|
||||
if self.get('is_return'):
|
||||
return
|
||||
|
||||
update_last_purchase_rate(self, is_submit = 0)
|
||||
|
||||
def validate_schedule_date(self):
|
||||
if not self.schedule_date:
|
||||
self.schedule_date = min([d.schedule_date for d in self.get("items")])
|
||||
@@ -418,8 +433,9 @@ class BuyingController(StockController):
|
||||
if not d.schedule_date:
|
||||
d.schedule_date = self.schedule_date
|
||||
|
||||
if d.schedule_date and getdate(d.schedule_date) < getdate(self.transaction_date):
|
||||
frappe.throw(_("Expected Date cannot be before Transaction Date"))
|
||||
if (d.schedule_date and self.transaction_date and
|
||||
getdate(d.schedule_date) < getdate(self.transaction_date)):
|
||||
frappe.throw(_("Row #{0}: Reqd by Date cannot be before Transaction Date").format(d.idx))
|
||||
else:
|
||||
frappe.throw(_("Please enter Schedule Date"))
|
||||
frappe.throw(_("Please enter Reqd by Date"))
|
||||
|
||||
|
||||
@@ -16,7 +16,10 @@ class SellingController(StockController):
|
||||
if hasattr(self, "taxes"):
|
||||
self.flags.print_taxes_with_zero_amount = cint(frappe.db.get_single_value("Print Settings",
|
||||
"print_taxes_with_zero_amount"))
|
||||
self.flags.show_inclusive_tax_in_print = self.is_inclusive_tax()
|
||||
|
||||
self.print_templates = {
|
||||
"total": "templates/print_formats/includes/total.html",
|
||||
"taxes": "templates/print_formats/includes/taxes.html"
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ class Lead(SellingController):
|
||||
|
||||
def set_lead_name(self):
|
||||
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()
|
||||
def make_customer(source_name, target_doc=None):
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"email_id": "test_lead4@example.com",
|
||||
"organization_lead": 1,
|
||||
"lead_name": "_Test Lead 4",
|
||||
"organization_name": "_Test Lead 4",
|
||||
"company_name": "_Test Lead 4",
|
||||
"status": "Open"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
# 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">
|
||||
|
||||
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">
|
||||
|
||||
**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}
|
||||
@@ -1,11 +1,19 @@
|
||||
// Copyright (c) 2016, Frappe and contributors
|
||||
// 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", {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("student", "title", "student_name");
|
||||
frm.add_fetch("student_applicant", "title", "student_name");
|
||||
},
|
||||
|
||||
"refresh": function(frm) {
|
||||
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) {
|
||||
@@ -18,7 +26,7 @@ frappe.ui.form.on("Program Enrollment Tool", {
|
||||
frm.set_value("students", r.message);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
"enroll_students": function(frm) {
|
||||
@@ -27,7 +35,8 @@ frappe.ui.form.on("Program Enrollment Tool", {
|
||||
doc:frm.doc,
|
||||
callback: function(r) {
|
||||
frm.set_value("students", []);
|
||||
frappe.hide_msgprint(true);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"label": "Get Students From",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nStudent Applicants\nProgram Enrollments",
|
||||
"options": "\nStudent Applicant\nProgram Enrollment",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -73,6 +73,67 @@
|
||||
"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": "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_on_submit": 0,
|
||||
@@ -110,8 +171,8 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "get_students",
|
||||
"fieldtype": "Button",
|
||||
"fieldname": "academic_term",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -119,9 +180,10 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Get Students",
|
||||
"label": "Academic Term",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Academic Term",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -163,6 +225,36 @@
|
||||
"set_only_once": 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_on_submit": 0,
|
||||
@@ -209,6 +301,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Enrollment Details",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@@ -229,7 +322,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.get_students_from==\"Program Enrollments\"",
|
||||
"depends_on": "eval:doc.get_students_from==\"Program Enrollment\"",
|
||||
"fieldname": "new_program",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -261,8 +354,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.get_students_from==\"Program Enrollments\"",
|
||||
"fieldname": "new_academic_year",
|
||||
"fieldname": "new_student_batch",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -271,10 +363,10 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "New Academic Year",
|
||||
"label": "New Student Batch",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Academic Year",
|
||||
"options": "Student Batch Name",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -316,6 +408,99 @@
|
||||
"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_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,
|
||||
@@ -328,7 +513,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-27 09:35:45.002469",
|
||||
"modified": "2018-01-02 11:59:40.230689",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program Enrollment Tool",
|
||||
|
||||
@@ -17,21 +17,26 @@ class ProgramEnrollmentTool(Document):
|
||||
elif not self.academic_year:
|
||||
frappe.throw(_("Mandatory field - Academic Year"))
|
||||
else:
|
||||
if self.get_students_from == "Student Applicants":
|
||||
students = frappe.db.sql("select name as student_applicant, title as student_name from \
|
||||
`tabStudent Applicant` where program = %s and academic_year = %s",(self.program, self.academic_year), as_dict=1)
|
||||
else:
|
||||
students = frappe.db.sql("select student, student_name, student_batch_name from \
|
||||
`tabProgram Enrollment` where program = %s and academic_year = %s",(self.program, self.academic_year), as_dict=1)
|
||||
condition = 'and academic_term=%(academic_term)s' if self.academic_term else " "
|
||||
if self.get_students_from == "Student Applicant":
|
||||
students = frappe.db.sql('''select name as student_applicant, title as student_name from `tabStudent Applicant`
|
||||
where application_status="Approved" and program=%(program)s and academic_year=%(academic_year)s {0}'''
|
||||
.format(condition), self.as_dict(), as_dict=1)
|
||||
elif self.get_students_from == "Program Enrollment":
|
||||
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('''
|
||||
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)
|
||||
|
||||
inactive_students = frappe.db.sql('''
|
||||
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)
|
||||
|
||||
for student in students:
|
||||
if student.student in [d.student for d in inactive_students]:
|
||||
students.remove(student)
|
||||
for student in students:
|
||||
if student.student in [d.student for d in inactive_students]:
|
||||
students.remove(student)
|
||||
|
||||
if students:
|
||||
return students
|
||||
@@ -39,18 +44,22 @@ class ProgramEnrollmentTool(Document):
|
||||
frappe.throw(_("No students Found"))
|
||||
|
||||
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:
|
||||
prog_enrollment = frappe.new_doc("Program Enrollment")
|
||||
prog_enrollment.student = stud.student
|
||||
prog_enrollment.student_name = stud.student_name
|
||||
prog_enrollment.student_batch_name = stud.student_batch_name
|
||||
prog_enrollment.program = self.new_program
|
||||
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()
|
||||
elif stud.student_applicant:
|
||||
prog_enrollment = enroll_student(stud.student_applicant)
|
||||
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()
|
||||
frappe.msgprint("Students have been enrolled.")
|
||||
|
||||
frappe.msgprint("{0} Students have been enrolled.".format(total))
|
||||
|
||||
@@ -133,6 +133,37 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 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,
|
||||
@@ -145,7 +176,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:09:59.530615",
|
||||
"modified": "2018-01-02 12:03:53.890741",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program Enrollment Tool Student",
|
||||
|
||||
@@ -320,6 +320,37 @@
|
||||
"set_only_once": 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_on_submit": 0,
|
||||
@@ -1058,7 +1089,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-11-10 19:08:55.049625",
|
||||
"modified": "2018-01-02 11:47:14.944338",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student Applicant",
|
||||
|
||||
@@ -262,27 +262,30 @@ frappe.ui.form.on("Expense Claim", {
|
||||
},
|
||||
|
||||
get_advances: function(frm) {
|
||||
return frappe.call({
|
||||
method: "erpnext.hr.doctype.expense_claim.expense_claim.get_advances",
|
||||
args: {
|
||||
employee: frm.doc.employee
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
frappe.model.clear_table(frm.doc, "advances");
|
||||
if(r.message) {
|
||||
$.each(r.message, function(i, d) {
|
||||
var row = frappe.model.add_child(frm.doc, "Expense Claim Advance", "advances");
|
||||
row.employee_advance = d.name;
|
||||
row.posting_date = d.posting_date;
|
||||
row.advance_account = d.advance_account;
|
||||
row.advance_paid = d.paid_amount;
|
||||
row.unclaimed_amount = flt(d.paid_amount) - flt(d.claimed_amount);
|
||||
row.allocated_amount = flt(d.paid_amount) - flt(d.claimed_amount);
|
||||
});
|
||||
refresh_field("advances");
|
||||
frappe.model.clear_table(frm.doc, "advances");
|
||||
if (frm.doc.employee) {
|
||||
return frappe.call({
|
||||
method: "erpnext.hr.doctype.expense_claim.expense_claim.get_advances",
|
||||
args: {
|
||||
employee: frm.doc.employee
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
|
||||
if(r.message) {
|
||||
$.each(r.message, function(i, d) {
|
||||
var row = frappe.model.add_child(frm.doc, "Expense Claim Advance", "advances");
|
||||
row.employee_advance = d.name;
|
||||
row.posting_date = d.posting_date;
|
||||
row.advance_account = d.advance_account;
|
||||
row.advance_paid = d.paid_amount;
|
||||
row.unclaimed_amount = flt(d.paid_amount) - flt(d.claimed_amount);
|
||||
row.allocated_amount = flt(d.paid_amount) - flt(d.claimed_amount);
|
||||
});
|
||||
refresh_field("advances");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -591,7 +591,7 @@ def validate_bom_no(item, bom_no):
|
||||
frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_children(doctype, parent=None, is_tree=False):
|
||||
def get_children(doctype, parent=None, is_root=False, **filters):
|
||||
if not parent:
|
||||
frappe.msgprint(_('Please select a BOM'))
|
||||
return
|
||||
|
||||
@@ -226,6 +226,7 @@ frappe.ui.form.on("Production Order", {
|
||||
args: { production_item: frm.doc.production_item },
|
||||
callback: function(r) {
|
||||
frm.set_query("sales_order", function() {
|
||||
erpnext.in_production_item_onchange = true;
|
||||
return {
|
||||
filters: [
|
||||
["Sales Order","name", "in", r.message]
|
||||
|
||||
@@ -478,7 +478,7 @@ erpnext.patches.v9_2.rename_net_weight_in_item_master
|
||||
erpnext.patches.v9_2.delete_process_payroll
|
||||
erpnext.patches.v10_0.add_agriculture_domain
|
||||
erpnext.patches.v10_0.add_non_profit_domain
|
||||
erpnext.patches.v10_0.setup_vat_for_uae_and_saudi_arabia #2017-12-27
|
||||
erpnext.patches.v10_0.setup_vat_for_uae_and_saudi_arabia #2017-12-28
|
||||
erpnext.patches.v10_0.set_primary_contact_for_customer
|
||||
erpnext.patches.v10_0.copy_projects_renamed_fields
|
||||
erpnext.patches.v10_0.enabled_regional_print_format_based_on_country
|
||||
|
||||
@@ -228,7 +228,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
erpnext.hide_company();
|
||||
this.set_dynamic_labels();
|
||||
this.setup_sms();
|
||||
|
||||
},
|
||||
|
||||
apply_default_taxes: function() {
|
||||
@@ -236,7 +235,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
var taxes_and_charges_field = frappe.meta.get_docfield(me.frm.doc.doctype, "taxes_and_charges",
|
||||
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({
|
||||
method: "erpnext.controllers.accounts_controller.get_default_taxes_and_charges",
|
||||
args: {
|
||||
@@ -521,6 +524,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
if(r.message) {
|
||||
me.frm.set_value("due_date", r.message);
|
||||
frappe.ui.form.trigger(me.frm.doc.doctype, "currency");
|
||||
me.recalculate_terms();
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -530,6 +534,54 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
},
|
||||
|
||||
due_date: function() {
|
||||
// due_date is to be changed, payment terms template and/or payment schedule must
|
||||
// be removed as due_date is automatically changed based on payment terms
|
||||
if (this.frm.doc.due_date) {
|
||||
if (this.frm.doc.payment_terms_template || this.frm.doc.payment_schedule.length) {
|
||||
var message1 = "";
|
||||
var message2 = "";
|
||||
var final_message = "Please clear the ";
|
||||
|
||||
if (this.frm.doc.payment_terms_template) {
|
||||
message1 = "selected Payment Terms Template";
|
||||
final_message = final_message + message1;
|
||||
}
|
||||
|
||||
if (this.frm.doc.payment_schedule.length) {
|
||||
message2 = "Payment Schedule Table";
|
||||
if (message1.length !== 0) message2 = " and " + message2;
|
||||
final_message = final_message + message2;
|
||||
}
|
||||
|
||||
frappe.msgprint(final_message);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
recalculate_terms: function() {
|
||||
const doc = this.frm.doc;
|
||||
|
||||
if (doc.payment_terms_template) {
|
||||
this.payment_terms_template();
|
||||
} else if (doc.payment_schedule) {
|
||||
const me = this;
|
||||
doc.payment_schedule.forEach(
|
||||
function(term) {
|
||||
if (term.payment_term) {
|
||||
me.payment_term(doc, term.doctype, term.name);
|
||||
} else {
|
||||
frappe.model.set_value(
|
||||
term.doctype, term.name, 'due_date',
|
||||
doc.posting_date || doc.transaction_date
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
get_company_currency: function() {
|
||||
return erpnext.get_currency(this.frm.doc.company);
|
||||
},
|
||||
|
||||
@@ -56,8 +56,11 @@ def make_custom_fields():
|
||||
dict(fieldname='total_amount', label='Total Amount',
|
||||
fieldtype='Currency', insert_after='tax_amount',
|
||||
print_hide=1, hidden=1, read_only=1, options="currency"),
|
||||
]
|
||||
|
||||
delivery_date_field = [
|
||||
dict(fieldname='delivery_date', label='Delivery Date',
|
||||
fieldtype='Date', insert_after='item_name', print_hide=1),
|
||||
fieldtype='Date', insert_after='item_name', print_hide=1)
|
||||
]
|
||||
|
||||
custom_fields = {
|
||||
@@ -74,9 +77,19 @@ def make_custom_fields():
|
||||
fieldtype='Data', insert_after='supplier_name'),
|
||||
],
|
||||
'Purchase Invoice': purchase_invoice_fields + invoice_fields,
|
||||
'Purchase Order': purchase_invoice_fields + invoice_fields,
|
||||
'Purchase Receipt': purchase_invoice_fields + invoice_fields,
|
||||
'Sales Invoice': sales_invoice_fields + invoice_fields,
|
||||
'Sales Invoice Item': invoice_item_fields,
|
||||
'Purchase Invoice Item': invoice_item_fields
|
||||
'Sales Order': sales_invoice_fields + invoice_fields,
|
||||
'Delivery Note': sales_invoice_fields + invoice_fields,
|
||||
'Sales Invoice Item': invoice_item_fields + delivery_date_field,
|
||||
'Purchase Invoice Item': invoice_item_fields,
|
||||
'Sales Order Item': invoice_item_fields,
|
||||
'Delivery Note Item': invoice_item_fields,
|
||||
'Quotation Item': invoice_item_fields,
|
||||
'Purchase Order Item': invoice_item_fields,
|
||||
'Purchase Receipt Item': invoice_item_fields,
|
||||
'Supplier Quotation Item': invoice_item_fields,
|
||||
}
|
||||
|
||||
create_custom_fields(custom_fields)
|
||||
|
||||
@@ -7,7 +7,9 @@ def update_itemised_tax_data(doc):
|
||||
itemised_tax = get_itemised_tax(doc.taxes)
|
||||
|
||||
for row in doc.items:
|
||||
tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
|
||||
tax_rate = 0.0
|
||||
if itemised_tax.get(row.item_code):
|
||||
tax_rate = sum([tax.get('tax_rate', 0) for d, tax in itemised_tax.get(row.item_code).items()])
|
||||
|
||||
row.tax_rate = flt(tax_rate, row.precision("tax_rate"))
|
||||
row.tax_amount = flt((row.net_amount * tax_rate) / 100, row.precision("net_amount"))
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test quotation with taxes and charges", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
@@ -27,7 +27,7 @@ QUnit.test("test quotation with taxes and charges", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
|
||||
// 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
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test sales order", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'},
|
||||
{payment_terms_template: '_Test Payment Term Template UI'}
|
||||
@@ -34,7 +34,7 @@ QUnit.test("test sales order", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 3', "Item name correct");
|
||||
// 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
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test sales order with taxes and charges", function(assert) {
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
@@ -27,7 +27,7 @@ QUnit.test("test sales order with taxes and charges", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
|
||||
// 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
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
|
||||
|
||||
@@ -320,7 +320,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
return new Promise((resolve) => {
|
||||
const on_submit = ({ pos_profile, set_as_default }) => {
|
||||
if (pos_profile) {
|
||||
this.frm.doc.pos_profile = pos_profile;
|
||||
this.pos_profile = pos_profile;
|
||||
}
|
||||
|
||||
if (set_as_default) {
|
||||
@@ -346,13 +346,19 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
}
|
||||
|
||||
on_change_pos_profile() {
|
||||
this.set_pos_profile_data()
|
||||
.then(() => {
|
||||
this.reset_cart();
|
||||
if (this.items) {
|
||||
this.items.reset_items();
|
||||
}
|
||||
});
|
||||
return frappe.run_serially([
|
||||
() => this.make_sales_invoice_frm(),
|
||||
() => {
|
||||
this.frm.doc.pos_profile = this.pos_profile;
|
||||
this.set_pos_profile_data()
|
||||
.then(() => {
|
||||
this.reset_cart();
|
||||
if (this.items) {
|
||||
this.items.reset_items();
|
||||
}
|
||||
});
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
get_promopt_fields() {
|
||||
@@ -360,6 +366,7 @@ erpnext.pos.PointOfSale = class PointOfSale {
|
||||
fieldtype: 'Link',
|
||||
label: __('POS Profile'),
|
||||
options: 'POS Profile',
|
||||
reqd: 1,
|
||||
get_query: () => {
|
||||
return {
|
||||
query: 'erpnext.accounts.doctype.pos_profile.pos_profile.pos_profile_query',
|
||||
@@ -1211,6 +1218,7 @@ class POSItems {
|
||||
return new Promise(res => {
|
||||
frappe.call({
|
||||
method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items",
|
||||
freeze: true,
|
||||
args: {
|
||||
start,
|
||||
page_length,
|
||||
|
||||
@@ -34,24 +34,52 @@ frappe.ui.form.on("Company", {
|
||||
|
||||
frm.add_custom_button(__('Cost Centers'), function() {
|
||||
frappe.set_route('Tree', 'Cost Center', {'company': frm.doc.name})
|
||||
})
|
||||
}, __("View"));
|
||||
|
||||
frm.add_custom_button(__('Chart of Accounts'), function() {
|
||||
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);
|
||||
|
||||
},
|
||||
|
||||
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) {
|
||||
if(frm.get_field("delete_company_transactions").$input)
|
||||
frm.get_field("delete_company_transactions").$input.addClass("btn-danger");
|
||||
},
|
||||
|
||||
country: function(frm) {
|
||||
erpnext.company.set_chart_of_accounts_options(frm.doc);
|
||||
},
|
||||
|
||||
delete_company_transactions: function(frm) {
|
||||
frappe.verify_password(function() {
|
||||
var d = frappe.prompt({
|
||||
|
||||
@@ -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)):
|
||||
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):
|
||||
for field in ["default_bank_account", "default_cash_account",
|
||||
"default_receivable_account", "default_payable_account",
|
||||
|
||||
@@ -82,7 +82,7 @@ def get_product_list_for_group(product_group=None, start=0, limit=10, search=Non
|
||||
|
||||
# base query
|
||||
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
|
||||
from `tabItem` I
|
||||
left join tabBin S on I.item_code = S.item_code and I.website_warehouse = S.warehouse
|
||||
|
||||
@@ -16,38 +16,44 @@ def create_sales_tax(args):
|
||||
tax_data.get('tax_rate'), sales_tax)
|
||||
|
||||
def make_tax_account_and_template(company, account_name, tax_rate, template_name=None):
|
||||
if not isinstance(account_name, (list, tuple)):
|
||||
account_name = [account_name]
|
||||
tax_rate = [tax_rate]
|
||||
|
||||
accounts = []
|
||||
for i, name in enumerate(account_name):
|
||||
tax_account = make_tax_account(company, account_name[i], tax_rate[i])
|
||||
if tax_account:
|
||||
accounts.append(tax_account)
|
||||
|
||||
try:
|
||||
if not isinstance(account_name, (list, tuple)):
|
||||
account_name = [account_name]
|
||||
tax_rate = [tax_rate]
|
||||
|
||||
accounts = []
|
||||
for i, name in enumerate(account_name):
|
||||
tax_account = make_tax_account(company, account_name[i], tax_rate[i])
|
||||
if tax_account:
|
||||
accounts.append(tax_account)
|
||||
|
||||
if accounts:
|
||||
make_sales_and_purchase_tax_templates(accounts, template_name)
|
||||
except frappe.NameError:
|
||||
pass
|
||||
frappe.message_log.pop()
|
||||
except RootNotEditable:
|
||||
pass
|
||||
|
||||
def make_tax_account(company, account_name, tax_rate):
|
||||
tax_group = get_tax_account_group(company)
|
||||
if tax_group:
|
||||
return frappe.get_doc({
|
||||
"doctype":"Account",
|
||||
"company": company,
|
||||
"parent_account": tax_group,
|
||||
"account_name": account_name,
|
||||
"is_group": 0,
|
||||
"report_type": "Balance Sheet",
|
||||
"root_type": "Liability",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": flt(tax_rate) if tax_rate else None
|
||||
}).insert(ignore_permissions=True, ignore_mandatory=True)
|
||||
try:
|
||||
return frappe.get_doc({
|
||||
"doctype":"Account",
|
||||
"company": company,
|
||||
"parent_account": tax_group,
|
||||
"account_name": account_name,
|
||||
"is_group": 0,
|
||||
"report_type": "Balance Sheet",
|
||||
"root_type": "Liability",
|
||||
"account_type": "Tax",
|
||||
"tax_rate": flt(tax_rate) if tax_rate else None
|
||||
}).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):
|
||||
if not template_name:
|
||||
@@ -62,7 +68,7 @@ def make_sales_and_purchase_tax_templates(accounts, template_name=None):
|
||||
|
||||
for account in accounts:
|
||||
sales_tax_template['taxes'].append({
|
||||
"category": "Valuation and Total",
|
||||
"category": "Total",
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": account.name,
|
||||
"description": "{0} @ {1}".format(account.account_name, account.tax_rate),
|
||||
|
||||
@@ -30,10 +30,10 @@ def get_product_info_for_website(item_code):
|
||||
product_info = {
|
||||
"price": price,
|
||||
"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,
|
||||
"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"]:
|
||||
|
||||
@@ -128,7 +128,7 @@ class TestShoppingCart(unittest.TestCase):
|
||||
"contact_email": frappe.session.user,
|
||||
"selling_price_list": "_Test Price List Rest of the World",
|
||||
"currency": "USD",
|
||||
"taxes_and_charges" : "_Test Tax 1",
|
||||
"taxes_and_charges" : "_Test Tax 1 - _TC",
|
||||
"conversion_rate":1,
|
||||
"transaction_date" : nowdate(),
|
||||
"valid_till" : add_months(nowdate(), 1),
|
||||
@@ -136,7 +136,7 @@ class TestShoppingCart(unittest.TestCase):
|
||||
"item_code": "_Test Item",
|
||||
"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"
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ QUnit.test("test delivery note", function(assert) {
|
||||
]},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{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'},
|
||||
{transporter_name:'TEST TRANSPORT'},
|
||||
{lr_no:'MH-04-FG 1111'}
|
||||
|
||||
@@ -137,10 +137,10 @@ class PackingSlip(Document):
|
||||
|
||||
for d in self.get("items"):
|
||||
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:
|
||||
d.net_weight = res["net_weight"]
|
||||
d.net_weight = res["weight_per_unit"]
|
||||
d.weight_uom = res["weight_uom"]
|
||||
|
||||
def get_recommended_case_no(self):
|
||||
|
||||
@@ -12,7 +12,7 @@ from frappe.utils import getdate
|
||||
from erpnext.controllers.buying_controller import BuyingController
|
||||
from erpnext.accounts.utils import get_account_currency
|
||||
from frappe.desk.notifications import clear_doctype_notifications
|
||||
from erpnext.buying.utils import check_for_closed_status, update_last_purchase_rate
|
||||
from erpnext.buying.utils import check_for_closed_status
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
@@ -111,6 +111,8 @@ class PurchaseReceipt(BuyingController):
|
||||
|
||||
# on submit
|
||||
def on_submit(self):
|
||||
super(PurchaseReceipt, self).on_submit()
|
||||
|
||||
# Check for Approving Authority
|
||||
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||
self.company, self.base_grand_total)
|
||||
@@ -119,9 +121,6 @@ class PurchaseReceipt(BuyingController):
|
||||
if self.per_billed < 100:
|
||||
self.update_billing_status()
|
||||
|
||||
if not self.is_return:
|
||||
update_last_purchase_rate(self, 1)
|
||||
|
||||
# Updating stock ledger should always be called after updating prevdoc status,
|
||||
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
||||
self.update_stock_ledger()
|
||||
@@ -140,6 +139,8 @@ class PurchaseReceipt(BuyingController):
|
||||
frappe.throw(_("Purchase Invoice {0} is already submitted").format(self.submit_rv[0][0]))
|
||||
|
||||
def on_cancel(self):
|
||||
super(PurchaseReceipt, self).on_cancel()
|
||||
|
||||
self.check_for_closed_status()
|
||||
# Check if Purchase Invoice has been submitted against current Purchase Order
|
||||
submitted = frappe.db.sql("""select t1.name
|
||||
@@ -152,9 +153,6 @@ class PurchaseReceipt(BuyingController):
|
||||
self.update_prevdoc_status()
|
||||
self.update_billing_status()
|
||||
|
||||
if not self.is_return:
|
||||
update_last_purchase_rate(self, 0)
|
||||
|
||||
# Updating stock ledger should always be called after updating prevdoc status,
|
||||
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
||||
self.update_stock_ledger()
|
||||
|
||||
@@ -17,7 +17,7 @@ QUnit.test("test Purchase Receipt", function(assert) {
|
||||
{'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'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
@@ -27,7 +27,7 @@ QUnit.test("test Purchase Receipt", function(assert) {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST - FT', "Tax details correct");
|
||||
// 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");
|
||||
// grand_total Calculated
|
||||
|
||||
@@ -23,7 +23,7 @@ def make_stock_entry(**args):
|
||||
|
||||
def process_serial_numbers(serial_nos_list):
|
||||
serial_nos_list = [
|
||||
'\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list)
|
||||
'\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list if serial_num.serial_no)
|
||||
]
|
||||
|
||||
uniques = list(set(serial_nos_list[0].split('\n')))
|
||||
|
||||
@@ -55,7 +55,9 @@ class StockReconciliation(StockController):
|
||||
|
||||
item.current_qty = qty
|
||||
item.current_valuation_rate = rate
|
||||
self.difference_amount += (flt(item.qty) * flt(item.valuation_rate or rate) - (flt(qty) * flt(rate)))
|
||||
self.difference_amount += (flt(item.qty, item.precision("qty")) * \
|
||||
flt(item.valuation_rate or rate, item.precision("valuation_rate")) \
|
||||
- flt(qty) * flt(rate))
|
||||
return True
|
||||
|
||||
items = filter(lambda d: _changed(d), self.items)
|
||||
@@ -197,8 +199,8 @@ class StockReconciliation(StockController):
|
||||
"company": self.company,
|
||||
"stock_uom": frappe.db.get_value("Item", row.item_code, "stock_uom"),
|
||||
"is_cancelled": "No",
|
||||
"qty_after_transaction": row.qty,
|
||||
"valuation_rate": row.valuation_rate
|
||||
"qty_after_transaction": flt(row.qty, row.precision("qty")),
|
||||
"valuation_rate": flt(row.valuation_rate, row.precision("valuation_rate"))
|
||||
})
|
||||
self.make_sl_entries([args])
|
||||
|
||||
@@ -242,7 +244,7 @@ class StockReconciliation(StockController):
|
||||
|
||||
def set_total_qty_and_amount(self):
|
||||
for d in self.get("items"):
|
||||
d.amount = flt(d.qty) * flt(d.valuation_rate)
|
||||
d.amount = flt(d.qty, d.precision("qty")) * flt(d.valuation_rate, d.precision("valuation_rate"))
|
||||
d.current_amount = flt(d.current_qty) * flt(d.current_valuation_rate)
|
||||
d.quantity_difference = flt(d.qty) - flt(d.current_qty)
|
||||
d.amount_difference = flt(d.amount) - flt(d.current_amount)
|
||||
|
||||
@@ -246,6 +246,7 @@ def get_basic_details(args, item):
|
||||
"is_fixed_asset": item.is_fixed_asset,
|
||||
"weight_per_unit":item.weight_per_unit,
|
||||
"weight_uom":item.weight_uom,
|
||||
"last_purchase_rate": item.last_purchase_rate if args.get("doctype") in ["Purchase Order"] else 0
|
||||
})
|
||||
|
||||
# calculate conversion factor
|
||||
@@ -258,6 +259,10 @@ def get_basic_details(args, item):
|
||||
args.conversion_factor = out.conversion_factor
|
||||
out.stock_qty = out.qty * out.conversion_factor
|
||||
|
||||
# calculate last purchase rate
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
|
||||
out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.item_code, out.conversion_factor)
|
||||
|
||||
# if default specified in item is for another company, fetch from company
|
||||
for d in [
|
||||
["Account", "income_account", "default_income_account"],
|
||||
|
||||
@@ -37,9 +37,10 @@ def get_item_price_qty_data(filters):
|
||||
from `tabItem Price` a left join `tabBin` b
|
||||
ON a.item_code = b.item_code
|
||||
{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)
|
||||
selling_price_map = get_selling_price_map(price_list_names)
|
||||
@@ -66,7 +67,8 @@ def get_buying_price_map(price_list_names):
|
||||
`tabItem Price`
|
||||
where
|
||||
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 = {}
|
||||
for d in buying_price:
|
||||
name = d["name"]
|
||||
@@ -84,7 +86,8 @@ def get_selling_price_map(price_list_names):
|
||||
`tabItem Price`
|
||||
where
|
||||
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 = {}
|
||||
for d in selling_price:
|
||||
name = d["name"]
|
||||
|
||||
@@ -64,7 +64,7 @@ frappe.ready(function() {
|
||||
// then chose the closest available one
|
||||
|
||||
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);
|
||||
|
||||
if (!item_code) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="product-image-img">
|
||||
{{ product_image_square(thumbnail or website_image) }}
|
||||
<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>
|
||||
{% else %}
|
||||
<div style='color: red'> <i class='fa fa-close'></i> {{ _("Not in stock") }}</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{{ render_discount_amount(doc) }}
|
||||
{%- endif -%}
|
||||
{%- for charge in data -%}
|
||||
{%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and not charge.included_in_print_rate -%}
|
||||
{%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
|
||||
<div class="row">
|
||||
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
|
||||
<label>{{ charge.get_formatted("description") }}</label></div>
|
||||
|
||||
15
erpnext/templates/print_formats/includes/total.html
Normal file
15
erpnext/templates/print_formats/includes/total.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<div class="row">
|
||||
{% if doc.flags.show_inclusive_tax_in_print %}
|
||||
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
|
||||
<label>{{ _("Total Excl. Tax") }}</label></div>
|
||||
<div class="col-xs-7 text-right">
|
||||
{{ doc.get_formatted("net_total", doc) }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
|
||||
<label>{{ _(doc.meta.get_label('total')) }}</label></div>
|
||||
<div class="col-xs-7 text-right">
|
||||
{{ doc.get_formatted("total", doc) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -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):
|
||||
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)
|
||||
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:
|
||||
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):
|
||||
template_item_code = frappe.db.get_value("Item", item_code, "variant_of")
|
||||
|
||||
Reference in New Issue
Block a user