Merge branch 'develop' into eval-group

This commit is contained in:
Neil Trini Lasrado 2017-02-02 17:30:10 +05:30 committed by GitHub
commit f37d329cf5
81 changed files with 2148 additions and 1146 deletions

View File

@ -86,9 +86,9 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
};
});
me.frm.set_query("party_type", "accounts", function(doc, cdt, cdn) {
return {
filters: {"name": ["in", ["Customer", "Supplier"]]}
me.frm.set_query("party_type", "accounts", function() {
return{
query: "erpnext.setup.doctype.party_type.party_type.get_party_type"
}
});

View File

@ -9,6 +9,7 @@ from erpnext.controllers.accounts_controller import AccountsController
from erpnext.accounts.utils import get_balance_on, get_account_currency
from erpnext.setup.utils import get_company_currency
from erpnext.accounts.party import get_party_account
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
class JournalEntry(AccountsController):
def __init__(self, arg1, arg2=None):
@ -375,7 +376,7 @@ class JournalEntry(AccountsController):
bank_amount = party_amount = total_amount = 0.0
currency = bank_account_currency = party_account_currency = pay_to_recd_from= None
for d in self.get('accounts'):
if d.party_type and d.party:
if d.party_type in ['Customer', 'Supplier'] and d.party:
if not pay_to_recd_from:
pay_to_recd_from = frappe.db.get_value(d.party_type, d.party,
"customer_name" if d.party_type=="Customer" else "supplier_name")
@ -503,11 +504,9 @@ class JournalEntry(AccountsController):
def update_expense_claim(self):
for d in self.accounts:
if d.reference_type=="Expense Claim":
amt = frappe.db.sql("""select sum(debit) as amt from `tabJournal Entry Account`
where reference_type = "Expense Claim" and
reference_name = %s and docstatus = 1""", d.reference_name ,as_dict=1)[0].amt
frappe.db.set_value("Expense Claim", d.reference_name , "total_amount_reimbursed", amt)
if d.reference_type=="Expense Claim" and d.party:
doc = frappe.get_doc("Expense Claim", d.reference_name)
update_reimbursed_amount(doc)
def validate_expense_claim(self):
for d in self.accounts:

View File

@ -26,6 +26,12 @@ frappe.ui.form.on('Payment Entry', {
}
});
frm.set_query("party_type", function() {
return{
query: "erpnext.setup.doctype.party_type.party_type.get_party_type"
}
});
frm.set_query("paid_to", function() {
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
["Bank", "Cash"] : party_account_type;

View File

@ -97,95 +97,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)",
"fieldname": "party_type",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Party Type",
"length": 0,
"no_copy": 0,
"options": "Customer\nSupplier",
"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_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
"fieldname": "party",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Party",
"length": 0,
"no_copy": 0,
"options": "party_type",
"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_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "party_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Party Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -300,6 +211,152 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
"fieldname": "party_section",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment From / To",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type)",
"fieldname": "party_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Party Type",
"length": 0,
"no_copy": 0,
"options": "DocType",
"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_on_submit": 0,
"bold": 1,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
"fieldname": "party",
"fieldtype": "Dynamic Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Party",
"length": 0,
"no_copy": 0,
"options": "party_type",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_11",
"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,
"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_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "eval:in_list([\"Receive\", \"Pay\"], doc.payment_type) && doc.party_type",
"description": "",
"fieldname": "party_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Party Name",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -1561,7 +1618,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-11-07 05:33:40.371480",
"modified": "2017-01-30 00:41:51.348616",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",
@ -1578,7 +1635,6 @@
"export": 1,
"if_owner": 0,
"import": 1,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1599,7 +1655,6 @@
"export": 1,
"if_owner": 0,
"import": 1,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1617,5 +1672,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 0,
"track_seen": 0
}

View File

@ -6,12 +6,10 @@ frappe.provide("erpnext.accounts");
erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.extend({
onload: function() {
var me = this
this.frm.set_query('party_type', function() {
return {
filters: {
"name": ["in", ["Customer", "Supplier"]]
}
};
this.frm.set_query("party_type", function() {
return{
query: "erpnext.setup.doctype.party_type.party_type.get_party_type"
}
});
this.frm.set_query('receivable_payable_account', function() {

View File

@ -22,6 +22,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference Type",
"length": 0,
"no_copy": 0,
@ -30,6 +31,7 @@
"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,
@ -48,7 +50,8 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Reference_name",
"in_standard_filter": 0,
"label": "Reference Name",
"length": 0,
"no_copy": 0,
"options": "reference_type",
@ -57,6 +60,7 @@
"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,
@ -75,6 +79,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Posting Date",
"length": 0,
"no_copy": 0,
@ -82,6 +87,7 @@
"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,
@ -100,6 +106,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is Advance",
"length": 0,
"no_copy": 0,
@ -107,6 +114,7 @@
"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,
@ -125,6 +133,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reference Row",
"length": 0,
"no_copy": 0,
@ -132,6 +141,7 @@
"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,
@ -150,6 +160,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
"length": 0,
"no_copy": 0,
@ -157,6 +168,7 @@
"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,
@ -175,6 +187,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Invoice Number",
"length": 0,
"no_copy": 0,
@ -183,6 +196,7 @@
"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,
@ -201,6 +215,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Amount",
"length": 0,
"no_copy": 0,
@ -208,6 +223,7 @@
"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,
@ -226,6 +242,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Allocated amount",
"length": 0,
"no_copy": 0,
@ -234,6 +251,7 @@
"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,
@ -252,6 +270,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
"length": 0,
"no_copy": 0,
@ -259,6 +278,7 @@
"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,
@ -277,6 +297,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Remark",
"length": 0,
"no_copy": 0,
@ -284,6 +305,7 @@
"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,
@ -302,7 +324,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
"modified": "2016-08-26 02:08:35.879133",
"modified": "2017-01-30 01:04:22.557237",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Payment",
@ -314,5 +336,6 @@
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}

View File

@ -30,6 +30,7 @@ def get_pos_data():
'doc': doc,
'default_customer': pos_profile.get('customer'),
'items': get_items_list(pos_profile),
'item_groups': get_item_group(pos_profile),
'customers': get_customers_list(pos_profile),
'serial_no_data': get_serial_no_data(pos_profile, doc.company),
'batch_no_data': get_batch_no_data(),
@ -140,6 +141,15 @@ def get_items_list(pos_profile):
disabled = 0 and has_variants = 0 and is_sales_item = 1 and {cond}
""".format(cond=cond), tuple(item_groups), as_dict=1)
def get_item_group(pos_profile):
if pos_profile.get('item_groups'):
item_groups = []
for d in pos_profile.get('item_groups'):
item_groups.extend(get_child_nodes('Item Group', d.item_group))
return item_groups
else:
return frappe.db.sql_list("""Select name from `tabItem Group` order by name""")
def get_customers_list(pos_profile):
cond = "1=1"
customer_groups = []
@ -276,11 +286,33 @@ def validate_customer(doc):
customer_doc = frappe.new_doc('Customer')
customer_doc.customer_name = doc.get('customer')
customer_doc.customer_type = 'Company'
customer_doc.customer_group = doc.get('customer_group')
customer_doc.territory = doc.get('territory')
customer_doc.customer_group = frappe.db.get_single_value('Selling Settings', 'customer_group')
customer_doc.territory = frappe.db.get_single_value('Selling Settings', 'territory')
customer_doc.flags.ignore_mandatory = True
customer_doc.save(ignore_permissions = True)
frappe.db.commit()
doc['customer'] = customer_doc.name
if doc.get('contact_details'):
args = json.loads(doc.get("contact_details"))
make_address(doc, args, customer_doc.name)
def make_address(doc, args, customer):
if args.get("address_line1"):
address = frappe.new_doc('Address')
address.address_line1 = args.get('address_line1')
address.address_line2 = args.get('address_line2')
address.city = args.get('city')
address.state = args.get('state')
address.zip_code = args.get('zip_code')
address.email_id = args.get('email_id')
address.flags.ignore_mandatory = True
address.country = frappe.db.get_value('Company', doc.get('company'), 'country')
address.append('links',{
'link_doctype': 'Customer',
'link_name': customer
})
address.save(ignore_permissions = True)
frappe.db.commit()
def validate_item(doc):
for item in doc.get('items'):

View File

@ -28,7 +28,7 @@
"label": "",
"length": 0,
"no_copy": 0,
"options": "fa fa-user",
"options": "icon-user",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@ -232,7 +232,7 @@
"in_standard_filter": 0,
"label": "Offline POS Name",
"length": 0,
"no_copy": 0,
"no_copy": 1,
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -1035,7 +1035,7 @@
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "fa fa-shopping-cart",
"options": "icon-shopping-cart",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@ -1122,7 +1122,7 @@
"label": "Packing List",
"length": 0,
"no_copy": 0,
"options": "fa fa-suitcase",
"options": "icon-suitcase",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -1462,7 +1462,7 @@
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "fa fa-money",
"options": "icon-money",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@ -1941,7 +1941,7 @@
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "fa fa-money",
"options": "icon-money",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -2238,7 +2238,7 @@
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "fa fa-money",
"options": "icon-money",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -2327,7 +2327,7 @@
"label": "Payments",
"length": 0,
"no_copy": 0,
"options": "fa fa-money",
"options": "icon-money",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@ -3252,7 +3252,7 @@
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "fa fa-file-text",
"options": "icon-file-text",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -3515,7 +3515,7 @@
"length": 0,
"no_copy": 0,
"oldfieldtype": "Section Break",
"options": "fa fa-group",
"options": "icon-group",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -3720,7 +3720,7 @@
"label": "Recurring",
"length": 0,
"no_copy": 0,
"options": "fa fa-time",
"options": "icon-time",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -4173,7 +4173,7 @@
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-file-text",
"icon": "icon-file-text",
"idx": 181,
"image_view": 0,
"in_create": 0,
@ -4282,5 +4282,6 @@
"sort_order": "DESC",
"timeline_field": "customer",
"title_field": "title",
"track_changes": 1,
"track_seen": 0
}

View File

@ -963,40 +963,6 @@ class TestSalesInvoice(unittest.TestCase):
si.insert()
self.assertEqual(si.get("items")[0].rate, flt((price_list_rate*25)/100 + price_list_rate))
def test_party_status(self):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from frappe.utils import random_string
customer_name = 'test customer for status'
if frappe.db.exists('Customer', customer_name):
customer = frappe.get_doc('Customer', customer_name)
customer.db_set('status', 'Active')
else:
customer = frappe.get_doc({
'doctype': 'Customer',
'customer_name': customer_name,
'customer_group': 'Commercial',
'customer_type': 'Individual',
'territory': 'Rest of the World'
}).insert()
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Active')
invoice = create_sales_invoice(customer="test customer for status",
debit_to="_Test Receivable - _TC",
currency="USD", conversion_rate=50)
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Open')
pe = get_payment_entry(invoice.doctype, invoice.name)
pe.reference_no = random_string(10)
pe.reference_date = invoice.posting_date
pe.insert()
pe.submit()
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Active')
def test_outstanding_amount_after_advance_jv_cancelation(self):
from erpnext.accounts.doctype.journal_entry.test_journal_entry \
import test_records as jv_test_records

File diff suppressed because it is too large Load Diff

View File

@ -171,13 +171,13 @@ def get_party_account(party_type, party, company):
account = frappe.db.get_value("Party Account",
{"parenttype": party_type, "parent": party, "company": company}, "account")
if not account:
if not account and party_type in ['Customer', 'Supplier']:
party_group_doctype = "Customer Group" if party_type=="Customer" else "Supplier Type"
group = frappe.db.get_value(party_type, party, scrub(party_group_doctype))
account = frappe.db.get_value("Party Account",
{"parenttype": party_group_doctype, "parent": group, "company": company}, "account")
if not account:
if not account and party_type in ['Customer', 'Supplier']:
default_account_name = "default_receivable_account" \
if party_type=="Customer" else "default_payable_account"
account = frappe.db.get_value("Company", company, default_account_name)
@ -249,7 +249,7 @@ def validate_party_accounts(doc):
if existing_gle_currency and party_account_currency != existing_gle_currency:
frappe.throw(_("Accounting entries have already been made in currency {0} for company {1}. Please select a receivable or payable account with currency {0}.").format(existing_gle_currency, account.company))
if doc.default_currency and party_account_currency and company_default_currency:
if doc.get("default_currency") and party_account_currency and company_default_currency:
if doc.default_currency != party_account_currency and doc.default_currency != company_default_currency:
frappe.throw(_("Billing currency must be equal to either default comapany's currency or party account currency"))

View File

@ -1,81 +0,0 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.utils import evaluate_filters
from frappe.desk.notifications import get_filters_for
# NOTE: if you change this also update triggers in erpnext/hooks.py
status_depends_on = {
'Customer': ('Opportunity', 'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice', 'Project', 'Issue'),
'Supplier': ('Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice')
}
default_status = {
'Customer': 'Active',
'Supplier': None
}
def notify_status(doc, method=None):
'''Notify status to customer, supplier'''
party_type = None
for key, doctypes in status_depends_on.iteritems():
if doc.doctype in doctypes:
party_type = key
break
if not party_type:
return
name = doc.get(party_type.lower())
if not name:
return
party = frappe.get_doc(party_type, name)
filters = get_filters_for(doc.doctype)
party.flags.ignore_mandatory = True
status = None
if filters:
if evaluate_filters(doc, filters):
# filters match, passed document is open
status = 'Open'
if status=='Open':
if party.status != 'Open':
# party not open, make it open
party.status = 'Open'
party.save(ignore_permissions=True)
else:
if party.status == 'Open':
# may be open elsewhere, check
# default status
update_status(party)
party.update_modified()
party.notify_update()
def get_party_status(doc):
'''return party status based on open documents'''
status = default_status[doc.doctype]
for doctype in status_depends_on[doc.doctype]:
filters = get_filters_for(doctype)
filters[doc.doctype.lower()] = doc.name
if filters:
open_count = frappe.get_all(doctype, fields='name', filters=filters, limit_page_length=1)
if len(open_count) > 0:
status = 'Open'
break
return status
def update_status(doc):
'''Set status as open if there is any open notification'''
status = get_party_status(doc)
if doc.status != status:
doc.db_set('status', status)

View File

@ -59,8 +59,8 @@ frappe.query_reports["General Ledger"] = {
{
"fieldname":"party_type",
"label": __("Party Type"),
"fieldtype": "Select",
"options": ["", "Customer", "Supplier"],
"fieldtype": "Link",
"options": "Party Type",
"default": ""
},
{

View File

@ -0,0 +1,12 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Unpaid Expense Claim"] = {
"filters": [
{
"fieldname":"employee",
"label": __("Employee"),
"fieldtype": "Link"
}
]
}

View File

@ -0,0 +1,18 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2017-01-04 16:26:18.309717",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2017-01-04 16:26:18.309717",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Unpaid Expense Claim",
"owner": "Administrator",
"ref_doctype": "Expense Claim",
"report_name": "Unpaid Expense Claim",
"report_type": "Script Report"
}

View File

@ -0,0 +1,34 @@
# 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_unclaimed_expese_claims(filters)
return columns, data
def get_columns():
return [_("Employee") + ":Link/Employee:120", _("Employee Name") + "::120",_("Expense Claim") + ":Link/Expense Claim:120",
_("Sanctioned Amount") + ":Currency:120", _("Paid Amount") + ":Currency:120", _("Outstanding Amount") + ":Currency:150"]
def get_unclaimed_expese_claims(filters):
cond = "1=1"
if filters.get("employee"):
cond = "ec.employee = %(employee)s"
return frappe.db.sql("""
select
ec.employee, ec.employee_name, ec.name, ec.total_sanctioned_amount, ec.total_amount_reimbursed,
sum(gle.credit_in_account_currency - gle.debit_in_account_currency) as outstanding_amt
from
`tabExpense Claim` ec, `tabGL Entry` gle
where
gle.against_voucher_type = "Expense Claim" and gle.against_voucher = ec.name
and gle.party is not null and ec.docstatus = 1 and ec.is_paid = 0 and {cond} group by ec.name
having
outstanding_amt > 0
""".format(cond=cond), filters, as_list=1)

View File

@ -158,35 +158,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Status",
"length": 0,
"no_copy": 0,
"options": "\nOpen",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -796,7 +767,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-11-07 05:24:30.465053",
"modified": "2017-01-30 00:52:31.193443",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",
@ -813,7 +784,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -834,7 +804,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -855,7 +824,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -876,7 +844,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 0,
"read": 1,
@ -897,7 +864,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -918,7 +884,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 0,
"read": 1,
@ -939,7 +904,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -957,5 +921,6 @@
"search_fields": "supplier_name, supplier_type",
"sort_order": "ASC",
"title_field": "supplier_name",
"track_changes": 0,
"track_seen": 0
}

View File

@ -11,7 +11,6 @@ from frappe.geo.address_and_contact import (load_address_and_contact,
from erpnext.utilities.transaction_base import TransactionBase
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
from erpnext.accounts.party_status import get_party_status
class Supplier(TransactionBase):
def get_feed(self):
@ -59,7 +58,6 @@ class Supplier(TransactionBase):
msgprint(_("Series is mandatory"), raise_exception=1)
validate_party_accounts(self)
self.status = get_party_status(self)
def on_trash(self):
delete_contact_and_address('Supplier', self.name)

View File

@ -1,8 +1,3 @@
frappe.listview_settings['Supplier'] = {
add_fields: ["supplier_name", "supplier_type", 'status'],
get_indicator: function(doc) {
if(doc.status==="Open") {
return [doc.status, "red", "status,=," + doc.status];
}
}
add_fields: ["supplier_name", "supplier_type"],
};

View File

@ -49,6 +49,11 @@ def get_data():
"name": "Stock Projected Qty",
"doctype": "Item",
},
{
"type": "page",
"name": "stock-balance",
"label": _("Stock Summary")
},
{
"type": "report",
"is_query_report": True,

View File

@ -6,7 +6,6 @@ import frappe
from frappe.utils import flt, comma_or, nowdate, getdate
from frappe import _
from frappe.model.document import Document
from erpnext.accounts.party_status import notify_status
def validate_status(status, options):
if status not in options:
@ -287,7 +286,6 @@ class StatusUpdater(Document):
target = frappe.get_doc(args["target_parent_dt"], args["name"])
target.set_status(update=True)
target.notify_update()
notify_status(target)
def _update_modified(self, args, update_modified):
args['update_modified'] = ''

View File

@ -4,7 +4,8 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import cstr, validate_email_add, cint, comma_and, has_gravatar, nowdate
from frappe.utils import (cstr, validate_email_add, cint, comma_and, has_gravatar,
getdate, nowdate)
from frappe.model.mapper import get_mapped_doc
from erpnext.controllers.selling_controller import SellingController
@ -45,7 +46,7 @@ class Lead(SellingController):
self.image = has_gravatar(self.email_id)
if self.contact_date and self.contact_date < nowdate():
if self.contact_date and getdate(self.contact_date) < nowdate():
frappe.throw(_("Next Contact Date cannot be in the past"))
def on_update(self):

View File

@ -6,6 +6,7 @@ from frappe.utils import random_string, add_days, get_last_day, getdate
from erpnext.projects.doctype.timesheet.test_timesheet import make_timesheet
from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice
from frappe.utils.make_random import get_random
from erpnext.hr.doctype.expense_claim.test_expense_claim import get_payable_account
from erpnext.hr.doctype.expense_claim.expense_claim import get_expense_approver, make_bank_entry
from erpnext.hr.doctype.leave_application.leave_application import (get_leave_balance_on,
OverlapError, AttendanceAlreadyMarkedError)
@ -50,6 +51,7 @@ def work():
expense_claim.extend('expenses', get_expenses())
expense_claim.employee = get_random("Employee")
expense_claim.company = frappe.flags.company
expense_claim.payable_account = get_payable_account(expense_claim.company)
expense_claim.posting_date = frappe.flags.current_date
expense_claim.exp_approver = filter((lambda x: x[0] != 'Administrator'), get_expense_approver(None, '', None, 0, 20, None))[0][0]
expense_claim.insert()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -9,6 +9,10 @@ To make a new Expense Claim, go to:
Set the Employee ID, date and the list of expenses that are to be claimed and
“Submit” the record.
### Set Account for Employee
Set employee's expense account on the employee form, system books an expense amount of an employee under this account.
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/employee_account.png">
### Approving Expenses
Approver for the Expense Claim is selected by an Employee himself. Users to whom `Expense Approver` role is assigned will shown in the Expense Claim Approver field.
@ -18,11 +22,25 @@ After saving Expense Claim, Employee should [Assign document to Approver]({{docs
Expense Claim Approver can update the “Sanctioned Amounts” against Claimed Amount of an Employee. If submitting, Approval Status should be submitted to Approved or Rejected. If Approved, then Expense Claim gets submitted. If rejected, then Expen
Comments can be added in the Comments section explaining why the claim was approved or rejected.
### Booking the Expense and Reimbursement
### Booking the Expense
The approved Expense Claim must then be converted into a Journal Entry and a
payment must be made. Note: This amount should not be clubbed with Salary
because the amount will then be taxable to the Employee.
On submission of Expense Claim, system books an expense against the expense account and the employee account
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/expense_claim_book.png">
User can view unpaid expense claim using report "Unclaimed Expense Claims"
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/unclaimed_expense_claims.png">
### Payment for Expense Claim
To make payment against the expense claim, user has to click on Make > Bank Entry
#### Expense Claim
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/payment.png">
#### Payment Entry
<img class="screenshot" alt="Expense Claim" src="{{docs_base_url}}/assets/img/human-resources/payment_entry.png">
Note: This amount should not be clubbed with Salary because the amount will then be taxable to the Employee.
### Linking with Task & Project

View File

@ -147,13 +147,6 @@ doc_events = {
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
},
# bubble transaction notification on master
('Opportunity', 'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
'Supplier Quotation', 'Purchase Order', 'Purchase Receipt',
'Purchase Invoice', 'Project', 'Issue'): {
'on_change': 'erpnext.accounts.party_status.notify_status'
},
"Website Settings": {
"validate": "erpnext.portal.doctype.products_settings.products_settings.home_page_is_products"
},

View File

@ -111,12 +111,11 @@ def check_repayment_method(repayment_method, loan_amount, monthly_repayment_amou
frappe.throw(_("Monthly Repayment Amount cannot be greater than Loan Amount"))
def get_monthly_repayment_amount(repayment_method, loan_amount, rate_of_interest, repayment_periods):
if repayment_method == "Repay Over Number of Periods":
if rate_of_interest:
monthly_interest_rate = flt(rate_of_interest) / (12 *100)
monthly_repayment_amount = math.ceil((loan_amount * monthly_interest_rate *
(1 + monthly_interest_rate)**repayment_periods) \
/ ((1 + monthly_interest_rate)**repayment_periods - 1))
if rate_of_interest:
monthly_interest_rate = flt(rate_of_interest) / (12 *100)
monthly_repayment_amount = math.ceil((loan_amount * monthly_interest_rate *
(1 + monthly_interest_rate)**repayment_periods) \
/ ((1 + monthly_interest_rate)**repayment_periods - 1))
else:
monthly_repayment_amount = math.ceil(flt(loan_amount) / repayment_periods)
return monthly_repayment_amount

View File

@ -158,6 +158,21 @@ erpnext.expense_claim = {
}
}
frappe.ui.form.on("Expense Claim", {
refresh: function(frm) {
if(frm.doc.docstatus == 1) {
frm.add_custom_button(__('Accounting Ledger'), function() {
frappe.route_options = {
voucher_no: frm.doc.name,
company: frm.doc.company,
group_by_voucher: false
};
frappe.set_route("query-report", "General Ledger");
}, __("View"));
}
}
})
frappe.ui.form.on("Expense Claim Detail", {
claim_amount: function(frm, cdt, cdn) {
var child = locals[cdt][cdn];
@ -176,6 +191,47 @@ frappe.ui.form.on("Expense Claim Detail", {
}
})
frappe.ui.form.on("Expense Claim",{
setup: function(frm) {
frm.trigger("set_query_for_cost_center")
frm.trigger("set_query_for_payable_account")
frm.add_fetch("company", "cost_center", "cost_center");
frm.add_fetch("company", "default_payable_account", "payable_account");
},
refresh: function(frm) {
frm.trigger("toggle_fields")
},
set_query_for_cost_center: function(frm) {
frm.fields_dict["cost_center"].get_query = function() {
return {
filters: {
"company": frm.doc.company
}
}
}
},
set_query_for_payable_account: function(frm) {
frm.fields_dict["payable_account"].get_query = function() {
return {
filters: {
"root_type": "Liability",
"account_type": "Payable"
}
}
}
},
is_paid: function(frm) {
frm.trigger("toggle_fields")
},
toggle_fields: function(frm) {
frm.toggle_reqd("mode_of_payment", frm.doc.is_paid)
}
});
frappe.ui.form.on("Expense Claim", "employee_name", function(frm) {
erpnext.expense_claim.set_title(frm);

View File

@ -41,6 +41,34 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "is_paid",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is Paid",
"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_on_submit": 0,
"bold": 0,
@ -55,7 +83,7 @@
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 1,
"in_standard_filter": 0,
"label": "Approval Status",
"length": 0,
"no_copy": 1,
@ -86,7 +114,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"in_standard_filter": 0,
"label": "Approver",
"length": 0,
"no_copy": 0,
@ -175,7 +203,7 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Total Sanctioned Amount",
"length": 0,
@ -322,7 +350,7 @@
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 1,
"in_standard_filter": 0,
"label": "From Employee",
"length": 0,
"no_copy": 0,
@ -370,36 +398,6 @@
"unique": 0,
"width": "150px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Company",
"length": 0,
"no_copy": 0,
"oldfieldname": "company",
"oldfieldtype": "Link",
"options": "Company",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 1,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -429,90 +427,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cb1",
"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,
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_amount_reimbursed",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Amount Reimbursed",
"length": 0,
"no_copy": 1,
"options": "Company:company:default_currency",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "remark",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Remark",
"length": 0,
"no_copy": 1,
"oldfieldname": "remark",
"oldfieldtype": "Small Text",
"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_on_submit": 0,
"bold": 0,
@ -571,6 +485,90 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cb1",
"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,
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_amount_reimbursed",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Total Amount Reimbursed",
"length": 0,
"no_copy": 1,
"options": "Company:company:default_currency",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "remark",
"fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Remark",
"length": 0,
"no_copy": 1,
"oldfieldname": "remark",
"oldfieldtype": "Small Text",
"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_on_submit": 1,
"bold": 0,
@ -613,7 +611,7 @@
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employees Email Address",
"label": "Employees Email Id",
"length": 0,
"no_copy": 0,
"oldfieldname": "email_id",
@ -629,6 +627,238 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "accounting_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounting Details",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
"length": 0,
"no_copy": 0,
"oldfieldname": "company",
"oldfieldtype": "Link",
"options": "Company",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 1,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "is_paid",
"fieldname": "mode_of_payment",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Mode of Payment",
"length": 0,
"no_copy": 0,
"options": "Mode of Payment",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_24",
"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,
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "payable_account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payable Account",
"length": 0,
"no_copy": 0,
"options": "Account",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "cost_center",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employees Email Address",
"length": 0,
"no_copy": 0,
"options": "Cost Center",
"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_on_submit": 0,
"bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "more_details",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "More Details",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Draft",
"fieldname": "status",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Status",
"length": 0,
"no_copy": 1,
"options": "Draft\nPaid\nUnpaid\nSubmitted\nCancelled",
"permlevel": 0,
"precision": "",
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
@ -663,7 +893,7 @@
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-money",
"icon": "icon-money",
"idx": 1,
"image_view": 0,
"in_create": 0,
@ -673,10 +903,11 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2016-11-07 05:52:48.548201",
"modified": "2017-01-19 18:15:35.968292",
"modified_by": "Administrator",
"module": "HR",
"name": "Expense Claim",
"name_case": "Title Case",
"owner": "harshada@webnotestech.com",
"permissions": [
{
@ -689,7 +920,6 @@
"export": 1,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -710,7 +940,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -732,7 +961,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -754,7 +982,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -775,5 +1002,6 @@
"sort_order": "DESC",
"timeline_field": "employee",
"title_field": "title",
"track_changes": 0,
"track_seen": 0
}

View File

@ -4,13 +4,17 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import get_fullname, flt
from frappe.utils import get_fullname, flt, cstr
from frappe.model.document import Document
from erpnext.hr.utils import set_employee_name
from erpnext.accounts.party import get_party_account
from erpnext.accounts.general_ledger import make_gl_entries
from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account
from erpnext.controllers.accounts_controller import AccountsController
class InvalidExpenseApproverError(frappe.ValidationError): pass
class ExpenseClaim(Document):
class ExpenseClaim(AccountsController):
def get_feed(self):
return _("{0}: From {0} for {1}").format(self.approval_status,
self.employee_name, self.total_claimed_amount)
@ -21,16 +25,53 @@ class ExpenseClaim(Document):
self.calculate_total_amount()
set_employee_name(self)
self.set_expense_account()
self.set_payable_account()
self.set_cost_center()
self.set_status()
if self.task and not self.project:
self.project = frappe.db.get_value("Task", self.task, "project")
def set_status(self):
self.status = {
"0": "Draft",
"1": "Submitted",
"2": "Cancelled"
}[cstr(self.docstatus or 0)]
if self.total_sanctioned_amount == self.total_amount_reimbursed and self.docstatus == 1:
self.status = "Paid"
elif self.docstatus == 1:
self.status = "Unpaid"
def set_payable_account(self):
if not self.payable_account and not self.is_paid:
self.payable_account = frappe.db.get_value("Company", self.company, "default_payable_account")
def set_cost_center(self):
if not self.cost_center:
self.cost_center = frappe.db.get_value('Company', self.company, 'cost_center')
def on_submit(self):
if self.approval_status=="Draft":
frappe.throw(_("""Approval Status must be 'Approved' or 'Rejected'"""))
self.update_task_and_project()
self.make_gl_entries()
if self.is_paid:
update_reimbursed_amount(self)
self.set_status()
def on_cancel(self):
self.update_task_and_project()
if self.payable_account:
self.make_gl_entries(cancel=True)
if self.is_paid:
update_reimbursed_amount(self)
self.set_status()
def update_task_and_project(self):
if self.task:
@ -38,6 +79,79 @@ class ExpenseClaim(Document):
elif self.project:
frappe.get_doc("Project", self.project).update_project()
def make_gl_entries(self, cancel = False):
if flt(self.total_sanctioned_amount) > 0:
gl_entries = self.get_gl_entries()
make_gl_entries(gl_entries, cancel)
def get_gl_entries(self):
gl_entry = []
self.validate_account_details()
# payable entry
gl_entry.append(
self.get_gl_dict({
"account": self.payable_account,
"credit": self.total_sanctioned_amount,
"credit_in_account_currency": self.total_sanctioned_amount,
"against": ",".join([d.default_account for d in self.expenses]),
"party_type": "Employee",
"party": self.employee,
"against_voucher_type": self.doctype,
"against_voucher": self.name
})
)
# expense entries
for data in self.expenses:
gl_entry.append(
self.get_gl_dict({
"account": data.default_account,
"debit": data.sanctioned_amount,
"debit_in_account_currency": data.sanctioned_amount,
"against": self.employee,
"cost_center": self.cost_center
})
)
if self.is_paid:
# payment entry
payment_account = get_bank_cash_account(self.mode_of_payment, self.company).get("account")
gl_entry.append(
self.get_gl_dict({
"account": payment_account,
"credit": self.total_sanctioned_amount,
"credit_in_account_currency": self.total_sanctioned_amount,
"against": self.employee
})
)
gl_entry.append(
self.get_gl_dict({
"account": self.payable_account,
"party_type": "Employee",
"party": self.employee,
"against": payment_account,
"debit": self.total_sanctioned_amount,
"debit_in_account_currency": self.total_sanctioned_amount,
"against_voucher": self.name,
"against_voucher_type": self.doctype,
})
)
return gl_entry
def validate_account_details(self):
if not self.cost_center:
frappe.throw(_("Cost center is required to book an expense claim"))
if not self.payable_account:
frappe.throw(_("Please set default payable account in the employee {0}").format(self.employee))
if self.is_paid:
if not self.mode_of_payment:
frappe.throw(_("Mode of payment is required to make a payment").format(self.employee))
def calculate_total_amount(self):
self.total_claimed_amount = 0
self.total_sanctioned_amount = 0
@ -65,6 +179,17 @@ class ExpenseClaim(Document):
if not expense.default_account:
expense.default_account = get_expense_claim_account(expense.expense_type, self.company)["account"]
def update_reimbursed_amount(doc):
amt = frappe.db.sql("""select ifnull(sum(debit_in_account_currency), 0) as amt
from `tabGL Entry` where against_voucher_type = 'Expense Claim' and against_voucher = %s
and party = %s """, (doc.name, doc.employee) ,as_dict=1)[0].amt
doc.total_amount_reimbursed = amt
frappe.db.set_value("Expense Claim", doc.name , "total_amount_reimbursed", amt)
doc.set_status()
frappe.db.set_value("Expense Claim", doc.name , "status", doc.status)
@frappe.whitelist()
def get_expense_approver(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""
@ -80,23 +205,26 @@ def make_bank_entry(docname):
expense_claim = frappe.get_doc("Expense Claim", docname)
default_bank_cash_account = get_default_bank_cash_account(expense_claim.company, "Bank")
if not default_bank_cash_account:
default_bank_cash_account = get_default_bank_cash_account(expense_claim.company, "Cash")
je = frappe.new_doc("Journal Entry")
je.voucher_type = 'Bank Entry'
je.company = expense_claim.company
je.remark = 'Payment against Expense Claim: ' + docname;
for expense in expense_claim.expenses:
je.append("accounts", {
"account": expense.default_account,
"debit_in_account_currency": expense.sanctioned_amount,
"reference_type": "Expense Claim",
"reference_name": expense_claim.name
})
je.append("accounts", {
"account": expense_claim.payable_account,
"debit_in_account_currency": flt(expense_claim.total_sanctioned_amount - expense_claim.total_amount_reimbursed),
"reference_type": "Expense Claim",
"party_type": "Employee",
"party": expense_claim.employee,
"reference_name": expense_claim.name
})
je.append("accounts", {
"account": default_bank_cash_account.account,
"credit_in_account_currency": expense_claim.total_sanctioned_amount,
"credit_in_account_currency": flt(expense_claim.total_sanctioned_amount - expense_claim.total_amount_reimbursed),
"reference_type": "Expense Claim",
"reference_name": expense_claim.name,
"balance": default_bank_cash_account.balance,

View File

@ -2,7 +2,10 @@ frappe.listview_settings['Expense Claim'] = {
add_fields: ["approval_status", "total_claimed_amount", "docstatus"],
filters:[["approval_status","!=", "Rejected"]],
get_indicator: function(doc) {
return [__(doc.approval_status), frappe.utils.guess_colour(doc.approval_status),
"approval_status,=," + doc.approval_status];
if(doc.status == "Paid") {
return [__("Paid"), "green", "status,=,'Paid'"];
} else {
return [__("Unpaid"), "orange"];
}
}
};

View File

@ -4,6 +4,8 @@ from __future__ import unicode_literals
import frappe
import unittest
from frappe.utils import random_string, nowdate
from erpnext.hr.doctype.expense_claim.expense_claim import make_bank_entry
test_records = frappe.get_test_records('Expense Claim')
@ -11,8 +13,6 @@ class TestExpenseClaim(unittest.TestCase):
def test_total_expense_claim_for_project(self):
frappe.db.sql("""delete from `tabTask` where project = "_Test Project 1" """)
frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
frappe.db.sql("""delete from `tabExpense Claim`""")
frappe.db.sql("""delete from `tabExpense Claim Detail`""")
frappe.get_doc({
"project_name": "_Test Project 1",
@ -22,15 +22,17 @@ class TestExpenseClaim(unittest.TestCase):
}).save()
task_name = frappe.db.get_value("Task", {"project": "_Test Project 1"})
payable_account = get_payable_account("Wind Power LLC")
expense_claim = frappe.get_doc({
"doctype": "Expense Claim",
"employee": "_T-Employee-0001",
"payable_account": payable_account,
"approval_status": "Approved",
"project": "_Test Project 1",
"task": task_name,
"expenses":
[{ "expense_type": "Food", "default_account": "Entertainment Expenses - _TC", "claim_amount": 300, "sanctioned_amount": 200 }]
[{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 300, "sanctioned_amount": 200 }]
})
expense_claim.submit()
@ -44,7 +46,7 @@ class TestExpenseClaim(unittest.TestCase):
"project": "_Test Project 1",
"task": task_name,
"expenses":
[{ "expense_type": "Food", "default_account": "Entertainment Expenses - _TC", "claim_amount": 600, "sanctioned_amount": 500 }]
[{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 600, "sanctioned_amount": 500 }]
})
expense_claim2.submit()
@ -52,6 +54,64 @@ class TestExpenseClaim(unittest.TestCase):
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 700)
expense_claim2.cancel()
frappe.delete_doc("Expenses Claim", expense_claim2.name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_expense_claim"), 200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_expense_claim"), 200)
def test_expense_claim_status(self):
payable_account = get_payable_account("Wind Power LLC")
expense_claim = frappe.get_doc({
"doctype": "Expense Claim",
"employee": "_T-Employee-0001",
"payable_account": payable_account,
"approval_status": "Approved",
"expenses":
[{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 300, "sanctioned_amount": 200 }]
})
expense_claim.submit()
je_dict = make_bank_entry(expense_claim.name)
je = frappe.get_doc(je_dict)
je.posting_date = nowdate()
je.cheque_no = random_string(5)
je.cheque_date = nowdate()
je.submit()
expense_claim = frappe.get_doc("Expense Claim", expense_claim.name)
self.assertEqual(expense_claim.status, "Paid")
je.cancel()
expense_claim = frappe.get_doc("Expense Claim", expense_claim.name)
self.assertEqual(expense_claim.status, "Unpaid")
def test_expense_claim_gl_entry(self):
payable_account = get_payable_account("Wind Power LLC")
expense_claim = frappe.get_doc({
"doctype": "Expense Claim",
"employee": "_T-Employee-0001",
"payable_account": payable_account,
"approval_status": "Approved",
"expenses":
[{ "expense_type": "Travel", "default_account": "Travel Expenses - WP", "claim_amount": 300, "sanctioned_amount": 200 }]
})
expense_claim.submit()
gl_entries = frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type='Expense Claim' and voucher_no=%s
order by account asc""", expense_claim.name, as_dict=1)
self.assertTrue(gl_entries)
expected_values = dict((d[0], d) for d in [
[payable_account, 0.0, 200.0],
["Travel Expenses - WP", 200.0, 0.0]
])
for gle in gl_entries:
self.assertEquals(expected_values[gle.account][0], gle.account)
self.assertEquals(expected_values[gle.account][1], gle.debit)
self.assertEquals(expected_values[gle.account][2], gle.credit)
def get_payable_account(company):
return frappe.db.get_value('Company', company, 'default_payable_account')

View File

@ -89,8 +89,8 @@ class SalarySlip(TransactionBase):
frappe.throw(_("Name error: {0}".format(err)))
except SyntaxError as err:
frappe.throw(_("Syntax error in formula or condition: {0}".format(err)))
except:
frappe.throw(_("Error in formula or condition"))
except Exception, e:
frappe.throw(_("Error in formula or condition: {0}".format(e)))
raise
def get_data_for_eval(self):
@ -99,7 +99,7 @@ class SalarySlip(TransactionBase):
for d in self._salary_structure_doc.employees:
if d.employee == self.employee:
data.base, data.variable = d.base, d.variable
data.update(frappe.get_doc("Salary Structure Employee", {"employee": self.employee}).as_dict())
data.update(frappe.get_doc("Employee", self.employee).as_dict())
data.update(self.as_dict())
@ -108,7 +108,6 @@ class SalarySlip(TransactionBase):
salary_components = frappe.get_all("Salary Component", fields=["salary_component_abbr"])
for salary_component in salary_components:
data[salary_component.salary_component_abbr] = 0
return data

View File

@ -21,7 +21,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -48,7 +47,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
@ -76,7 +74,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Letter Head",
@ -107,7 +104,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payroll Frequency",
@ -136,7 +132,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -164,7 +159,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Is Active",
@ -195,7 +189,6 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is Default",
@ -224,7 +217,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "From Date",
@ -253,7 +245,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "To Date",
@ -282,7 +273,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -310,7 +300,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employees",
@ -339,7 +328,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
@ -368,7 +356,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Salary Slip Based on Timesheet",
@ -396,7 +383,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -425,7 +411,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Salary Component",
@ -455,7 +440,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Hour Rate",
@ -485,7 +469,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
@ -515,7 +498,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Earning",
@ -546,7 +528,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Earnings",
@ -576,7 +557,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Deduction",
@ -606,7 +586,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Deductions",
@ -637,7 +616,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -664,7 +642,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -691,7 +668,6 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Earning",
@ -721,7 +697,6 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Deduction",
@ -751,7 +726,6 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Net Pay",
@ -779,7 +753,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Account",
@ -807,7 +780,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Mode of Payment",
@ -836,7 +808,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -863,7 +834,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payment Account",
@ -894,7 +864,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-01-11 02:02:10.848614",
"modified": "2017-02-02 01:23:49.179497",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Structure",
@ -910,7 +880,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -928,10 +897,9 @@
"create": 1,
"delete": 1,
"email": 1,
"export": 0,
"export": 1,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"import": 1,
"permlevel": 0,
"print": 1,
"read": 1,
@ -950,5 +918,6 @@
"sort_order": "DESC",
"timeline_field": "",
"title_field": "",
"track_changes": 0,
"track_seen": 0
}

View File

@ -4,8 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import cstr, flt, getdate, cint
from frappe.model.naming import make_autoname
from frappe.utils import flt, cint
from frappe import _
from frappe.model.mapper import get_mapped_doc
from frappe.model.document import Document
@ -15,7 +14,6 @@ class SalaryStructure(Document):
def validate(self):
self.validate_amount()
self.validate_joining_date()
for e in self.get('employees'):
set_employee_name(e)
@ -30,18 +28,13 @@ class SalaryStructure(Document):
if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet:
frappe.throw(_("Net pay cannot be negative"))
def validate_joining_date(self):
for e in self.get('employees'):
joining_date = getdate(frappe.db.get_value("Employee", e.employee, "date_of_joining"))
if getdate(self.from_date) < joining_date:
frappe.throw(_("From Date in Salary Structure cannot be lesser than Employee Joining Date."))
@frappe.whitelist()
def make_salary_slip(source_name, target_doc = None, employee = None, as_print = False, print_format = None):
def postprocess(source, target):
if employee:
target.employee = employee
target.employee_name = frappe.get_value("Employee",employee, "employee_name")
target.run_method('process_salary_structure')
doc = get_mapped_doc("Salary Structure", source_name, {

View File

@ -15,13 +15,14 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Employee",
"length": 0,
"no_copy": 0,
@ -31,6 +32,7 @@
"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,
@ -41,21 +43,24 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "employee_name",
"fieldtype": "Data",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Employee Name",
"length": 0,
"no_copy": 0,
"options": "employee.employee_name",
"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,
@ -66,13 +71,14 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "base",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Base",
"length": 0,
"no_copy": 0,
@ -81,6 +87,7 @@
"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,
@ -91,13 +98,14 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "variable",
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Variable",
"length": 0,
"no_copy": 0,
@ -106,6 +114,7 @@
"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,
@ -123,7 +132,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-08-11 12:18:14.526977",
"modified": "2017-02-02 02:06:33.809285",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Structure Employee",
@ -135,5 +144,6 @@
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}

View File

@ -7,7 +7,7 @@
<div class="col-xs-2 col-sm-1">
{{ avatar }}
</div>
<div class="col-xs-10 col-sm-11 small" style="padding-top: 5px;">
<div class="col-xs-10 col-sm-11 small content">
{{ content }}
</div>
</div>

View File

@ -23,9 +23,25 @@
background: #5e64ff;
}
.activity-row {
}
.activity-message {
border-left: 1px solid #d1d8dd;
}
.activity-message .row {
padding: 15px;
margin-right: 0px;
border-bottom: 1px solid #d1d8dd;
}
.activity-row:last-child .activity-message .row {
border-bottom: none;
}
.activity-row .content {
padding-left: 0px;
padding-right: 30px;
}

View File

@ -21,7 +21,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Item",
@ -51,7 +50,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item Name",
@ -81,7 +79,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Quantity",
@ -110,7 +107,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -137,7 +133,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Is Active",
@ -167,7 +162,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Is Default",
@ -197,7 +191,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "With Operations",
@ -224,7 +217,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Rate Of Materials Based On",
@ -253,7 +245,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Price List",
@ -281,7 +272,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
@ -309,7 +299,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Currency",
@ -338,7 +327,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -365,7 +353,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Conversion Rate",
@ -395,7 +382,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Operations",
@ -423,7 +409,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Operations",
@ -453,7 +438,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Materials",
@ -481,7 +465,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Items",
@ -511,7 +494,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Scrap",
@ -539,7 +521,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Scrap Items",
@ -568,7 +549,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Costing",
@ -596,7 +576,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Operating Cost",
@ -624,7 +603,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Raw Material Cost",
@ -652,7 +630,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Scrap Material Cost",
@ -681,7 +658,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -707,7 +683,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Operating Cost (Company Currency)",
@ -736,7 +711,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Raw Material Cost(Company Currency)",
@ -765,7 +739,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Scrap Material Cost(Company Currency)",
@ -794,7 +767,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -821,7 +793,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Total Cost",
@ -849,7 +820,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -876,7 +846,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Cost(Company Currency)",
@ -905,7 +874,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
@ -932,7 +900,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Project",
@ -962,7 +929,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Company",
@ -991,7 +957,6 @@
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
@ -1019,7 +984,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -1045,7 +1009,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item UOM",
@ -1073,7 +1036,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -1100,7 +1062,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Item Description",
@ -1127,7 +1088,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -1154,7 +1114,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Image",
@ -1182,7 +1141,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Image View",
@ -1212,7 +1170,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Materials Required (Exploded)",
@ -1239,7 +1196,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Exploded_items",
@ -1271,8 +1227,8 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-11-21 17:06:49.349654",
"modified_by": "rohit@erpnext.com",
"modified": "2017-02-01 14:27:17.949390",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",
"owner": "Administrator",
@ -1287,7 +1243,6 @@
"export": 1,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1308,7 +1263,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1329,7 +1283,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1347,5 +1300,6 @@
"search_fields": "item",
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,
"track_seen": 0
}

View File

@ -500,10 +500,15 @@ def validate_bom_no(item, bom_no):
@frappe.whitelist()
def get_children():
if frappe.form_dict.parent:
return frappe.db.sql("""select item_code,
bom_no as value, qty,
if(ifnull(bom_no, "")!="", 1, 0) as expandable
from `tabBOM Item`
where parent=%s
order by idx
return frappe.db.sql("""select
bom_item.item_code,
bom_item.bom_no as value,
bom_item.qty,
if(ifnull(bom_item.bom_no, "")!="", 1, 0) as expandable,
item.image,
item.description
from `tabBOM Item` bom_item, tabItem item
where bom_item.parent=%s
and bom_item.item_code = item.name
order by bom_item.idx
""", frappe.form_dict.parent, as_dict=True)

View File

@ -0,0 +1,21 @@
<div style="padding: 15px;">
{% if data.image %}
<img class="responsive" src={{ data.image }}>
<hr style="margin: 15px -15px;">
{% endif %}
<h4>
{{ __("Description") }}
</h4>
<div style="padding-top: 10px;">
{{ data.description }}
</div>
<hr style="margin: 15px -15px;">
<p>
{% if data.value %}
<a style="margin-right: 7px; margin-bottom: 7px" class="btn btn-default btn-xs" href="#Form/BOM/{{ data.value }}">
{{ __("Open BOM {0}", [data.value.bold()]) }}</a>
{% endif %}
<a class="btn btn-default btn-xs" href="#Form/Item/{{ data.item_code }}">
{{ __("Open Item {0}", [data.item_code.bold()]) }}</a>
</p>
</div>

View File

@ -20,7 +20,7 @@ frappe.treeview_settings["BOM"] = {
}
},
toolbar: [
{toggle_btn: true},
{ toggle_btn: true },
{
label:__("Edit"),
condition: function(node) {
@ -40,5 +40,6 @@ frappe.treeview_settings["BOM"] = {
},
condition: 'frappe.boot.user.can_create.indexOf("BOM") !== -1'
}
]
],
view_template: 'bom_item_preview'
}

View File

@ -7,7 +7,10 @@ frappe.views.calendar["Production Order"] = {
"end": "planned_end_date",
"id": "name",
"title": "name",
"allDay": "allDay"
"allDay": "allDay",
"progress": function(data) {
return flt(data.produced_qty) / data.qty * 100;
}
},
gantt: true,
get_css_class: function(data) {

View File

@ -370,3 +370,4 @@ erpnext.patches.v7_2.set_null_value_to_fields
erpnext.patches.v7_2.update_guardian_name_in_student_master
erpnext.patches.v7_2.update_abbr_in_salary_slips
erpnext.patches.v7_2.rename_evaluation_criteria
erpnext.patches.v7_2.update_party_type

View File

@ -1,8 +1,7 @@
import frappe
from erpnext.accounts.party_status import status_depends_on, default_status
from frappe.desk.notifications import get_filters_for
def execute():
return
for party_type in ('Customer', 'Supplier'):
frappe.reload_doctype(party_type)

View File

@ -0,0 +1 @@
from __future__ import unicode_literals

View File

@ -0,0 +1,16 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doc('setup', 'doctype', 'party_type')
make_party_type()
def make_party_type():
for party_type in ["Customer", "Supplier", "Employee"]:
if not frappe.db.get_value("Party Type", party_type):
doc = frappe.new_doc("Party Type")
doc.party_type = party_type
doc.save(ignore_permissions=True)

View File

@ -7,7 +7,8 @@ frappe.views.calendar["Task"] = {
"end": "exp_end_date",
"id": "name",
"title": "subject",
"allDay": "allDay"
"allDay": "allDay",
"progress": "progress"
},
gantt: true,
filters: [

View File

@ -67,7 +67,6 @@
.pos-toolbar,
.pos-bill-toolbar {
padding: 10px 0px;
border-bottom: 1px solid #d1d8dd;
height: 51px;
}
.pos-item-toolbar .form-group {
@ -79,6 +78,7 @@
margin-right: -1px;
}
.pos-bill {
border-top: 1px solid #d1d8dd;
margin-left: -15px;
margin-right: -15px;
}
@ -171,6 +171,9 @@
.payment-toolbar {
padding-right: 30px;
}
.list-row-head.pos-invoice-list {
border-top: 1px solid #d1d8dd;
}
body[data-route="pos"] .modal-dialog {
width: 750px;
}

View File

@ -1,14 +1,26 @@
<div class="pos">
<div class="row">
<div class="col-sm-5 pos-bill-wrapper">
<div class="pos-bill-toolbar row">
<div class="party-area col-xs-12"></div>
<div class="col-sm-6 pos-bill-wrapper">
<div class="pos-bill-toolbar" style="display: flex;">
<div class="party-area" style="flex: 1;"></div>
<button class="btn btn-default list-customers-btn" style="margin: 0 5px 0 15px;">
<i class="fa fa-list"></i>
</button>
<button class="btn btn-default add-customer-btn">
<i class="fa fa-plus"></i>
</button>
{% if (allow_delete) { %}
<button class="btn btn-default btn-danger" style="margin: 0 5px 0 5px;display:none">
<i class="octicon octicon-trashcan"></i>
</button>
{% } %}
</div>
<div class="pos-bill">
<div class="item-cart">
<div class="row pos-bill-row pos-bill-header">
<div class="col-xs-5"><h6>{%= __("Item") %}</h6></div>
<div class="col-xs-4"><h6 class="text-right">{%= __("Quantity") %}</h6></div>
<div class="col-xs-4"><h6>{%= __("Item") %}</h6></div>
<div class="col-xs-3"><h6 class="text-right">{%= __("Quantity") %}</h6></div>
<div class="col-xs-2"><h6 class="text-right">{%= __("Discount") %}</h6></div>
<div class="col-xs-3"><h6 class="text-right">{%= __("Rate") %}</h6></div>
</div>
<div class="items"></div>
@ -48,18 +60,27 @@
</div>
</div>
</div>
<div class="list-customers">
</div>
</div>
<div class="col-sm-7 pos-items-section">
<div class="col-sm-6 pos-items-section">
<div class="row pos-item-area">
</div>
<span id="customer-results" style="color:#68a;"></span>
<div class="row pos-item-toolbar">
<div class="search-area col-xs-12"></div>
<div class="search-item-group col-xs-5"></div>
<div class="search-item col-xs-7"></div>
</div>
<div class="item-list-area">
<div class="item-list-area" style="auto">
<div class="app-listing item-list"></ul>
</div>
</div>
<div class="row">
<div class="text-right list-paging-area">
<button class="btn btn-default btn-more btn-sm" style="margin:5px 20px">{{ __("More") }}</button>
</div>
</div>
</div>
</div>

View File

@ -1,25 +1,30 @@
<div class="row pos-bill-row pos-bill-item" data-item-code="{%= item_code %}">
<div class="col-xs-5"><h6>{%= item_code || "" %}{%= item_name || "" %}</h6></div>
<div class="col-xs-4">
<div class="col-xs-4"><h6>{%= item_code || "" %}{%= __(item_name) || "" %}</h6></div>
<div class="col-xs-3">
<div class="row pos-qty-row">
<div class="col-xs-2 text-center pos-qty-btn" data-action="decrease-qty"><i class="fa fa-minus text-muted" style="font-size:12px"></i></div>
<div class="col-xs-8">
<div>
<input type="text" value="{%= qty %}" class="form-control input-sm pos-item-qty text-right">
<input type="tel" value="{%= qty %}" class="form-control pos-item-qty text-right">
</div>
{% if(actual_qty != null) { %}
<div style="margin-top: 5px;" class="text-muted small text-right">
<span title="{%= __("In Stock") %}">{%= actual_qty || 0 %}<span>
{%= __("In Stock: ") %} <span>{%= actual_qty || 0.0 %}</span>
</div>
{% } %}
</div>
<div class="col-xs-2 text-center pos-qty-btn" data-action="increase-qty"><i class="fa fa-plus text-muted" style="font-size:12px"></i></div>
</div>
</div>
<div class="col-xs-2 text-right">
<div class="row input-sm">
<input type="tel" value="{%= discount_percentage %}" class="form-control text-right pos-item-discount">
</div>
</div>
<div class="col-xs-3 text-right">
<div class="text-muted" style="margin-top: 5px;">
{% if(enabled) { %}
<input type="text" value="{%= rate %}" class="form-control input-sm pos-item-rate text-right">
<input type="tel" value="{%= rate %}" class="form-control input-sm pos-item-rate text-right">
{% } else { %}
<h6>{%= format_currency(rate) %}</h6>
{% } %}

View File

@ -82,7 +82,7 @@
.pos-toolbar, .pos-bill-toolbar {
padding: 10px 0px;
border-bottom: 1px solid #d1d8dd;
// border-bottom: 1px solid #d1d8dd;
height: 51px;
}
@ -97,6 +97,7 @@
}
.pos-bill {
border-top: 1px solid @border-color;
margin-left: -15px;
margin-right: -15px;
}
@ -213,6 +214,10 @@
padding-right: 30px;
}
.list-row-head.pos-invoice-list {
border-top: 1px solid @border-color;
}
body[data-route="pos"] .modal-dialog {
width: 750px;

View File

@ -7,6 +7,17 @@ cur_frm.add_fetch("examiner", "instructor_name", "examiner_name");
cur_frm.add_fetch("supervisor", "instructor_name", "supervisor_name");
frappe.ui.form.on("Assessment Plan", {
refresh: function(frm) {
if (!frm.doc.__islocal) {
frm.add_custom_button(__("Assessment Result"), function() {
frappe.route_options = {
assessment_plan: frm.doc.name
}
frappe.set_route("Form", "Assessment Result Tool");
});
}
},
course: function(frm) {
if (frm.doc.course && frm.doc.maximum_assessment_score) {
frappe.call({

View File

@ -129,14 +129,15 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"fieldname": "date_of_birth",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Date of Birth",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -156,15 +157,14 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "date_of_birth",
"fieldtype": "Date",
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Date of Birth",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -263,61 +263,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Image",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_9",
"fieldtype": "Section 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,
"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_on_submit": 0,
"bold": 0,
@ -346,6 +291,91 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Image",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_13",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Guardian Of ",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "students",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Students",
"length": 0,
"no_copy": 0,
"options": "Guardian Student",
"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_on_submit": 0,
"bold": 0,
@ -359,6 +389,7 @@
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Guardian Interests",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -414,7 +445,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-12-28 16:14:58.836437",
"modified": "2017-01-31 16:47:23.436075",
"modified_by": "Administrator",
"module": "Schools",
"name": "Guardian",
@ -431,7 +462,6 @@
"export": 1,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -449,5 +479,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "guardian_name",
"track_changes": 0,
"track_seen": 0
}

View File

@ -7,4 +7,22 @@ import frappe
from frappe.model.document import Document
class Guardian(Document):
pass
def __setup__(self):
self.onload()
def onload(self):
"""Load Students for quick view"""
self.load_students()
def load_students(self):
"""Load `students` from the database"""
self.students = []
students = frappe.get_all("Student Guardian", filters={"guardian":self.name}, fields=["parent"])
for student in students:
self.append("students", {
"student":student.parent,
"student_name": frappe.db.get_value("Student", student.parent, "title")
})
def validate(self):
self.students = []

View File

@ -0,0 +1,123 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2017-01-31 11:53:21.580099",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Student",
"length": 0,
"no_copy": 0,
"options": "Student",
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_2",
"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,
"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_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student_name",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Student Name",
"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
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2017-01-31 16:40:26.551040",
"modified_by": "Administrator",
"module": "Schools",
"name": "Guardian Student",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

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

View File

@ -23,7 +23,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Name and Type",
@ -52,7 +51,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Series",
@ -80,7 +78,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Full Name",
@ -109,7 +106,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Type",
@ -139,7 +135,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "From Lead",
@ -169,7 +164,6 @@
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Image",
@ -187,36 +181,6 @@
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Active",
"fieldname": "status",
"fieldtype": "Select",
"hidden": 1,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Status",
"length": 0,
"no_copy": 0,
"options": "Active\nDormant\nOpen",
"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_on_submit": 0,
"bold": 0,
@ -227,7 +191,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -255,7 +218,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Customer Group",
@ -286,7 +248,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Territory",
@ -316,7 +277,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Tax ID",
@ -345,7 +305,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Disabled",
@ -373,7 +332,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Currency and Price List",
@ -401,7 +359,6 @@
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Billing Currency",
@ -429,7 +386,6 @@
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Default Price List",
@ -457,7 +413,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -484,7 +439,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Language",
@ -514,7 +468,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Address and Contact",
@ -542,7 +495,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Address HTML",
@ -569,7 +521,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Website",
@ -596,7 +547,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
@ -623,7 +573,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Contact HTML",
@ -652,7 +601,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounting",
@ -681,7 +629,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounts",
@ -710,7 +657,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Credit Limit",
@ -738,7 +684,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Credit Days Based On",
@ -768,7 +713,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Credit Days",
@ -797,7 +741,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Credit Limit",
@ -828,7 +771,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "More Information",
@ -858,7 +800,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Customer Details",
@ -887,7 +828,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is Frozen",
@ -916,7 +856,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Partner and Commission",
@ -945,7 +884,6 @@
"hidden": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Partner",
@ -975,7 +913,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Commission Rate",
@ -1005,7 +942,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Team",
@ -1033,7 +969,6 @@
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sales Team Details",
@ -1066,7 +1001,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-11-07 05:26:57.948263",
"modified": "2017-02-01 12:00:06.045170",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer",
@ -1083,7 +1018,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1104,7 +1038,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 1,
"print": 0,
"read": 1,
@ -1125,7 +1058,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1146,7 +1078,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1167,7 +1098,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 1,
"print": 0,
"read": 1,
@ -1188,7 +1118,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1209,7 +1138,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1230,7 +1158,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1251,7 +1178,6 @@
"export": 0,
"if_owner": 0,
"import": 0,
"is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
@ -1269,5 +1195,6 @@
"search_fields": "customer_name,customer_group,territory",
"sort_order": "ASC",
"title_field": "customer_name",
"track_changes": 1,
"track_seen": 0
}

View File

@ -11,7 +11,6 @@ from frappe.desk.reportview import build_match_conditions
from erpnext.utilities.transaction_base import TransactionBase
from frappe.geo.address_and_contact import load_address_and_contact, delete_contact_and_address
from erpnext.accounts.party import validate_party_accounts, get_timeline_data # keep this
from erpnext.accounts.party_status import get_party_status
from erpnext import get_default_currency
class Customer(TransactionBase):
@ -70,7 +69,6 @@ class Customer(TransactionBase):
self.flags.is_new_doc = self.is_new()
self.flags.old_lead = self.lead_name
validate_party_accounts(self)
self.status = get_party_status(self)
self.validate_credit_limit_on_change()
def on_update(self):

View File

@ -1,12 +1,3 @@
frappe.listview_settings['Customer'] = {
add_fields: ["customer_name", "territory", "customer_group", "customer_type", 'status'],
get_indicator: function(doc) {
color = {
'Open': 'red',
'Active': 'green',
'Dormant': 'darkgrey'
}
return [__(doc.status), color[doc.status], "status,=," + doc.status];
}
add_fields: ["customer_name", "territory", "customer_group", "customer_type"],
};

View File

@ -68,47 +68,6 @@ class TestQuotation(unittest.TestCase):
self.assertEquals(quotation.get("items")[0].rate, total_margin)
si.save()
def test_party_status_open(self):
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
customer = frappe.get_doc(get_customer_dict('Party Status Test')).insert()
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Active')
quotation = frappe.get_doc(get_quotation_dict(customer=customer.name)).insert()
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Open')
quotation.submit()
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Active')
quotation.cancel()
quotation.delete()
customer.delete()
def test_party_status_close(self):
from erpnext.selling.doctype.customer.test_customer import get_customer_dict
customer = frappe.get_doc(get_customer_dict('Party Status Test')).insert()
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Active')
# open quotation
quotation = frappe.get_doc(get_quotation_dict(customer=customer.name)).insert()
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Open')
# close quotation (submit)
quotation.submit()
quotation1 = frappe.get_doc(get_quotation_dict(customer=customer.name)).insert()
# still open
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Open')
quotation.cancel()
quotation.delete()
quotation1.delete()
customer.delete()
test_records = frappe.get_test_records('Quotation')
def get_quotation_dict(customer=None, item_code=None):

View File

@ -4,6 +4,17 @@
frappe.provide("erpnext.company");
frappe.ui.form.on("Company", {
setup: function(frm) {
frm.fields_dict['default_payable_account'].get_query = function() {
return{
filters: {
"root_type": "Liability",
"account_type": "Payable"
}
}
}
},
onload: function(frm) {
erpnext.company.setup_queries(frm);
},

View File

@ -153,6 +153,8 @@ class Company(Document):
self.db_set("default_income_account", frappe.db.get_value("Account",
{"account_name": _("Sales"), "company": self.name}))
if not self.default_payable_account:
self.db_set("default_payable_account", self.default_payable_account)
def _set_default_account(self, fieldname, account_type):
if self.get(fieldname):

View File

@ -0,0 +1,15 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt
frappe.ui.form.on('Party Type', {
setup: function(frm) {
frm.fields_dict["party_type"].get_query = function(frm) {
return {
filters: {
"istable": 0,
"is_submittable": 0
}
}
}
}
});

View File

@ -0,0 +1,130 @@
{
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "field:party_type",
"beta": 0,
"creation": "2016-12-26 11:26:51.508286",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "party_type",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Party Type",
"length": 0,
"no_copy": 0,
"options": "DocType",
"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
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-01-19 17:55:33.428335",
"modified_by": "Administrator",
"module": "Setup",
"name": "Party Type",
"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
},
{
"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,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class PartyType(Document):
pass
@frappe.whitelist()
def get_party_type(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""select name from `tabParty Type`
where `{key}` LIKE %(txt)s
order by name limit %(start)s, %(page_len)s"""
.format(key=searchfield), {
'txt': "%%%s%%" % frappe.db.escape(txt),
'start': start, 'page_len': page_len
})

View File

@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
from __future__ import unicode_literals
import frappe
import unittest
# test_records = frappe.get_test_records('Party Type')
class TestPartyType(unittest.TestCase):
pass

View File

@ -171,6 +171,10 @@ def install(country=None):
{'doctype': "Email Account", "email_id": "support@example.com", "append_to": "Issue"},
{'doctype': "Email Account", "email_id": "jobs@example.com", "append_to": "Job Applicant"},
{'doctype': "Party Type", "party_type": "Customer"},
{'doctype': "Party Type", "party_type": "Supplier"},
{'doctype': "Party Type", "party_type": "Employee"},
{"doctype": "Offer Term", "offer_term": _("Date of Joining")},
{"doctype": "Offer Term", "offer_term": _("Annual Salary")},
{"doctype": "Offer Term", "offer_term": _("Probationary Period")},

View File

@ -11,8 +11,6 @@ def get_notification_config():
"Task": {"status": "Overdue"},
"Project": {"status": "Open"},
"Item": {"total_projected_qty": ("<", 0)},
"Customer": {"status": "Open"},
"Supplier": {"status": "Open"},
"Lead": {"status": "Open"},
"Contact": {"status": "Open"},
"Opportunity": {"status": "Open"},

View File

@ -117,6 +117,10 @@ class StockReconciliation(StockController):
if buying_rate:
row.valuation_rate = buying_rate
else:
# get valuation rate from Item
row.valuation_rate = frappe.get_value('Item', row.item_code, 'valuation_rate')
# throw all validation messages
if self.validation_messages:
for msg in self.validation_messages: