Merge branch 'develop' into payment-terms

This commit is contained in:
tunde 2017-11-14 09:59:45 +01:00
commit ffa659fd2c
124 changed files with 5882 additions and 4171 deletions

View File

@ -132,6 +132,7 @@
"get_url_arg": true,
"get_server_fields": true,
"set_multiple": true,
"QUnit": true
"QUnit": true,
"Chart": true
}
}

View File

@ -4,7 +4,7 @@ import inspect
import frappe
from erpnext.hooks import regional_overrides
__version__ = '9.2.2'
__version__ = '9.2.11'
def get_default_company(user=None):
'''Get default company for user'''

View File

@ -205,12 +205,10 @@ class Account(Document):
return new_account
def after_rename(self, old, new, merge=False):
super(Account, self).after_rename(old, new, merge)
if not merge:
frappe.db.set_value("Account", new, "account_name",
" - ".join(new.split(" - ")[:-1]))
else:
from frappe.utils.nestedset import rebuild_tree
rebuild_tree("Account", "parent_account")
frappe.db.set_value("Account", new, "account_name", " - ".join(new.split(" - ")[:-1]))
def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select name from tabAccount

View File

@ -151,11 +151,14 @@ def restore_asset(asset_name):
asset.set_status()
@frappe.whitelist()
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
def get_gl_entries_on_asset_disposal(asset, is_sale=False):
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
expense_account, cost_center = get_disposal_account_and_cost_center(asset.company)
if is_sale:
expense_account = depr_expense_account
gl_entries = [
{
"account": fixed_asset_account,
@ -169,14 +172,12 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
}
]
profit_amount = flt(selling_amount) - flt(asset.value_after_depreciation)
if flt(asset.value_after_depreciation) and profit_amount:
debit_or_credit = "debit" if profit_amount < 0 else "credit"
if flt(asset.value_after_depreciation):
gl_entries.append({
"account": disposal_account,
"cost_center": depreciation_cost_center,
debit_or_credit: abs(profit_amount),
debit_or_credit + "_in_account_currency": abs(profit_amount)
"account": expense_account,
"cost_center": cost_center,
"debit": flt(asset.value_after_depreciation),
"debit_in_account_currency": flt(asset.value_after_depreciation)
})
return gl_entries

View File

@ -189,7 +189,6 @@ class TestAsset(unittest.TestCase):
depr_entry = asset.get("schedules")[0].journal_entry
self.assertFalse(depr_entry)
def test_scrap_asset(self):
asset = frappe.get_doc("Asset", "Macbook Pro 1")
asset.submit()
@ -234,8 +233,9 @@ class TestAsset(unittest.TestCase):
expected_gle = (
("_Test Accumulated Depreciations - _TC", 30000.0, 0.0),
("_Test Depreciations - _TC", 70000.0, 0.0),
("_Test Fixed Asset - _TC", 0.0, 100000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 45000.0, 0.0),
("_Test Gain/Loss on Asset Disposal - _TC", 0.0, 25000.0),
("Debtors - _TC", 25000.0, 0.0)
)

View File

@ -11,36 +11,6 @@
"doctype": "DocType",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"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,
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": "50%",
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -438,7 +408,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 3,
"modified": "2017-06-13 14:28:56.667292",
"modified": "2017-11-10 18:44:44.081464",
"modified_by": "Administrator",
"module": "Accounts",
"name": "C-Form",

View File

@ -59,9 +59,8 @@ class CostCenter(NestedSet):
return new_cost_center
def after_rename(self, olddn, newdn, merge=False):
super(CostCenter, self).after_rename(olddn, newdn, merge)
if not merge:
frappe.db.set_value("Cost Center", newdn, "cost_center_name",
" - ".join(newdn.split(" - ")[:-1]))
else:
super(CostCenter, self).after_rename(olddn, newdn, merge)

View File

@ -567,17 +567,26 @@ def get_default_bank_cash_account(company, account_type=None, mode_of_payment=No
account = get_bank_cash_account(mode_of_payment, company).get("account")
if not account:
'''
Set the default account first. If the user hasn't set any default account then, he doesn't
want us to set any random account. In this case set the account only if there is single
account (of that type), otherwise return empty dict.
'''
if account_type=="Bank":
account = frappe.db.get_value("Company", company, "default_bank_account")
if not account:
account = frappe.db.get_value("Account",
{"company": company, "account_type": "Bank", "is_group": 0})
account_list = frappe.get_all("Account", filters = {"company": company,
"account_type": "Bank", "is_group": 0})
if len(account_list) == 1:
account = account_list[0].name
elif account_type=="Cash":
account = frappe.db.get_value("Company", company, "default_cash_account")
if not account:
account = frappe.db.get_value("Account",
{"company": company, "account_type": "Cash", "is_group": 0})
account_list = frappe.get_all("Account", filters = {"company": company,
"account_type": "Cash", "is_group": 0})
if len(account_list) == 1:
account = account_list[0].name
if account:
account_details = frappe.db.get_value("Account", account,

View File

@ -647,13 +647,13 @@ frappe.ui.form.on('Payment Entry', {
set_difference_amount: function(frm) {
var unallocated_amount = 0;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
if(frm.doc.party) {
var party_amount = frm.doc.payment_type=="Receive" ?
frm.doc.paid_amount : frm.doc.received_amount;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
if(frm.doc.total_allocated_amount < party_amount) {
if(frm.doc.payment_type == "Receive") {
unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions);

View File

@ -294,7 +294,7 @@ def get_gateway_details(args):
if args.get("payment_gateway"):
return get_payment_gateway_account(args.get("payment_gateway"))
if args.cart:
if args.order_type == "Shopping Cart":
payment_gateway_account = frappe.get_doc("Shopping Cart Settings").payment_gateway_account
return get_payment_gateway_account(payment_gateway_account)

View File

@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "PCE/.###",
@ -12,34 +13,7 @@
"engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"oldfieldtype": "Column Break",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -50,6 +24,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Transaction Date",
@ -69,6 +44,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -79,6 +55,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Posting Date",
@ -98,6 +75,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -108,6 +86,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Closing Fiscal Year",
@ -128,6 +107,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -138,6 +118,7 @@
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
@ -158,6 +139,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -168,6 +150,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
@ -188,6 +171,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -198,6 +182,7 @@
"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,
@ -215,6 +200,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -226,6 +212,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Closing Account Head",
@ -246,6 +233,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -256,6 +244,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Remarks",
@ -275,18 +264,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-11-07 05:32:15.691681",
"modified": "2017-11-10 18:41:10.881530",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Period Closing Voucher",
@ -302,7 +291,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -323,7 +311,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -339,8 +326,10 @@
"read_only": 0,
"read_only_onload": 0,
"search_fields": "posting_date, fiscal_year",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "closing_account_head",
"track_changes": 0,
"track_seen": 0
}

View File

@ -3,7 +3,7 @@
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "hash",
"autoname": "field:pos_profile_name",
"beta": 0,
"creation": "2013-05-24 12:15:51",
"custom": 0,
@ -11,6 +11,96 @@
"doctype": "DocType",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "disabled",
"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": "Disabled",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_2",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "pos_profile_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "POS Profile Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -112,9 +202,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "update_stock",
"fieldname": "warehouse",
"fieldtype": "Link",
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -122,13 +211,11 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Warehouse",
"label": "Ignore Pricing Rule",
"length": 0,
"no_copy": 0,
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@ -145,8 +232,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "campaign",
"fieldtype": "Link",
"fieldname": "allow_delete",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -154,10 +241,39 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Campaign",
"label": "Allow Delete",
"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": "allow_user_to_edit_rate",
"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": "Allow user to edit Rate",
"length": 0,
"no_copy": 0,
"options": "Campaign",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -300,7 +416,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"depends_on": "update_stock",
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@ -309,19 +426,19 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Currency",
"label": "Warehouse",
"length": 0,
"no_copy": 0,
"oldfieldname": "currency",
"oldfieldtype": "Select",
"options": "Currency",
"oldfieldname": "warehouse",
"oldfieldtype": "Link",
"options": "Warehouse",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@ -332,8 +449,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"fieldname": "campaign",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -341,7 +458,38 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ignore Pricing Rule",
"label": "Campaign",
"length": 0,
"no_copy": 0,
"options": "Campaign",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_15",
"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": "Applicable for Users",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -362,8 +510,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "allow_delete",
"fieldtype": "Check",
"fieldname": "applicable_for_users",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -371,39 +519,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Delete",
"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": "allow_user_to_edit_rate",
"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": "Allow user to edit Rate",
"label": "Applicable for Users",
"length": 0,
"no_copy": 0,
"options": "POS Profile User",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -482,6 +601,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_14",
"fieldtype": "Section Break",
"hidden": 0,
@ -602,6 +722,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_16",
"fieldtype": "Section Break",
"hidden": 0,
@ -882,6 +1003,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "offline_pos_section",
"fieldtype": "Section Break",
"hidden": 0,
@ -1037,6 +1159,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_19",
"fieldtype": "Section Break",
"hidden": 0,
@ -1046,6 +1169,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounting",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -1060,6 +1184,38 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "currency",
"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": "Currency",
"length": 0,
"no_copy": 0,
"oldfieldname": "currency",
"oldfieldtype": "Select",
"options": "Currency",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -1154,38 +1310,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges",
"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": "Taxes and Charges",
"length": 0,
"no_copy": 0,
"oldfieldname": "charge",
"oldfieldtype": "Link",
"options": "Sales Taxes and Charges Template",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -1309,6 +1433,38 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "taxes_and_charges",
"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": "Taxes and Charges",
"length": 0,
"no_copy": 0,
"oldfieldname": "charge",
"oldfieldtype": "Link",
"options": "Sales Taxes and Charges Template",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
@ -1322,7 +1478,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-01 15:55:14.890452",
"modified": "2017-10-27 06:45:32.957674",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",
@ -1375,7 +1531,7 @@
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "user",
"title_field": "pos_profile_name",
"track_changes": 0,
"track_seen": 0
}

View File

@ -11,7 +11,7 @@ from frappe.model.document import Document
class POSProfile(Document):
def validate(self):
self.check_for_duplicate()
# self.check_for_duplicate()
self.validate_all_link_fields()
self.validate_duplicate_groups()
self.check_default_payment()
@ -94,3 +94,45 @@ class POSProfile(Document):
@frappe.whitelist()
def get_series():
return frappe.get_meta("Sales Invoice").get_field("naming_series").options or ""
@frappe.whitelist()
def get_pos_profiles_for_user(user=None):
out = []
if not user:
user = frappe.session.user
res = frappe.db.sql('''
select
parent
from
`tabPOS Profile User`
where
user = %s
''', (user), as_dict=1)
if not res:
company = frappe.defaults.get_user_default('company')
res = frappe.db.sql('''
select
pos_profile_name
from
`tabPOS Profile`
where
company = %s
''', (company), as_dict=1)
out = [r.pos_profile_name for r in res]
return out
for r in res:
name = frappe.db.get_value('POS Profile', r.parent, 'pos_profile_name')
out.append(name)
return out
@frappe.whitelist()
def get_pos_profile(pos_profile_name=None):
if not pos_profile_name: return
name = frappe.db.get_value('POS Profile', { 'pos_profile_name': pos_profile_name })
return frappe.get_doc('POS Profile', name)

View File

@ -41,6 +41,7 @@ def make_pos_profile():
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"income_account": "Sales - _TC",
"name": "_Test POS Profile",
"pos_profile_name": "_Test POS Profile",
"naming_series": "_T-POS Profile-",
"selling_price_list": "_Test Price List",
"territory": "_Test Territory",

View File

@ -0,0 +1,6 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('POS Profile User', {
});

View File

@ -0,0 +1,93 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2017-10-27 16:46:06.060930",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "user",
"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": "User",
"length": 0,
"no_copy": 0,
"options": "User",
"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,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-10-27 16:46:12.784244",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile User",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
from frappe.model.document import Document
class POSProfileUser(Document):
pass

View File

@ -16,6 +16,8 @@ def get_pos_data():
doc = frappe.new_doc('Sales Invoice')
doc.is_pos = 1;
pos_profile = get_pos_profile(doc.company) or {}
if not pos_profile:
frappe.throw(_("POS Profile is required to use Point-of-Sale"))
if not doc.company: doc.company = pos_profile.get('company')
doc.update_stock = pos_profile.get('update_stock')
@ -92,6 +94,7 @@ def update_pos_profile_data(doc, pos_profile, company_data):
doc.customer_group = pos_profile.get('customer_group') or get_root('Customer Group')
doc.territory = pos_profile.get('territory') or get_root('Territory')
doc.terms = frappe.db.get_value('Terms and Conditions', pos_profile.get('tc_name'), 'terms') or doc.terms or ''
doc.offline_pos_name = ''
def get_root(table):
root = frappe.db.sql(""" select name from `tab%(table)s` having

View File

@ -4531,7 +4531,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-10-24 12:46:48.331723",
"modified": "2017-11-03 05:31:56.636424",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
@ -4629,5 +4629,5 @@
"timeline_field": "customer",
"title_field": "title",
"track_changes": 1,
"track_seen": 0
"track_seen": 1
}

View File

@ -70,7 +70,6 @@ class SalesInvoice(SellingController):
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
self.add_remarks()
self.validate_write_off_account()
self.validate_duplicate_offline_pos_entry()
self.validate_account_for_change_amount()
self.validate_fixed_asset()
self.set_income_account_for_fixed_assets()
@ -305,6 +304,7 @@ class SalesInvoice(SellingController):
self.account_for_change_amount = frappe.db.get_value('Company', self.company, 'default_cash_account')
if pos:
self.pos_profile = pos.name
if not for_validate and not self.customer:
self.customer = pos.customer
self.mode_of_payment = pos.mode_of_payment
@ -463,12 +463,6 @@ class SalesInvoice(SellingController):
if flt(self.write_off_amount) and not self.write_off_account:
msgprint(_("Please enter Write Off Account"), raise_exception=1)
def validate_duplicate_offline_pos_entry(self):
if self.is_pos and self.offline_pos_name \
and frappe.db.get_value('Sales Invoice',
{'offline_pos_name': self.offline_pos_name, 'docstatus': 1}):
frappe.throw(_("Duplicate offline pos sales invoice {0}").format(self.offline_pos_name))
def validate_account_for_change_amount(self):
if flt(self.change_amount) and not self.account_for_change_amount:
msgprint(_("Please enter Account for Change Amount"), raise_exception=1)
@ -696,17 +690,6 @@ class SalesInvoice(SellingController):
# income account gl entries
for item in self.get("items"):
if flt(item.base_net_amount):
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount)
for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle))
asset.db_set("disposal_date", self.posting_date)
asset.set_status("Sold" if self.docstatus==1 else None)
else:
account_currency = get_account_currency(item.income_account)
gl_entries.append(
self.get_gl_dict({
@ -719,6 +702,17 @@ class SalesInvoice(SellingController):
}, account_currency)
)
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, is_sale=True)
for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle))
asset.db_set("disposal_date", self.posting_date)
asset.set_status("Sold" if self.docstatus==1 else None)
# expense account gl entries
if cint(self.update_stock) and \
erpnext.is_perpetual_inventory_enabled(self.company):

View File

@ -179,41 +179,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}
},
dialog_actions: function () {
var me = this;
$(this.list_body).find('.list-select-all').click(function () {
me.removed_items = [];
$(me.list_body).find('.list-delete').prop("checked", $(this).is(":checked"))
if ($(this).is(":checked")) {
$.each(me.si_docs, function (index, data) {
for (key in data) {
me.removed_items.push(key)
}
})
}
me.toggle_delete_button();
})
$(this.list_body).find('.list-delete').click(function () {
me.name = $(this).parent().parent().attr('invoice-name');
if ($(this).is(":checked")) {
me.removed_items.push(me.name);
} else {
me.removed_items.pop(me.name)
}
me.toggle_delete_button();
})
},
edit_record: function () {
var me = this;
doc_data = this.get_invoice_doc(this.si_docs);
if (doc_data) {
this.frm.doc = doc_data[0][this.name];
this.frm.doc = doc_data[0][this.frm.doc.offline_pos_name];
this.set_missing_values();
this.refresh(false);
this.toggle_input_field();
@ -226,16 +197,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.validate_list()
this.remove_doc_from_localstorage()
this.update_localstorage();
// this.dialog_actions();
this.toggle_delete_button();
},
validate_list: function() {
var me = this;
this.si_docs = this.get_submitted_invoice()
$.each(this.removed_items, function(index, name){
$.each(this.removed_items, function(index, pos_name){
$.each(me.si_docs, function(key, data){
if(me.si_docs[key][name] && me.si_docs[key][name].offline_pos_name == name ){
if(me.si_docs[key][pos_name] && me.si_docs[key][pos_name].offline_pos_name == pos_name ){
frappe.throw(__("Submitted orders can not be deleted"))
}
})
@ -294,7 +264,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
return $.grep(this.si_docs, function (data) {
for (key in data) {
return key == me.name
return key == me.frm.doc.offline_pos_name;
}
})
},
@ -348,7 +318,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
create_new: function () {
var me = this;
this.frm = {}
this.name = null;
this.load_data(true);
this.setup();
this.set_default_customer()
@ -362,6 +331,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
if (load_doc) {
this.frm.doc = JSON.parse(localStorage.getItem('doc'));
this.frm.doc.offline_pos_name = null;
}
$.each(this.meta, function (i, data) {
@ -629,6 +599,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
// this.list_customers.empty();
this.si_docs = this.get_doc_from_localstorage();
if (!this.si_docs.length) {
this.list_customers.find('.list-customers-table').html("");
return;
}
@ -655,7 +626,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
me.list_customers_btn.toggleClass("view_customer");
me.pos_bill.show();
me.list_customers_btn.show();
me.name = $(this).parents().attr('invoice-name')
me.frm.doc.offline_pos_name = $(this).parents().attr('invoice-name')
me.edit_record();
})
@ -675,11 +646,11 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
});
$(this.wrapper).find('.list-delete').click(function () {
me.name = $(this).parent().parent().attr('invoice-name');
me.frm.doc.offline_pos_name = $(this).parent().parent().attr('invoice-name');
if ($(this).is(":checked")) {
me.removed_items.push(me.name);
me.removed_items.push(me.frm.doc.offline_pos_name);
} else {
me.removed_items.pop(me.name)
me.removed_items.pop(me.frm.doc.offline_pos_name)
}
me.toggle_delete_button();
@ -1435,7 +1406,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
update_paid_amount_status: function (update_paid_amount) {
if (this.name) {
if (this.frm.doc.offline_pos_name) {
update_paid_amount = update_paid_amount ? false : true;
}
@ -1643,18 +1614,17 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
create_invoice: function () {
var me = this;
var invoice_data = {}
var invoice_data = {};
this.si_docs = this.get_doc_from_localstorage();
if (this.name) {
this.update_invoice()
if (this.frm.doc.offline_pos_name) {
this.update_invoice();
} else {
this.name = $.now();
this.frm.doc.offline_pos_name = this.name;
this.frm.doc.offline_pos_name = $.now();
this.frm.doc.posting_date = frappe.datetime.get_today();
this.frm.doc.posting_time = frappe.datetime.now_time();
this.frm.doc.pos_profile = this.pos_profile_data['name'];
invoice_data[this.name] = this.frm.doc
this.si_docs.push(invoice_data)
invoice_data[this.frm.doc.offline_pos_name] = this.frm.doc;
this.si_docs.push(invoice_data);
this.update_localstorage();
this.set_primary_action();
}
@ -1666,12 +1636,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
this.si_docs = this.get_doc_from_localstorage();
$.each(this.si_docs, function (index, data) {
for (var key in data) {
if (key == me.name) {
if (key == me.frm.doc.offline_pos_name) {
me.si_docs[index][key] = me.frm.doc;
me.update_localstorage();
}
}
})
});
},
update_localstorage: function () {
@ -1710,6 +1680,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
freeze_screen = this.freeze_screen || false;
if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) {
this.freeze = true;
frappe.call({
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
freeze: freeze_screen,
@ -1720,17 +1692,19 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
},
callback: function (r) {
if (r.message) {
me.freeze = false;
me.customers = r.message.synced_customers_list;
me.address = r.message.synced_address;
me.contacts = r.message.synced_contacts;
me.removed_items = r.message.invoice;
me.removed_email = r.message.email_queue
me.removed_customers = r.message.customers
me.removed_email = r.message.email_queue;
me.removed_customers = r.message.customers;
me.remove_doc_from_localstorage();
me.remove_email_queue_from_localstorage();
me.remove_customer_from_localstorage();
me.prepare_customer_mapper()
me.autocomplete_customers()
me.prepare_customer_mapper();
me.autocomplete_customers();
me.render_list_customers();
}
}
})

View File

@ -6,6 +6,7 @@ QUnit.test("test:Sales Invoice", function(assert) {
() => {
return frappe.tests.make("POS Profile", [
{naming_series: "SINV"},
{pos_profile_name: "_Test POS Profile"},
{country: "India"},
{currency: "INR"},
{write_off_account: "Write Off - FT"},

View File

@ -177,7 +177,9 @@ def get_party_account(party_type, party, company):
if not company:
frappe.throw(_("Please select a Company"))
if party:
if not party:
return
account = frappe.db.get_value("Party Account",
{"parenttype": party_type, "parent": party, "company": company}, "account")
@ -199,6 +201,9 @@ def get_party_account(party_type, party, company):
if (account and account_currency != existing_gle_currency) or not account:
account = get_party_gle_account(party_type, party, company)
if not account:
frappe.throw(_("Party account not specified, please setup default party account in company"))
return account
def get_party_account_currency(party_type, party, company):

View File

@ -309,14 +309,16 @@ class ReceivablePayableReport(object):
rows = []
for d in data:
rows.append(d[self.ageing_col_idx_start : self.ageing_col_idx_start+4])
if rows:
rows.insert(0, [[d.get("label")] for d in ageing_columns])
rows.append(
{
'values': d[self.ageing_col_idx_start : self.ageing_col_idx_start+4]
}
)
return {
"data": {
'labels': rows
'labels': [d.get("label") for d in ageing_columns],
'datasets': rows
},
"type": 'percentage'
}

View File

@ -1,5 +1,5 @@
{
"add_total_row": 0,
"add_total_row": 1,
"apply_user_permissions": 1,
"creation": "2013-07-30 17:28:49",
"disabled": 0,
@ -7,7 +7,7 @@
"doctype": "Report",
"idx": 3,
"is_standard": "Yes",
"modified": "2017-02-24 20:20:20.613388",
"modified": "2017-11-06 13:04:36.338268",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Delivered Items To Be Billed",

View File

@ -1,5 +1,5 @@
{
"add_total_row": 0,
"add_total_row": 1,
"apply_user_permissions": 1,
"creation": "2013-02-21 14:26:44",
"disabled": 0,
@ -7,7 +7,7 @@
"doctype": "Report",
"idx": 3,
"is_standard": "Yes",
"modified": "2017-02-24 20:20:13.972178",
"modified": "2017-11-06 13:04:51.559061",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Ordered Items To Be Billed",

View File

@ -1,5 +1,5 @@
{
"add_total_row": 0,
"add_total_row": 1,
"apply_user_permissions": 1,
"creation": "2013-07-30 18:35:10",
"disabled": 0,
@ -7,7 +7,7 @@
"doctype": "Report",
"idx": 3,
"is_standard": "Yes",
"modified": "2017-02-24 19:59:52.887744",
"modified": "2017-11-06 13:04:26.094432",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Received Items To Be Billed",

View File

@ -0,0 +1,57 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.query_reports["Sales Payment Summary"] = {
"filters": [
{
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today(),
"width": "80"
},
{
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today()
},
{
"fieldname":"company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company")
},
{
"fieldname":"mode_of_payment",
"label": __("Mode of Payment"),
"fieldtype": "Link",
"options": "Mode of Payment"
},
{
"fieldname":"owner",
"label": __("Owner"),
"fieldtype": "Link",
"options": "User",
"defaults": user
},
{
"fieldname":"cost_center",
"label": __("Cost Center"),
"fieldtype": "Link",
"options": "Cost Center"
},
{
"fieldname":"warehouse",
"label": __("Warehouse"),
"fieldtype": "Link",
"options": "Warehouse"
},
{
"fieldname":"is_pos",
"label": __("POS?"),
"fieldtype": "Check"
}
]
};

View File

@ -0,0 +1,26 @@
{
"add_total_row": 1,
"apply_user_permissions": 1,
"creation": "2017-11-03 16:31:45.757516",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2017-11-04 05:15:35.892659",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Payment Summary",
"owner": "Administrator",
"ref_doctype": "Sales Invoice",
"report_name": "Sales Payment Summary",
"report_type": "Script Report",
"roles": [
{
"role": "Accounts Manager"
},
{
"role": "Accounts User"
}
]
}

View File

@ -0,0 +1,66 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
def execute(filters=None):
columns, data = [], []
columns=get_columns()
data=get_sales_payment_data(filters, columns)
return columns, data
def get_columns():
return [
_("Date") + ":Date:80",
_("Owner") + "::150",
_("Payment Mode") + "::120",
_("Warehouse") + ":Link/Cost Center:100",
_("Cost Center") + ":Link/Warehouse:100",
_("Sales and Returns") + ":Currency/currency:120",
_("Taxes") + ":Currency/currency:120",
_("Payments") + ":Currency/currency:120",
_("Reconciliation") + ":Currency/currency:120"
]
def get_sales_payment_data(filters, columns):
sales_invoice_data = get_sales_invoice_data(filters)
data = []
for inv in sales_invoice_data:
row = [inv.posting_date, inv.owner, inv.mode_of_payment,inv.warehouse,
inv.cost_center,inv.net_total, inv.total_taxes, inv.paid_amount,
(inv.net_total + inv.total_taxes - inv.paid_amount)]
data.append(row)
return data
def get_conditions(filters):
conditions = ""
if filters.get("company"): conditions += " a.company=%(company)s"
if filters.get("customer"): conditions += " and a.customer = %(customer)s"
if filters.get("owner"): conditions += " and a.owner = %(owner)s"
if filters.get("from_date"): conditions += " and a.posting_date >= %(from_date)s"
if filters.get("to_date"): conditions += " and a.posting_date <= %(to_date)s"
if filters.get("mode_of_payment"): conditions += " and c.mode_of_payment >= %(mode_of_payment)s"
if filters.get("warehouse"): conditions += " and b.warehouse <= %(warehouse)s"
if filters.get("cost_center"): conditions += " and b.cost_center <= %(cost_center)s"
if filters.get("is_pos"): conditions += " and a.is_pos = %(is_pos)s"
return conditions
def get_sales_invoice_data(filters):
conditions = get_conditions(filters)
return frappe.db.sql("""
select
a.owner, a.posting_date, c.mode_of_payment, b.warehouse, b.cost_center,
sum(a.net_total) as "net_total",
sum(a.total_taxes_and_charges) as "total_taxes",
sum(a.base_paid_amount) as "paid_amount"
from `tabSales Invoice` a, `tabSales Invoice Item` b, `tabSales Invoice Payment` c
where
a.name = b.parent
and a.name = c.parent
and {conditions}
group by
a.owner, a.posting_date, c.mode_of_payment, b.warehouse, b.cost_center
""".format(conditions=conditions), filters, as_dict=1)

View File

@ -589,7 +589,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
select ifnull(sum({payment_dr_or_cr}), 0)
from `tabGL Entry` payment_gl_entry
where payment_gl_entry.against_voucher_type = invoice_gl_entry.voucher_type
and payment_gl_entry.against_voucher = invoice_gl_entry.voucher_no
and payment_gl_entry.against_voucher = invoice_gl_entry.against_voucher
and payment_gl_entry.party_type = invoice_gl_entry.party_type
and payment_gl_entry.party = invoice_gl_entry.party
and payment_gl_entry.account = invoice_gl_entry.account
@ -660,16 +660,14 @@ def get_companies():
order_by="name")]
@frappe.whitelist()
def get_children():
def get_children(doctype, parent, company, is_root=False):
from erpnext.accounts.report.financial_statements import sort_root_accounts
args = frappe.local.form_dict
doctype, company = args['doctype'], args['company']
fieldname = frappe.db.escape(doctype.lower().replace(' ','_'))
doctype = frappe.db.escape(doctype)
# root
if args['parent'] in ("Accounts", "Cost Centers"):
if is_root:
fields = ", root_type, report_type, account_currency" if doctype=="Account" else ""
acc = frappe.db.sql(""" select
name as value, is_group as expandable {fields}
@ -679,7 +677,7 @@ def get_children():
order by name""".format(fields=fields, fieldname = fieldname, doctype=doctype),
company, as_dict=1)
if args["parent"]=="Accounts":
if parent=="Accounts":
sort_root_accounts(acc)
else:
# other
@ -690,7 +688,7 @@ def get_children():
where ifnull(`parent_{fieldname}`,'') = %s
and docstatus<2
order by name""".format(fields=fields, fieldname=fieldname, doctype=doctype),
args['parent'], as_dict=1)
parent, as_dict=1)
if doctype == 'Account':
company_currency = frappe.db.get_value("Company", company, "default_currency")

View File

@ -468,6 +468,12 @@ def get_data():
"name": "Customer Credit Balance",
"doctype": "Customer"
},
{
"type": "report",
"is_query_report": True,
"name": "Sales Payment Summary",
"doctype": "Sales Invoice"
}
]
},
{

View File

@ -15,6 +15,7 @@ def get_data():
{
"type": "doctype",
"name": "Task",
"route": "Tree/Task",
"description": _("Project activity / task."),
},
{

View File

@ -122,10 +122,6 @@ def get_data():
"type": "doctype",
"name": "Assessment Result"
},
{
"type": "doctype",
"name": "Grading Scale"
},
{
"type": "doctype",
"name": "Assessment Criteria"
@ -144,6 +140,12 @@ def get_data():
"name": "Course wise Assessment Report",
"doctype": "Assessment Result"
},
{
"type": "report",
"is_query_report": True,
"name": "Assessment Plan Status",
"doctype": "Assessment Plan"
},
]
},
@ -201,6 +203,10 @@ def get_data():
"type": "doctype",
"name": "Student Batch Name"
},
{
"type": "doctype",
"name": "Grading Scale"
},
{
"type": "doctype",
"name": "Academic Term"

View File

@ -235,10 +235,10 @@ class AccountsController(TransactionBase):
tax_master_doctype = self.meta.get_field("taxes_and_charges").options
if not self.get("taxes"):
if self.is_new() and not self.get("taxes"):
if not self.get("taxes_and_charges"):
# get the default tax master
self.set("taxes_and_charges", frappe.db.get_value(tax_master_doctype, {"is_default": 1}))
self.taxes_and_charges = frappe.db.get_value(tax_master_doctype, {"is_default": 1})
self.append_taxes_from_master(tax_master_doctype)
@ -691,7 +691,10 @@ def get_tax_rate(account_head):
@frappe.whitelist()
def get_default_taxes_and_charges(master_doctype):
default_tax = frappe.db.get_value(master_doctype, {"is_default": 1})
return get_taxes_and_charges(master_doctype, default_tax)
return {
'taxes_and_charges': default_tax,
'taxes': get_taxes_and_charges(master_doctype, default_tax)
}
@frappe.whitelist()
def get_taxes_and_charges(master_doctype, master_name):

View File

@ -204,8 +204,8 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
{
'txt': "%%%s%%" % frappe.db.escape(txt),
'_txt': txt.replace("%", ""),
'start': start,
'page_len': page_len
'start': start or 0,
'page_len': page_len or 20
})
def get_project_name(doctype, txt, searchfield, start, page_len, filters):

View File

@ -233,8 +233,8 @@ def make_quotation(source_name, target_doc=None):
# get default taxes
taxes = get_default_taxes_and_charges("Sales Taxes and Charges Template")
if taxes:
quotation.extend("taxes", taxes)
if taxes.get('taxes'):
quotation.update(taxes)
quotation.run_method("set_missing_values")
quotation.run_method("calculate_taxes_and_totals")

View File

@ -18,8 +18,5 @@ data = {
'set_value': [
['Stock Settings', None, 'show_barcode_field', 1]
],
'restricted_roles': [
'Manufacturing User'
],
'default_portal_role': 'Customer'
}

View File

View File

@ -0,0 +1,45 @@
from __future__ import unicode_literals
import frappe
from frappe.data_migration.doctype.data_migration_connector.connectors.base import BaseConnection
from github import Github
class GithubConnection(BaseConnection):
def __init__(self, connector):
self.connector = connector
try:
password = self.get_password()
except frappe.AuthenticationError:
password = None
if self.connector.username and password:
self.connection = Github(self.connector.username, self.get_password())
else:
self.connection = Github()
self.name_field = 'id'
def insert(self, doctype, doc):
pass
def update(self, doctype, doc, migration_id):
pass
def delete(self, doctype, migration_id):
pass
def get(self, remote_objectname, fields=None, filters=None, start=0, page_length=10):
repo = filters.get('repo')
if remote_objectname == 'Milestone':
return self.get_milestones(repo, start, page_length)
if remote_objectname == 'Issue':
return self.get_issues(repo, start, page_length)
def get_milestones(self, repo, start=0, page_length=10):
_repo = self.connection.get_repo(repo)
return list(_repo.get_milestones()[start:start+page_length])
def get_issues(self, repo, start=0, page_length=10):
_repo = self.connection.get_repo(repo)
return list(_repo.get_issues()[start:start+page_length])

View File

@ -0,0 +1,11 @@
import frappe
def pre_process(issue):
project = frappe.db.get_value('Project', filters={'project_name': issue.milestone})
return {
'title': issue.title,
'body': frappe.utils.to_html(issue.body or ''),
'state': issue.state.title(),
'project': project or ''
}

View File

@ -0,0 +1,36 @@
{
"condition": "{\"repo\":\"frappe/erpnext\"}",
"creation": "2017-10-16 16:03:32.772191",
"docstatus": 0,
"doctype": "Data Migration Mapping",
"fields": [
{
"is_child_table": 0,
"local_fieldname": "subject",
"remote_fieldname": "title"
},
{
"is_child_table": 0,
"local_fieldname": "description",
"remote_fieldname": "body"
},
{
"is_child_table": 0,
"local_fieldname": "status",
"remote_fieldname": "state"
}
],
"idx": 0,
"local_doctype": "Task",
"local_primary_key": "name",
"mapping_name": "Issue to Task",
"mapping_type": "Pull",
"migration_id_field": "github_sync_id",
"modified": "2017-10-20 11:48:54.575993",
"modified_by": "Administrator",
"name": "Issue to Task",
"owner": "Administrator",
"page_length": 10,
"remote_objectname": "Issue",
"remote_primary_key": "id"
}

View File

@ -0,0 +1,6 @@
def pre_process(milestone):
return {
'title': milestone.title,
'description': milestone.description,
'state': milestone.state.title()
}

View File

@ -0,0 +1,36 @@
{
"condition": "{\"repo\": \"frappe/erpnext\"}",
"creation": "2017-10-13 11:16:49.664925",
"docstatus": 0,
"doctype": "Data Migration Mapping",
"fields": [
{
"is_child_table": 0,
"local_fieldname": "project_name",
"remote_fieldname": "title"
},
{
"is_child_table": 0,
"local_fieldname": "notes",
"remote_fieldname": "description"
},
{
"is_child_table": 0,
"local_fieldname": "status",
"remote_fieldname": "state"
}
],
"idx": 0,
"local_doctype": "Project",
"local_primary_key": "project_name",
"mapping_name": "Milestone to Project",
"mapping_type": "Pull",
"migration_id_field": "github_sync_id",
"modified": "2017-10-20 11:48:54.552305",
"modified_by": "Administrator",
"name": "Milestone to Project",
"owner": "Administrator",
"page_length": 10,
"remote_objectname": "Milestone",
"remote_primary_key": "id"
}

View File

@ -0,0 +1,22 @@
{
"creation": "2017-10-13 11:16:53.600026",
"docstatus": 0,
"doctype": "Data Migration Plan",
"idx": 0,
"mappings": [
{
"enabled": 1,
"mapping": "Milestone to Project"
},
{
"enabled": 1,
"mapping": "Issue to Task"
}
],
"modified": "2017-10-20 11:48:54.496123",
"modified_by": "Administrator",
"module": "ERPNext Integrations",
"name": "GitHub Sync",
"owner": "Administrator",
"plan_name": "GitHub Sync"
}

View File

@ -87,6 +87,7 @@ frappe.ui.form.on('Employee Loan', {
},
employee_loan_application: function (frm) {
if(frm.doc.employee_loan_application){
return frappe.call({
method: "erpnext.hr.doctype.employee_loan.employee_loan.get_employee_loan_application",
args: {
@ -102,7 +103,8 @@ frappe.ui.form.on('Employee Loan', {
frm.set_value("rate_of_interest", r.message.rate_of_interest);
}
}
})
});
}
},
repayment_method: function (frm) {

View File

@ -13,35 +13,6 @@
"editable_grid": 0,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"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,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@ -507,7 +478,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-13 14:29:01.066538",
"modified": "2017-11-10 18:41:38.845159",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Allocation",

View File

@ -11,34 +11,7 @@
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"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,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -69,6 +42,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -99,6 +73,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -129,6 +104,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -159,6 +135,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -189,6 +166,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -217,6 +195,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -246,6 +225,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -275,6 +255,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -304,6 +285,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -333,6 +315,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -361,6 +344,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -401,7 +385,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-03-29 11:24:17.013862",
"modified": "2017-11-10 18:42:17.060492",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Control Panel",

View File

@ -161,18 +161,15 @@ var calculate_earning_total = function(doc, dt, dn, reset_amount) {
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days) /
cint(doc.total_working_days)*100)/100;
refresh_field('amount', tbl[i].name, 'earnings');
} else if(reset_amount) {
tbl[i].amount = tbl[i].default_amount;
refresh_field('amount', tbl[i].name, 'earnings');
}
if(!tbl[i].do_not_include_in_total) {
total_earn += flt(tbl[i].amount);
}
}
doc.gross_pay = total_earn;
refresh_many(['amount','gross_pay']);
refresh_many(['earnings', 'amount','gross_pay']);
}
// Calculate deduction total
@ -183,17 +180,15 @@ var calculate_ded_total = function(doc, dt, dn, reset_amount) {
for(var i = 0; i < tbl.length; i++){
if(cint(tbl[i].depends_on_lwp) == 1) {
tbl[i].amount = Math.round(tbl[i].default_amount)*(flt(doc.payment_days)/cint(doc.total_working_days)*100)/100;
refresh_field('amount', tbl[i].name, 'deductions');
} else if(reset_amount) {
tbl[i].amount = tbl[i].default_amount;
refresh_field('amount', tbl[i].name, 'deductions');
}
if(!tbl[i].do_not_include_in_total) {
total_ded += flt(tbl[i].amount);
}
}
doc.total_deduction = total_ded;
refresh_field('total_deduction');
refresh_many(['deductions', 'total_deduction']);
}
// Calculate net payable amount

View File

@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
@ -12,35 +13,7 @@
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"oldfieldtype": "Column Break",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -53,7 +26,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Posting Date",
"length": 0,
@ -71,6 +44,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -82,7 +56,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Employee",
"length": 0,
@ -102,6 +76,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -113,7 +88,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Employee Name",
"length": 0,
@ -133,6 +108,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -164,6 +140,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -196,6 +173,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -227,6 +205,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -256,6 +235,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -286,6 +266,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -316,6 +297,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -327,7 +309,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Company",
"length": 0,
@ -345,6 +327,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
@ -374,6 +357,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -402,6 +386,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -433,6 +418,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -463,6 +449,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -494,6 +481,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -522,6 +510,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -553,6 +542,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -585,6 +575,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -616,6 +607,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -647,6 +639,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -678,6 +671,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -708,6 +702,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -739,6 +734,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -767,6 +763,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -796,6 +793,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -826,6 +824,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -856,6 +855,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -886,6 +886,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -916,6 +917,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -944,6 +946,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -975,6 +978,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1004,6 +1008,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1034,6 +1039,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1066,6 +1072,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1096,6 +1103,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1127,6 +1135,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1156,6 +1165,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1187,6 +1197,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1214,6 +1225,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1245,6 +1257,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1275,6 +1288,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1305,6 +1319,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1335,6 +1350,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1363,6 +1379,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1393,6 +1410,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1422,6 +1440,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1454,6 +1473,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1482,6 +1502,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@ -1511,6 +1532,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1539,6 +1561,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -1570,18 +1593,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"idx": 9,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-03-02 02:25:53.844701",
"modified": "2017-11-10 18:40:33.817074",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Slip",

View File

@ -348,7 +348,8 @@ class SalarySlip(TransactionBase):
/ cint(self.total_working_days)), self.precision("amount", component_type)
)
elif not self.payment_days and not self.salary_slip_based_on_timesheet:
elif not self.payment_days and not self.salary_slip_based_on_timesheet and \
cint(d.depends_on_lwp):
d.amount = 0
elif not d.amount:
d.amount = d.default_amount

View File

@ -1,5 +1,6 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "Prompt",
@ -12,34 +13,7 @@
"editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break0",
"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,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0,
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -69,6 +43,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -99,6 +74,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -127,6 +103,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -159,6 +136,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -191,6 +169,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -222,6 +201,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -250,6 +230,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -281,6 +262,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -310,6 +292,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -340,6 +323,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -368,6 +352,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -400,6 +385,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -431,6 +417,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -464,6 +451,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -495,6 +483,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -527,6 +516,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -558,6 +548,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -589,6 +580,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -618,6 +610,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -646,6 +639,7 @@
"width": "50%"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -677,6 +671,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -708,6 +703,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -737,6 +733,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -766,6 +763,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -796,6 +794,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -824,6 +823,7 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@ -854,18 +854,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-02-22 06:09:55.491748",
"modified": "2017-11-10 18:45:07.120254",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Structure",

View File

@ -1,28 +1,39 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2013-01-25 11:34:53",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"editable_grid": 0,
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"description": "Download the Template, fill appropriate data and attach the modified file.\nAll dates and employee combination in the selected period will come in the template, with existing attendance records",
"columns": 0,
"description": "",
"fieldname": "download_template",
"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": "Download Template",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -30,22 +41,30 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "att_fr_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Attendance From Date",
"length": 0,
"no_copy": 0,
"oldfieldname": "attenadnce_date",
"oldfieldtype": "Date",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@ -53,20 +72,28 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "att_to_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Attendance To Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@ -74,21 +101,29 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "get_template",
"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 Template",
"length": 0,
"no_copy": 0,
"oldfieldtype": "Button",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -96,20 +131,28 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "upload_attendance_data",
"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": "Import Attendance",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -117,20 +160,28 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "upload_html",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Upload HTML",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -138,20 +189,28 @@
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "import_log",
"fieldtype": "HTML",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Import Log",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@ -159,17 +218,18 @@
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 1,
"icon": "fa fa-upload-alt",
"idx": 1,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"max_attachments": 1,
"modified": "2015-06-05 11:37:04.348120",
"modified": "2017-11-14 12:51:34.980103",
"modified_by": "Administrator",
"module": "HR",
"name": "Upload Attendance",
@ -216,6 +276,10 @@
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0
"read_only_onload": 0,
"show_name_in_global_search": 0,
"track_changes": 0,
"track_seen": 0
}

View File

@ -37,7 +37,9 @@ def get_categories():
return response
@frappe.whitelist()
def get_item_details(hub_sync_id):
def get_item_details(hub_sync_id=None):
if not hub_sync_id:
return
connection = get_connection()
return connection.get_doc('Hub Item', hub_sync_id)

View File

@ -382,6 +382,7 @@ erpnext.hub.Hub = class Hub {
},
method: "erpnext.hub_node.get_item_details",
callback: (r) => {
if (!r || !r.message) return;
let item = r.message;
this.item_cache[item_code] = item;
this.render_item_page(item);

View File

@ -587,7 +587,11 @@ 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():
def get_children(doctype, parent=None, is_tree=False):
if not parent:
frappe.msgprint(_('Please select a BOM'))
return
if frappe.form_dict.parent:
return frappe.db.sql("""select
bom_item.item_code,

View File

@ -11,7 +11,7 @@ frappe.treeview_settings["BOM"] = {
title: "BOM",
breadcrumb: "Manufacturing",
disable_add_node: true,
root_label: "bom", //fieldname from filters
root_label: "All Bill of Materials", //fieldname from filters
get_label: function(node) {
if(node.data.qty) {
return node.data.qty + " x " + node.data.item_code;

View File

@ -17,6 +17,14 @@ frappe.ui.form.on("Production Order", {
}
});
frm.set_query("source_warehouse", function() {
return {
filters: {
'company': frm.doc.company,
}
}
});
frm.set_query("source_warehouse", "required_items", function() {
return {
filters: {

View File

@ -1358,7 +1358,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-07-10 14:29:00.457874",
"modified": "2017-11-03 05:31:56.636424",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Order",
@ -1412,5 +1412,5 @@
"sort_order": "ASC",
"title_field": "production_item",
"track_changes": 1,
"track_seen": 0
"track_seen": 1
}

View File

@ -64,7 +64,7 @@ erpnext.ProductionAnalytics = frappe.views.GridReportWithPlot.extend({
var chart_data = this.get_chart_data ? this.get_chart_data() : null;
this.chart = new frappe.chart.FrappeChart({
this.chart = new Chart({
parent: ".chart",
data: chart_data,
type: 'line'

View File

@ -17,3 +17,4 @@ Schools
Regional
Healthcare
Restaurant
ERPNext Integrations

View File

@ -448,6 +448,7 @@ erpnext.patches.v8_9.remove_employee_from_salary_structure_parent
erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts
erpnext.patches.v8_9.set_default_fields_in_variant_settings
erpnext.patches.v8_9.update_billing_gstin_for_indian_account
erpnext.patches.v9_0.add_user_to_child_table_in_pos_profile
erpnext.patches.v9_0.set_schedule_date_for_material_request_and_purchase_order
erpnext.patches.v9_0.student_admission_childtable_migrate
erpnext.patches.v9_0.fix_subscription_next_date #2017-10-23
@ -455,6 +456,10 @@ erpnext.patches.v9_0.add_healthcare_domain
erpnext.patches.v9_0.set_variant_item_description
erpnext.patches.v9_0.set_uoms_in_variant_field
erpnext.patches.v9_0.copy_old_fees_field_data
execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
erpnext.patches.v9_0.set_pos_profile_name
erpnext.patches.v9_0.remove_non_existing_warehouse_from_stock_settings
execute:frappe.delete_doc_if_exists("DocType", "Program Fee")
erpnext.patches.v8_10.add_due_date_to_gle
erpnext.patches.v8_10.update_gl_due_date_for_pi_and_si
erpnext.patches.v8_10.add_payment_terms_field_to_supplier

View File

@ -1,5 +1,5 @@
import frappe
from MySQLdb import OperationalError
from pymysql import InternalError
def execute():
frappe.reload_doctype("Journal Entry Account")
@ -15,6 +15,6 @@ def execute():
frappe.db.sql("""update `tabJournal Entry Account`
set reference_type=%s, reference_name={0} where ifnull({0}, '') != ''
""".format(fieldname), doctype)
except OperationalError:
except InternalError:
# column not found
pass

View File

@ -3,7 +3,7 @@
from __future__ import print_function, unicode_literals
import frappe
import MySQLdb
from frappe.exceptions import SQLError
def execute():
"""
@ -31,7 +31,7 @@ def execute():
try:
migrate_item_variants()
except MySQLdb.ProgrammingError:
except SQLError:
print("`tabItem Variant` not found")
def rename_and_reload_doctypes():

View File

@ -0,0 +1,22 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
doctype = 'POS Profile'
frappe.reload_doc('accounts', 'doctype', doctype)
frappe.reload_doc('accounts', 'doctype', 'POS Profile User')
for doc in frappe.get_all(doctype):
_doc = frappe.get_doc(doctype, doc.name)
user = frappe.db.get_value(doctype, doc.name, 'user')
if not user: continue
_doc.append('applicable_for_users', {
'user': user
})
_doc.pos_profile_name = user + ' - ' + _doc.company
_doc.save()

View File

@ -5,7 +5,8 @@ from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doctype('Fees')
frappe.reload_doc("schools", "doctype", "fees")
if "total_amount" not in frappe.db.get_table_columns("Fees"):
return

View File

@ -0,0 +1,7 @@
import frappe
def execute():
default_warehouse = frappe.db.get_value("Stock Settings", None, "default_warehouse")
if default_warehouse:
if not frappe.db.get_value("Warehouse", {"name": default_warehouse}):
frappe.db.set_value("Stock Settings", None, "default_warehouse", "")

View File

@ -0,0 +1,21 @@
import frappe
def execute():
if 'Manufacturing' in frappe.get_active_domains(): return
role = 'Manufacturing User'
frappe.db.set_value('Role', role, 'restrict_to_domain', '')
frappe.db.set_value('Role', role, 'disabled', 0)
users = frappe.get_all('Has Role', filters = {
'parenttype': 'User',
'role': ('in', ['System Manager', 'Manufacturing Manager'])
}, fields=['parent'], as_list=1)
for user in users:
_user = frappe.get_doc('User', user[0])
_user.append('roles', {
'role': role
})
_user.flags.ignore_validate = True
_user.save()

View File

@ -0,0 +1,24 @@
# Copyright (c) 2017, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
doctype = 'POS Profile'
frappe.reload_doctype(doctype)
for pos in frappe.get_all(doctype, filters={'disabled': 0}):
doc = frappe.get_doc(doctype, pos.name)
if not doc.user or doc.pos_profile_name: continue
try:
doc.pos_profile_name = doc.user + ' - ' + doc.company
doc.flags.ignore_validate = True
doc.flags.ignore_mandatory = True
doc.save()
frappe.rename_doc(doctype, doc.name, doc.pos_profile_name, force=True)
except frappe.LinkValidationError:
frappe.db.set_value("POS Profile", doc.name, 'disabled', 1)

View File

@ -19,6 +19,14 @@ frappe.ui.form.on("Task", {
},
refresh: function(frm) {
frm.fields_dict['parent_task'].get_query = function() {
return {
filters: {
"is_group": 1,
}
}
}
if(!frm.is_group){
var doc = frm.doc;
if(doc.__islocal) {
if(!frm.doc.exp_end_date) {
@ -54,6 +62,7 @@ frappe.ui.form.on("Task", {
}
}
}
}
},
setup: function(frm) {
@ -71,6 +80,21 @@ frappe.ui.form.on("Task", {
}
},
is_group: function(frm) {
frappe.call({
method:"erpnext.projects.doctype.task.task.check_if_child_exists",
args: {
name: frm.doc.name
},
callback: function(r){
if(r.message){
frappe.msgprint(__('Cannot convert it to non-group. Child Tasks exist.'));
frm.reload_doc();
}
}
})
},
validate: function(frm) {
frm.doc.project && frappe.model.remove_from_locals("Project",
frm.doc.project);

View File

@ -2,7 +2,7 @@
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"allow_rename": 0,
"autoname": "TASK.#####",
"beta": 0,
"creation": "2013-01-29 19:25:50",
@ -30,9 +30,8 @@
"label": "Subject",
"length": 0,
"no_copy": 0,
"oldfieldname": "subject",
"oldfieldtype": "Data",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@ -75,6 +74,37 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"default": "0",
"fieldname": "is_group",
"fieldtype": "Check",
"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": "Is Group",
"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,
@ -173,9 +203,42 @@
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"fieldname": "parent_task",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Parent Task",
"length": 0,
"no_copy": 0,
"options": "Task",
"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": 1,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
"fieldname": "section_break_10",
"fieldtype": "Section Break",
"hidden": 0,
@ -205,6 +268,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "exp_start_date",
"fieldtype": "Date",
"hidden": 0,
@ -237,6 +301,7 @@
"collapsible": 0,
"columns": 0,
"default": "0",
"depends_on": "",
"description": "",
"fieldname": "expected_time",
"fieldtype": "Float",
@ -269,6 +334,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "task_weight",
"fieldtype": "Float",
"hidden": 0,
@ -328,6 +394,7 @@
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "exp_end_date",
"fieldtype": "Date",
"hidden": 0,
@ -359,6 +426,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "progress",
"fieldtype": "Percent",
"hidden": 0,
@ -389,6 +457,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "is_milestone",
"fieldtype": "Check",
"hidden": 0,
@ -418,7 +487,9 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
"fieldname": "section_break0",
"fieldtype": "Section Break",
"hidden": 0,
@ -449,6 +520,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
@ -481,7 +553,9 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
"fieldname": "section_break",
"fieldtype": "Section Break",
"hidden": 0,
@ -512,6 +586,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "depends_on",
"fieldtype": "Table",
"hidden": 0,
@ -543,6 +618,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "depends_on_tasks",
"fieldtype": "Data",
"hidden": 1,
@ -572,7 +648,9 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
"description": "",
"fieldname": "actual",
"fieldtype": "Section Break",
@ -606,6 +684,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "act_start_date",
"fieldtype": "Date",
"hidden": 0,
@ -638,6 +717,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"depends_on": "",
"description": "",
"fieldname": "actual_time",
"fieldtype": "Float",
@ -699,6 +779,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "act_end_date",
"fieldtype": "Date",
"hidden": 0,
@ -730,6 +811,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "section_break_17",
"fieldtype": "Section Break",
"hidden": 0,
@ -759,6 +841,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "total_costing_amount",
"fieldtype": "Currency",
"hidden": 0,
@ -791,6 +874,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "total_expense_claim",
"fieldtype": "Currency",
"hidden": 0,
@ -851,6 +935,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "total_billing_amount",
"fieldtype": "Currency",
"hidden": 0,
@ -1025,6 +1110,96 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "lft",
"fieldtype": "Int",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "lft",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "rgt",
"fieldtype": "Int",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "rgt",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "old_parent",
"fieldtype": "Data",
"hidden": 1,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Old Parent",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
}
],
"has_web_view": 0,
@ -1039,7 +1214,7 @@
"istable": 0,
"max_attachments": 5,
"menu_index": 0,
"modified": "2017-05-23 11:28:28.161600",
"modified": "2017-11-10 18:37:19.660293",
"modified_by": "Administrator",
"module": "Projects",
"name": "Task",

View File

@ -5,13 +5,14 @@ from __future__ import unicode_literals
import frappe, json
from frappe.utils import getdate, date_diff, add_days, cstr
from frappe import _
from frappe.model.document import Document
from frappe import _, throw
from frappe.utils.nestedset import NestedSet
class CircularReferenceError(frappe.ValidationError): pass
class Task(Document):
class Task(NestedSet):
nsm_parent_field = 'parent_task'
def get_feed(self):
return '{0}: {1}'.format(_(self.status), self.subject)
@ -59,7 +60,11 @@ class Task(Document):
depends_on_tasks += d.task + ","
self.depends_on_tasks = depends_on_tasks
def update_nsm_model(self):
frappe.utils.nestedset.update_nsm(self)
def on_update(self):
self.update_nsm_model()
self.check_recursion()
self.reschedule_dependent_tasks()
self.update_project()
@ -105,16 +110,20 @@ class Task(Document):
frappe.throw(_("Circular Reference Error"), CircularReferenceError)
if b[0]:
task_list.append(b[0])
if count == 15:
break
def reschedule_dependent_tasks(self):
end_date = self.exp_end_date or self.act_end_date
if end_date:
for task_name in frappe.db.sql("""select name from `tabTask` as parent where parent.project = %(project)s and parent.name in \
(select parent from `tabTask Depends On` as child where child.task = %(task)s and child.project = %(project)s)""",
{'project': self.project, 'task':self.name }, as_dict=1):
for task_name in frappe.db.sql("""
select name from `tabTask` as parent
where parent.project = %(project)s
and parent.name in (
select parent from `tabTask Depends On` as child
where child.task = %(task)s and child.project = %(project)s)
""", {'project': self.project, 'task':self.name }, as_dict=1):
task = frappe.get_doc("Task", task_name.name)
if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(end_date) and task.status == "Open":
task_duration = date_diff(task.exp_end_date, task.exp_start_date)
@ -128,6 +137,17 @@ class Task(Document):
if project_user:
return True
def on_trash(self):
if check_if_child_exists(self.name):
throw(_("Child Task exists for this Task. You can not delete this Task."))
self.update_nsm_model()
@frappe.whitelist()
def check_if_child_exists(name):
return frappe.db.sql("""select name from `tabTask`
where parent_task = %s""", name)
@frappe.whitelist()
def get_events(start, end, filters=None):
"""Returns events for Gantt / Calendar view rendering.
@ -177,4 +197,54 @@ def set_tasks_as_overdue():
and exp_end_date < CURDATE()
and `status` not in ('Closed', 'Cancelled')""")
@frappe.whitelist()
def get_children(doctype, parent, task=None, project=None, is_root=False):
conditions = ''
if task:
# via filters
conditions += ' and parent_task = "{0}"'.format(frappe.db.escape(task))
elif parent and not is_root:
# via expand child
conditions += ' and parent_task = "{0}"'.format(frappe.db.escape(parent))
else:
conditions += ' and ifnull(parent_task, "")=""'
if project:
conditions += ' and project = "{0}"'.format(frappe.db.escape(project))
tasks = frappe.db.sql("""select name as value,
subject as title,
is_group as expandable
from `tabTask`
where docstatus < 2
{conditions}
order by name""".format(conditions=conditions), as_dict=1)
# return tasks
return tasks
@frappe.whitelist()
def add_node():
from frappe.desk.treeview import make_tree_args
args = frappe.form_dict
args.update({
"name_field": "subject"
})
args = make_tree_args(**args)
if args.parent_task == 'task':
args.parent_task = None
frappe.get_doc(args).insert()
@frappe.whitelist()
def add_multiple_tasks(data, parent):
data = json.loads(data)['tasks']
tasks = data.split('\n')
new_doc = {'doctype': 'Task', 'parent_task': parent}
for d in tasks:
new_doc['subject'] = d
new_task = frappe.get_doc(new_doc)
new_task.insert()

View File

@ -25,7 +25,9 @@ frappe.listview_settings['Task'] = {
return [__(doc.status), colors[doc.status], "status,=," + doc.status];
},
gantt_custom_popup_html: function(ganttobj, task) {
var html = `<h5>${ganttobj.name}</h5>`;
var html = `<h5><a style="text-decoration:underline"\
href="#Form/Task/${ganttobj.id}""> ${ganttobj.name} </a></h5>`;
if(task.project) html += `<p>Project: ${task.project}</p>`;
html += `<p>Progress: ${ganttobj.progress}</p>`;

View File

@ -0,0 +1,60 @@
frappe.provide("frappe.treeview_settings");
frappe.treeview_settings['Task'] = {
get_tree_nodes: "erpnext.projects.doctype.task.task.get_children",
add_tree_node: "erpnext.projects.doctype.task.task.add_node",
filters: [
{
fieldname: "project",
fieldtype:"Link",
options: "Project",
label: __("Project"),
},
{
fieldname: "task",
fieldtype:"Link",
options: "Task",
label: __("Task"),
get_query: function() {
return {
filters: [["Task", 'is_group', '=', 1]]
};
}
}
],
breadcrumb: "Projects",
get_tree_root: false,
root_label: "All Tasks",
ignore_fields: ["parent_task"],
onload: function(me) {
me.make_tree();
},
toolbar: [
{
label:__("Add Multiple"),
condition: function(node) {
return node.expandable;
},
click: function(node) {
var d = new frappe.ui.Dialog({
'fields': [
{'fieldname': 'tasks', 'label': 'Tasks', 'fieldtype': 'Text'},
],
primary_action: function() {
d.hide();
return frappe.call({
method: "erpnext.projects.doctype.task.task.add_multiple_tasks",
args: {
data: d.get_values(),
parent: node.data.value
},
callback: function() { }
});
}
});
d.show();
}
}
],
extend_toolbar: true
};

View File

@ -1,15 +0,0 @@
[
{
"status": "Open",
"subject": "_Test Task",
"name": "task001"
},
{
"status": "Open",
"subject": "_Test Task 1"
},
{
"status": "Open",
"subject": "_Test Task 2"
}
]

View File

@ -5,134 +5,58 @@ import frappe
import unittest
from frappe.utils import getdate, nowdate, add_days
# test_records = frappe.get_test_records('Task')
from erpnext.projects.doctype.task.task import CircularReferenceError
class TestTask(unittest.TestCase):
def test_circular_reference(self):
task1 = create_task("_Test Task 1", nowdate(), add_days(nowdate(), 10))
task2 = create_task("_Test Task 2", add_days(nowdate(), 11), add_days(nowdate(), 15), task1.name)
task3 = create_task("_Test Task 3", add_days(nowdate(), 11), add_days(nowdate(), 15), task2.name)
task1 = frappe.new_doc('Task')
task1.update({
"status": "Open",
"subject": "_Test Task 1",
"project": "_Test Project",
"exp_start_date": "2015-1-1",
"exp_end_date": "2015-1-10"
})
task1.save()
task2 = frappe.new_doc('Task')
task2.update({
"status": "Open",
"subject": "_Test Task 2",
"project": "_Test Project",
"exp_start_date": "2015-1-11",
"exp_end_date": "2015-1-15",
"depends_on":[
{
"task": task1.name
}
]
})
task2.save()
task3 = frappe.new_doc('Task')
task3.update({
"status": "Open",
"subject": "_Test Task 2",
"project": "_Test Project",
"exp_start_date": "2015-1-11",
"exp_end_date": "2015-1-15",
"depends_on":[
{
"task": task2.name
}
]
})
task3.save()
task1.reload()
task1.append("depends_on", {
"task": task3.name
})
self.assertRaises(CircularReferenceError, task1.save)
task1.set("depends_on", [])
task1.save()
task4 = frappe.new_doc('Task')
task4.update({
"status": "Open",
"subject": "_Test Task 1",
"exp_start_date": "2015-1-1",
"exp_end_date": "2015-1-15",
"depends_on":[
{
"task": task1.name
}
]
})
task4.save()
task4 = create_task("_Test Task 4", nowdate(), add_days(nowdate(), 15), task1.name)
task3.append("depends_on", {
"task": task4.name
})
def test_reschedule_dependent_task(self):
task1 = frappe.new_doc('Task')
task1.update({
"status": "Open",
"subject": "_Test Task 1",
"project": "_Test Project",
"exp_start_date": "2015-1-1",
"exp_end_date": "2015-1-10"
})
task1.save()
task1 = create_task("_Test Task 1", nowdate(), add_days(nowdate(), 10))
task2 = frappe.new_doc('Task')
task2.update({
"status": "Open",
"subject": "_Test Task 2",
"project": "_Test Project",
"exp_start_date": "2015-1-11",
"exp_end_date": "2015-1-15",
"depends_on":[
{
"task": task1.name,
"project": "_Test Project"
}
]
})
task2 = create_task("_Test Task 2", add_days(nowdate(), 11), add_days(nowdate(), 15), task1.name)
task2.get("depends_on")[0].project = "_Test Project"
task2.save()
task3 = frappe.new_doc('Task')
task3.update({
"status": "Open",
"subject": "_Test Task 3",
"project": "_Test Project",
"exp_start_date": "2015-1-16",
"exp_end_date": "2015-1-18",
"depends_on":[
{
"task": task2.name,
"project": "_Test Project"
}
]
})
task3 = create_task("_Test Task 3", add_days(nowdate(), 11), add_days(nowdate(), 15), task2.name)
task3.get("depends_on")[0].project = "_Test Project"
task3.save()
task1.update({
"exp_end_date": "2015-1-20"
"exp_end_date": add_days(nowdate(), 20)
})
task1.save()
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"),
getdate(add_days(nowdate(), 21)))
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"),
getdate(add_days(nowdate(), 25)))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"),
getdate(add_days(nowdate(), 26)))
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"),
getdate(add_days(nowdate(), 30)))
def test_close_assignment(self):
if not frappe.db.exists("Task", "Test Close Assignment"):
task = frappe.new_doc("Task")
task.subject = "Test Close Assignment"
task.insert()
@ -147,8 +71,10 @@ class TestTask(unittest.TestCase):
})
def get_owner_and_status():
return frappe.db.get_value("ToDo", filters={"reference_type": task.doctype, "reference_name": task.name,
"description": "Close this task"}, fieldname=("owner", "status"), as_dict=True)
return frappe.db.get_value("ToDo",
filters={"reference_type": task.doctype, "reference_name": task.name,
"description": "Close this task"},
fieldname=("owner", "status"), as_dict=True)
assign()
todo = get_owner_and_status()
@ -164,16 +90,29 @@ class TestTask(unittest.TestCase):
self.assertEquals(todo.status, "Closed")
def test_overdue(self):
task = frappe.get_doc({
"doctype":"Task",
"subject": "Testing Overdue",
"status": "Open",
"exp_end_date": add_days(nowdate(), -1)
})
task.insert()
task = create_task("Testing Overdue", add_days(nowdate(), -10), add_days(nowdate(), -5))
from erpnext.projects.doctype.task.task import set_tasks_as_overdue
set_tasks_as_overdue()
self.assertEquals(frappe.db.get_value("Task", task.name, "status"), "Overdue")
def create_task(subject, start=None, end=None, depends_on=None, project=None):
if not frappe.db.exists("Task", subject):
task = frappe.new_doc('Task')
task.status = "Open"
task.subject = subject
task.exp_start_date = start or nowdate()
task.exp_end_date = end or nowdate()
task.project = project or "_Test Project"
task.save()
else:
task = frappe.get_doc("Task", subject)
if depends_on:
task.append("depends_on", {
"task": depends_on
})
task.save()
return task

View File

@ -0,0 +1,99 @@
/* eslint-disable */
// rename this file from _test_[name] to test_[name] to activate
// and remove above this line
QUnit.test("test: Task Tree", function (assert) {
let done = assert.async();
// number of asserts
assert.expect(5);
frappe.run_serially([
// insert a new Task
() => frappe.set_route('Tree', 'Task'),
() => frappe.timeout(0.5),
// Checking adding child without selecting any Node
() => frappe.tests.click_button('New'),
() => frappe.timeout(0.5),
() => {assert.equal($(`.msgprint`).text(), "Select a group node first.", "Error message success");},
() => frappe.tests.click_button('Close'),
() => frappe.timeout(0.5),
// Creating child nodes
() => frappe.tests.click_link('task'),
() => frappe.map_group.make('Test-1'),
() => frappe.map_group.make('Test-2'),
() => frappe.map_group.make('Test-3', 1),
() => frappe.timeout(1),
() => frappe.tests.click_link('Test-3'),
() => frappe.map_group.make('Test-4', 0),
// Checking Edit button
() => frappe.timeout(0.5),
() => frappe.tests.click_link('Test-1'),
() => frappe.tests.click_button('Edit'),
() => frappe.timeout(0.5),
() => {assert.deepEqual(frappe.get_route(), ["Form", "Task", "Test-1"], "Edit route checks");},
// Deleting child Node
() => frappe.set_route('Tree', 'Task'),
() => frappe.timeout(0.5),
() => frappe.tests.click_link('Test-1'),
() => frappe.tests.click_button('Delete'),
() => frappe.timeout(0.5),
() => frappe.tests.click_button('Yes'),
// Deleting Group Node that has child nodes in it
() => frappe.timeout(0.5),
() => frappe.tests.click_link('Test-3'),
() => frappe.tests.click_button('Delete'),
() => frappe.timeout(0.5),
() => frappe.tests.click_button('Yes'),
() => frappe.timeout(1),
() => {assert.equal(cur_dialog.title, 'Message', 'Error thrown correctly');},
() => frappe.tests.click_button('Close'),
// Renaming Child node
() => frappe.timeout(0.5),
() => frappe.tests.click_link('Test-2'),
() => frappe.tests.click_button('Rename'),
() => frappe.timeout(1),
() => cur_dialog.set_value('new_name', 'Test-5'),
() => frappe.timeout(1.5),
() => cur_dialog.get_primary_btn().click(),
() => frappe.timeout(1),
() => {assert.equal($(`a:contains("Test-5"):visible`).length, 1, 'Rename successfull');},
// Add multiple child tasks
() => frappe.tests.click_link('Test-3'),
() => frappe.timeout(0.5),
() => frappe.click_button('Add Multiple'),
() => frappe.timeout(1),
() => cur_dialog.set_value('tasks', 'Test-6\nTest-7'),
() => frappe.timeout(0.5),
() => frappe.click_button('Submit'),
() => frappe.timeout(2),
() => frappe.click_button('Expand All'),
() => frappe.timeout(1),
() => {
let count = $(`a:contains("Test-6"):visible`).length + $(`a:contains("Test-7"):visible`).length;
assert.equal(count, 2, "Multiple Tasks added successfully");
},
() => done()
]);
});
frappe.map_group = {
make:function(subject, is_group = 0){
return frappe.run_serially([
() => frappe.click_button('Add Child'),
() => frappe.timeout(1),
() => cur_dialog.set_value('is_group', is_group),
() => cur_dialog.set_value('subject', subject),
() => frappe.click_button('Create New'),
() => frappe.timeout(1.5)
]);
}
};

View File

@ -235,8 +235,16 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
},
callback: function(r) {
if(!r.exc) {
me.frm.set_value("taxes", r.message);
me.calculate_taxes_and_totals();
frappe.run_serially([
() => {
// directly set in doc, so as not to call triggers
me.frm.doc.taxes_and_charges = r.message.taxes_and_charges;
// set taxes table
me.frm.set_value("taxes", r.message.taxes);
},
() => me.calculate_taxes_and_totals()
]);
}
}
});
@ -939,19 +947,27 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
return;
}
if (me.in_apply_price_list == true) return;
me.in_apply_price_list = true;
return this.frm.call({
method: "erpnext.stock.get_item_details.apply_price_list",
args: { args: args },
callback: function(r) {
if (!r.exc) {
me.in_apply_price_list = true;
me.frm.set_value("price_list_currency", r.message.parent.price_list_currency);
me.frm.set_value("plc_conversion_rate", r.message.parent.plc_conversion_rate);
me.in_apply_price_list = false;
frappe.run_serially([
() => me.frm.set_value("price_list_currency", r.message.parent.price_list_currency),
() => me.frm.set_value("plc_conversion_rate", r.message.parent.plc_conversion_rate),
() => {
if(args.items.length) {
me._set_values_for_item_list(r.message.children);
}
},
() => { me.in_apply_price_list = false; }
]);
} else {
me.in_apply_price_list = false;
}
}
});
@ -1116,7 +1132,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
filters: {'item': item.item_code}
}
} else {
filters = {
let filters = {
'item_code': item.item_code,
'posting_date': me.frm.doc.posting_date || frappe.datetime.nowdate(),
}

View File

@ -8,7 +8,7 @@
<input type="tel" class="form-control cell" disabled value="{%= price_list_rate %}"/>
</div>
<div class="pos-list-row">
<div class="cell">{{ __("Discount") }}:</div>
<div class="cell">{{ __("Discount") }}: %</div>
<input type="tel" class="form-control cell pos-item-disc" value="{%= discount_percentage %}">
</div>
<div class="pos-list-row">

View File

@ -38,7 +38,7 @@ $.extend(erpnext, {
},
stale_rate_allowed: () => {
return cint(frappe.boot.sysdefaults.allow_stale) || 1;
return cint(frappe.boot.sysdefaults.allow_stale);
},
setup_serial_no: function() {

View File

@ -43,7 +43,7 @@ class AssessmentPlan(Document):
assessment_criteria_list = frappe.db.sql_list(''' select apc.assessment_criteria
from `tabAssessment Plan` ap , `tabAssessment Plan Criteria` apc
where ap.name = apc.parent and ap.course=%s and ap.student_group=%s and ap.assessment_group=%s
and ap.name != %s''', (self.course, self.student_group, self.assessment_group, self.name))
and ap.name != %s and ap.docstatus=1''', (self.course, self.student_group, self.assessment_group, self.name))
for d in self.assessment_criteria:
if d.assessment_criteria in assessment_criteria_list:
frappe.throw(_("You have already assessed for the assessment criteria {}.")

View File

@ -2,7 +2,7 @@
QUnit.module('schools');
QUnit.test('Test: Assessment Plan', function(assert){
assert.expect(7);
assert.expect(6);
let done = assert.async();
let room_name, instructor_name, assessment_name;
@ -49,10 +49,6 @@ QUnit.test('Test: Assessment Plan', function(assert){
assert.equal(cur_frm.doc.assessment_plan, assessment_name, 'Assessment correctly set');
assert.equal(cur_frm.doc.student_group, 'test-course-wise-group-2', 'Course for Assessment correctly set');
},
() => cur_frm.print_doc(),
() => frappe.timeout(1),
() => {assert.ok($('.btn-print-print').is(':visible'), "Print Format Available");},
() => done()
]);
});

View File

@ -7,6 +7,7 @@ cur_frm.add_fetch("assessment_plan", "maximum_assessment_score", "maximum_score"
frappe.ui.form.on("Assessment Result", {
assessment_plan: function(frm) {
if (frm.doc.assessment_plan) {
frappe.call({
method: "erpnext.schools.api.get_assessment_details",
args: {
@ -25,12 +26,13 @@ frappe.ui.form.on("Assessment Result", {
}
});
}
}
});
frappe.ui.form.on("Assessment Result Detail", {
score: function(frm, cdt, cdn) {
var d = locals[cdt][cdn];
if (d.score >= d.maximum_score) {
if (d.score > d.maximum_score) {
frappe.throw(__("Score cannot be greater than Maximum Score"));
}
else {

View File

@ -12,10 +12,11 @@ frappe.ui.form.on('Assessment Result Tool', {
frm.set_value("student_group", frappe.route_options.student_group);
frm.set_value("assessment_plan", frappe.route_options.assessment_plan);
frappe.route_options = null;
} else {
frm.trigger("assessment_plan");
}
frm.disable_save();
frm.page.clear_indicator();
frm.trigger("assessment_plan");
},
assessment_plan: function(frm) {

View File

@ -175,7 +175,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-30 08:21:47.184562",
"modified": "2017-11-08 11:51:43.247815",
"modified_by": "Administrator",
"module": "Schools",
"name": "Assessment Result Tool",
@ -188,17 +188,17 @@
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"print": 0,
"read": 1,
"report": 0,
"role": "Academics User",
"set_user_permissions": 0,
"share": 1,
"share": 0,
"submit": 0,
"write": 1
}

View File

@ -90,7 +90,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-06-30 08:21:47.851347",
"modified": "2017-11-02 17:57:18.069158",
"modified_by": "Administrator",
"module": "Schools",
"name": "Fee Category",
@ -116,6 +116,46 @@
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
}
],
"quick_entry": 1,

View File

@ -25,7 +25,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_global_search": 1,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Fee Structure",
@ -1029,7 +1029,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-09-19 16:24:17.266071",
"modified": "2017-11-02 17:55:22.851581",
"modified_by": "Administrator",
"module": "Schools",
"name": "Fee Schedule",
@ -1039,7 +1039,7 @@
{
"amend": 1,
"apply_user_permissions": 0,
"cancel": 1,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
@ -1053,6 +1053,46 @@
"role": "Academics User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
}
@ -1060,6 +1100,7 @@
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Education",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",

View File

@ -9,6 +9,7 @@ from frappe.model.mapper import get_mapped_doc
from frappe.utils import money_in_words
from frappe.utils import cint, flt, cstr
from frappe.utils.background_jobs import enqueue
from frappe import _
class FeeSchedule(Document):
@ -57,6 +58,10 @@ def generate_fee(fee_schedule):
error = False
total_records = sum([int(d.total_students) for d in doc.student_groups])
created_records = 0
if not total_records:
frappe.throw(_("Please setup Students under Student Groups"))
for d in doc.student_groups:
students = frappe.db.sql(""" select sg.program, sg.batch, sgs.student, sgs.student_name
from `tabStudent Group` sg, `tabStudent Group Student` sgs

View File

@ -165,7 +165,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"reqd": 0,
"search_index": 1,
"set_only_once": 0,
"unique": 0,
@ -197,7 +197,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@ -577,7 +577,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-09-11 15:18:27.975666",
"modified": "2017-11-02 17:43:16.796845",
"modified_by": "Administrator",
"module": "Schools",
"name": "Fee Structure",
@ -587,7 +587,7 @@
{
"amend": 1,
"apply_user_permissions": 0,
"cancel": 1,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
@ -601,6 +601,46 @@
"role": "Academics User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
}
@ -609,6 +649,7 @@
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Education",
"search_fields": "program, student_category, academic_year",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",

View File

@ -1,7 +1,7 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_import": 1,
"allow_rename": 0,
"autoname": "naming_series:",
"beta": 1,
@ -87,7 +87,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Student Name",
@ -118,7 +118,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Fee Schedule",
@ -158,7 +158,7 @@
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -249,7 +249,7 @@
"options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 1,
@ -310,7 +310,7 @@
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -494,7 +494,7 @@
"options": "Student Batch Name",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -708,7 +708,7 @@
"options": "Currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
@ -739,7 +739,7 @@
"options": "Fee Structure",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -1011,7 +1011,7 @@
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -1132,7 +1132,7 @@
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -1163,7 +1163,7 @@
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -1194,7 +1194,7 @@
"options": "Account",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -1223,7 +1223,7 @@
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@ -1254,6 +1254,35 @@
"options": "Cost Center",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"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": "data_42",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
@ -1276,13 +1305,53 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-09-20 23:17:09.819606",
"modified": "2017-11-02 17:31:47.155873",
"modified_by": "Administrator",
"module": "Schools",
"name": "Fees",
"name_case": "",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Academics User",
"set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
},
{
"amend": 0,
"apply_user_permissions": 0,
@ -1297,7 +1366,7 @@
"print": 1,
"read": 1,
"report": 1,
"role": "Academics User",
"role": "Accounts Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
@ -1308,7 +1377,8 @@
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Education",
"show_name_in_global_search": 0,
"search_fields": "student, student_name",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "student_name",

View File

@ -223,67 +223,6 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "fee_schedule",
"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": "Fee Schedule",
"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": "fees",
"fieldtype": "Table",
"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": "Fees",
"length": 0,
"no_copy": 0,
"options": "Program Fee",
"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,
@ -297,7 +236,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2017-06-30 08:21:49.176708",
"modified": "2017-11-02 18:08:20.823972",
"modified_by": "Administrator",
"module": "Schools",
"name": "Program",

View File

@ -12,10 +12,14 @@ class StudentApplicant(Document):
def autoname(self):
from frappe.model.naming import set_name_by_naming_series
if self.student_admission:
naming_series = None
if self.program:
# set the naming series from the student admission if provided.
student_admission = get_student_admission_data(self.student_admission, self.program)
if student_admission:
naming_series = student_admission.get("applicant_naming_series")
else:
naming_series = None
else:
frappe.throw(_("Select the program first"))
@ -40,16 +44,17 @@ class StudentApplicant(Document):
def validation_from_student_admission(self):
student_admission = get_student_admission_data(self.student_admission, self.program)
if student_admission:
if ((
student_admission.minimum_age
and getdate(student_admission.minimum_age) > getdate(self.date_of_birth)
) or (
student_admission.maximum_age
and getdate(student_admission.maximum_age) < getdate(self.date_of_birth)
)):
# different validation for minimum and maximum age so that either min/max can also work independently.
if student_admission and student_admission.minimum_age and \
getdate(student_admission.minimum_age) < getdate(self.date_of_birth):
frappe.throw(_("Not eligible for the admission in this program as per DOB"))
if student_admission and student_admission.maximum_age and \
getdate(student_admission.maximum_age) > getdate(self.date_of_birth):
frappe.throw(_("Not eligible for the admission in this program as per DOB"))
def on_payment_authorized(self, *args, **kwargs):
self.db_set('paid', 1)

View File

@ -273,7 +273,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2017-06-30 08:21:51.390809",
"modified": "2017-11-08 11:53:27.994112",
"modified_by": "Administrator",
"module": "Schools",
"name": "Student Attendance Tool",
@ -306,17 +306,17 @@
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"print": 0,
"read": 1,
"report": 0,
"role": "Academics User",
"set_user_permissions": 0,
"share": 1,
"share": 0,
"submit": 0,
"write": 1
}

View File

@ -7,6 +7,7 @@ import frappe
from frappe.model.document import Document
from frappe import _
from erpnext.schools.utils import validate_duplicate_student
from frappe.utils import cint
class StudentGroup(Document):
def validate(self):
@ -34,9 +35,13 @@ class StudentGroup(Document):
for d in self.students:
if not frappe.db.get_value("Student", d.student, "enabled") and d.active:
frappe.throw(_("{0} - {1} is inactive student".format(d.group_roll_number, d.student_name)))
if self.group_based_on == "Batch" and d.student not in students and frappe.defaults.get_defaults().validate_batch:
if (self.group_based_on == "Batch") and cint(frappe.defaults.get_defaults().validate_batch)\
and d.student not in students:
frappe.throw(_("{0} - {1} is not enrolled in the Batch {2}".format(d.group_roll_number, d.student_name, self.batch)))
if self.group_based_on == "Course" and d.student not in students and frappe.defaults.get_defaults().validate_course:
if (self.group_based_on == "Course") and cint(frappe.defaults.get_defaults().validate_course)\
and (d.student not in students):
frappe.throw(_("{0} - {1} is not enrolled in the Course {2}".format(d.group_roll_number, d.student_name, self.course)))
def validate_and_set_child_table_fields(self):
@ -108,14 +113,14 @@ def fetch_students(doctype, txt, searchfield, start, page_len, filters):
students = ([d.student for d in enrolled_students if d.student not in student_group_student]
if enrolled_students else [""]) or [""]
return frappe.db.sql("""select name, title from tabStudent
where name in ({0}) and `{1}` LIKE %s
where name in ({0}) and (`{1}` LIKE %s or title LIKE %s)
order by idx desc, name
limit %s, %s""".format(", ".join(['%s']*len(students)), searchfield),
tuple(students + ["%%%s%%" % txt, start, page_len]))
tuple(students + ["%%%s%%" % txt, "%%%s%%" % txt, start, page_len]))
else:
return frappe.db.sql("""select name, title from tabStudent
where `{0}` LIKE %s
where `{0}` LIKE %s or title LIKE %s
order by idx desc, name
limit %s, %s""".format(searchfield),
tuple(["%%%s%%" % txt, start, page_len]))
tuple(["%%%s%%" % txt, "%%%s%%" % txt, start, page_len]))

Some files were not shown because too many files have changed in this diff Show More