Merge pull request #7465 from KanchanChauhan/attendance-enhancement
[Enhancement] Attendance Module
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index bc7ef57..45602f1 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
import frappe
-__version__ = '7.2.8'
+__version__ = '7.2.12'
def get_default_company(user=None):
'''Get default company for user'''
@@ -24,3 +24,18 @@
company = get_default_company()
if company:
return frappe.db.get_value('Company', company, 'default_currency')
+
+def set_perpetual_inventory(enable=1):
+ accounts_settings = frappe.get_doc("Accounts Settings")
+ accounts_settings.auto_accounting_for_stock = enable
+ accounts_settings.save()
+
+def encode_company_abbr(name, company):
+ '''Returns name encoded with company abbreviation'''
+ company_abbr = frappe.db.get_value("Company", company, "abbr")
+ parts = name.rsplit(" - ", 1)
+
+ if parts[-1].lower() != company_abbr.lower():
+ parts.append(company_abbr)
+
+ return " - ".join([parts[0], company_abbr])
diff --git a/erpnext/accounts/doctype/account/account.py b/erpnext/accounts/doctype/account/account.py
index cedaf60..11f376d 100644
--- a/erpnext/accounts/doctype/account/account.py
+++ b/erpnext/accounts/doctype/account/account.py
@@ -3,11 +3,12 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import cstr, cint
+from frappe.utils import cint, fmt_money
from frappe import throw, _
from frappe.model.document import Document
class RootNotEditable(frappe.ValidationError): pass
+class BalanceMismatchError(frappe.ValidationError): pass
class Account(Document):
nsm_parent_field = 'parent_account'
@@ -162,23 +163,38 @@
throw(_("Report Type is mandatory"))
def validate_warehouse_account(self):
+ '''If perpetual inventory is set, and warehouse is linked,
+ the account balance and stock balance as of now must always match.
+ '''
+ from erpnext.accounts.utils import get_balance_on
+ from erpnext.stock.utils import get_stock_value_on
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
return
-
- if self.account_type == "Stock" and not cint(self.is_group):
- if not self.warehouse:
- throw(_("Warehouse is mandatory"))
-
- old_warehouse = cstr(frappe.db.get_value("Account", self.name, "warehouse"))
- if old_warehouse != cstr(self.warehouse):
- if old_warehouse and frappe.db.exists("Warehouse", old_warehouse):
- self.validate_warehouse(old_warehouse)
- if self.warehouse:
- self.validate_warehouse(self.warehouse)
-
+
+ if self.account_type == "Stock":
+ if self.is_group == 0 and not self.warehouse:
+ frappe.throw(_("Warehouse is mandatory for non group Accounts of type Stock"))
+
+ if self.warehouse:
+ # company must be same
+ if frappe.get_value('Warehouse', self.warehouse, 'company') != self.company:
+ frappe.throw(_("Warehouse company must be same as Account company"))
+
+ # balance must be same
+ stock_balance = get_stock_value_on(self.warehouse)
+ if self.is_new():
+ account_balance = 0.0
+ else:
+ account_balance = get_balance_on(self.name)
+
+ if account_balance != stock_balance:
+ frappe.throw(_('Account balance ({0}) and stock value ({1}) must be same')\
+ .format(fmt_money(account_balance, self.account_currency),
+ fmt_money(stock_balance, self.account_currency)))
+
elif self.warehouse:
self.warehouse = None
-
+
def validate_warehouse(self, warehouse):
lft, rgt = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"])
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 5fc4fbf..15d6f10 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -63,7 +63,7 @@
and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"}):
if args.project:
- condition = "and exists(select name from `tabProject` where name=b.project)"
+ condition = "and b.project='%s'" % frappe.db.escape(args.project)
args.budget_against_field = "Project"
elif args.cost_center:
@@ -88,12 +88,13 @@
""".format(condition=condition,
budget_against_field=frappe.scrub(args.get("budget_against_field"))),
(args.fiscal_year, args.account), as_dict=True)
-
- validate_budget_records(args, budget_records)
+
+ if budget_records:
+ validate_budget_records(args, budget_records)
def validate_budget_records(args, budget_records):
for budget in budget_records:
- if budget.budget_amount:
+ if flt(budget.budget_amount):
yearly_action = budget.action_if_annual_budget_exceeded
monthly_action = budget.action_if_accumulated_monthly_budget_exceeded
diff --git a/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py b/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py
index 752ecda..5b7d73f 100644
--- a/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py
+++ b/erpnext/accounts/doctype/cheque_print_template/cheque_print_template.py
@@ -35,7 +35,7 @@
</span>
<span style="top:%(date_dist_from_top_edge)s cm; left:%(date_dist_from_left_edge)scm;
position: absolute;">
- {{doc.reference_date or '' }}
+ {{ frappe.utils.formatdate(doc.reference_date) or '' }}
</span>
<span style="top:%(acc_no_dist_from_top_edge)scm;left:%(acc_no_dist_from_left_edge)scm;
position: absolute;">
diff --git a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
index 2ff98da..517a2a3 100644
--- a/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
+++ b/erpnext/accounts/doctype/fiscal_year/fiscal_year.py
@@ -43,11 +43,13 @@
def on_update(self):
check_duplicate_fiscal_year(self)
+ frappe.cache().delete_value("fiscal_years")
def on_trash(self):
global_defaults = frappe.get_doc("Global Defaults")
if global_defaults.current_fiscal_year == self.name:
frappe.throw(_("You cannot delete Fiscal Year {0}. Fiscal Year {0} is set as default in Global Settings").format(self.name))
+ frappe.cache().delete_value("fiscal_years")
def validate_overlap(self):
existing_fiscal_years = frappe.db.sql("""select name from `tabFiscal Year`
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.py b/erpnext/accounts/doctype/gl_entry/gl_entry.py
index 5773813..ce60298 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.py
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.py
@@ -18,22 +18,27 @@
def validate(self):
self.flags.ignore_submit_comment = True
self.check_mandatory()
- self.pl_must_have_cost_center()
- self.check_pl_account()
- self.validate_cost_center()
- self.validate_party()
- self.validate_currency()
self.validate_and_set_fiscal_year()
+
+ if not self.flags.from_repost:
+ self.pl_must_have_cost_center()
+ self.check_pl_account()
+ self.validate_cost_center()
+ self.validate_party()
+ self.validate_currency()
- def on_update_with_args(self, adv_adj, update_outstanding = 'Yes'):
- self.validate_account_details(adv_adj)
+
+ def on_update_with_args(self, adv_adj, update_outstanding = 'Yes', from_repost=False):
+ if not from_repost:
+ self.validate_account_details(adv_adj)
+ check_freezing_date(self.posting_date, adv_adj)
+
validate_frozen_account(self.account, adv_adj)
- check_freezing_date(self.posting_date, adv_adj)
validate_balance_type(self.account, adv_adj)
# Update outstanding amt on against voucher
if self.against_voucher_type in ['Journal Entry', 'Sales Invoice', 'Purchase Invoice'] \
- and self.against_voucher and update_outstanding == 'Yes':
+ and self.against_voucher and update_outstanding == 'Yes' and not from_repost:
update_outstanding_amt(self.account, self.party_type, self.party, self.against_voucher_type,
self.against_voucher)
diff --git a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
index b4bb542..8756ca4 100644
--- a/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/test_journal_entry.py
@@ -171,7 +171,7 @@
})
jv.submit()
-
+
def test_clear_blank_rows(self):
je = make_journal_entry("_Test Bank - _TC", "_Test Account Stock Expenses - _TC", 100, save=False)
je.append("accounts", {
@@ -180,11 +180,11 @@
"credit_in_account_currency": 0,
"exchange_rate": 1
})
-
+
self.assertEqual(len(je.get("accounts")), 3)
je.save()
- self.assertEqual(len(je.get("accounts")), 2)
-
+ self.assertEqual(len(je.get("accounts")), 2)
+
def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False, project=None):
if not cost_center:
diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
index 04d4ed7..03d0918 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
@@ -35,9 +35,9 @@
def validate_posting_date(self):
from erpnext.accounts.utils import get_fiscal_year, validate_fiscal_year
- validate_fiscal_year(self.posting_date, self.fiscal_year, label=_("Posting Date"), doc=self)
+ validate_fiscal_year(self.posting_date, self.fiscal_year, self.company, label=_("Posting Date"), doc=self)
- self.year_start_date = get_fiscal_year(self.posting_date, self.fiscal_year)[1]
+ self.year_start_date = get_fiscal_year(self.posting_date, self.fiscal_year, company=self.company)[1]
pce = frappe.db.sql("""select name from `tabPeriod Closing Voucher`
where posting_date > %s and fiscal_year = %s and docstatus = 1""",
diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
index d68e291..9ef66ed 100644
--- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
+++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
@@ -11,7 +11,7 @@
class TestPeriodClosingVoucher(unittest.TestCase):
def test_closing_entry(self):
- year_start_date = get_fiscal_year(today())[1]
+ year_start_date = get_fiscal_year(today(), company="_Test Company")[1]
make_journal_entry("_Test Bank - _TC", "Sales - _TC", 400,
"_Test Cost Center - _TC", posting_date=now(), submit=True)
@@ -70,7 +70,7 @@
"doctype": "Period Closing Voucher",
"closing_account_head": "_Test Account Reserves and Surplus - _TC",
"company": "_Test Company",
- "fiscal_year": get_fiscal_year(today())[0],
+ "fiscal_year": get_fiscal_year(today(), company="_Test Company")[0],
"posting_date": today(),
"remarks": "test"
})
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index b6378f1..c322370 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -8,7 +8,7 @@
erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
onload: function() {
this._super();
-
+
if(!this.frm.doc.__islocal) {
// show credit_to in print format
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
@@ -32,7 +32,7 @@
if(doc.update_stock==1 && doc.docstatus==1) {
this.show_stock_ledger();
}
-
+
if(!doc.is_return && doc.docstatus==1) {
if(doc.outstanding_amount != 0) {
this.frm.add_custom_button(__('Payment'), this.make_payment_entry, __("Make"));
@@ -218,18 +218,6 @@
}
}
-cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{'supplier': doc.supplier}
- }
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{'supplier': doc.supplier}
- }
-}
-
cur_frm.fields_dict['items'].grid.get_field("item_code").get_query = function(doc, cdt, cdn) {
return {
query: "erpnext.controllers.queries.item_query",
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 14459fa..c0693d1 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -302,11 +302,11 @@
asset.flags.ignore_validate_update_after_submit = True
asset.save()
- def make_gl_entries(self, repost_future_gle=True):
+ def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
if not self.grand_total:
return
-
- gl_entries = self.get_gl_entries()
+ if not gl_entries:
+ gl_entries = self.get_gl_entries()
if gl_entries:
update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes"
diff --git a/erpnext/accounts/doctype/sales_invoice/pos.py b/erpnext/accounts/doctype/sales_invoice/pos.py
index f5721e8..9fb7ceb 100644
--- a/erpnext/accounts/doctype/sales_invoice/pos.py
+++ b/erpnext/accounts/doctype/sales_invoice/pos.py
@@ -39,14 +39,21 @@
'pricing_rules': get_pricing_rule_data(doc),
'print_template': print_template,
'pos_profile': pos_profile,
- 'meta': {
- 'invoice': frappe.get_meta('Sales Invoice'),
- 'customer': frappe.get_meta('Customer'),
- 'items': frappe.get_meta('Sales Invoice Item'),
- 'taxes': frappe.get_meta('Sales Taxes and Charges')
- }
+ 'meta': get_meta()
}
+def get_meta():
+ doctype_meta = {
+ 'customer': frappe.get_meta('Customer'),
+ 'invoice': frappe.get_meta('Sales Invoice')
+ }
+
+ for row in frappe.get_all('DocField', fields = ['fieldname', 'options'],
+ filters = {'parent': 'Sales Invoice', 'fieldtype': 'Table'}):
+ doctype_meta[row.fieldname] = frappe.get_meta(row.options)
+
+ return doctype_meta
+
def get_company_data(company):
return frappe.get_all('Company', fields = ["*"], filters= {'name': company})[0]
@@ -63,10 +70,10 @@
doc.currency = pos_profile.get('currency') or company_data.default_currency
doc.conversion_rate = 1.0
-
+
if doc.currency != company_data.default_currency:
doc.conversion_rate = get_exchange_rate(doc.currency, company_data.default_currency, doc.posting_date)
-
+
doc.selling_price_list = pos_profile.get('selling_price_list') or \
frappe.db.get_value('Selling Settings', None, 'selling_price_list')
doc.naming_series = pos_profile.get('naming_series') or 'SINV-'
@@ -75,6 +82,8 @@
doc.apply_discount_on = pos_profile.get('apply_discount_on') if pos_profile.get('apply_discount') else ''
doc.customer_group = pos_profile.get('customer_group') or get_root('Customer Group')
doc.territory = pos_profile.get('territory') or get_root('Territory')
+ if pos_profile.get('tc_name'):
+ doc.terms = frappe.db.get_value('Terms and Conditions', pos_profile.get('tc_name'), 'terms')
def get_root(table):
root = frappe.db.sql(""" select name from `tab%(table)s` having
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index db6d594..890641b 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -532,10 +532,12 @@
if d.delivery_note and frappe.db.get_value("Delivery Note", d.delivery_note, "docstatus") != 1:
throw(_("Delivery Note {0} is not submitted").format(d.delivery_note))
- def make_gl_entries(self, repost_future_gle=True):
+ def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
if not self.grand_total:
return
- gl_entries = self.get_gl_entries()
+
+ if not gl_entries:
+ gl_entries = self.get_gl_entries()
if gl_entries:
from erpnext.accounts.general_ledger import make_gl_entries
@@ -651,32 +653,34 @@
def make_pos_gl_entries(self, gl_entries):
if cint(self.is_pos):
for payment_mode in self.payments:
- # POS, make payment entries
- gl_entries.append(
- self.get_gl_dict({
- "account": self.debit_to,
- "party_type": "Customer",
- "party": self.customer,
- "against": payment_mode.account,
- "credit": payment_mode.base_amount,
- "credit_in_account_currency": payment_mode.base_amount \
- if self.party_account_currency==self.company_currency \
- else payment_mode.amount,
- "against_voucher": self.return_against if cint(self.is_return) else self.name,
- "against_voucher_type": self.doctype,
- }, self.party_account_currency)
- )
+ if payment_mode.amount:
+ # POS, make payment entries
+ gl_entries.append(
+ self.get_gl_dict({
+ "account": self.debit_to,
+ "party_type": "Customer",
+ "party": self.customer,
+ "against": payment_mode.account,
+ "credit": payment_mode.base_amount,
+ "credit_in_account_currency": payment_mode.base_amount \
+ if self.party_account_currency==self.company_currency \
+ else payment_mode.amount,
+ "against_voucher": self.return_against if cint(self.is_return) else self.name,
+ "against_voucher_type": self.doctype,
+ }, self.party_account_currency)
+ )
- payment_mode_account_currency = get_account_currency(payment_mode.account)
- gl_entries.append(
- self.get_gl_dict({
- "account": payment_mode.account,
- "against": self.customer,
- "debit": payment_mode.base_amount,
- "debit_in_account_currency": payment_mode.base_amount \
- if payment_mode_account_currency==self.company_currency else payment_mode.amount
- }, payment_mode_account_currency)
- )
+ payment_mode_account_currency = get_account_currency(payment_mode.account)
+ gl_entries.append(
+ self.get_gl_dict({
+ "account": payment_mode.account,
+ "against": self.customer,
+ "debit": payment_mode.base_amount,
+ "debit_in_account_currency": payment_mode.base_amount \
+ if payment_mode_account_currency==self.company_currency \
+ else payment_mode.amount
+ }, payment_mode_account_currency)
+ )
def make_gle_for_change_amount(self, gl_entries):
if cint(self.is_pos) and self.change_amount:
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py
index 7ec833e..606d067 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py
@@ -7,6 +7,7 @@
from frappe import _
from frappe.model.document import Document
from frappe.utils import cstr, cint
+from frappe.geo.doctype.address.address import get_default_address
class IncorrectCustomerGroup(frappe.ValidationError): pass
class IncorrectSupplierType(frappe.ValidationError): pass
@@ -96,27 +97,31 @@
@frappe.whitelist()
def get_party_details(party, party_type, args=None):
out = {}
+ billing_address, shipping_address = None, None
if args:
- billing_filters= {"name": args.get("billing_address")}
- shipping_filters= {"name": args.get("shipping_address")}
+ if args.get('billing_address'):
+ billing_address = frappe.get_doc('Address', args.get('billing_address'))
+ if args.get('shipping_address'):
+ shipping_address = frappe.get_doc('Address', args.get('shipping_address'))
else:
- billing_filters= {party_type: party, "is_primary_address": 1}
- shipping_filters= {party_type:party, "is_shipping_address": 1}
-
- billing_address= frappe.get_all("Address", fields=["city", "county", "state", "country"], filters= billing_filters)
- shipping_address= frappe.get_all("Address", fields=["city", "county", "state", "country"], filters= shipping_filters)
+ billing_address_name = get_default_address(party_type, party)
+ shipping_address_name = get_default_address(party_type, party, 'is_shipping_address')
+ if billing_address_name:
+ billing_address = frappe.get_doc('Address', billing_address_name)
+ if shipping_address_name:
+ shipping_address = frappe.get_doc('Address', shipping_address_name)
if billing_address:
- out["billing_city"]= billing_address[0].city
- out["billing_county"]= billing_address[0].county
- out["billing_state"]= billing_address[0].state
- out["billing_country"]= billing_address[0].country
+ out["billing_city"]= billing_address.city
+ out["billing_county"]= billing_address.county
+ out["billing_state"]= billing_address.state
+ out["billing_country"]= billing_address.country
if shipping_address:
- out["shipping_city"]= shipping_address[0].city
- out["shipping_county"]= shipping_address[0].county
- out["shipping_state"]= shipping_address[0].state
- out["shipping_country"]= shipping_address[0].country
+ out["shipping_city"]= shipping_address.city
+ out["shipping_county"]= shipping_address.county
+ out["shipping_state"]= shipping_address.state
+ out["shipping_country"]= shipping_address.country
return out
diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py
index 392902c..4c5535d 100644
--- a/erpnext/accounts/general_ledger.py
+++ b/erpnext/accounts/general_ledger.py
@@ -11,12 +11,12 @@
class StockAccountInvalidTransaction(frappe.ValidationError): pass
-def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, update_outstanding='Yes'):
+def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, update_outstanding='Yes', from_repost=False):
if gl_map:
if not cancel:
gl_map = process_gl_map(gl_map, merge_entries)
if gl_map and len(gl_map) > 1:
- save_entries(gl_map, adv_adj, update_outstanding)
+ save_entries(gl_map, adv_adj, update_outstanding, from_repost)
else:
frappe.throw(_("Incorrect number of General Ledger Entries found. You might have selected a wrong Account in the transaction."))
else:
@@ -78,21 +78,26 @@
and cstr(e.get('project')) == cstr(gle.get('project')):
return e
-def save_entries(gl_map, adv_adj, update_outstanding):
- validate_account_for_auto_accounting_for_stock(gl_map)
+def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
+ if not from_repost:
+ validate_account_for_auto_accounting_for_stock(gl_map)
+
round_off_debit_credit(gl_map)
for entry in gl_map:
- make_entry(entry, adv_adj, update_outstanding)
+ make_entry(entry, adv_adj, update_outstanding, from_repost)
+
# check against budget
- validate_expense_against_budget(entry)
+ if not from_repost:
+ validate_expense_against_budget(entry)
-def make_entry(args, adv_adj, update_outstanding):
+def make_entry(args, adv_adj, update_outstanding, from_repost=False):
args.update({"doctype": "GL Entry"})
gle = frappe.get_doc(args)
gle.flags.ignore_permissions = 1
+ gle.flags.from_repost = from_repost
gle.insert()
- gle.run_method("on_update_with_args", adv_adj, update_outstanding)
+ gle.run_method("on_update_with_args", adv_adj, update_outstanding, from_repost)
gle.submit()
def validate_account_for_auto_accounting_for_stock(gl_map):
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index c65a845..eb705cd 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -8,8 +8,8 @@
from frappe import _, msgprint, scrub
from frappe.defaults import get_user_permissions
from frappe.utils import add_days, getdate, formatdate, get_first_day, date_diff, add_years
-from erpnext.utilities.doctype.address.address import get_address_display
-from erpnext.utilities.doctype.contact.contact import get_contact_details
+from frappe.geo.doctype.address.address import get_address_display, get_default_address
+from frappe.email.doctype.contact.contact import get_contact_details, get_default_contact
from erpnext.exceptions import PartyFrozen, InvalidCurrency, PartyDisabled, InvalidAccountCurrency
class DuplicatePartyAccountError(frappe.ValidationError): pass
@@ -60,21 +60,18 @@
def set_address_details(out, party, party_type):
billing_address_field = "customer_address" if party_type == "Lead" \
else party_type.lower() + "_address"
- out[billing_address_field] = frappe.db.get_value("Address",
- {party_type.lower(): party.name, "is_primary_address":1}, "name")
+ out[billing_address_field] = get_default_address(party_type, party.name)
# address display
out.address_display = get_address_display(out[billing_address_field])
# shipping address
if party_type in ["Customer", "Lead"]:
- out.shipping_address_name = frappe.db.get_value("Address",
- {party_type.lower(): party.name, "is_shipping_address":1}, "name")
+ out.shipping_address_name = get_default_address(party_type, party.name, 'is_shipping_address')
out.shipping_address = get_address_display(out["shipping_address_name"])
def set_contact_details(out, party, party_type):
- out.contact_person = frappe.db.get_value("Contact",
- {party_type.lower(): party.name, "is_primary_contact":1}, "name")
+ out.contact_person = get_default_contact(party_type, party.name)
if not out.contact_person:
out.update({
@@ -184,7 +181,7 @@
default_account_name = "default_receivable_account" \
if party_type=="Customer" else "default_payable_account"
account = frappe.db.get_value("Company", company, default_account_name)
-
+
existing_gle_currency = get_party_gle_currency(party_type, party, company)
if existing_gle_currency:
if account:
@@ -211,7 +208,7 @@
return frappe.local_cache("party_gle_currency", (party_type, party, company), generator,
regenerate_if_none=True)
-
+
def get_party_gle_account(party_type, party, company):
def generator():
existing_gle_account = frappe.db.sql("""select account from `tabGL Entry`
diff --git a/erpnext/accounts/print_format/point_of_sale/point_of_sale.json b/erpnext/accounts/print_format/point_of_sale/point_of_sale.json
index 367ce07..f7d5f63 100644
--- a/erpnext/accounts/print_format/point_of_sale/point_of_sale.json
+++ b/erpnext/accounts/print_format/point_of_sale/point_of_sale.json
@@ -7,10 +7,10 @@
"docstatus": 0,
"doctype": "Print Format",
"font": "Default",
- "html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"POS No : \") }}{{offline_pos_name}}<br>\n</p>\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(paid_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
+ "html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"POS No : \") }}{{offline_pos_name}}<br>\n</p>\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(paid_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p>{{ terms }}</p>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
"idx": 0,
"line_breaks": 0,
- "modified": "2016-12-27 17:22:17.391673",
+ "modified": "2017-01-12 14:56:12.571032",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Point of Sale",
diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py
index 182878a..7a776f5 100644
--- a/erpnext/accounts/report/cash_flow/cash_flow.py
+++ b/erpnext/accounts/report/cash_flow/cash_flow.py
@@ -10,7 +10,8 @@
def execute(filters=None):
- period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity)
+ period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
+ filters.periodicity)
operation_accounts = {
"section_name": "Operations",
@@ -103,7 +104,7 @@
data = {}
total = 0
for period in period_list:
- start_date = get_start_date(period, accumulated_values)
+ start_date = get_start_date(period, accumulated_values, company)
gl_sum = frappe.db.sql_list("""
select sum(credit) - sum(debit)
from `tabGL Entry`
@@ -126,10 +127,10 @@
data["total"] = total
return data
-def get_start_date(period, accumulated_values):
+def get_start_date(period, accumulated_values, company):
start_date = period["year_start_date"]
if accumulated_values:
- start_date = get_fiscal_year(period.to_date)[1]
+ start_date = get_fiscal_year(period.to_date, company=company)[1]
return start_date
diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py
index bc4a220..c897d1c 100644
--- a/erpnext/accounts/report/financial_statements.py
+++ b/erpnext/accounts/report/financial_statements.py
@@ -3,10 +3,8 @@
from __future__ import unicode_literals
import frappe
-import math
from frappe import _
-from frappe.utils import (flt, getdate, get_first_day, get_last_day, date_diff,
- add_months, add_days, formatdate, cint)
+from frappe.utils import flt, getdate, get_first_day, add_months, add_days, formatdate
def get_period_list(from_fiscal_year, to_fiscal_year, periodicity):
"""Get a list of dict {"from_date": from_date, "to_date": to_date, "key": key, "label": label}
@@ -149,7 +147,6 @@
def get_date_fiscal_year(date):
from erpnext.accounts.utils import get_fiscal_year
-
return get_fiscal_year(date)[0]
def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 8e59d8f..c35ca82 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -20,32 +20,63 @@
return get_fiscal_years(date, fiscal_year, label, verbose, company, as_dict=as_dict)[0]
def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False):
- # if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate)
- cond = " disabled = 0"
- if fiscal_year:
- cond += " and fy.name = %(fiscal_year)s"
- else:
- cond += " and %(transaction_date)s >= fy.year_start_date and %(transaction_date)s <= fy.year_end_date"
+ fiscal_years = frappe.cache().hget("fiscal_years", company) or []
+
+ if not fiscal_years:
+ # if year start date is 2012-04-01, year end date should be 2013-03-31 (hence subdate)
+ cond = ""
+ if fiscal_year:
+ cond += " and fy.name = {0}".format(frappe.db.escape(fiscal_year))
+ if company:
+ cond += """
+ and (not exists (select name
+ from `tabFiscal Year Company` fyc
+ where fyc.parent = fy.name)
+ or exists(select company
+ from `tabFiscal Year Company` fyc
+ where fyc.parent = fy.name
+ and fyc.company=%(company)s)
+ )
+ """
- if company:
- cond += """ and (not exists(select name from `tabFiscal Year Company` fyc where fyc.parent = fy.name)
- or exists(select company from `tabFiscal Year Company` fyc where fyc.parent = fy.name and fyc.company=%(company)s ))"""
+ fiscal_years = frappe.db.sql("""
+ select
+ fy.name, fy.year_start_date, fy.year_end_date
+ from
+ `tabFiscal Year` fy
+ where
+ disabled = 0 {0}
+ order by
+ fy.year_start_date desc""".format(cond), {
+ "company": company
+ }, as_dict=True)
+
+ frappe.cache().hset("fiscal_years", company, fiscal_years)
- fy = frappe.db.sql("""select fy.name, fy.year_start_date, fy.year_end_date from `tabFiscal Year` fy
- where %s order by fy.year_start_date desc""" % cond, {
- "fiscal_year": fiscal_year,
- "transaction_date": transaction_date,
- "company": company
- }, as_dict=as_dict)
+ if transaction_date:
+ transaction_date = getdate(transaction_date)
- if not fy:
- error_msg = _("""{0} {1} not in any active Fiscal Year. For more details check {2}.""").format(label, formatdate(transaction_date), "https://frappe.github.io/erpnext/user/manual/en/accounts/articles/fiscal-year-error")
- if verbose==1: frappe.msgprint(error_msg)
- raise FiscalYearError, error_msg
- return fy
+ for fy in fiscal_years:
+ matched = False
+ if fiscal_year and fy.name == fiscal_year:
+ matched = True
-def validate_fiscal_year(date, fiscal_year, label=_("Date"), doc=None):
- years = [f[0] for f in get_fiscal_years(date, label=label)]
+ if (transaction_date and getdate(fy.year_start_date) <= transaction_date
+ and getdate(fy.year_end_date) >= transaction_date):
+ matched = True
+
+ if matched:
+ if as_dict:
+ return (fy,)
+ else:
+ return ((fy.name, fy.year_start_date, fy.year_end_date),)
+
+ error_msg = _("""{0} {1} not in any active Fiscal Year.""").format(label, formatdate(transaction_date))
+ if verbose==1: frappe.msgprint(error_msg)
+ raise FiscalYearError, error_msg
+
+def validate_fiscal_year(date, fiscal_year, company, label=_("Date"), doc=None):
+ years = [f[0] for f in get_fiscal_years(date, label=label, company=company)]
if fiscal_year not in years:
if doc:
doc.fiscal_year = years[0]
@@ -206,9 +237,12 @@
@frappe.whitelist()
def add_ac(args=None):
+ from frappe.desk.treeview import make_tree_args
+
if not args:
args = frappe.local.form_dict
- args.pop("cmd")
+
+ args = make_tree_args(**args)
ac = frappe.new_doc("Account")
@@ -233,9 +267,12 @@
@frappe.whitelist()
def add_cc(args=None):
+ from frappe.desk.treeview import make_tree_args
+
if not args:
args = frappe.local.form_dict
- args.pop("cmd")
+
+ args = make_tree_args(**args)
cc = frappe.new_doc("Cost Center")
cc.update(args)
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index 5d74760..720a1dc 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -50,13 +50,9 @@
});
}
- $.each([["supplier", "supplier"],
- ["contact_person", "supplier_filter"],
- ["supplier_address", "supplier_filter"]],
- function(i, opts) {
- if(me.frm.fields_dict[opts[0]])
- me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
- });
+ me.frm.set_query('supplier', erpnext.queries.supplier);
+ me.frm.set_query('contact_person', erpnext.queries.contact_query);
+ me.frm.set_query('supplier_address', erpnext.queries.address_query);
if(this.frm.fields_dict.supplier) {
this.frm.set_query("supplier", function() {
@@ -79,6 +75,8 @@
},
refresh: function(doc) {
+ frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'supplier', doctype: 'Supplier'};
+
this.frm.toggle_display("supplier_name",
(this.frm.doc.supplier_name && this.frm.doc.supplier_name!==this.frm.doc.supplier));
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 15356fd..f2f04fe 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -226,18 +226,6 @@
})
}
-cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
- return {
- filters: {'supplier': doc.supplier}
- }
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return {
- filters: {'supplier': doc.supplier}
- }
-}
-
cur_frm.fields_dict['items'].grid.get_field('project').get_query = function(doc, cdt, cdn) {
return {
filters:[
diff --git a/erpnext/buying/doctype/supplier/supplier.js b/erpnext/buying/doctype/supplier/supplier.js
index b176e00..ce6f451 100644
--- a/erpnext/buying/doctype/supplier/supplier.js
+++ b/erpnext/buying/doctype/supplier/supplier.js
@@ -16,6 +16,8 @@
});
},
refresh: function(frm) {
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Supplier'}
+
if(frappe.defaults.get_default("supp_master_name")!="Naming Series") {
frm.toggle_display("naming_series", false);
} else {
diff --git a/erpnext/buying/doctype/supplier/supplier.py b/erpnext/buying/doctype/supplier/supplier.py
index 3677ee2..9eaaad1 100644
--- a/erpnext/buying/doctype/supplier/supplier.py
+++ b/erpnext/buying/doctype/supplier/supplier.py
@@ -6,7 +6,9 @@
import frappe.defaults
from frappe import msgprint, _
from frappe.model.naming import make_autoname
-from erpnext.utilities.address_and_contact import load_address_and_contact
+from erpnext.utilities.address_and_contact import (load_address_and_contact,
+ delete_contact_and_address)
+
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
@@ -46,21 +48,10 @@
else:
self.name = make_autoname(self.naming_series + '.#####')
- def update_address(self):
- frappe.db.sql("""update `tabAddress` set supplier_name=%s, modified=NOW()
- where supplier=%s""", (self.supplier_name, self.name))
-
- def update_contact(self):
- frappe.db.sql("""update `tabContact` set supplier_name=%s, modified=NOW()
- where supplier=%s""", (self.supplier_name, self.name))
-
def on_update(self):
if not self.naming_series:
self.naming_series = ''
- self.update_address()
- self.update_contact()
-
def validate(self):
#validation for Naming Series mandatory field...
if frappe.defaults.get_global_default('supp_master_name') == 'Naming Series':
@@ -78,28 +69,9 @@
else:
return ''
- def delete_supplier_address(self):
- for rec in frappe.db.sql("select * from `tabAddress` where supplier=%s", (self.name,), as_dict=1):
- frappe.db.sql("delete from `tabAddress` where name=%s",(rec['name']))
-
- def delete_supplier_contact(self):
- for contact in frappe.db.sql_list("""select name from `tabContact`
- where supplier=%s""", self.name):
- frappe.delete_doc("Contact", contact)
-
def on_trash(self):
- self.delete_supplier_address()
- self.delete_supplier_contact()
+ delete_contact_and_address('Supplier', self.name)
def after_rename(self, olddn, newdn, merge=False):
- set_field = ''
if frappe.defaults.get_global_default('supp_master_name') == 'Supplier Name':
frappe.db.set(self, "supplier_name", newdn)
- self.update_contact()
- set_field = ", supplier_name=%(newdn)s"
- self.update_supplier_address(newdn, set_field)
-
- def update_supplier_address(self, newdn, set_field):
- frappe.db.sql("""update `tabAddress` set address_title=%(newdn)s
- {set_field} where supplier=%(newdn)s"""\
- .format(set_field=set_field), ({"newdn": newdn}))
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
index fc9cc3b..b3bdeb0 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
@@ -59,15 +59,3 @@
]
}
}
-
-cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
- return {
- filters:{'supplier': doc.supplier}
- }
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return {
- filters:{'supplier': doc.supplier}
- }
-}
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index 9397ffc..029ef74 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -229,15 +229,6 @@
"type": "list"
},
{
- "module_name": "Assessment",
- "color": "#8a70be",
- "icon": "fa fa-file-text-alt",
- "label": _("Assessment"),
- "link": "List/Assessment",
- "_doctype": "Assessment",
- "type": "list"
- },
- {
"module_name": "Fees",
"color": "#83C21E",
"icon": "fa fa-money",
diff --git a/erpnext/config/hr.py b/erpnext/config/hr.py
index 55363ab..3a18a27 100644
--- a/erpnext/config/hr.py
+++ b/erpnext/config/hr.py
@@ -166,6 +166,21 @@
},
]
},
+
+ {
+ "label": _("Fleet Management"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Vehicle"
+ },
+ {
+ "type": "doctype",
+ "name": "Vehicle Log"
+ },
+ ]
+ },
+
{
"label": _("Setup"),
@@ -232,7 +247,7 @@
{
"type": "report",
"is_query_report": True,
- "name": "Monthly Salary Register",
+ "name": "Salary Register",
"doctype": "Salary Slip"
},
{
@@ -241,6 +256,12 @@
"name": "Monthly Attendance Sheet",
"doctype": "Attendance"
},
+ {
+ "type": "report",
+ "is_query_report": True,
+ "name": "Vehicle Expenses",
+ "doctype": "Vehicle"
+ },
]
},
diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py
index 366810d..903f54b 100644
--- a/erpnext/config/schools.py
+++ b/erpnext/config/schools.py
@@ -112,7 +112,7 @@
"items": [
{
"type": "doctype",
- "name": "Assessment"
+ "name": "Assessment Plan"
},
{
"type": "doctype",
@@ -120,7 +120,19 @@
},
{
"type": "doctype",
- "name": "Grading Structure"
+ "name": "Assessment Result"
+ },
+ {
+ "type": "doctype",
+ "name": "Grading Scale"
+ },
+ {
+ "type": "doctype",
+ "name": "Evaluation Criteria"
+ },
+ {
+ "type": "doctype",
+ "name": "Assessment Result Tool"
}
]
},
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 554529c..67d4822 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -113,7 +113,7 @@
date_field = "transaction_date"
if date_field and self.get(date_field):
- validate_fiscal_year(self.get(date_field), self.fiscal_year,
+ validate_fiscal_year(self.get(date_field), self.fiscal_year, self.company,
self.meta.get_label(date_field), self)
def validate_due_date(self):
@@ -131,7 +131,7 @@
transaction_date = self.posting_date
else:
transaction_date = self.transaction_date
-
+
if self.meta.get_field("currency"):
# price list part
fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \
@@ -144,7 +144,7 @@
self.plc_conversion_rate = 1.0
elif not self.plc_conversion_rate:
- self.plc_conversion_rate = get_exchange_rate(self.price_list_currency,
+ self.plc_conversion_rate = get_exchange_rate(self.price_list_currency,
self.company_currency, transaction_date)
# currency
@@ -570,7 +570,7 @@
elif asset.status in ("Scrapped", "Cancelled", "Sold"):
frappe.throw(_("Row #{0}: Asset {1} cannot be submitted, it is already {2}")
.format(d.idx, d.asset, asset.status))
-
+
def delink_advance_entries(self, linked_doc_name):
total_allocated_amount = 0
for adv in self.advances:
@@ -583,7 +583,7 @@
if consider_for_total_advance:
total_allocated_amount += flt(adv.allocated_amount, adv.precision("allocated_amount"))
- frappe.db.set_value(self.doctype, self.name, "total_advance",
+ frappe.db.set_value(self.doctype, self.name, "total_advance",
total_allocated_amount, update_modified=False)
def group_similar_items(self):
@@ -711,7 +711,7 @@
.format(order_doctype, order_condition))
reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
-
+
journal_entries = frappe.db.sql("""
select
"Journal Entry" as reference_type, t1.name as reference_name,
@@ -771,8 +771,8 @@
def update_invoice_status():
# Daily update the status of the invoices
- frappe.db.sql(""" update `tabSales Invoice` set status = 'Overdue'
+ frappe.db.sql(""" update `tabSales Invoice` set status = 'Overdue'
where due_date < CURDATE() and docstatus = 1 and outstanding_amount > 0""")
- frappe.db.sql(""" update `tabPurchase Invoice` set status = 'Overdue'
+ frappe.db.sql(""" update `tabPurchase Invoice` set status = 'Overdue'
where due_date < CURDATE() and docstatus = 1 and outstanding_amount > 0""")
\ No newline at end of file
diff --git a/erpnext/controllers/js/contact_address_common.js b/erpnext/controllers/js/contact_address_common.js
deleted file mode 100644
index c51ff46..0000000
--- a/erpnext/controllers/js/contact_address_common.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
- cur_frm.add_fetch('customer', 'customer_name', 'customer_name');
- cur_frm.add_fetch('supplier', 'supplier_name', 'supplier_name');
-
- cur_frm.fields_dict.customer.get_query = erpnext.queries.customer;
- cur_frm.fields_dict.supplier.get_query = erpnext.queries.supplier;
-
- if(cur_frm.fields_dict.lead) {
- cur_frm.fields_dict.lead.get_query = erpnext.queries.lead;
- cur_frm.add_fetch('lead', 'lead_name', 'lead_name');
- }
-
- if(doc.__islocal) {
- var last_route = frappe.route_history.slice(-2, -1)[0];
- if(last_route && last_route[0]==="Form") {
- var doctype = last_route[1],
- docname = last_route.slice(2).join("/");
-
- if(["Customer", "Quotation", "Sales Order", "Sales Invoice", "Delivery Note",
- "Installation Note", "Opportunity", "Warranty Claim", "Maintenance Visit",
- "Maintenance Schedule"]
- .indexOf(doctype)!==-1) {
- var refdoc = frappe.get_doc(doctype, docname);
- if((refdoc.doctype == "Quotation" && refdoc.quotation_to=="Customer") ||
- (refdoc.doctype == "Opportunity" && refdoc.enquiry_from=="Customer") ||
- !in_list(["Opportunity", "Quotation"], doctype)) {
- cur_frm.set_value("customer", refdoc.customer || refdoc.name);
- cur_frm.set_value("customer_name", refdoc.customer_name);
- if(cur_frm.doc.doctype==="Address")
- cur_frm.set_value("address_title", cur_frm.doc.customer_name);
- }
- }
- else if(["Supplier", "Supplier Quotation", "Purchase Order", "Purchase Invoice", "Purchase Receipt"]
- .indexOf(doctype)!==-1) {
- var refdoc = frappe.get_doc(doctype, docname);
- cur_frm.set_value("supplier", refdoc.supplier || refdoc.name);
- cur_frm.set_value("supplier_name", refdoc.supplier_name);
- if(cur_frm.doc.doctype==="Address")
- cur_frm.set_value("address_title", cur_frm.doc.supplier_name);
- }
- else if(["Lead", "Opportunity", "Quotation"]
- .indexOf(doctype)!==-1) {
- var refdoc = frappe.get_doc(doctype, docname);
-
- if((refdoc.doctype == "Quotation" && refdoc.quotation_to=="Lead") ||
- (refdoc.doctype == "Opportunity" && refdoc.enquiry_from=="Lead") || (doctype=="Lead")) {
- cur_frm.set_value("lead", refdoc.lead || refdoc.name);
- cur_frm.set_value("lead_name", refdoc.customer_name || refdoc.company_name || refdoc.lead_name);
- if(cur_frm.doc.doctype==="Address")
- cur_frm.set_value("address_title", cur_frm.doc.lead_name);
- }
- }
- else if(doctype == "Sales Partner") {
- cur_frm.set_value("sales_partner", docname);
- }
- }
- }
-}
diff --git a/erpnext/controllers/queries.py b/erpnext/controllers/queries.py
index 98390ff..cc3f277 100644
--- a/erpnext/controllers/queries.py
+++ b/erpnext/controllers/queries.py
@@ -3,32 +3,9 @@
from __future__ import unicode_literals
import frappe
-from frappe.desk.reportview import get_match_cond
-from frappe.model.db_query import DatabaseQuery
+from frappe.desk.reportview import get_match_cond, get_filters_cond
from frappe.utils import nowdate
-def get_filters_cond(doctype, filters, conditions):
- if filters:
- flt = filters
- if isinstance(filters, dict):
- filters = filters.items()
- flt = []
- for f in filters:
- if isinstance(f[1], basestring) and f[1][0] == '!':
- flt.append([doctype, f[0], '!=', f[1][1:]])
- else:
- value = frappe.db.escape(f[1]) if isinstance(f[1], basestring) else f[1]
- flt.append([doctype, f[0], '=', value])
-
- query = DatabaseQuery(doctype)
- query.filters = flt
- query.conditions = conditions
- query.build_filter_conditions(flt, conditions)
-
- cond = ' and ' + ' and '.join(query.conditions)
- else:
- cond = ''
- return cond
# searches for active employees
def employee_query(doctype, txt, searchfield, start, page_len, filters):
@@ -88,7 +65,7 @@
fields = ["name", "customer_group", "territory"]
else:
fields = ["name", "customer_name", "customer_group", "territory"]
-
+
meta = frappe.get_meta("Customer")
fields = fields + [f for f in meta.get_search_fields() if not f in fields]
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index 096bb2d..4fbee58 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -103,6 +103,8 @@
def set_status(self, update=False, status=None, update_modified=True):
if self.is_new():
+ if self.get('amended_from'):
+ self.status = 'Draft'
return
if self.doctype in status_map:
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index f0c8dbf..74ea774 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -14,8 +14,8 @@
def validate(self):
super(StockController, self).validate()
self.validate_inspection()
-
- def make_gl_entries(self, repost_future_gle=True):
+
+ def make_gl_entries(self, gl_entries=None, repost_future_gle=True, from_repost=False):
if self.docstatus == 2:
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
@@ -23,8 +23,9 @@
warehouse_account = get_warehouse_account()
if self.docstatus==1:
- gl_entries = self.get_gl_entries(warehouse_account)
- make_gl_entries(gl_entries)
+ if not gl_entries:
+ gl_entries = self.get_gl_entries(warehouse_account)
+ make_gl_entries(gl_entries, from_repost=from_repost)
if repost_future_gle:
items, warehouses = self.get_items_and_warehouses()
@@ -42,16 +43,16 @@
gl_list = []
warehouse_with_no_account = []
-
+
for item_row in voucher_details:
sle_list = sle_map.get(item_row.name)
if sle_list:
for sle in sle_list:
if warehouse_account.get(sle.warehouse):
# from warehouse account
-
+
self.check_expense_account(item_row)
-
+
if not sle.stock_value_difference:
self.validate_negative_stock(sle)
@@ -79,16 +80,16 @@
for wh in warehouse_with_no_account:
if frappe.db.get_value("Warehouse", wh, "company"):
frappe.throw(_("Warehouse {0} is not linked to any account, please create/link the corresponding (Asset) account for the warehouse.").format(wh))
-
+
msgprint(_("No accounting entries for the following warehouses") + ": \n" +
"\n".join(warehouse_with_no_account))
return process_gl_map(gl_list)
-
+
def validate_negative_stock(self, sle):
if sle.qty_after_transaction < 0 and sle.actual_qty < 0:
frappe.throw(_("For the Item {0}, valuation rate not found for warehouse {1}. To be able to do accounting entries (for booking expenses), we need valuation rate for item {2}. Please create an incoming stock transaction, on or before {3} {4}, and then try submiting {5}")
- .format(sle.item_code, sle.warehouse,
+ .format(sle.item_code, sle.warehouse,
sle.item_code, sle.posting_date, sle.posting_time, self.name))
def get_voucher_details(self, default_expense_account, default_cost_center, sle_map):
@@ -224,7 +225,7 @@
def make_gl_entries_on_cancel(self, repost_future_gle=True):
if frappe.db.sql("""select name from `tabGL Entry` where voucher_type=%s
and voucher_no=%s""", (self.doctype, self.name)):
- self.make_gl_entries(repost_future_gle)
+ self.make_gl_entries(repost_future_gle=repost_future_gle)
def get_serialized_items(self):
serialized_items = []
@@ -247,7 +248,7 @@
incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
return incoming_rate
-
+
def validate_warehouse(self):
from erpnext.stock.utils import validate_warehouse_company
@@ -256,7 +257,7 @@
for w in warehouses:
validate_warehouse_company(w, self.company)
-
+
def update_billing_percentage(self, update_modified=True):
self._update_percent_field({
"target_dt": self.doctype + " Item",
@@ -270,21 +271,21 @@
def validate_inspection(self):
'''Checks if quality inspection is set for Items that require inspection.
On submit, throw an exception'''
-
+
inspection_required_fieldname = None
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
inspection_required_fieldname = "inspection_required_before_purchase"
elif self.doctype in ["Delivery Note", "Sales Invoice"]:
inspection_required_fieldname = "inspection_required_before_delivery"
-
+
if not inspection_required_fieldname or \
(self.doctype in ["Sales Invoice", "Purchase Invoice"] and not self.update_stock):
return
-
+
for d in self.get('items'):
- if (frappe.db.get_value("Item", d.item_code, inspection_required_fieldname)
+ if (frappe.db.get_value("Item", d.item_code, inspection_required_fieldname)
and not d.quality_inspection):
-
+
frappe.msgprint(_("Quality Inspection required for Item {0}").format(d.item_code))
if self.docstatus==1:
raise frappe.ValidationError
@@ -300,7 +301,7 @@
future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items)
gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)
-
+
for voucher_type, voucher_no in future_stock_vouchers:
existing_gle = gle.get((voucher_type, voucher_no), [])
voucher_obj = frappe.get_doc(voucher_type, voucher_no)
@@ -308,7 +309,7 @@
if expected_gle:
if not existing_gle or not compare_existing_and_expected_gle(existing_gle, expected_gle):
_delete_gl_entries(voucher_type, voucher_no)
- voucher_obj.make_gl_entries(repost_future_gle=False)
+ voucher_obj.make_gl_entries(gl_entries=expected_gle, repost_future_gle=False, from_repost=True)
else:
_delete_gl_entries(voucher_type, voucher_no)
@@ -363,10 +364,19 @@
return gl_entries
def get_warehouse_account():
- warehouse_account = frappe._dict()
+ if not frappe.flags.warehouse_account_map or frappe.flags.in_test:
+ warehouse_account = frappe._dict()
- for d in frappe.db.sql("""select warehouse, name, account_currency from tabAccount
- where account_type = 'Stock' and (warehouse is not null and warehouse != ''
- and is_group != 1) and is_group=0 """, as_dict=1):
+ for d in frappe.db.sql("""select
+ warehouse, name, account_currency
+ from
+ tabAccount
+ where
+ account_type = 'Stock'
+ and (warehouse is not null and warehouse != '')
+ and is_group=0 """, as_dict=1):
warehouse_account.setdefault(d.warehouse, d)
- return warehouse_account
+
+ frappe.flags.warehouse_account_map = warehouse_account
+
+ return frappe.flags.warehouse_account_map
diff --git a/erpnext/crm/doctype/opportunity/opportunity.js b/erpnext/crm/doctype/opportunity/opportunity.js
index 21fba7b..32171b0 100644
--- a/erpnext/crm/doctype/opportunity/opportunity.js
+++ b/erpnext/crm/doctype/opportunity/opportunity.js
@@ -6,9 +6,14 @@
cur_frm.email_field = "contact_email";
frappe.ui.form.on("Opportunity", {
customer: function(frm) {
+ frm.trigger('set_contact_link');
erpnext.utils.get_party_details(frm);
},
+ lead: function(frm) {
+ frm.trigger('set_contact_link');
+ },
+
customer_address: function(frm, cdt, cdn) {
erpnext.utils.get_address_display(frm, 'customer_address', 'address_display', false);
},
@@ -23,6 +28,8 @@
refresh: function(frm) {
var doc = frm.doc;
frm.events.enquiry_from(frm);
+ frm.trigger('set_contact_link');
+
if(doc.status!=="Lost") {
if(doc.with_items){
frm.add_custom_button(__('Supplier Quotation'),
@@ -35,7 +42,7 @@
cur_frm.cscript.create_quotation, __("Make"));
frm.page.set_inner_btn_group_as_primary(__("Make"));
-
+
if(doc.status!=="Quotation") {
frm.add_custom_button(__('Lost'),
cur_frm.cscript['Declare Opportunity Lost']);
@@ -43,6 +50,14 @@
}
},
+ set_contact_link: function(frm) {
+ if(frm.doc.customer) {
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'customer', doctype: 'Customer'}
+ } else if(frm.doc.lead) {
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'lead', doctype: 'Lead'}
+ }
+ },
+
make_supplier_quotation: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.crm.doctype.opportunity.opportunity.make_supplier_quotation",
@@ -62,7 +77,7 @@
if(!this.frm.doc.status)
set_multiple(this.frm.doc.doctype, this.frm.doc.name, { status:'Open' });
if(!this.frm.doc.company && frappe.defaults.get_user_default("Company"))
- set_multiple(this.frm.doc.doctype, this.frm.doc.name,
+ set_multiple(this.frm.doc.doctype, this.frm.doc.name,
{ company:frappe.defaults.get_user_default("Company") });
this.setup_queries();
@@ -75,10 +90,7 @@
this.frm.set_query("contact_by", erpnext.queries.user);
}
- this.frm.set_query("customer_address", function() {
- if(me.frm.doc.lead) return {filters: { lead: me.frm.doc.lead } };
- else if(me.frm.doc.customer) return {filters: { customer: me.frm.doc.customer } };
- });
+ me.frm.set_query('customer_address', erpnext.queries.address_query);
this.frm.set_query("item_code", "items", function() {
return {
diff --git a/erpnext/demo/data/address.json b/erpnext/demo/data/address.json
index be4d5ec..7618c2c 100644
--- a/erpnext/demo/data/address.json
+++ b/erpnext/demo/data/address.json
@@ -1,245 +1,218 @@
[
{
- "address_line1": "254 Theotokopoulou Str.",
- "address_type": "Office",
- "city": "Larnaka",
- "country": "Cyprus",
- "customer": "Adaptas",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "254 Theotokopoulou Str.",
+ "address_type": "Office",
+ "city": "Larnaka",
+ "country": "Cyprus",
+ "links": [{"link_doctype": "Customer", "link_name": "Adaptas"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "R Patr\u00e3o Caramelho 116",
- "address_type": "Office",
- "city": "Fajozes",
- "country": "Portugal",
- "customer": "Asian Fusion",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "R Patr\u00e3o Caramelho 116",
+ "address_type": "Office",
+ "city": "Fajozes",
+ "country": "Portugal",
+ "links": [{"link_doctype": "Customer", "link_name": "Asian Fusion"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "30 Fulford Road",
- "address_type": "Office",
- "city": "PENTRE-PIOD",
- "country": "United Kingdom",
- "customer": "Asian Junction",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "30 Fulford Road",
+ "address_type": "Office",
+ "city": "PENTRE-PIOD",
+ "country": "United Kingdom",
+ "links": [{"link_doctype": "Customer", "link_name": "Asian Junction"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Schoenebergerstrasse 13",
- "address_type": "Office",
- "city": "Raschau",
- "country": "Germany",
- "customer": "Big D Supermarkets",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Schoenebergerstrasse 13",
+ "address_type": "Office",
+ "city": "Raschau",
+ "country": "Germany",
+ "links": [{"link_doctype": "Customer", "link_name": "Big D Supermarkets"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Hoheluftchaussee 43",
- "address_type": "Office",
- "city": "Kieritzsch",
- "country": "Germany",
- "customer": "Buttrey Food & Drug",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Hoheluftchaussee 43",
+ "address_type": "Office",
+ "city": "Kieritzsch",
+ "country": "Germany",
+ "links": [{"link_doctype": "Customer", "link_name": "Buttrey Food & Drug"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "R Cimo Vila 6",
- "address_type": "Office",
- "city": "Rebordosa",
- "country": "Portugal",
- "customer": "Chi-Chis",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "R Cimo Vila 6",
+ "address_type": "Office",
+ "city": "Rebordosa",
+ "country": "Portugal",
+ "links": [{"link_doctype": "Customer", "link_name": "Chi-Chis"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "R 5 Outubro 9",
- "address_type": "Office",
- "city": "Quinta Nova S\u00e3o Domingos",
- "country": "Portugal",
- "customer": "Choices",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "R 5 Outubro 9",
+ "address_type": "Office",
+ "city": "Quinta Nova S\u00e3o Domingos",
+ "country": "Portugal",
+ "links": [{"link_doctype": "Customer", "link_name": "Choices"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Avenida Macambira 953",
- "address_type": "Office",
- "city": "Goi\u00e2nia",
- "country": "Brazil",
- "customer": "Consumers and Consumers Express",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Avenida Macambira 953",
+ "address_type": "Office",
+ "city": "Goi\u00e2nia",
+ "country": "Brazil",
+ "links": [{"link_doctype": "Customer", "link_name": "Consumers and Consumers Express"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "2342 Goyeau Ave",
- "address_type": "Office",
- "city": "Windsor",
- "country": "Canada",
- "customer": "Crafts Canada",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "2342 Goyeau Ave",
+ "address_type": "Office",
+ "city": "Windsor",
+ "country": "Canada",
+ "links": [{"link_doctype": "Customer", "link_name": "Crafts Canada"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Laukaantie 82",
- "address_type": "Office",
- "city": "KOKKOLA",
- "country": "Finland",
- "customer": "Endicott Shoes",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Laukaantie 82",
+ "address_type": "Office",
+ "city": "KOKKOLA",
+ "country": "Finland",
+ "links": [{"link_doctype": "Customer", "link_name": "Endicott Shoes"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "9 Brown Street",
- "address_type": "Office",
- "city": "PETERSHAM",
- "country": "Australia",
- "customer": "Fayva",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "9 Brown Street",
+ "address_type": "Office",
+ "city": "PETERSHAM",
+ "country": "Australia",
+ "links": [{"link_doctype": "Customer", "link_name": "Fayva"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Via Donnalbina 41",
- "address_type": "Office",
- "city": "Cala Gonone",
- "country": "Italy",
- "customer": "Intelacard",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Via Donnalbina 41",
+ "address_type": "Office",
+ "city": "Cala Gonone",
+ "country": "Italy",
+ "links": [{"link_doctype": "Customer", "link_name": "Intelacard"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Liljerum Grenadj\u00e4rtorpet 69",
- "address_type": "Office",
- "city": "TOMTEBODA",
- "country": "Sweden",
- "customer": "Landskip Yard Care",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Liljerum Grenadj\u00e4rtorpet 69",
+ "address_type": "Office",
+ "city": "TOMTEBODA",
+ "country": "Sweden",
+ "links": [{"link_doctype": "Customer", "link_name": "Landskip Yard Care"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "72 Bishopgate Street",
- "address_type": "Office",
- "city": "SEAHAM",
- "country": "United Kingdom",
- "customer": "Life Plan Counselling",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "72 Bishopgate Street",
+ "address_type": "Office",
+ "city": "SEAHAM",
+ "country": "United Kingdom",
+ "links": [{"link_doctype": "Customer", "link_name": "Life Plan Counselling"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "\u03a3\u03ba\u03b1\u03c6\u03af\u03b4\u03b9\u03b1 105",
- "address_type": "Office",
- "city": "\u03a0\u0391\u03a1\u0395\u039a\u039a\u039b\u0397\u03a3\u0399\u0391",
- "country": "Cyprus",
- "customer": "Mr Fables",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "\u03a3\u03ba\u03b1\u03c6\u03af\u03b4\u03b9\u03b1 105",
+ "address_type": "Office",
+ "city": "\u03a0\u0391\u03a1\u0395\u039a\u039a\u039b\u0397\u03a3\u0399\u0391",
+ "country": "Cyprus",
+ "links": [{"link_doctype": "Customer", "link_name": "Mr Fables"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Mellemvej 7",
- "address_type": "Office",
- "city": "Aabybro",
- "country": "Denmark",
- "customer": "Nelson Brothers",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Mellemvej 7",
+ "address_type": "Office",
+ "city": "Aabybro",
+ "country": "Denmark",
+ "links": [{"link_doctype": "Customer", "link_name": "Nelson Brothers"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "Plougg\u00e5rdsvej 98",
- "address_type": "Office",
- "city": "Karby",
- "country": "Denmark",
- "customer": "Netobill",
- "phone": "23566775757",
- "supplier": null
- },
+ "address_line1": "Plougg\u00e5rdsvej 98",
+ "address_type": "Office",
+ "city": "Karby",
+ "country": "Denmark",
+ "links": [{"link_doctype": "Customer", "link_name": "Netobill"}],
+ "phone": "23566775757"
+ },
{
- "address_line1": "176 Michalakopoulou Street",
- "address_type": "Office",
- "city": "Agio Georgoudi",
- "country": "Cyprus",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Helios Air"
- },
+ "address_line1": "176 Michalakopoulou Street",
+ "address_type": "Office",
+ "city": "Agio Georgoudi",
+ "country": "Cyprus",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Helios Air"}]
+ },
{
- "address_line1": "Fibichova 1102",
- "address_type": "Office",
- "city": "Kokor\u00edn",
- "country": "Czech Republic",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Ks Merchandise"
- },
+ "address_line1": "Fibichova 1102",
+ "address_type": "Office",
+ "city": "Kokor\u00edn",
+ "country": "Czech Republic",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Ks Merchandise"}]
+ },
{
- "address_line1": "Zahradn\u00ed 888",
- "address_type": "Office",
- "city": "Cecht\u00edn",
- "country": "Czech Republic",
- "customer": null,
- "phone": "23566775757",
- "supplier": "HomeBase"
- },
+ "address_line1": "Zahradn\u00ed 888",
+ "address_type": "Office",
+ "city": "Cecht\u00edn",
+ "country": "Czech Republic",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "HomeBase"}]
+ },
{
- "address_line1": "ul. Grochowska 94",
- "address_type": "Office",
- "city": "Warszawa",
- "country": "Poland",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Scott Ties"
- },
+ "address_line1": "ul. Grochowska 94",
+ "address_type": "Office",
+ "city": "Warszawa",
+ "country": "Poland",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Scott Ties"}]
+ },
{
- "address_line1": "Norra Esplanaden 87",
- "address_type": "Office",
- "city": "HELSINKI",
- "country": "Finland",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Reliable Investments"
- },
+ "address_line1": "Norra Esplanaden 87",
+ "address_type": "Office",
+ "city": "HELSINKI",
+ "country": "Finland",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Reliable Investments"}]
+ },
{
- "address_line1": "2038 Fallon Drive",
- "address_type": "Office",
- "city": "Dresden",
- "country": "Canada",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Nan Duskin"
- },
+ "address_line1": "2038 Fallon Drive",
+ "address_type": "Office",
+ "city": "Dresden",
+ "country": "Canada",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Nan Duskin"}]
+ },
{
- "address_line1": "77 cours Franklin Roosevelt",
- "address_type": "Office",
- "city": "MARSEILLE",
- "country": "France",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Rainbow Records"
- },
+ "address_line1": "77 cours Franklin Roosevelt",
+ "address_type": "Office",
+ "city": "MARSEILLE",
+ "country": "France",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Rainbow Records"}]
+ },
{
- "address_line1": "ul. Tuwima Juliana 85",
- "address_type": "Office",
- "city": "\u0141\u00f3d\u017a",
- "country": "Poland",
- "customer": null,
- "phone": "23566775757",
- "supplier": "New World Realty"
- },
+ "address_line1": "ul. Tuwima Juliana 85",
+ "address_type": "Office",
+ "city": "\u0141\u00f3d\u017a",
+ "country": "Poland",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "New World Realty"}]
+ },
{
- "address_line1": "Gl. Sygehusvej 41",
- "address_type": "Office",
- "city": "Narsaq",
- "country": "Greenland",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Asiatic Solutions"
- },
+ "address_line1": "Gl. Sygehusvej 41",
+ "address_type": "Office",
+ "city": "Narsaq",
+ "country": "Greenland",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Asiatic Solutions"}]
+ },
{
- "address_line1": "Gosposka ulica 50",
- "address_type": "Office",
- "city": "Nova Gorica",
- "country": "Slovenia",
- "customer": null,
- "phone": "23566775757",
- "supplier": "Eagle Hardware"
+ "address_line1": "Gosposka ulica 50",
+ "address_type": "Office",
+ "city": "Nova Gorica",
+ "country": "Slovenia",
+ "phone": "23566775757",
+ "links": [{"link_doctype": "Supplier", "link_name": "Eagle Hardware"}]
}
]
\ No newline at end of file
diff --git a/erpnext/demo/data/contact.json b/erpnext/demo/data/contact.json
index 130845b..113b561 100644
--- a/erpnext/demo/data/contact.json
+++ b/erpnext/demo/data/contact.json
@@ -1,191 +1,164 @@
[
{
- "customer": "Adaptas",
- "email_id": "JanVaclavik@example.com",
- "first_name": "January",
- "last_name": "V\u00e1clav\u00edk",
- "supplier": null
- },
+ "email_id": "JanVaclavik@example.com",
+ "first_name": "January",
+ "last_name": "V\u00e1clav\u00edk",
+ "links": [{"link_doctype": "Customer", "link_name": "Adaptas"}]
+ },
{
- "customer": "Asian Fusion",
- "email_id": "ChidumagaTobeolisa@example.com",
- "first_name": "Chidumaga",
- "last_name": "Tobeolisa",
- "supplier": null
- },
+ "email_id": "ChidumagaTobeolisa@example.com",
+ "first_name": "Chidumaga",
+ "last_name": "Tobeolisa",
+ "links": [{"link_doctype": "Customer", "link_name": "Asian Fusion"}]
+ },
{
- "customer": "Asian Junction",
- "email_id": "JanaKubanova@example.com",
- "first_name": "Jana",
- "last_name": "Kub\u00e1\u0148ov\u00e1",
- "supplier": null
- },
+ "email_id": "JanaKubanova@example.com",
+ "first_name": "Jana",
+ "last_name": "Kub\u00e1\u0148ov\u00e1",
+ "links": [{"link_doctype": "Customer", "link_name": "Asian Junction"}]
+ },
{
- "customer": "Big D Supermarkets",
- "email_id": "XuChaoXuan@example.com",
- "first_name": "\u7d39\u8431",
- "last_name": "\u4e8e",
- "supplier": null
- },
+ "email_id": "XuChaoXuan@example.com",
+ "first_name": "\u7d39\u8431",
+ "last_name": "\u4e8e",
+ "links": [{"link_doctype": "Customer", "link_name": "Big D Supermarkets"}]
+ },
{
- "customer": "Buttrey Food & Drug",
- "email_id": "OzlemVerwijmeren@example.com",
- "first_name": "\u00d6zlem",
- "last_name": "Verwijmeren",
- "supplier": null
- },
+ "email_id": "OzlemVerwijmeren@example.com",
+ "first_name": "\u00d6zlem",
+ "last_name": "Verwijmeren",
+ "links": [{"link_doctype": "Customer", "link_name": "Buttrey Food & Drug"}]
+ },
{
- "customer": "Chi-Chis",
- "email_id": "HansRasmussen@example.com",
- "first_name": "Hans",
- "last_name": "Rasmussen",
- "supplier": null
- },
+ "email_id": "HansRasmussen@example.com",
+ "first_name": "Hans",
+ "last_name": "Rasmussen",
+ "links": [{"link_doctype": "Customer", "link_name": "Chi-Chis"}]
+ },
{
- "customer": "Choices",
- "email_id": "SatomiShigeki@example.com",
- "first_name": "Satomi",
- "last_name": "Shigeki",
- "supplier": null
- },
+ "email_id": "SatomiShigeki@example.com",
+ "first_name": "Satomi",
+ "last_name": "Shigeki",
+ "links": [{"link_doctype": "Customer", "link_name": "Choices"}]
+ },
{
- "customer": "Consumers and Consumers Express",
- "email_id": "SimonVJessen@example.com",
- "first_name": "Simon",
- "last_name": "Jessen",
- "supplier": null
- },
+ "email_id": "SimonVJessen@example.com",
+ "first_name": "Simon",
+ "last_name": "Jessen",
+ "links": [{"link_doctype": "Customer", "link_name": "Consumers and Consumers Express"}]
+ },
{
- "customer": "Crafts Canada",
- "email_id": "NeguaranShahsaah@example.com",
- "first_name": "\u0646\u06af\u0627\u0631\u06cc\u0646",
- "last_name": "\u0634\u0627\u0647 \u0633\u06cc\u0627\u0647",
- "supplier": null
- },
+ "email_id": "NeguaranShahsaah@example.com",
+ "first_name": "\u0646\u06af\u0627\u0631\u06cc\u0646",
+ "last_name": "\u0634\u0627\u0647 \u0633\u06cc\u0627\u0647",
+ "links": [{"link_doctype": "Customer", "link_name": "Crafts Canada"}]
+ },
{
- "customer": "Endicott Shoes",
- "email_id": "Lom-AliBataev@example.com",
- "first_name": "Lom-Ali",
- "last_name": "Bataev",
- "supplier": null
- },
+ "email_id": "Lom-AliBataev@example.com",
+ "first_name": "Lom-Ali",
+ "last_name": "Bataev",
+ "links": [{"link_doctype": "Customer", "link_name": "Endicott Shoes"}]
+ },
{
- "customer": "Fayva",
- "email_id": "VanNgocTien@example.com",
- "first_name": "Ti\u00ean",
- "last_name": "V\u0103n",
- "supplier": null
- },
+ "email_id": "VanNgocTien@example.com",
+ "first_name": "Ti\u00ean",
+ "last_name": "V\u0103n",
+ "links": [{"link_doctype": "Customer", "link_name": "Fayva"}]
+ },
{
- "customer": "Intelacard",
- "email_id": "QuimeyOsorioRuelas@example.com",
- "first_name": "Quimey",
- "last_name": "Osorio",
- "supplier": null
- },
+ "email_id": "QuimeyOsorioRuelas@example.com",
+ "first_name": "Quimey",
+ "last_name": "Osorio",
+ "links": [{"link_doctype": "Customer", "link_name": "Intelacard"}]
+ },
{
- "customer": "Landskip Yard Care",
- "email_id": "EdgardaSalcedoRaya@example.com",
- "first_name": "Edgarda",
- "last_name": "Salcedo",
- "supplier": null
- },
+ "email_id": "EdgardaSalcedoRaya@example.com",
+ "first_name": "Edgarda",
+ "last_name": "Salcedo",
+ "links": [{"link_doctype": "Customer", "link_name": "Landskip Yard Care"}]
+ },
{
- "customer": "Life Plan Counselling",
- "email_id": "HafsteinnBjarnarsonar@example.com",
- "first_name": "Hafsteinn",
- "last_name": "Bjarnarsonar",
- "supplier": null
- },
+ "email_id": "HafsteinnBjarnarsonar@example.com",
+ "first_name": "Hafsteinn",
+ "last_name": "Bjarnarsonar",
+ "links": [{"link_doctype": "Customer", "link_name": "Life Plan Counselling"}]
+ },
{
- "customer": "Mr Fables",
- "email_id": "\u0434\u0430\u043d\u0438\u0438\u043b@example.com",
- "first_name": "\u0414\u0430\u043d\u0438\u0438\u043b",
- "last_name": "\u041a\u043e\u043d\u043e\u0432\u0430\u043b\u043e\u0432",
- "supplier": null
- },
+ "email_id": "\u0434\u0430\u043d\u0438\u0438\u043b@example.com",
+ "first_name": "\u0414\u0430\u043d\u0438\u0438\u043b",
+ "last_name": "\u041a\u043e\u043d\u043e\u0432\u0430\u043b\u043e\u0432",
+ "links": [{"link_doctype": "Customer", "link_name": "Mr Fables"}]
+ },
{
- "customer": "Nelson Brothers",
- "email_id": "SelmaMAndersen@example.com",
- "first_name": "Selma",
- "last_name": "Andersen",
- "supplier": null
- },
+ "email_id": "SelmaMAndersen@example.com",
+ "first_name": "Selma",
+ "last_name": "Andersen",
+ "links": [{"link_doctype": "Customer", "link_name": "Nelson Brothers"}]
+ },
{
- "customer": "Netobill",
- "email_id": "LadislavKolaja@example.com",
- "first_name": "Ladislav",
- "last_name": "Kolaja",
- "supplier": null
- },
+ "email_id": "LadislavKolaja@example.com",
+ "first_name": "Ladislav",
+ "last_name": "Kolaja",
+ "links": [{"link_doctype": "Customer", "link_name": "Netobill"}]
+ },
{
- "customer": null,
- "email_id": "TewoldeAbaalom@example.com",
- "first_name": "Tewolde",
- "last_name": "Abaalom",
- "supplier": "Helios Air"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "Helios Air"}],
+ "email_id": "TewoldeAbaalom@example.com",
+ "first_name": "Tewolde",
+ "last_name": "Abaalom"
+ },
{
- "customer": null,
- "email_id": "LeilaFernandesRodrigues@example.com",
- "first_name": "Leila",
- "last_name": "Rodrigues",
- "supplier": "Ks Merchandise"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "Ks Merchandise"}],
+ "email_id": "LeilaFernandesRodrigues@example.com",
+ "first_name": "Leila",
+ "last_name": "Rodrigues"
+ },
{
- "customer": null,
- "email_id": "DmitryBulgakov@example.com",
- "first_name": "Dmitry",
- "last_name": "Bulgakov",
- "supplier": "HomeBase"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "HomeBase"}],
+ "email_id": "DmitryBulgakov@example.com",
+ "first_name": "Dmitry",
+ "last_name": "Bulgakov"
+ },
{
- "customer": null,
- "email_id": "HaiducWhitfoot@example.com",
- "first_name": "Haiduc",
- "last_name": "Whitfoot",
- "supplier": "Scott Ties"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "Scott Ties"}],
+ "email_id": "HaiducWhitfoot@example.com",
+ "first_name": "Haiduc",
+ "last_name": "Whitfoot"
+ },
{
- "customer": null,
- "email_id": "SesseljaPetursdottir@example.com",
- "first_name": "Sesselja",
- "last_name": "P\u00e9tursd\u00f3ttir",
- "supplier": "Reliable Investments"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "Reliable Investments"}],
+ "email_id": "SesseljaPetursdottir@example.com",
+ "first_name": "Sesselja",
+ "last_name": "P\u00e9tursd\u00f3ttir"
+ },
{
- "customer": null,
- "email_id": "HajdarPignar@example.com",
- "first_name": "Hajdar",
- "last_name": "Pignar",
- "supplier": "Nan Duskin"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "Nan Duskin"}],
+ "email_id": "HajdarPignar@example.com",
+ "first_name": "Hajdar",
+ "last_name": "Pignar"
+ },
{
- "customer": null,
- "email_id": "GustavaLorenzo@example.com",
- "first_name": "Gustava",
- "last_name": "Lorenzo",
- "supplier": "Rainbow Records"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "Rainbow Records"}],
+ "email_id": "GustavaLorenzo@example.com",
+ "first_name": "Gustava",
+ "last_name": "Lorenzo"
+ },
{
- "customer": null,
- "email_id": "BethanyWood@example.com",
- "first_name": "Bethany",
- "last_name": "Wood",
- "supplier": "New World Realty"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "New World Realty"}],
+ "email_id": "BethanyWood@example.com",
+ "first_name": "Bethany",
+ "last_name": "Wood"
+ },
{
- "customer": null,
- "email_id": "GlorianaBrownlock@example.com",
- "first_name": "Gloriana",
- "last_name": "Brownlock",
- "supplier": "Asiatic Solutions"
- },
+ "links": [{"link_doctype": "Supplier", "link_name": "Asiatic Solutions"}],
+ "email_id": "GlorianaBrownlock@example.com",
+ "first_name": "Gloriana",
+ "last_name": "Brownlock"
+ },
{
- "customer": null,
- "email_id": "JensonFraser@gustr.com",
- "first_name": "Jenson",
- "last_name": "Fraser",
- "supplier": "Eagle Hardware"
+ "links": [{"link_doctype": "Supplier", "link_name": "Eagle Hardware"}],
+ "email_id": "JensonFraser@gustr.com",
+ "first_name": "Jenson",
+ "last_name": "Fraser"
}
]
\ No newline at end of file
diff --git a/erpnext/demo/setup/setup_data.py b/erpnext/demo/setup/setup_data.py
index 902bbab..0c6a9b8 100644
--- a/erpnext/demo/setup/setup_data.py
+++ b/erpnext/demo/setup/setup_data.py
@@ -32,7 +32,7 @@
import_json('Contact')
import_json('Lead')
setup_currency_exchange()
- setup_mode_of_payment()
+ #setup_mode_of_payment()
setup_account_to_expense_type()
setup_budget()
setup_pos_profile()
@@ -163,11 +163,10 @@
ss.append('deductions', {
'salary_component': 'Income Tax',
"abbr":'IT',
- 'condition': 'base > 1000',
- 'amount': random.random() * 1000,
+ 'condition': 'base > 10000',
+ 'formula': 'base*.1',
"idx": 1
})
-
ss.insert()
return ss
diff --git a/erpnext/docs/assets/img/fleet-management/__init__.py b/erpnext/docs/assets/img/fleet-management/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/docs/assets/img/fleet-management/__init__.py
+++ /dev/null
diff --git a/erpnext/docs/assets/img/fleet-management/expense-claim-3.1.png b/erpnext/docs/assets/img/human-resources/expense-claim-3.1.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/expense-claim-3.1.png
rename to erpnext/docs/assets/img/human-resources/expense-claim-3.1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/expense-claim-3.2.png b/erpnext/docs/assets/img/human-resources/expense-claim-3.2.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/expense-claim-3.2.png
rename to erpnext/docs/assets/img/human-resources/expense-claim-3.2.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-1.1.png b/erpnext/docs/assets/img/human-resources/vehicle-1.1.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/vehicle-1.1.png
rename to erpnext/docs/assets/img/human-resources/vehicle-1.1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-1.2.png b/erpnext/docs/assets/img/human-resources/vehicle-1.2.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/vehicle-1.2.png
rename to erpnext/docs/assets/img/human-resources/vehicle-1.2.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-1.3.png b/erpnext/docs/assets/img/human-resources/vehicle-1.3.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/vehicle-1.3.png
rename to erpnext/docs/assets/img/human-resources/vehicle-1.3.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-expenses.png b/erpnext/docs/assets/img/human-resources/vehicle-expenses.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/vehicle-expenses.png
rename to erpnext/docs/assets/img/human-resources/vehicle-expenses.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-log-2.1.png b/erpnext/docs/assets/img/human-resources/vehicle-log-2.1.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/vehicle-log-2.1.png
rename to erpnext/docs/assets/img/human-resources/vehicle-log-2.1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/fleet-management/vehicle-log-2.2.png b/erpnext/docs/assets/img/human-resources/vehicle-log-2.2.png
similarity index 100%
rename from erpnext/docs/assets/img/fleet-management/vehicle-log-2.2.png
rename to erpnext/docs/assets/img/human-resources/vehicle-log-2.2.png
Binary files differ
diff --git a/erpnext/docs/user/manual/en/human-resources/fleet-management.md b/erpnext/docs/user/manual/en/human-resources/fleet-management.md
new file mode 100644
index 0000000..e55caa5
--- /dev/null
+++ b/erpnext/docs/user/manual/en/human-resources/fleet-management.md
@@ -0,0 +1,64 @@
+Fleet Management section of Human Resources helps your Organization manage their fleet of vehicles and track their expenses.
+
+To use Fleet Management in ERPNext,
+
+ 1. Set Up a Vehicle.
+ 2. Enter Vehicle Logs regularly.
+ 3. Make Expense Claims for Vehicle Expenses.
+ 4. View Reports for Vehicle Expenses.
+
+### Vehicle Set Up
+
+The Vehicle Set Up allows you to define the different types of Vehicles in your Organization.It acts as the Vehicle Master for Fleet Management.
+
+To create a new Vehicle go to:
+
+Human Resources > Fleet Management > Vehicle
+
+* Enter License Plate, Make, Model, Odometer Value, Fuel Type and Fuel UOM for a quick entry.
+
+ <img class="screenshot" alt="Vehicle" src="{{docs_base_url}}/assets/img/human-resources/vehicle-1.1.png">
+
+* Enter details like Insurance, Chassis, Vehicle Value, Location and Employee.
+
+ <img class="screenshot" alt="Vehicle" src="{{docs_base_url}}/assets/img/human-resources/vehicle-1.2.png">
+
+* Enter Vehicle attributes like color, wheels, doors and last carbon check
+
+ <img class="screenshot" alt="Vehicle" src="{{docs_base_url}}/assets/img/human-resources/vehicle-1.3.png">
+
+### Vehicle Log
+
+Vehicle Log is used to enter Odometer readings, Fuel Expenses and Service Expense details.
+
+To create a new Vehicle Log go to:
+
+Human Resources > Fleet Management > Vehicle Log
+
+* Enter License Plate, Employee, Date, Odometer reading for a quick entry.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/human-resources/vehicle-log-2.1.png">
+
+* Enter Refueling details, Service details if applicable.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/human-resources/vehicle-log-2.2.png">
+
+### Make Expense Claim
+
+* Click on Make Expense Claim button. This button appears only in case of Submitted Vehicle Logs.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/human-resources/expense-claim-3.1.png">
+
+When you click on 'Make Expense Claim',
+
+ 1. The date,employee,expense total are copied over to the created Expense Claim.
+ 2. The sum of Fuel Expenses and Service Expenses is copied over to Expense Claim Amount.
+ 3. Employee can submit the Expense Claim for further processing.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/human-resources/expense-claim-3.2.png">
+
+### Vehicle Expenses Report
+
+* To track and monitor Vehicle Expenses you can use the Vehicle Expenses report.This report gives a one stop view of all your vehicle expenses month wise.
+
+ <img class="screenshot" alt="Vehicle Log" src="{{docs_base_url}}/assets/img/human-resources/vehicle-expenses.png">
diff --git a/erpnext/docs/user/manual/en/human-resources/index.txt b/erpnext/docs/user/manual/en/human-resources/index.txt
index 5615790..f91edfa 100644
--- a/erpnext/docs/user/manual/en/human-resources/index.txt
+++ b/erpnext/docs/user/manual/en/human-resources/index.txt
@@ -14,4 +14,5 @@
holiday-list
human-resource-setup
daily-work-summary
+fleet-management
articles
diff --git a/erpnext/fleet_management/__init__.py b/erpnext/fleet_management/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/fleet_management/__init__.py
+++ /dev/null
diff --git a/erpnext/fleet_management/doctype/__init__.py b/erpnext/fleet_management/doctype/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/fleet_management/doctype/__init__.py
+++ /dev/null
diff --git a/erpnext/fleet_management/report/__init__.py b/erpnext/fleet_management/report/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/fleet_management/report/__init__.py
+++ /dev/null
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 59a1e2b..8443cdf 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -108,16 +108,12 @@
{"title": _("Issues"), "route": "/issues", "reference_doctype": "Issue", "role":"Customer"},
{"title": _("Addresses"), "route": "/addresses", "reference_doctype": "Address"},
{"title": _("Announcements"), "route": "/announcement", "reference_doctype": "Announcement"},
- {"title": _("Courses"), "route": "/course", "reference_doctype": "Course", "role":"Student"},
- {"title": _("Assessment Schedule"), "route": "/assessment", "reference_doctype": "Assessment", "role":"Student"},
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"}
]
default_roles = [
- {'role': 'Customer', 'doctype':'Contact', 'email_field': 'email_id',
- 'filters': {'ifnull(customer, "")': ('!=', '')}},
- {'role': 'Supplier', 'doctype':'Contact', 'email_field': 'email_id',
- 'filters': {'ifnull(supplier, "")': ('!=', '')}},
+ {'role': 'Customer', 'doctype':'Contact', 'email_field': 'email_id'},
+ {'role': 'Supplier', 'doctype':'Contact', 'email_field': 'email_id'},
{'role': 'Student', 'doctype':'Student', 'email_field': 'student_email_id'}
]
@@ -127,7 +123,6 @@
"Supplier Quotation": "erpnext.controllers.website_list_for_contact.has_website_permission",
"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission",
- "Address": "erpnext.utilities.doctype.address.address.has_website_permission",
"Discussion": "erpnext.schools.web_form.discussion.discussion.has_website_permission"
}
@@ -155,16 +150,14 @@
"on_cancel": "erpnext.stock.doctype.material_request.material_request.update_completed_and_requested_qty"
},
"User": {
+ "after_insert": "frappe.email.doctype.contact.contact.update_contact",
"validate": "erpnext.hr.doctype.employee.employee.validate_employee_role",
"on_update": "erpnext.hr.doctype.employee.employee.update_user_permissions",
- "on_update": "erpnext.utilities.doctype.contact.contact.update_contact"
+ "on_update": "erpnext.utilities.address_and_contact.set_default_role"
},
("Sales Taxes and Charges Template", 'Price List'): {
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
},
- "Address": {
- "validate": "erpnext.shopping_cart.cart.set_customer_in_address"
- },
# bubble transaction notification on master
('Opportunity', 'Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice',
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index 6b80a37..afa21e0 100755
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -26,6 +26,8 @@
self.name = make_autoname(self.naming_series + '.####')
elif naming_method == 'Employee Number':
self.name = self.employee_number
+ elif naming_method == 'Full Name':
+ self.name = self.employee_name
self.employee = self.name
@@ -271,7 +273,7 @@
last_name = employee_name[1]
first_name = employee_name[0]
-
+
user = frappe.new_doc("User")
user.update({
"name": emp.employee_name,
@@ -286,4 +288,4 @@
"bio": emp.bio
})
user.insert()
- return user.name
\ No newline at end of file
+ return user.name
diff --git a/erpnext/hr/doctype/hr_settings/hr_settings.json b/erpnext/hr/doctype/hr_settings/hr_settings.json
index e9d2098..5281045 100644
--- a/erpnext/hr/doctype/hr_settings/hr_settings.json
+++ b/erpnext/hr/doctype/hr_settings/hr_settings.json
@@ -22,6 +22,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Employee Settings",
"length": 0,
"no_copy": 0,
@@ -50,6 +51,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Retirement Age",
"length": 0,
"no_copy": 0,
@@ -79,10 +81,11 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Employee Records to be created by",
"length": 0,
"no_copy": 0,
- "options": "Naming Series\nEmployee Number",
+ "options": "Naming Series\nEmployee Number\nFull Name",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@@ -106,6 +109,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -133,6 +137,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Stop Birthday Reminders",
"length": 0,
"no_copy": 0,
@@ -159,6 +164,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Maintain Billing Hours and Working Hours Same on Timesheet",
"length": 0,
"no_copy": 0,
@@ -186,6 +192,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Payroll Settings",
"length": 0,
"no_copy": 0,
@@ -213,6 +220,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Include holidays in Total no. of Working Days",
"length": 0,
"no_copy": 0,
@@ -241,6 +249,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Email Salary Slip to Employee",
"length": 0,
"no_copy": 0,
@@ -268,6 +277,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Max working hours against Timesheet",
"length": 0,
"no_copy": 0,
@@ -295,8 +305,8 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-12-21 18:52:03.633251",
- "modified_by": "Administrator",
+ "modified": "2017-01-16 14:01:31.183485",
+ "modified_by": "anastasiadis.st00@gmail.com",
"module": "HR",
"name": "HR Settings",
"owner": "Administrator",
@@ -327,5 +337,6 @@
"read_only": 0,
"read_only_onload": 0,
"sort_order": "ASC",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index 16b5207..6794a31 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -296,17 +296,18 @@
frappe.db.set_value("Salary Slip", ss_obj.name, "journal_entry", jv_name)
def set_start_end_dates(self):
- self.update(get_start_end_dates(self.payroll_frequency, self.start_date or self.posting_date))
+ self.update(get_start_end_dates(self.payroll_frequency,
+ self.start_date or self.posting_date, self.company))
@frappe.whitelist()
-def get_start_end_dates(payroll_frequency, start_date=None):
+def get_start_end_dates(payroll_frequency, start_date=None, company=None):
'''Returns dict of start and end dates for given payroll frequency based on start_date'''
if not payroll_frequency:
frappe.throw(_("Please set Payroll Frequency first"))
if payroll_frequency == "Monthly" or payroll_frequency == "Bimonthly":
- fiscal_year = get_fiscal_year(start_date)[0]
+ fiscal_year = get_fiscal_year(start_date, company=company)[0]
month = "%02d" % getdate(start_date).month
m = get_month_details(fiscal_year, month)
if payroll_frequency == "Bimonthly":
diff --git a/erpnext/hr/doctype/salary_slip/test_salary_slip.py b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
index 3eec686..3d119c3 100644
--- a/erpnext/hr/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/test_salary_slip.py
@@ -134,7 +134,7 @@
self.assertTrue(email_queue)
def test_payroll_frequency(self):
- fiscal_year = get_fiscal_year(nowdate())[0]
+ fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")[0]
month = "%02d" % getdate(nowdate()).month
m = get_month_details(fiscal_year, month)
@@ -185,7 +185,7 @@
}).insert()
def make_holiday_list(self):
- fiscal_year = get_fiscal_year(nowdate())
+ fiscal_year = get_fiscal_year(nowdate(), company="_Test Company")
if not frappe.db.get_value("Holiday List", "Salary Slip Test Holiday List"):
holiday_list = frappe.get_doc({
"doctype": "Holiday List",
diff --git a/erpnext/fleet_management/doctype/vehicle/__init__.py b/erpnext/hr/doctype/vehicle/__init__.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle/__init__.py
rename to erpnext/hr/doctype/vehicle/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle/test_vehicle.py b/erpnext/hr/doctype/vehicle/test_vehicle.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle/test_vehicle.py
rename to erpnext/hr/doctype/vehicle/test_vehicle.py
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle.js b/erpnext/hr/doctype/vehicle/vehicle.js
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle/vehicle.js
rename to erpnext/hr/doctype/vehicle/vehicle.js
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle.json b/erpnext/hr/doctype/vehicle/vehicle.json
similarity index 99%
rename from erpnext/fleet_management/doctype/vehicle/vehicle.json
rename to erpnext/hr/doctype/vehicle/vehicle.json
index edad8a2..39735e6 100644
--- a/erpnext/fleet_management/doctype/vehicle/vehicle.json
+++ b/erpnext/hr/doctype/vehicle/vehicle.json
@@ -779,9 +779,9 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-11-07 06:00:22.056662",
+ "modified": "2017-01-09 11:10:11.678834",
"modified_by": "Administrator",
- "module": "Fleet Management",
+ "module": "HR",
"name": "Vehicle",
"name_case": "",
"owner": "Administrator",
@@ -815,5 +815,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "",
+ "track_changes": 1,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle.py b/erpnext/hr/doctype/vehicle/vehicle.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle/vehicle.py
rename to erpnext/hr/doctype/vehicle/vehicle.py
diff --git a/erpnext/fleet_management/doctype/vehicle/vehicle_dashboard.py b/erpnext/hr/doctype/vehicle/vehicle_dashboard.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle/vehicle_dashboard.py
rename to erpnext/hr/doctype/vehicle/vehicle_dashboard.py
diff --git a/erpnext/fleet_management/doctype/vehicle_log/__init__.py b/erpnext/hr/doctype/vehicle_log/__init__.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle_log/__init__.py
rename to erpnext/hr/doctype/vehicle_log/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle_log/test_vehicle_log.py b/erpnext/hr/doctype/vehicle_log/test_vehicle_log.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle_log/test_vehicle_log.py
rename to erpnext/hr/doctype/vehicle_log/test_vehicle_log.py
diff --git a/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.js b/erpnext/hr/doctype/vehicle_log/vehicle_log.js
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle_log/vehicle_log.js
rename to erpnext/hr/doctype/vehicle_log/vehicle_log.js
diff --git a/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.json b/erpnext/hr/doctype/vehicle_log/vehicle_log.json
similarity index 99%
rename from erpnext/fleet_management/doctype/vehicle_log/vehicle_log.json
rename to erpnext/hr/doctype/vehicle_log/vehicle_log.json
index 26a4a01..a2cfa27 100644
--- a/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.json
+++ b/erpnext/hr/doctype/vehicle_log/vehicle_log.json
@@ -640,9 +640,9 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-11-07 05:24:55.310831",
+ "modified": "2017-01-09 11:10:21.208266",
"modified_by": "Administrator",
- "module": "Fleet Management",
+ "module": "HR",
"name": "Vehicle Log",
"name_case": "",
"owner": "Administrator",
@@ -675,5 +675,6 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "",
+ "track_changes": 1,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle_log/vehicle_log.py b/erpnext/hr/doctype/vehicle_log/vehicle_log.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle_log/vehicle_log.py
rename to erpnext/hr/doctype/vehicle_log/vehicle_log.py
diff --git a/erpnext/fleet_management/doctype/vehicle_service/__init__.py b/erpnext/hr/doctype/vehicle_service/__init__.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle_service/__init__.py
rename to erpnext/hr/doctype/vehicle_service/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json b/erpnext/hr/doctype/vehicle_service/vehicle_service.json
similarity index 89%
rename from erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
rename to erpnext/hr/doctype/vehicle_service/vehicle_service.json
index 6b80efc..635a0b6 100644
--- a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
+++ b/erpnext/hr/doctype/vehicle_service/vehicle_service.json
@@ -22,6 +22,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Service Item",
"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": 0,
"search_index": 0,
@@ -49,6 +51,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Type",
"length": 0,
"no_copy": 0,
@@ -58,6 +61,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,
@@ -76,6 +80,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Frequency",
"length": 0,
"no_copy": 0,
@@ -85,6 +90,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,
@@ -103,6 +109,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Expense",
"length": 0,
"no_copy": 0,
@@ -111,6 +118,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,
@@ -128,9 +136,9 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-20 07:29:50.852748",
+ "modified": "2017-01-09 11:10:29.476907",
"modified_by": "Administrator",
- "module": "Fleet Management",
+ "module": "HR",
"name": "Vehicle Service",
"name_case": "",
"owner": "Administrator",
@@ -140,5 +148,6 @@
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
+ "track_changes": 1,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.py b/erpnext/hr/doctype/vehicle_service/vehicle_service.py
similarity index 100%
rename from erpnext/fleet_management/doctype/vehicle_service/vehicle_service.py
rename to erpnext/hr/doctype/vehicle_service/vehicle_service.py
diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js
deleted file mode 100644
index a879b39..0000000
--- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-frappe.query_reports["Monthly Salary Register"] = {
- "filters": [
- {
- "fieldname":"from_date",
- "label": __("From"),
- "fieldtype": "Date",
- "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
- "reqd": 1
- },
- {
- "fieldname":"to_date",
- "label": __("To"),
- "fieldtype": "Date",
- "default": frappe.datetime.get_today(),
- "reqd": 1
- },
- {
- "fieldname":"employee",
- "label": __("Employee"),
- "fieldtype": "Link",
- "options": "Employee"
- },
- {
- "fieldname":"company",
- "label": __("Company"),
- "fieldtype": "Link",
- "options": "Company",
- "default": frappe.defaults.get_user_default("Company")
- }
- ]
-}
\ No newline at end of file
diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.json b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.json
deleted file mode 100644
index d32e71e..0000000
--- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "add_total_row": 1,
- "apply_user_permissions": 1,
- "creation": "2013-05-07 18:09:42",
- "docstatus": 0,
- "doctype": "Report",
- "idx": 1,
- "is_standard": "Yes",
- "modified": "2014-06-03 07:18:17.187018",
- "modified_by": "Administrator",
- "module": "HR",
- "name": "Monthly Salary Register",
- "owner": "Administrator",
- "ref_doctype": "Salary Slip",
- "report_name": "Monthly Salary Register",
- "report_type": "Script Report"
-}
\ No newline at end of file
diff --git a/erpnext/hr/report/monthly_salary_register/__init__.py b/erpnext/hr/report/salary_register/__init__.py
similarity index 100%
rename from erpnext/hr/report/monthly_salary_register/__init__.py
rename to erpnext/hr/report/salary_register/__init__.py
diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.html b/erpnext/hr/report/salary_register/salary_register.html
similarity index 89%
rename from erpnext/hr/report/monthly_salary_register/monthly_salary_register.html
rename to erpnext/hr/report/salary_register/salary_register.html
index c77e4e5..2a9cd3e 100644
--- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.html
+++ b/erpnext/hr/report/salary_register/salary_register.html
@@ -2,8 +2,7 @@
{%= frappe.boot.letter_heads[filters.letter_head || frappe.defaults.get_default("letter_head")] %}
</div>
<h2 class="text-center">{%= __(report.report_name) %}</h2>
-<h5 class="text-center">Fiscal Year: {%= filters.fiscal_year %}</h5>
-<h5 class="text-center">Month: {%= filters.month %}</h5>
+<h5 class="text-center">From {%= filters.date_range[0] %} to {%= filters.date_range[1] %}</h5>
<hr>
<table class="table table-bordered">
<thead>
@@ -36,4 +35,3 @@
</tbody>
</table>
<p class="text-right text-muted">Printed On {%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
-
diff --git a/erpnext/hr/report/salary_register/salary_register.js b/erpnext/hr/report/salary_register/salary_register.js
new file mode 100644
index 0000000..8b0faf5
--- /dev/null
+++ b/erpnext/hr/report/salary_register/salary_register.js
@@ -0,0 +1,27 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.query_reports["Salary Register"] = {
+ "filters": [
+ {
+ "fieldname":"date_range",
+ "label": __("Date Range"),
+ "fieldtype": "DateRange",
+ "default": [frappe.datetime.add_months(get_today(),-1), frappe.datetime.get_today()],
+ "reqd": 1
+ },
+ {
+ "fieldname":"employee",
+ "label": __("Employee"),
+ "fieldtype": "Link",
+ "options": "Employee"
+ },
+ {
+ "fieldname":"company",
+ "label": __("Company"),
+ "fieldtype": "Link",
+ "options": "Company",
+ "default": frappe.defaults.get_user_default("Company")
+ }
+ ]
+}
diff --git a/erpnext/hr/report/salary_register/salary_register.json b/erpnext/hr/report/salary_register/salary_register.json
new file mode 100644
index 0000000..1166915
--- /dev/null
+++ b/erpnext/hr/report/salary_register/salary_register.json
@@ -0,0 +1,18 @@
+{
+ "add_total_row": 1,
+ "apply_user_permissions": 1,
+ "creation": "2017-01-10 17:36:58.153863",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2017-01-10 17:38:00.832224",
+ "modified_by": "Administrator",
+ "module": "HR",
+ "name": "Salary Register",
+ "owner": "Administrator",
+ "ref_doctype": "Salary Slip",
+ "report_name": "Salary Register",
+ "report_type": "Script Report"
+}
\ No newline at end of file
diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py b/erpnext/hr/report/salary_register/salary_register.py
similarity index 92%
rename from erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
rename to erpnext/hr/report/salary_register/salary_register.py
index e8d0a0b..1e36b92 100644
--- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
+++ b/erpnext/hr/report/salary_register/salary_register.py
@@ -3,12 +3,11 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, cstr
-from frappe import msgprint, _
+from frappe.utils import flt
+from frappe import _
def execute(filters=None):
if not filters: filters = {}
-
salary_slips = get_salary_slips(filters)
columns, earning_types, ded_types = get_columns(salary_slips)
ss_earning_map = get_ss_earning_map(salary_slips)
@@ -58,6 +57,7 @@
return columns, salary_components[_("Earning")], salary_components[_("Deduction")]
def get_salary_slips(filters):
+ filters.update({"from_date": filters.get("date_range")[0], "to_date":filters.get("date_range")[1]})
conditions, filters = get_conditions(filters)
salary_slips = frappe.db.sql("""select * from `tabSalary Slip` where docstatus = 1 %s
order by employee""" % conditions, filters, as_dict=1)
@@ -65,13 +65,12 @@
if not salary_slips:
frappe.throw(_("No salary slip found between {0} and {1}").format(
filters.get("from_date"), filters.get("to_date")))
-
return salary_slips
def get_conditions(filters):
conditions = ""
- if filters.get("from_date"): conditions += " and start_date >= %(from_date)s"
- if filters.get("to_date"): conditions += " and end_date <= %(to_date)s"
+ if filters.get("date_range"): conditions += " and start_date >= %(from_date)s"
+ if filters.get("date_range"): conditions += " and end_date <= %(to_date)s"
if filters.get("company"): conditions += " and company = %(company)s"
if filters.get("employee"): conditions += " and employee = %(employee)s"
diff --git a/erpnext/fleet_management/report/vehicle_expenses/__init__.py b/erpnext/hr/report/vehicle_expenses/__init__.py
similarity index 100%
rename from erpnext/fleet_management/report/vehicle_expenses/__init__.py
rename to erpnext/hr/report/vehicle_expenses/__init__.py
diff --git a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.js b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.js
similarity index 100%
rename from erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.js
rename to erpnext/hr/report/vehicle_expenses/vehicle_expenses.js
diff --git a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.json b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.json
similarity index 83%
rename from erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.json
rename to erpnext/hr/report/vehicle_expenses/vehicle_expenses.json
index 380c873..f151c67 100644
--- a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.json
+++ b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.json
@@ -7,9 +7,9 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
- "modified": "2016-09-18 08:54:12.080753",
+ "modified": "2017-01-09 11:18:31.959124",
"modified_by": "Administrator",
- "module": "Fleet Management",
+ "module": "HR",
"name": "Vehicle Expenses",
"owner": "Administrator",
"ref_doctype": "Vehicle",
diff --git a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.py b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
similarity index 98%
rename from erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.py
rename to erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
index 717a94f..a03b7f3 100644
--- a/erpnext/fleet_management/report/vehicle_expenses/vehicle_expenses.py
+++ b/erpnext/hr/report/vehicle_expenses/vehicle_expenses.py
@@ -15,7 +15,7 @@
columns=get_columns()
data=get_log_data(filters)
chart=get_chart_data(data,period_list)
- return columns,data,None,chart
+ return columns, data, None, chart
def get_columns():
columns = [_("License") + ":Link/Vehicle:100", _("Make") + ":data:50",
diff --git a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
index bcf1ae6..9639e7f 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
+++ b/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.js
@@ -3,18 +3,28 @@
frappe.provide("erpnext.maintenance");
-frappe.ui.form.on_change("Maintenance Schedule", "customer", function(frm) {
- erpnext.utils.get_party_details(frm) });
-frappe.ui.form.on_change("Maintenance Schedule", "customer_address", function(){
- erpnext.utils.get_address_display(cur_frm, 'customer_address', 'address_display');
-});
-frappe.ui.form.on_change("Maintenance Schedule", "contact_person", function(){
- erpnext.utils.get_contact_details(cur_frm);
-});
+frappe.ui.form.on('Maintenance Schedule', {
+ setup: function(frm) {
+ frm.set_query('contact_person', erpnext.queries.contact_query);
+ frm.set_query('customer_address', erpnext.queries.address_query);
+ },
+ customer: function(frm) {
+ erpnext.utils.get_party_details(frm)
+ },
+ customer_address: function(frm) {
+ erpnext.utils.get_address_display(frm, 'customer_address', 'address_display');
+ },
+ contact_person: function(frm) {
+ erpnext.utils.get_contact_details(frm);
+ }
+
+})
// TODO commonify this code
erpnext.maintenance.MaintenanceSchedule = frappe.ui.form.Controller.extend({
refresh: function() {
+ frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+
var me = this;
if (this.frm.doc.docstatus === 0) {
@@ -94,18 +104,6 @@
}
-cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
- return {
- filters:{ 'customer': doc.customer }
- }
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return {
- filters:{ 'customer': doc.customer }
- }
-}
-
cur_frm.cscript.generate_schedule = function(doc, cdt, cdn) {
if (!doc.__islocal) {
return $c('runserverobj', args={'method':'generate_schedule', 'docs':doc},
diff --git a/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json b/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json
index e9192f7..1e68fab 100644
--- a/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json
+++ b/erpnext/maintenance/doctype/maintenance_schedule_item/maintenance_schedule_item.json
@@ -10,11 +10,13 @@
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "item_code",
"fieldtype": "Link",
"hidden": 0,
@@ -32,6 +34,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": 1,
@@ -42,6 +45,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "item_name",
"fieldtype": "Data",
"hidden": 0,
@@ -58,6 +62,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,
@@ -68,8 +73,9 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "description",
- "fieldtype": "Data",
+ "fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -85,6 +91,7 @@
"print_hide_if_no_value": 0,
"print_width": "300px",
"read_only": 1,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
@@ -96,6 +103,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "schedule_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -110,6 +118,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,
@@ -120,6 +129,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "start_date",
"fieldtype": "Date",
"hidden": 0,
@@ -136,6 +146,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": 1,
@@ -146,6 +157,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "end_date",
"fieldtype": "Date",
"hidden": 0,
@@ -162,6 +174,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": 1,
@@ -172,6 +185,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "periodicity",
"fieldtype": "Select",
"hidden": 0,
@@ -189,6 +203,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,
@@ -199,6 +214,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "no_of_visits",
"fieldtype": "Int",
"hidden": 0,
@@ -215,6 +231,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,
@@ -225,6 +242,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "sales_person",
"fieldtype": "Link",
"hidden": 0,
@@ -242,6 +260,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 +271,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "reference",
"fieldtype": "Section Break",
"hidden": 0,
@@ -266,6 +286,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,
@@ -276,6 +297,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "serial_no",
"fieldtype": "Small Text",
"hidden": 0,
@@ -292,6 +314,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,
@@ -302,6 +325,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "sales_order",
"fieldtype": "Link",
"hidden": 0,
@@ -320,6 +344,7 @@
"print_hide_if_no_value": 0,
"print_width": "150px",
"read_only": 1,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 1,
@@ -338,7 +363,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-07-11 03:28:02.260189",
+ "modified": "2017-01-11 12:02:38.449129",
"modified_by": "Administrator",
"module": "Maintenance",
"name": "Maintenance Schedule Item",
diff --git a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
index 38c20da..62cdf86 100644
--- a/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
+++ b/erpnext/maintenance/doctype/maintenance_visit/maintenance_visit.js
@@ -2,20 +2,31 @@
// License: GNU General Public License v3. See license.txt
frappe.provide("erpnext.maintenance");
+me.frm.set_query('contact_person', erpnext.queries.contact_query);
-frappe.ui.form.on_change("Maintenance Visit", "customer", function(frm) {
- erpnext.utils.get_party_details(frm) });
-frappe.ui.form.on_change("Maintenance Visit", "customer_address", function(frm){
- erpnext.utils.get_address_display(frm, 'customer_address', 'address_display')
-});
-frappe.ui.form.on_change("Maintenance Visit", "contact_person", function(frm){
- erpnext.utils.get_contact_details(frm)
-});
+frappe.ui.form.on('Maintenance Visit', {
+ setup: function(frm) {
+ frm.set_query('contact_person', erpnext.queries.contact_query);
+ frm.set_query('customer_address', erpnext.queries.address_query);
+ },
+ customer: function(frm) {
+ erpnext.utils.get_party_details(frm)
+ },
+ customer_address: function(frm) {
+ erpnext.utils.get_address_display(frm, 'customer_address', 'address_display');
+ },
+ contact_person: function(frm) {
+ erpnext.utils.get_contact_details(frm);
+ }
+
+})
// TODO commonify this code
erpnext.maintenance.MaintenanceVisit = frappe.ui.form.Controller.extend({
refresh: function() {
+ frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+
if (this.frm.doc.docstatus===0) {
cur_frm.add_custom_button(__('Maintenance Schedule'),
function() {
@@ -69,18 +80,6 @@
cur_frm.add_fetch('item_code', 'description', 'description');
}
-cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{'customer': doc.customer}
- }
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{'customer': doc.customer}
- }
-}
-
cur_frm.fields_dict.customer.get_query = function(doc,cdt,cdn) {
return {query: "erpnext.controllers.queries.customer_query" }
}
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index aa69342..f690878 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -304,9 +304,9 @@
def get_operations_data(self, data):
return {
- 'from_time': data.planned_start_time,
+ 'from_time': get_datetime(data.planned_start_time),
'hours': data.time_in_mins / 60.0,
- 'to_time': data.planned_end_time,
+ 'to_time': get_datetime(data.planned_end_time),
'project': self.project,
'operation': data.operation,
'operation_id': data.name,
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index 4daf0eb..609a3fe 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -1,7 +1,6 @@
Accounts
CRM
Buying
-Fleet Management
Projects
Selling
Setup
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index ef1e2c1..3e3c9ed 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -360,3 +360,7 @@
erpnext.patches.v7_1.repost_stock_for_deleted_bins_for_merging_items
execute:frappe.delete_doc('Desktop Icon', {'module_name': 'Profit and Loss Statment'})
erpnext.patches.v7_2.update_website_for_variant
+erpnext.patches.v7_2.update_assessment_modules
+erpnext.patches.v7_2.update_doctype_status
+erpnext.patches.v7_2.update_salary_slips
+erpnext.patches.v7_2.delete_fleet_management_module_def
\ No newline at end of file
diff --git a/erpnext/patches/v7_2/contact_address_links.py b/erpnext/patches/v7_2/contact_address_links.py
new file mode 100644
index 0000000..490834b
--- /dev/null
+++ b/erpnext/patches/v7_2/contact_address_links.py
@@ -0,0 +1,24 @@
+import frappe
+
+def execute():
+ frappe.reload_doctype('Contact')
+ frappe.reload_doctype('Address')
+ map_fields = (
+ ('Customer', 'customer'),
+ ('Supplier', 'supplier'),
+ ('Load', 'lead'),
+ ('Sales Partner', 'sales_partner')
+ )
+ for doctype in ('Contact', 'Address'):
+ if frappe.db.has_column(doctype, 'customer'):
+ for doc in frappe.get_all(doctype, fields='*'):
+ doc.doctype = doctype
+ doc = frappe.get_doc(doc)
+ dirty = False
+ for field in map_fields:
+ if doc.get(field[1]):
+ doc.append('links', dict(link_doctype=field[0], link_name=doc.get(field[1])))
+ dirty = True
+
+ if dirty:
+ doc.save()
diff --git a/erpnext/patches/v7_2/delete_fleet_management_module_def.py b/erpnext/patches/v7_2/delete_fleet_management_module_def.py
new file mode 100644
index 0000000..542ac11
--- /dev/null
+++ b/erpnext/patches/v7_2/delete_fleet_management_module_def.py
@@ -0,0 +1,10 @@
+# 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
+
+def execute():
+ if frappe.db.exists('Module Def', 'Fleet Management'):
+ frappe.db.sql("""delete from `tabModule Def`
+ where module_name = 'Fleet Management'""")
\ No newline at end of file
diff --git a/erpnext/patches/v7_2/update_assessment_modules.py b/erpnext/patches/v7_2/update_assessment_modules.py
new file mode 100644
index 0000000..43c5764
--- /dev/null
+++ b/erpnext/patches/v7_2/update_assessment_modules.py
@@ -0,0 +1,31 @@
+import frappe
+from frappe.model.utils.rename_field import rename_field
+
+def execute():
+ #Rename Grading Structure to Grading Scale
+ frappe.rename_doc("DocType", "Grading Structure", "Grading Scale", force=True)
+ frappe.rename_doc("DocType", "Grade Interval", "Grading Scale Interval", force=True)
+
+ frappe.reload_doc("schools", "doctype", "grading_scale_interval")
+ rename_field("Grading Scale Interval", "to_score", "threshold")
+
+ frappe.rename_doc("DocType", "Assessment", "Assessment Plan", force=True)
+
+ #Rename Assessment Results
+ frappe.reload_doc("schools", "doctype", "assessment_plan")
+ rename_field("Assessment Plan", "grading_structure", "grading_scale")
+
+ frappe.reload_doc("schools", "doctype", "assessment_result")
+ for assessment in frappe.get_all("Assessment Plan", fields=["name", "grading_scale"]):
+ for stud_result in frappe.db.sql("select * from `tabAssessment Result` where parent= %s", assessment.name, as_dict=True):
+ if stud_result.result:
+ assessment_result = frappe.new_doc("Assessment Result")
+ assessment_result.student = stud_result.student
+ assessment_result.student_name = stud_result.student_name
+ assessment_result.assessment_plan = assessment.name
+ assessment_result.grading_scale = assessment.grading_scale
+ assessment_result.total_score = stud_result.result
+ assessment_result.flags.ignore_validate = True
+ assessment_result.save()
+
+ frappe.db.sql("""delete from `tabAssessment Result` where parent != '' or parent is not null""")
\ No newline at end of file
diff --git a/erpnext/patches/v7_2/update_doctype_status.py b/erpnext/patches/v7_2/update_doctype_status.py
new file mode 100644
index 0000000..c66f3f2
--- /dev/null
+++ b/erpnext/patches/v7_2/update_doctype_status.py
@@ -0,0 +1,11 @@
+# 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
+
+def execute():
+ doctypes = ["Opportunity", "Quotation", "Sales Order", "Sales Invoice", "Purchase Invoice", "Purchase Order", "Delivery Note", "Purchase Receipt"]
+ for doctype in doctypes:
+ frappe.db.sql(""" update `tab{doctype}` set status = 'Draft'
+ where status = 'Cancelled' and docstatus = 0 """.format(doctype = doctype))
\ No newline at end of file
diff --git a/erpnext/patches/v7_2/update_salary_slips.py b/erpnext/patches/v7_2/update_salary_slips.py
new file mode 100644
index 0000000..612b900
--- /dev/null
+++ b/erpnext/patches/v7_2/update_salary_slips.py
@@ -0,0 +1,19 @@
+import frappe
+from erpnext.hr.doctype.process_payroll.process_payroll import get_month_details
+
+def execute():
+ frappe.reload_doctype('Salary Slip')
+ if not frappe.db.has_column('Salary Slip', 'fiscal_year'):
+ return
+
+ salary_slips = frappe.db.sql("""select month, name from `tabSalary Slip`
+ where (month is not null and month != '') and
+ (start_date is null or start_date = '') and
+ (end_date is null or end_date = '') and docstatus != 2""", as_dict=True)
+
+ for salary_slip in salary_slips:
+ get_start_end_date = get_month_details(salary_slip.fiscal_year, salary_slip.month)
+ start_date = get_start_end_date['month_start_date']
+ end_date = get_start_end_date['month_end_date']
+ frappe.db.sql("""update `tabSalary Slip` set start_date = %s, end_date = %s where name = %s""",
+ (start_date, end_date, salary_slip.name))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 37ca968..38ebbcb 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -10,6 +10,7 @@
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
@@ -24,7 +25,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Project Name",
"length": 0,
"no_copy": 0,
@@ -53,7 +53,6 @@
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
- "in_standard_filter": 1,
"label": "Status",
"length": 0,
"no_copy": 1,
@@ -83,7 +82,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 1,
"label": "Project Type",
"length": 0,
"no_copy": 0,
@@ -113,7 +111,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 1,
"label": "Is Active",
"length": 0,
"no_copy": 0,
@@ -144,7 +141,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "% Complete Method",
"length": 0,
"no_copy": 0,
@@ -173,7 +169,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -200,7 +195,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 1,
"label": "Priority",
"length": 0,
"no_copy": 0,
@@ -230,7 +224,6 @@
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Expected Start Date",
"length": 0,
"no_copy": 0,
@@ -259,7 +252,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Expected End Date",
"length": 0,
"no_copy": 0,
@@ -288,7 +280,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "% Completed",
"length": 0,
"no_copy": 1,
@@ -315,7 +306,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Customer Details",
"length": 0,
"no_copy": 0,
@@ -344,7 +334,6 @@
"ignore_xss_filter": 0,
"in_filter": 1,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Customer",
"length": 0,
"no_copy": 0,
@@ -374,7 +363,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -401,7 +389,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Sales Order",
"length": 0,
"no_copy": 0,
@@ -430,7 +417,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Users",
"length": 0,
"no_copy": 0,
@@ -459,7 +445,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Users",
"length": 0,
"no_copy": 0,
@@ -488,7 +473,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Tasks",
"length": 0,
"no_copy": 0,
@@ -517,7 +501,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Tasks",
"length": 0,
"no_copy": 0,
@@ -546,7 +529,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Notes",
"length": 0,
"no_copy": 0,
@@ -575,7 +557,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Notes",
"length": 0,
"no_copy": 0,
@@ -604,7 +585,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Start and End Dates",
"length": 0,
"no_copy": 0,
@@ -632,7 +612,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Actual Start Date",
"length": 0,
"no_copy": 0,
@@ -660,7 +639,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Actual Time (in Hours)",
"length": 0,
"no_copy": 0,
@@ -688,7 +666,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -715,7 +692,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Actual End Date",
"length": 0,
"no_copy": 0,
@@ -744,7 +720,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Costing and Billing",
"length": 0,
"no_copy": 0,
@@ -773,7 +748,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "in_standard_filter": 0,
"label": "Estimated Cost",
"length": 0,
"no_copy": 0,
@@ -804,7 +778,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Total Costing Amount (via Time Logs)",
"length": 0,
"no_copy": 0,
@@ -833,7 +806,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Total Expense Claim (via Expense Claims)",
"length": 0,
"no_copy": 0,
@@ -861,7 +833,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Company",
"length": 0,
"no_copy": 0,
@@ -889,7 +860,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Default Cost Center",
"length": 0,
"no_copy": 0,
@@ -917,7 +887,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -945,7 +914,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Total Billing Amount (via Time Logs)",
"length": 0,
"no_copy": 0,
@@ -973,7 +941,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Total Purchase Cost (via Purchase Invoice)",
"length": 0,
"no_copy": 0,
@@ -1001,7 +968,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Margin",
"length": 0,
"no_copy": 0,
@@ -1030,7 +996,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Gross Margin",
"length": 0,
"no_copy": 0,
@@ -1060,7 +1025,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -1087,7 +1051,6 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "in_standard_filter": 0,
"label": "Gross Margin %",
"length": 0,
"no_copy": 0,
@@ -1117,7 +1080,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 4,
- "modified": "2016-11-07 05:55:56.179455",
+ "modified": "2017-01-10 16:33:54.691885",
"modified_by": "Administrator",
"module": "Projects",
"name": "Project",
@@ -1164,6 +1127,27 @@
"share": 0,
"submit": 0,
"write": 0
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Projects Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
}
],
"quick_entry": 1,
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 30b0900..c405681 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -28,7 +28,8 @@
"public/js/templates/item_selector.html",
"public/js/utils/item_selector.js",
"public/js/help_links.js",
- "public/js/schools/student_button.html"
+ "public/js/schools/student_button.html",
+ "public/js/schools/assessment_result_tool.html"
],
"js/item-dashboard.min.js": [
"stock/dashboard/item_dashboard.html",
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index ca3b4b5..7f85de9 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -212,3 +212,25 @@
margin: 15px;
width: 130px;
}
+.frappe-control[data-fieldname='result_html'] {
+ overflow: scroll;
+}
+.assessment-result-tool {
+ table-layout: fixed;
+}
+.assessment-result-tool input {
+ width: 100%;
+ border: 0;
+ outline: none;
+ text-align: right;
+}
+.assessment-result-tool th {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.assessment-result-tool .total-score,
+.assessment-result-tool .grade,
+.assessment-result-tool .score {
+ text-align: right;
+}
diff --git a/erpnext/public/js/pos/pos_bill_item.html b/erpnext/public/js/pos/pos_bill_item.html
index d8833bb..f5d1a76 100644
--- a/erpnext/public/js/pos/pos_bill_item.html
+++ b/erpnext/public/js/pos/pos_bill_item.html
@@ -2,7 +2,7 @@
<div class="col-xs-5"><h6>{%= item_code || "" %}{%= item_name || "" %}</h6></div>
<div class="col-xs-4">
<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-sign text-muted"></i></div>
+ <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">
@@ -13,7 +13,7 @@
</div>
{% } %}
</div>
- <div class="col-xs-2 text-center pos-qty-btn" data-action="increase-qty"><i class="fa fa-plus-sign text-muted"></i></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-3 text-right">
diff --git a/erpnext/public/js/queries.js b/erpnext/public/js/queries.js
index 7c4bf0f..1141f99 100644
--- a/erpnext/public/js/queries.js
+++ b/erpnext/public/js/queries.js
@@ -36,17 +36,41 @@
customer_filter: function(doc) {
if(!doc.customer) {
- frappe.throw(__("Please specify a") + " " +
- __(frappe.meta.get_label(doc.doctype, "customer", doc.name)));
+ frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype, "customer", doc.name))));
}
return { filters: { customer: doc.customer } };
},
+ contact_query: function(doc) {
+ if(frappe.dynamic_link) {
+ if(!doc[frappe.dynamic_link.fieldname]) {
+ frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype,
+ frappe.dynamic_link.fieldname, doc.name))));
+ }
+
+ return {
+ query: 'frappe.email.doctype.contact.contact.contact_query',
+ filters: { link_doctype: frappe.dynamic_link.doctype, link_name: doc[frappe.dynamic_link.fieldname] } };
+ }
+ },
+
+ address_query: function(doc) {
+ if(frappe.dynamic_link) {
+ if(!doc[frappe.dynamic_link.fieldname]) {
+ frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype,
+ frappe.dynamic_link.fieldname, doc.name))));
+ }
+
+ return {
+ query: 'frappe.geo.doctype.address.address.address_query',
+ filters: { link_doctype: frappe.dynamic_link.doctype, link_name: doc[frappe.dynamic_link.fieldname] } };
+ }
+ },
+
supplier_filter: function(doc) {
if(!doc.supplier) {
- frappe.throw(__("Please specify a") + " " +
- __(frappe.meta.get_label(doc.doctype, "supplier", doc.name)));
+ frappe.throw(__("Please set {0}", __(frappe.meta.get_label(doc.doctype, "supplier", doc.name))));
}
return { filters: { supplier: doc.supplier } };
@@ -74,7 +98,7 @@
filters: [
["Warehouse", "company", "in", ["", cstr(doc.company)]],
["Warehouse", "is_group", "=",0]
-
+
]
}
}
diff --git a/erpnext/public/js/schools/assessment_result_tool.html b/erpnext/public/js/schools/assessment_result_tool.html
new file mode 100644
index 0000000..6f9e256
--- /dev/null
+++ b/erpnext/public/js/schools/assessment_result_tool.html
@@ -0,0 +1,44 @@
+<table class="table table-bordered assessment-result-tool">
+ <thead>
+ <tr>
+ <th style="width: 100px" rowspan="2">Student</th>
+ <th style="width: 200px" rowspan="2">Student Name</th>
+ {% for c in criterias %}
+ <th class="score" style="width: 100px">{{ c.evaluation_criteria }}</th>
+ {% endfor %}
+ <th class="score" style="width: 100px">Total Marks</th>
+ <!--criteria-->
+ </tr>
+ <tr>
+ {% for c in criterias %}
+ <th class="score" style="width: 100px">{{ c.maximum_score }}</th>
+ {% endfor %}
+ <th class="score" style="width: 100px">{{max_total_score}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for s in students %}
+ <tr
+ {% if(s.assessment_details) { %} class="text-muted" {% } %}
+ data-student="{{s.student}}">
+ <td>{{ s.student }}</td>
+ <td>{{ s.student_name }}</td>
+ {% for c in criterias %}
+ <td>
+ <input type="text"
+ data-max-score="{{c.maximum_score}}"
+ data-criteria="{{c.evaluation_criteria}}"
+ data-student="{{s.student}}"
+ {% if(s.assessment_details) { %}
+ disabled
+ value="{{s.assessment_details[c.evaluation_criteria]}}"
+ {% } %}/>
+ </td>
+ {% endfor %}
+ <td data-student="{{s.student}}" class="total-score">
+ {% if(s.assessment_details) { %} {{s.assessment_details.total_score}} {% } %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
\ No newline at end of file
diff --git a/erpnext/public/js/templates/address_list.html b/erpnext/public/js/templates/address_list.html
index 6ee7d78..f9a317f 100644
--- a/erpnext/public/js/templates/address_list.html
+++ b/erpnext/public/js/templates/address_list.html
@@ -2,7 +2,7 @@
<div class="clearfix"></div>
{% for(var i=0, l=addr_list.length; i<l; i++) { %}
<p class="h6">
- {%= i+1 %}. {%= addr_list[i].address_type %}
+ {%= i+1 %}. {%= addr_list[i].address_type!="Other" ? addr_list[i].address_type : addr_list[i].address_title %}
{% if(addr_list[i].is_primary_address) { %}
<span class="text-muted">({%= __("Primary") %})</span>{% } %}
{% if(addr_list[i].is_shipping_address) { %}
diff --git a/erpnext/public/js/templates/contact_list.html b/erpnext/public/js/templates/contact_list.html
index ddd3e52..765ddf8 100644
--- a/erpnext/public/js/templates/contact_list.html
+++ b/erpnext/public/js/templates/contact_list.html
@@ -8,7 +8,9 @@
{% if(contact_list[i].is_primary_contact) { %}
<span class="text-muted">({%= __("Primary") %})</span>
{% } %}
-
+ {% if(contact_list[i].designation){ %}
+ <span class="text-muted">– {%= contact_list[i].designation %}</span>
+ {% } %}
<a href="#Form/Contact/{%= encodeURIComponent(contact_list[i].name) %}"
class="btn btn-xs btn-default pull-right">
{%= __("Edit") %}</a>
diff --git a/erpnext/public/js/utils/party.js b/erpnext/public/js/utils/party.js
index a3f3550..a1d200f 100644
--- a/erpnext/public/js/utils/party.js
+++ b/erpnext/public/js/utils/party.js
@@ -65,7 +65,7 @@
if(!display_field) display_field = "address_display";
if(frm.doc[address_field]) {
frappe.call({
- method: "erpnext.utilities.doctype.address.address.get_address_display",
+ method: "frappe.geo.doctype.address.address.get_address_display",
args: {"address_dict": frm.doc[address_field] },
callback: function(r) {
if(r.message) {
@@ -151,7 +151,7 @@
erpnext.utils.get_shipping_address = function(frm, callback){
frappe.call({
- method: "erpnext.utilities.doctype.address.address.get_shipping_address",
+ method: "frappe.geo.doctype.address.address.get_shipping_address",
args: {company: frm.doc.company},
callback: function(r){
if(r.message){
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index e2ccddd..790a031 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -257,3 +257,28 @@
margin: 15px;
width: 130px;
}
+
+// assessment tool
+.frappe-control[data-fieldname='result_html'] {
+ overflow: scroll;
+}
+.assessment-result-tool {
+ table-layout: fixed;
+
+ input {
+ width: 100%;
+ border: 0;
+ outline: none;
+ text-align: right;
+ }
+
+ th {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ .total-score, .grade, .score {
+ text-align: right;
+ }
+}
\ No newline at end of file
diff --git a/erpnext/schools/api.py b/erpnext/schools/api.py
index bf09351..e31a944 100644
--- a/erpnext/schools/api.py
+++ b/erpnext/schools/api.py
@@ -7,7 +7,7 @@
import json
from frappe import _
from frappe.model.mapper import get_mapped_doc
-from frappe.utils import flt
+from frappe.utils import flt, cstr
@frappe.whitelist()
def enroll_student(source_name):
@@ -84,7 +84,7 @@
@frappe.whitelist()
def get_student_batch_students(student_batch):
- """Returns List of student, student_name in Student Batch.
+ """Returns List of student, student_name, idx in Student Batch.
:param student_batch: Student Batch.
"""
@@ -163,3 +163,92 @@
}, as_dict=True, update={"allDay": 0})
return data
+
+@frappe.whitelist()
+def get_evaluation_criterias(course):
+ """Returns Evaluation Criterias and their Weightage from Course Master.
+
+ :param Course: Course
+ """
+ return frappe.get_list("Course Evaluation Criteria", \
+ fields=["evaluation_criteria", "weightage"], filters={"parent": course}, order_by= "idx")
+
+@frappe.whitelist()
+def get_assessment_students(assessment_plan, student_group=None, student_batch=None):
+ student_list = []
+ if student_group:
+ student_list = get_student_group_students(student_group)
+ elif student_batch:
+ student_list = get_student_batch_students(student_batch)
+ for i, student in enumerate(student_list):
+ result = get_result(student.student, assessment_plan)
+ if result:
+ student_result = {}
+ for d in result.details:
+ student_result.update({d.evaluation_criteria: cstr(d.score) + " ("+ d.grade + ")"})
+ student_result.update({"total_score": cstr(result.total_score) + " (" + result.grade + ")"})
+ student.update({'assessment_details': student_result})
+ else:
+ student.update({'assessment_details': None})
+ return student_list
+
+@frappe.whitelist()
+def get_assessment_details(assessment_plan):
+ """Returns Evaluation Criteria and Maximum Score from Assessment Plan Master.
+
+ :param Assessment Plan: Assessment Plan
+ """
+ return frappe.get_list("Assessment Evaluation Criteria", \
+ fields=["evaluation_criteria", "maximum_score"], filters={"parent": assessment_plan}, order_by= "idx")
+
+@frappe.whitelist()
+def get_result(student, assessment_plan):
+ """Returns Submitted Result of given student for specified Assessment Plan
+
+ :param Student: Student
+ :param Assessment Plan: Assessment Plan
+ """
+ results = frappe.get_all("Assessment Result", filters={"student": student, "assessment_plan": assessment_plan, "docstatus": 1})
+ if results:
+ return frappe.get_doc("Assessment Result", results[0])
+ else:
+ return None
+
+@frappe.whitelist()
+def get_grade(grading_scale, percentage):
+ """Returns Grade based on the Grading Scale and Score.
+
+ :param Grading Scale: Grading Scale
+ :param Percentage: Score Percentage Percentage
+ """
+ grading_scale_intervals = {}
+ for d in frappe.get_all("Grading Scale Interval", fields=["grade_code", "threshold"], filters={"parent": grading_scale}):
+ grading_scale_intervals.update({d.threshold:d.grade_code})
+ intervals = sorted(grading_scale_intervals.keys(), key=float, reverse=True)
+ for interval in intervals:
+ if flt(percentage) >= interval:
+ grade = grading_scale_intervals.get(interval)
+ break
+ else:
+ grade = ""
+ return grade
+
+@frappe.whitelist()
+def mark_assessment_result(student, assessment_plan, scores):
+ student_score = json.loads(scores)
+ details = []
+ for s in student_score.keys():
+ details.append({
+ "evaluation_criteria": s,
+ "score": flt(student_score[s])
+ })
+ assessment_result = frappe.new_doc("Assessment Result")
+ assessment_result.update({
+ "student": student,
+ "student_name": frappe.db.get_value("Student", student, "title"),
+ "assessment_plan": assessment_plan,
+ "details": details
+ })
+ assessment_result.save()
+ assessment_result.submit()
+ return assessment_result
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/assessment.js b/erpnext/schools/doctype/assessment/assessment.js
deleted file mode 100644
index e842f41..0000000
--- a/erpnext/schools/doctype/assessment/assessment.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-cur_frm.add_fetch("student_group", "course", "course");
-cur_frm.add_fetch("examiner", "instructor_name", "examiner_name");
-cur_frm.add_fetch("supervisor", "instructor_name", "supervisor_name");
-cur_frm.add_fetch("student", "title", "student_name");
-
-frappe.ui.form.on("Assessment", {
- student_group: function(frm) {
- frm.set_value("results", "");
- if (frm.doc.student_group) {
- frappe.call({
- method: "erpnext.schools.api.get_student_group_students",
- args: {
- "student_group": frm.doc.student_group
- },
- callback: function(r) {
- if (r.message) {
- $.each(r.message, function(i, d) {
- var row = frappe.model.add_child(cur_frm.doc, "Assessment Result", "results");
- row.student = d.student;
- row.student_name = d.student_name;
- });
- }
- refresh_field("results");
- }
- });
- }
- }
-});
-
-frappe.ui.form.on("Assessment Result", {
- result: function(frm, cdt, cdn) {
- if (frm.doc.grading_structure) {
- var assessment_result = locals[cdt][cdn];
- frappe.call({
- method: "erpnext.schools.doctype.assessment.assessment.get_grade",
- args: {
- grading_structure: frm.doc.grading_structure,
- result: assessment_result.result
- },
- callback: function(r) {
- if (r.message) {
- frappe.model.set_value(cdt, cdn, 'grade', r.message);
- }
- }
- });
- }
- }
-});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/assessment.py b/erpnext/schools/doctype/assessment/assessment.py
deleted file mode 100644
index 003b427..0000000
--- a/erpnext/schools/doctype/assessment/assessment.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-from frappe.model.document import Document
-import frappe
-from frappe import _
-
-class Assessment(Document):
- def validate(self):
- self.validate_overlap()
-
- def validate_overlap(self):
- """Validates overlap for Student Group/Student Batch, Instructor, Room"""
-
- from erpnext.schools.utils import validate_overlap_for
-
- #Validate overlapping course schedules.
- if self.student_batch:
- validate_overlap_for(self, "Course Schedule", "student_batch")
-
- if self.student_group:
- validate_overlap_for(self, "Course Schedule", "student_group")
-
- validate_overlap_for(self, "Course Schedule", "instructor")
- validate_overlap_for(self, "Course Schedule", "room")
-
- #validate overlapping assessment schedules.
- if self.student_batch:
- validate_overlap_for(self, "Assessment", "student_batch")
-
- if self.student_group:
- validate_overlap_for(self, "Assessment", "student_group")
-
- validate_overlap_for(self, "Assessment", "room")
- validate_overlap_for(self, "Assessment", "supervisor", self.instructor)
-
-
-def get_assessment_list(doctype, txt, filters, limit_start, limit_page_length=20):
- user = frappe.session.user
- student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user)
- if student:
- return frappe. db.sql('''select course, schedule_date, from_time, to_time, sgs.name from `tabAssessment` as assessment,
- `tabStudent Group Student` as sgs where assessment.student_group = sgs.parent and sgs.student = %s and assessment.docstatus=1
- order by assessment.name asc limit {0} , {1}'''
- .format(limit_start, limit_page_length), student, as_dict = True)
-
-def get_list_context(context=None):
- return {
- "show_sidebar": True,
- 'no_breadcrumbs': True,
- "title": _("Assessment Schedule"),
- "get_list": get_assessment_list,
- "row_template": "templates/includes/assessment/assessment_row.html"
- }
-
-@frappe.whitelist()
-def get_grade(grading_structure, result):
- grade = frappe.db.sql("""select gi.from_score, gi.to_score, gi.grade_code, gi.grade_description
- from `tabGrading Structure` as gs, `tabGrade Interval` as gi
- where gs.name = gi.parent and gs.name = %(grading_structure)s and gi.from_score <= %(result)s
- and gi.to_score >= %(result)s""".format(),
- {
- "grading_structure":grading_structure,
- "result": result
- },
- as_dict=True)
-
- return grade[0].grade_code if grade else ""
-
-def validate_grade(score, grade):
- pass
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/assessment_evaluation_criteria/__init__.py
similarity index 100%
copy from erpnext/schools/doctype/assessment/__init__.py
copy to erpnext/schools/doctype/assessment_evaluation_criteria/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json b/erpnext/schools/doctype/assessment_evaluation_criteria/assessment_evaluation_criteria.json
similarity index 60%
copy from erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
copy to erpnext/schools/doctype/assessment_evaluation_criteria/assessment_evaluation_criteria.json
index 6b80efc..870aaa0 100644
--- a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
+++ b/erpnext/schools/doctype/assessment_evaluation_criteria/assessment_evaluation_criteria.json
@@ -2,35 +2,67 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
+ "autoname": "",
"beta": 0,
- "creation": "2016-09-03 19:20:14.561962",
+ "creation": "2016-12-14 17:20:27.738226",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
- "document_type": "Document",
+ "document_type": "",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "service_item",
- "fieldtype": "Select",
+ "fieldname": "evaluation_criteria",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Service Item",
+ "in_standard_filter": 0,
+ "label": "Evaluation Criteria",
"length": 0,
"no_copy": 0,
- "options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels",
+ "options": "Evaluation Criteria",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_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,
+ "label": "",
+ "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,
@@ -42,68 +74,15 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "type",
- "fieldtype": "Select",
+ "fieldname": "maximum_score",
+ "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Type",
- "length": 0,
- "no_copy": 0,
- "options": "\nInspection\nService\nChange",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 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": "frequency",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Frequency",
- "length": 0,
- "no_copy": 0,
- "options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 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": "expense_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Expense",
+ "in_standard_filter": 0,
+ "label": "Maximum Score",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -111,8 +90,9 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -128,10 +108,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-20 07:29:50.852748",
+ "modified": "2016-12-14 17:31:11.950549",
"modified_by": "Administrator",
- "module": "Fleet Management",
- "name": "Vehicle Service",
+ "module": "Schools",
+ "name": "Assessment Evaluation Criteria",
"name_case": "",
"owner": "Administrator",
"permissions": [],
diff --git a/erpnext/schools/doctype/assessment_evaluation_criteria/assessment_evaluation_criteria.py b/erpnext/schools/doctype/assessment_evaluation_criteria/assessment_evaluation_criteria.py
new file mode 100644
index 0000000..08f6fd4
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_evaluation_criteria/assessment_evaluation_criteria.py
@@ -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 AssessmentEvaluationCriteria(Document):
+ pass
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/assessment_plan/__init__.py
similarity index 100%
rename from erpnext/schools/doctype/assessment/__init__.py
rename to erpnext/schools/doctype/assessment_plan/__init__.py
diff --git a/erpnext/schools/doctype/assessment_plan/assessment_plan.js b/erpnext/schools/doctype/assessment_plan/assessment_plan.js
new file mode 100644
index 0000000..374b444
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.js
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+cur_frm.add_fetch("student_group", "course", "course");
+cur_frm.add_fetch("student_group", "student_batch", "student_batch");
+cur_frm.add_fetch("examiner", "instructor_name", "examiner_name");
+cur_frm.add_fetch("supervisor", "instructor_name", "supervisor_name");
+
+frappe.ui.form.on("Assessment Plan", {
+ course: function(frm) {
+ if (frm.doc.course && frm.doc.maximum_assessment_score) {
+ frappe.call({
+ method: "erpnext.schools.api.get_evaluation_criterias",
+ args: {
+ course: frm.doc.course
+ },
+ callback: function(r) {
+ if (r.message) {
+ frm.doc.evaluation_criterias = [];
+ $.each(r.message, function(i, d) {
+ var row = frappe.model.add_child(frm.doc, "Assessment Evaluation Criteria", "evaluation_criterias");
+ row.evaluation_criteria = d.evaluation_criteria;
+ row.maximum_score = d.weightage / 100 * frm.doc.maximum_assessment_score;
+ });
+ }
+ refresh_field("evaluation_criterias");
+
+ }
+ });
+ }
+ },
+
+ maximum_assessment_score: function(frm) {
+ frm.trigger("course");
+ }
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/assessment.json b/erpnext/schools/doctype/assessment_plan/assessment_plan.json
similarity index 85%
rename from erpnext/schools/doctype/assessment/assessment.json
rename to erpnext/schools/doctype/assessment_plan/assessment_plan.json
index 845f2f6..967c689 100644
--- a/erpnext/schools/doctype/assessment/assessment.json
+++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.json
@@ -73,6 +73,175 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "assessment_group",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Assessment Group",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Assessment Group",
+ "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_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": "course",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Course",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Course",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "maximum_assessment_score",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Maximum Assessment Score",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "grading_scale",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Grading Scale",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Grading Scale",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_10",
+ "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,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "student_group",
"fieldtype": "Link",
"hidden": 0,
@@ -102,6 +271,33 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "column_break_10",
+ "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_batch",
"fieldtype": "Link",
"hidden": 0,
@@ -130,234 +326,6 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "columns": 0,
- "fieldname": "grading_structure",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Grading Structure",
- "length": 0,
- "no_copy": 0,
- "options": "Grading Structure",
- "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": "course",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Course",
- "length": 0,
- "no_copy": 0,
- "options": "Course",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "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": "assessment_group",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Assessment Group",
- "length": 0,
- "no_copy": 0,
- "options": "Assessment Group",
- "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": "supervisor",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Supervisor",
- "length": 0,
- "no_copy": 0,
- "options": "Instructor",
- "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": "supervisor_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": "Supervisor 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
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "examiner",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Examiner",
- "length": 0,
- "no_copy": 0,
- "options": "Instructor",
- "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": "examiner_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": "Examiner 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
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
"collapsible_depends_on": "",
"columns": 0,
"depends_on": "",
@@ -447,6 +415,63 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "examiner",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Examiner",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Instructor",
+ "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": "examiner_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": "Examiner 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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -528,9 +553,66 @@
{
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 1,
+ "collapsible": 0,
"columns": 0,
- "fieldname": "section_break_11",
+ "fieldname": "supervisor",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Supervisor",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Instructor",
+ "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": "supervisor_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": "Supervisor 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
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_20",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -538,7 +620,6 @@
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Results",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -558,7 +639,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "results",
+ "fieldname": "evaluation_criterias",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -566,10 +647,10 @@
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "results",
+ "label": "Evaluation Criterias",
"length": 0,
"no_copy": 0,
- "options": "Assessment Result",
+ "options": "Assessment Evaluation Criteria",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -577,7 +658,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -598,7 +679,7 @@
"label": "Amended From",
"length": 0,
"no_copy": 1,
- "options": "Assessment",
+ "options": "Assessment Plan",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@@ -622,10 +703,10 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-11-16 13:05:54.953750",
+ "modified": "2017-01-05 12:15:33.183100",
"modified_by": "Administrator",
"module": "Schools",
- "name": "Assessment",
+ "name": "Assessment Plan",
"name_case": "",
"owner": "Administrator",
"permissions": [
@@ -656,5 +737,6 @@
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment_plan/assessment_plan.py b/erpnext/schools/doctype/assessment_plan/assessment_plan.py
new file mode 100644
index 0000000..aa84ae3
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+import frappe
+from frappe import _
+
+class AssessmentPlan(Document):
+ def validate(self):
+ if not (self.student_batch or self.student_group):
+ frappe.throw(_("Please select Student Group or Student Batch"))
+ self.validate_student_batch()
+ self.validate_overlap()
+
+
+ def validate_overlap(self):
+ """Validates overlap for Student Group/Student Batch, Instructor, Room"""
+
+ from erpnext.schools.utils import validate_overlap_for
+
+ #Validate overlapping course schedules.
+ if self.student_batch:
+ validate_overlap_for(self, "Course Schedule", "student_batch")
+
+ if self.student_group:
+ validate_overlap_for(self, "Course Schedule", "student_group")
+
+ validate_overlap_for(self, "Course Schedule", "instructor")
+ validate_overlap_for(self, "Course Schedule", "room")
+
+ #validate overlapping assessment schedules.
+ if self.student_batch:
+ validate_overlap_for(self, "Assessment Plan", "student_batch")
+
+ if self.student_group:
+ validate_overlap_for(self, "Assessment Plan", "student_group")
+
+ validate_overlap_for(self, "Assessment Plan", "room")
+ validate_overlap_for(self, "Assessment Plan", "supervisor", self.supervisor)
+
+ def validate_student_batch(self):
+ if self.student_group:
+ self.student_batch = frappe.db.get_value("Student Group", self.student_group, "student_batch")
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/test_assessment.py b/erpnext/schools/doctype/assessment_plan/test_assessment_plan.py
similarity index 64%
copy from erpnext/schools/doctype/assessment/test_assessment.py
copy to erpnext/schools/doctype/assessment_plan/test_assessment_plan.py
index ce06007..2de4f23 100644
--- a/erpnext/schools/doctype/assessment/test_assessment.py
+++ b/erpnext/schools/doctype/assessment_plan/test_assessment_plan.py
@@ -6,7 +6,7 @@
import frappe
import unittest
-# test_records = frappe.get_test_records('Assessment')
+# test_records = frappe.get_test_records('Assessment Plan')
-class TestAssessment(unittest.TestCase):
+class TestAssessmentPlan(unittest.TestCase):
pass
diff --git a/erpnext/schools/doctype/assessment_result/assessment_result.js b/erpnext/schools/doctype/assessment_result/assessment_result.js
new file mode 100644
index 0000000..265a626
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result/assessment_result.js
@@ -0,0 +1,51 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+cur_frm.add_fetch("student", "title", "student_name");
+cur_frm.add_fetch("assessment_plan", "grading_scale", "grading_scale");
+cur_frm.add_fetch("assessment_plan", "maximum_assessment_score", "maximum_score");
+
+frappe.ui.form.on("Assessment Result", {
+ assessment_plan: function(frm) {
+ frappe.call({
+ method: "erpnext.schools.api.get_assessment_details",
+ args: {
+ assessment_plan: frm.doc.assessment_plan
+ },
+ callback: function(r) {
+ if (r.message) {
+ frm.doc.details = [];
+ $.each(r.message, function(i, d) {
+ var row = frappe.model.add_child(frm.doc, "Assessment Result Detail", "details");
+ row.evaluation_criteria = d.evaluation_criteria;
+ row.maximum_score = d.maximum_score;
+ });
+ }
+ refresh_field("details");
+ }
+ });
+ }
+});
+
+frappe.ui.form.on("Assessment Result Detail", {
+ score: function(frm, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ if (d.score >= d.maximum_score) {
+ frappe.throw(_("Score cannot be greater than Maximum Score"));
+ }
+ else {
+ frappe.call({
+ method: "erpnext.schools.api.get_grade",
+ args: {
+ grading_scale: frm.doc.grading_scale,
+ percentage: ((d.score/d.maximum_score) * 100)
+ },
+ callback: function(r) {
+ if (r.message) {
+ frappe.model.set_value(cdt, cdn, "grade", r.message);
+ }
+ }
+ });
+ }
+ }
+});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment_result/assessment_result.json b/erpnext/schools/doctype/assessment_result/assessment_result.json
index 91e580d..3bf9758 100644
--- a/erpnext/schools/doctype/assessment_result/assessment_result.json
+++ b/erpnext/schools/doctype/assessment_result/assessment_result.json
@@ -2,6 +2,7 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
+ "autoname": "RES.######",
"beta": 0,
"creation": "2015-11-13 17:18:06.468332",
"custom": 0,
@@ -9,18 +10,21 @@
"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_list_view": 0,
+ "in_standard_filter": 0,
"label": "Student",
"length": 0,
"no_copy": 0,
@@ -30,6 +34,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,
@@ -40,6 +45,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "student_name",
"fieldtype": "Data",
"hidden": 0,
@@ -47,6 +53,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Student Name",
"length": 0,
"no_copy": 0,
@@ -55,6 +62,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,
@@ -65,6 +73,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -72,6 +81,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -79,6 +89,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,
@@ -89,21 +100,54 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "result",
- "fieldtype": "Data",
+ "columns": 0,
+ "fieldname": "assessment_plan",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Result",
+ "in_standard_filter": 0,
+ "label": "Assessment Plan",
"length": 0,
"no_copy": 0,
+ "options": "Assessment Plan",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "grading_scale",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Grading Scale",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Grading Scale",
+ "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,
@@ -114,6 +158,174 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_5",
+ "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,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "details",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Details",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Assessment Result Detail",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_8",
+ "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,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "maximum_score",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Maximum Score",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_score",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Total Score",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_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": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "grade",
"fieldtype": "Data",
"hidden": 0,
@@ -121,6 +333,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Grade",
"length": 0,
"no_copy": 0,
@@ -129,6 +342,35 @@
"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": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Assessment Result",
+ "permlevel": 0,
+ "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,
@@ -142,21 +384,45 @@
"image_view": 0,
"in_create": 0,
"in_dialog": 0,
- "is_submittable": 0,
+ "is_submittable": 1,
"issingle": 0,
- "istable": 1,
+ "istable": 0,
"max_attachments": 0,
- "modified": "2016-08-27 12:15:01.923000",
+ "modified": "2017-01-04 16:56:33.868949",
"modified_by": "Administrator",
"module": "Schools",
"name": "Assessment Result",
"name_case": "",
"owner": "Administrator",
- "permissions": [],
+ "permissions": [
+ {
+ "amend": 1,
+ "apply_user_permissions": 0,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Academics User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ }
+ ],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
+ "title_field": "student_name",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment_result/assessment_result.py b/erpnext/schools/doctype/assessment_result/assessment_result.py
index 84cbcfa..860dcbd 100644
--- a/erpnext/schools/doctype/assessment_result/assessment_result.py
+++ b/erpnext/schools/doctype/assessment_result/assessment_result.py
@@ -4,7 +4,33 @@
from __future__ import unicode_literals
import frappe
+from frappe import _
+from frappe.utils import flt
from frappe.model.document import Document
+from erpnext.schools.api import get_grade
+from erpnext.schools.api import get_assessment_details
class AssessmentResult(Document):
- pass
+ def validate(self):
+ self.grading_scale = frappe.db.get_value("Assessment Plan", self.assessment_plan, "grading_scale")
+ self.validate_maximum_score()
+ self.validate_grade()
+
+ def validate_maximum_score(self):
+ self.maximum_score = frappe.db.get_value("Assessment Plan", self.assessment_plan, "maximum_assessment_score")
+ assessment_details = get_assessment_details(self.assessment_plan)
+ max_scores = {}
+ for d in assessment_details:
+ max_scores.update({d.evaluation_criteria: d.maximum_score})
+
+ for d in self.details:
+ d.maximum_score = max_scores.get(d.evaluation_criteria)
+ if d.score > d.maximum_score:
+ frappe.throw(_("Score cannot be greater than Maximum Score"))
+
+ def validate_grade(self):
+ self.total_score = 0.0
+ for d in self.details:
+ d.grade = get_grade(self.grading_scale, (flt(d.score)/d.maximum_score)*100)
+ self.total_score += d.score
+ self.grade = get_grade(self.grading_scale, (self.total_score/self.maximum_score)*100)
diff --git a/erpnext/schools/doctype/assessment_result/test_assessment_result.py b/erpnext/schools/doctype/assessment_result/test_assessment_result.py
new file mode 100644
index 0000000..66e611c
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result/test_assessment_result.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from erpnext.schools.api import get_grade
+
+# test_records = frappe.get_test_records('Assessment Result')
+
+class TestAssessmentResult(unittest.TestCase):
+ def test_grade(self):
+ grade = get_grade("_Test Grading Scale", 80)
+ self.assertEquals("A", grade)
+
+ grade = get_grade("_Test Grading Scale", 70)
+ self.assertEquals("B", grade)
+
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/assessment_result_detail/__init__.py
similarity index 100%
copy from erpnext/schools/doctype/assessment/__init__.py
copy to erpnext/schools/doctype/assessment_result_detail/__init__.py
diff --git a/erpnext/schools/doctype/assessment_result_detail/assessment_result_detail.json b/erpnext/schools/doctype/assessment_result_detail/assessment_result_detail.json
new file mode 100644
index 0000000..87ce120
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result_detail/assessment_result_detail.json
@@ -0,0 +1,180 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "",
+ "beta": 0,
+ "creation": "2016-12-14 17:44:35.583123",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 4,
+ "fieldname": "evaluation_criteria",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Evaluation Criteria",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Evaluation Criteria",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 2,
+ "fieldname": "maximum_score",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Maximum Score",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_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,
+ "label": "",
+ "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": 2,
+ "fieldname": "score",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Score",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 2,
+ "fieldname": "grade",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Grade",
+ "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": "2016-12-27 16:18:12.022257",
+ "modified_by": "Administrator",
+ "module": "Schools",
+ "name": "Assessment Result Detail",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment_result_detail/assessment_result_detail.py b/erpnext/schools/doctype/assessment_result_detail/assessment_result_detail.py
new file mode 100644
index 0000000..d051593
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result_detail/assessment_result_detail.py
@@ -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 AssessmentResultDetail(Document):
+ pass
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/assessment_result_tool/__init__.py
similarity index 100%
copy from erpnext/schools/doctype/assessment/__init__.py
copy to erpnext/schools/doctype/assessment_result_tool/__init__.py
diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js
new file mode 100644
index 0000000..c58304b
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js
@@ -0,0 +1,105 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+cur_frm.add_fetch("assessment_plan", "student_group", "student_group");
+cur_frm.add_fetch("assessment_plan", "student_batch", "student_batch");
+
+frappe.ui.form.on('Assessment Result Tool', {
+ refresh: function(frm) {
+ frm.disable_save();
+ frm.page.clear_indicator();
+ },
+
+ assessment_plan: function(frm) {
+ if(!(frm.doc.student_batch || frm.doc.student_group)) return;
+ frappe.call({
+ method: "erpnext.schools.api.get_assessment_students",
+ args: {
+ "assessment_plan": frm.doc.assessment_plan,
+ "student_batch": frm.doc.student_batch,
+ "student_group": frm.doc.student_group
+ },
+ callback: function(r) {
+ frm.events.render_table(frm, r.message);
+ }
+ });
+ },
+
+ render_table: function(frm, students) {
+ $(frm.fields_dict.result_html.wrapper).empty();
+ var assessment_plan = frm.doc.assessment_plan;
+ var student_scores = {};
+ students.forEach(function(stu) {
+ student_scores[stu.student] = {}
+ });
+
+ frappe.call({
+ method: "erpnext.schools.api.get_assessment_details",
+ args: {
+ assessment_plan: assessment_plan
+ },
+ callback: function(r) {
+ var criterias = r.message;
+ var max_total_score = 0;
+ criterias.forEach(function(c) {
+ max_total_score += c.maximum_score
+ });
+ var result_table = $(frappe.render_template('assessment_result_tool', {
+ frm: frm,
+ students: students,
+ criterias: criterias,
+ max_total_score: max_total_score
+ }));
+ result_table.appendTo(frm.fields_dict.result_html.wrapper)
+
+ result_table.on('change', 'input', function(e) {
+ var $input = $(e.target);
+ var max_score = $input.data().maxScore;
+ var student = $input.data().student;
+ var criteria = $input.data().criteria;
+ var value = $input.val();
+ if(value < 0) {
+ $input.val(0);
+ value = 0;
+ }
+ if(value > max_score) {
+ $input.val(max_score);
+ value = max_score;
+ }
+ student_scores[student][criteria] = value;
+ if(Object.keys(student_scores[student]).length == criterias.length) {
+ frappe.call(({
+ method: "erpnext.schools.api.mark_assessment_result",
+ args: {
+ "student": student,
+ "assessment_plan": assessment_plan,
+ "scores": student_scores[student]
+ },
+ callback: function(r) {
+ var doc = r.message;
+ var student = doc.student;
+ result_table.find(`[data-student=${student}].total-score`)
+ .html(doc.total_score + ' ('+ doc.grade + ')');
+ var details = doc.details;
+ result_table.find(`tr[data-student=${student}]`).addClass('text-muted');
+ result_table.find(`input[data-student=${student}]`).each(function(el, input) {
+ var $input = $(input);
+ var criteria = $input.data().criteria;
+ var value = $input.val();
+ var grade = details.find(function(d) {
+ return d.evaluation_criteria === criteria;
+ }).grade;
+ $input.val(`${value} (${grade})`);
+ $input.attr('disabled', true);
+ });
+
+ }
+ }))
+ }
+ });
+
+ }
+ });
+ },
+
+});
diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.json b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.json
new file mode 100644
index 0000000..87dff4d
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.json
@@ -0,0 +1,232 @@
+{
+ "allow_copy": 1,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-01-05 12:27:48.951036",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "assessment_plan",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Assessment Plan",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Assessment Plan",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_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_group",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Student Group",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Student Group",
+ "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": "student_batch",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Student Batch",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Student Batch",
+ "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,
+ "depends_on": "assessment_plan",
+ "fieldname": "section_break_5",
+ "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,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "result_html",
+ "fieldtype": "HTML",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Result HTML",
+ "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
+ }
+ ],
+ "hide_heading": 1,
+ "hide_toolbar": 1,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 1,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-01-05 15:45:59.338722",
+ "modified_by": "Administrator",
+ "module": "Schools",
+ "name": "Assessment Result Tool",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Academics User",
+ "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": 0,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py
new file mode 100644
index 0000000..a0d286c
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py
@@ -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 AssessmentResultTool(Document):
+ pass
diff --git a/erpnext/schools/doctype/course/course.js b/erpnext/schools/doctype/course/course.js
index fe38806..c667eca 100644
--- a/erpnext/schools/doctype/course/course.js
+++ b/erpnext/schools/doctype/course/course.js
@@ -21,11 +21,11 @@
frappe.set_route("List", "Course Schedule");
});
- frm.add_custom_button(__("Assessment"), function() {
+ frm.add_custom_button(__("Assessment Plan"), function() {
frappe.route_options = {
course: frm.doc.name
}
- frappe.set_route("List", "Assessment");
+ frappe.set_route("List", "Assessment Plan");
});
}
});
\ No newline at end of file
diff --git a/erpnext/schools/doctype/course/course.json b/erpnext/schools/doctype/course/course.json
index 6fada19..3f16619 100644
--- a/erpnext/schools/doctype/course/course.json
+++ b/erpnext/schools/doctype/course/course.json
@@ -1,278 +1,362 @@
{
- "allow_copy": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:course_name",
- "beta": 0,
- "creation": "2015-09-07 12:39:55.181893",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 0,
- "engine": "InnoDB",
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "course_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": "Course Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "course_code",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Course Code",
- "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": "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,
- "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": "course_abbreviation",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Course Abbreviation",
- "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": "department",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Department",
- "length": 0,
- "no_copy": 0,
- "options": "Department",
- "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_6",
- "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,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "course_intro",
- "fieldtype": "Text Editor",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Course Intro",
- "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
- }
- ],
- "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,
- "menu_index": 0,
- "modified": "2016-08-08 05:26:26.442635",
- "modified_by": "Administrator",
- "module": "Schools",
- "name": "Course",
- "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,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Academics User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "HR Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- }
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "department",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_seen": 0
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:course_name",
+ "beta": 0,
+ "creation": "2015-09-07 12:39:55.181893",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 0,
+ "engine": "InnoDB",
+ "fields": [{
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "course_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": "Course Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "course_code",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Course Code",
+ "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": "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,
+ "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": "course_abbreviation",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Course Abbreviation",
+ "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": "department",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 1,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Department",
+ "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_6",
+ "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,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "course_intro",
+ "fieldtype": "Text Editor",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Course Intro",
+ "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": "assessment",
+ "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": "Assessment",
+ "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": "default_grading_scale",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Grading Scale",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Grading Scale",
+ "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": "evaluation_criterias",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Evaluation Criterias",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Course Evaluation Criteria",
+ "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
+ }
+ ],
+ "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,
+ "menu_index": 0,
+ "modified": "2016-12-14 16:48:16.642813",
+ "modified_by": "Administrator",
+ "module": "Schools",
+ "name": "Course",
+ "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,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Academics User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "HR Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "search_fields": "department",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/course/course.py b/erpnext/schools/doctype/course/course.py
index b590acb..3baccdf 100644
--- a/erpnext/schools/doctype/course/course.py
+++ b/erpnext/schools/doctype/course/course.py
@@ -8,21 +8,13 @@
from frappe import _
class Course(Document):
- pass
-
-def get_sg_list(doctype, txt, filters, limit_start, limit_page_length=20):
- user = frappe.session.user
- student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user)
- if student:
- return frappe.db.sql('''select course, academic_term, academic_year, SG.name from `tabStudent Group`
- as SG, `tabStudent Group Student` as SGS where SG.name = SGS.parent and SGS.student = %s
- order by SG.name asc limit {0} , {1}'''.format(limit_start, limit_page_length), student, as_dict=True)
-
-def get_list_context(context=None):
- return {
- "show_sidebar": True,
- 'no_breadcrumbs': True,
- "title": _("Courses"),
- "get_list": get_sg_list,
- "row_template": "templates/includes/course/course_row.html"
- }
\ No newline at end of file
+ def validate(self):
+ self.validate_evaluation_criterias()
+
+ def validate_evaluation_criterias(self):
+ if self.evaluation_criterias:
+ total_weightage = 0
+ for criteria in self.evaluation_criterias:
+ total_weightage += criteria.weightage
+ if total_weightage != 100:
+ frappe.throw(_("Total Weightage of all Evaluation Criterias must be 100%"))
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/course_evaluation_criteria/__init__.py
similarity index 100%
copy from erpnext/schools/doctype/assessment/__init__.py
copy to erpnext/schools/doctype/course_evaluation_criteria/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json b/erpnext/schools/doctype/course_evaluation_criteria/course_evaluation_criteria.json
similarity index 60%
copy from erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
copy to erpnext/schools/doctype/course_evaluation_criteria/course_evaluation_criteria.json
index 6b80efc..a4d3ce4 100644
--- a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
+++ b/erpnext/schools/doctype/course_evaluation_criteria/course_evaluation_criteria.json
@@ -2,35 +2,67 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
+ "autoname": "",
"beta": 0,
- "creation": "2016-09-03 19:20:14.561962",
+ "creation": "2016-12-14 16:46:46.786353",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
- "document_type": "Document",
+ "document_type": "",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "service_item",
- "fieldtype": "Select",
+ "fieldname": "evaluation_criteria",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Service Item",
+ "in_standard_filter": 0,
+ "label": "Evaluation Criteria",
"length": 0,
"no_copy": 0,
- "options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels",
+ "options": "Evaluation Criteria",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_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,
+ "label": "",
+ "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,
@@ -42,68 +74,15 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "type",
- "fieldtype": "Select",
+ "fieldname": "weightage",
+ "fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Type",
- "length": 0,
- "no_copy": 0,
- "options": "\nInspection\nService\nChange",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 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": "frequency",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Frequency",
- "length": 0,
- "no_copy": 0,
- "options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 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": "expense_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Expense",
+ "in_standard_filter": 0,
+ "label": "Weightage",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -111,6 +90,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,
@@ -128,10 +108,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-20 07:29:50.852748",
+ "modified": "2016-12-14 16:59:17.353023",
"modified_by": "Administrator",
- "module": "Fleet Management",
- "name": "Vehicle Service",
+ "module": "Schools",
+ "name": "Course Evaluation Criteria",
"name_case": "",
"owner": "Administrator",
"permissions": [],
diff --git a/erpnext/schools/doctype/course_evaluation_criteria/course_evaluation_criteria.py b/erpnext/schools/doctype/course_evaluation_criteria/course_evaluation_criteria.py
new file mode 100644
index 0000000..b8398a3
--- /dev/null
+++ b/erpnext/schools/doctype/course_evaluation_criteria/course_evaluation_criteria.py
@@ -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 CourseEvaluationCriteria(Document):
+ pass
diff --git a/erpnext/schools/doctype/course_schedule/course_schedule.py b/erpnext/schools/doctype/course_schedule/course_schedule.py
index ec30c62..7550ab1 100644
--- a/erpnext/schools/doctype/course_schedule/course_schedule.py
+++ b/erpnext/schools/doctype/course_schedule/course_schedule.py
@@ -55,11 +55,11 @@
#validate overlapping assessment schedules.
if self.student_batch:
- validate_overlap_for(self, "Assessment", "student_batch")
+ validate_overlap_for(self, "Assessment Plan", "student_batch")
if self.student_group:
- validate_overlap_for(self, "Assessment", "student_group")
+ validate_overlap_for(self, "Assessment Plan", "student_group")
- validate_overlap_for(self, "Assessment", "room")
- validate_overlap_for(self, "Assessment", "supervisor", self.instructor)
+ validate_overlap_for(self, "Assessment Plan", "room")
+ validate_overlap_for(self, "Assessment Plan", "supervisor", self.instructor)
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/evaluation_criteria/__init__.py
similarity index 100%
copy from erpnext/schools/doctype/assessment/__init__.py
copy to erpnext/schools/doctype/evaluation_criteria/__init__.py
diff --git a/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.js b/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.js
new file mode 100644
index 0000000..5e0269b
--- /dev/null
+++ b/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Evaluation Criteria', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.json b/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.json
new file mode 100644
index 0000000..f830abe
--- /dev/null
+++ b/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.json
@@ -0,0 +1,89 @@
+{
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "field:evaluation_criteria",
+ "beta": 0,
+ "creation": "2016-12-14 16:40:15.144115",
+ "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": "evaluation_criteria",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Evaluation Criteria",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "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": "2016-12-14 16:40:36.351183",
+ "modified_by": "Administrator",
+ "module": "Schools",
+ "name": "Evaluation Criteria",
+ "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,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Academics User",
+ "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_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.py b/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.py
new file mode 100644
index 0000000..85c1b32
--- /dev/null
+++ b/erpnext/schools/doctype/evaluation_criteria/evaluation_criteria.py
@@ -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 EvaluationCriteria(Document):
+ pass
diff --git a/erpnext/schools/doctype/assessment/test_assessment.py b/erpnext/schools/doctype/evaluation_criteria/test_evaluation_criteria.py
similarity index 62%
copy from erpnext/schools/doctype/assessment/test_assessment.py
copy to erpnext/schools/doctype/evaluation_criteria/test_evaluation_criteria.py
index ce06007..0182db6 100644
--- a/erpnext/schools/doctype/assessment/test_assessment.py
+++ b/erpnext/schools/doctype/evaluation_criteria/test_evaluation_criteria.py
@@ -6,7 +6,7 @@
import frappe
import unittest
-# test_records = frappe.get_test_records('Assessment')
+# test_records = frappe.get_test_records('Evaluation Criteria')
-class TestAssessment(unittest.TestCase):
+class TestEvaluationCriteria(unittest.TestCase):
pass
diff --git a/erpnext/schools/doctype/evaluation_criteria/test_records.json b/erpnext/schools/doctype/evaluation_criteria/test_records.json
new file mode 100644
index 0000000..64ff701
--- /dev/null
+++ b/erpnext/schools/doctype/evaluation_criteria/test_records.json
@@ -0,0 +1,8 @@
+[
+ {
+ "evaluation_criteria": "_Test Evaluation Criteria"
+ },
+ {
+ "evaluation_criteria": "_Test Evaluation Criteria 1"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/schools/doctype/grade_interval/grade_interval.json b/erpnext/schools/doctype/grade_interval/grade_interval.json
index 79ef9f4..c9c5949 100644
--- a/erpnext/schools/doctype/grade_interval/grade_interval.json
+++ b/erpnext/schools/doctype/grade_interval/grade_interval.json
@@ -9,11 +9,13 @@
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "grade_code",
"fieldtype": "Data",
"hidden": 0,
@@ -21,6 +23,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Grade Code",
"length": 0,
"no_copy": 0,
@@ -29,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,
@@ -39,14 +43,16 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "from_score",
- "fieldtype": "Float",
+ "columns": 0,
+ "fieldname": "min_score",
+ "fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "From Score",
+ "in_standard_filter": 0,
+ "label": "Min Score",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -54,6 +60,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,
@@ -64,31 +71,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "to_score",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "To Score",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "1",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
+ "columns": 0,
"fieldname": "grade_description",
"fieldtype": "Small Text",
"hidden": 0,
@@ -96,6 +79,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Grade Description",
"length": 0,
"no_copy": 0,
@@ -104,6 +88,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,
@@ -121,7 +106,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-08-27 15:45:04.657328",
+ "modified": "2016-12-14 12:54:56.902465",
"modified_by": "Administrator",
"module": "Schools",
"name": "Grade Interval",
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/grading_scale/__init__.py
similarity index 100%
copy from erpnext/schools/doctype/assessment/__init__.py
copy to erpnext/schools/doctype/grading_scale/__init__.py
diff --git a/erpnext/schools/doctype/grading_scale/grading_scale.js b/erpnext/schools/doctype/grading_scale/grading_scale.js
new file mode 100644
index 0000000..622388c
--- /dev/null
+++ b/erpnext/schools/doctype/grading_scale/grading_scale.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Grading Scale', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/schools/doctype/grading_scale/grading_scale.json b/erpnext/schools/doctype/grading_scale/grading_scale.json
new file mode 100644
index 0000000..99c6948
--- /dev/null
+++ b/erpnext/schools/doctype/grading_scale/grading_scale.json
@@ -0,0 +1,203 @@
+{
+ "allow_copy": 0,
+ "allow_import": 0,
+ "allow_rename": 1,
+ "autoname": "field:grading_scale_name",
+ "beta": 0,
+ "creation": "2016-08-26 03:06:53.922972",
+ "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": "grading_scale_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": "Grading Scale Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Description",
+ "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": "grading_intervals_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": "Grading Scale Intervals",
+ "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": "intervals",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Intervals",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Grading Scale Interval",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amended_from",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Amended From",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Grading Scale",
+ "permlevel": 0,
+ "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
+ }
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2016-12-14 14:35:22.907023",
+ "modified_by": "Administrator",
+ "module": "Schools",
+ "name": "Grading Scale",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 1,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "is_custom": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Academics User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 1,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "",
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/grading_scale/grading_scale.py b/erpnext/schools/doctype/grading_scale/grading_scale.py
new file mode 100644
index 0000000..f7f6ba9
--- /dev/null
+++ b/erpnext/schools/doctype/grading_scale/grading_scale.py
@@ -0,0 +1,19 @@
+# -*- 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 import _
+from frappe.model.document import Document
+
+class GradingScale(Document):
+ def validate(self):
+ thresholds = []
+ for d in self.intervals:
+ if d.threshold in thresholds:
+ frappe.throw(_("Treshold {0}% appears more than once.".format(d.threshold)))
+ else:
+ thresholds.append(d.threshold)
+ if 0 not in thresholds:
+ frappe.throw(_("Please define grade for treshold 0%"))
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/test_assessment.py b/erpnext/schools/doctype/grading_scale/test_grading_scale.py
similarity index 64%
rename from erpnext/schools/doctype/assessment/test_assessment.py
rename to erpnext/schools/doctype/grading_scale/test_grading_scale.py
index ce06007..5364d7c 100644
--- a/erpnext/schools/doctype/assessment/test_assessment.py
+++ b/erpnext/schools/doctype/grading_scale/test_grading_scale.py
@@ -6,7 +6,7 @@
import frappe
import unittest
-# test_records = frappe.get_test_records('Assessment')
+# test_records = frappe.get_test_records('Grading Scale')
-class TestAssessment(unittest.TestCase):
+class TestGradingScale(unittest.TestCase):
pass
diff --git a/erpnext/schools/doctype/grading_scale/test_records.json b/erpnext/schools/doctype/grading_scale/test_records.json
new file mode 100644
index 0000000..72b6954
--- /dev/null
+++ b/erpnext/schools/doctype/grading_scale/test_records.json
@@ -0,0 +1,19 @@
+[
+ {
+ "grading_scale_name": "_Test Grading Scale",
+ "intervals": [
+ {
+ "grade_code": "A",
+ "threshold": 75
+ },
+ {
+ "grade_code": "B",
+ "threshold": 50
+ },
+ {
+ "grade_code": "C",
+ "threshold": 0
+ }
+ ]
+ }
+]
\ No newline at end of file
diff --git a/erpnext/schools/doctype/assessment/__init__.py b/erpnext/schools/doctype/grading_scale_interval/__init__.py
similarity index 100%
copy from erpnext/schools/doctype/assessment/__init__.py
copy to erpnext/schools/doctype/grading_scale_interval/__init__.py
diff --git a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json b/erpnext/schools/doctype/grading_scale_interval/grading_scale_interval.json
similarity index 60%
copy from erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
copy to erpnext/schools/doctype/grading_scale_interval/grading_scale_interval.json
index 6b80efc..10b229c 100644
--- a/erpnext/fleet_management/doctype/vehicle_service/vehicle_service.json
+++ b/erpnext/schools/doctype/grading_scale_interval/grading_scale_interval.json
@@ -3,36 +3,38 @@
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
- "creation": "2016-09-03 19:20:14.561962",
+ "creation": "2016-08-26 03:11:09.591049",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
- "document_type": "Document",
+ "document_type": "",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "service_item",
- "fieldtype": "Select",
+ "fieldname": "grade_code",
+ "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Service Item",
+ "in_standard_filter": 0,
+ "label": "Grade Code",
"length": 0,
"no_copy": 0,
- "options": "\nBrake Oil\nBrake Pad\nClutch Plate\nEngine Oil\nOil Change\nWheels",
"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,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -42,24 +44,26 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "type",
- "fieldtype": "Select",
+ "default": "0",
+ "fieldname": "threshold",
+ "fieldtype": "Percent",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Type",
+ "in_standard_filter": 0,
+ "label": "Threshold",
"length": 0,
"no_copy": 0,
- "options": "\nInspection\nService\nChange",
"permlevel": 0,
- "precision": "",
+ "precision": "1",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -69,41 +73,15 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "frequency",
- "fieldtype": "Select",
+ "fieldname": "grade_description",
+ "fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Frequency",
- "length": 0,
- "no_copy": 0,
- "options": "\nMileage\nMonthly\nQuarterly\nHalf Yearly\nYearly",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 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": "expense_amount",
- "fieldtype": "Currency",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "label": "Expense",
+ "in_standard_filter": 0,
+ "label": "Grade Description",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -111,6 +89,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,
@@ -128,10 +107,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-09-20 07:29:50.852748",
+ "modified": "2017-01-04 15:27:56.729286",
"modified_by": "Administrator",
- "module": "Fleet Management",
- "name": "Vehicle Service",
+ "module": "Schools",
+ "name": "Grading Scale Interval",
"name_case": "",
"owner": "Administrator",
"permissions": [],
@@ -140,5 +119,6 @@
"read_only_onload": 0,
"sort_field": "modified",
"sort_order": "DESC",
+ "track_changes": 1,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/grading_scale_interval/grading_scale_interval.py b/erpnext/schools/doctype/grading_scale_interval/grading_scale_interval.py
new file mode 100644
index 0000000..41ac5ff
--- /dev/null
+++ b/erpnext/schools/doctype/grading_scale_interval/grading_scale_interval.py
@@ -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 GradingScaleInterval(Document):
+ pass
diff --git a/erpnext/schools/doctype/grading_structure/grading_structure.json b/erpnext/schools/doctype/grading_structure/grading_structure.json
index cda6bd4..3c30f29 100644
--- a/erpnext/schools/doctype/grading_structure/grading_structure.json
+++ b/erpnext/schools/doctype/grading_structure/grading_structure.json
@@ -10,11 +10,13 @@
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "grading_system_name",
"fieldtype": "Data",
"hidden": 0,
@@ -22,6 +24,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Grading System Name",
"length": 0,
"no_copy": 0,
@@ -30,6 +33,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,
@@ -40,6 +44,34 @@
"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": "description",
"fieldtype": "Text",
"hidden": 0,
@@ -47,6 +79,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
+ "in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
@@ -55,6 +88,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,
@@ -65,30 +99,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 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": "grading_intervals_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -96,6 +107,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Grading Intervals",
"length": 0,
"no_copy": 0,
@@ -104,6 +116,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,
@@ -114,6 +127,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "grade_intervals",
"fieldtype": "Table",
"hidden": 0,
@@ -121,6 +135,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
+ "in_standard_filter": 0,
"label": "Grade Intervals",
"length": 0,
"no_copy": 0,
@@ -130,6 +145,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,
@@ -147,7 +163,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-08-27 14:20:50.709823",
+ "modified": "2016-12-14 12:35:39.690256",
"modified_by": "Administrator",
"module": "Schools",
"name": "Grading Structure",
@@ -164,6 +180,7 @@
"export": 1,
"if_owner": 0,
"import": 0,
+ "is_custom": 0,
"permlevel": 0,
"print": 1,
"read": 1,
diff --git a/erpnext/schools/doctype/student/student_dashboard.py b/erpnext/schools/doctype/student/student_dashboard.py
index 8b5fb41..ca2a660 100644
--- a/erpnext/schools/doctype/student/student_dashboard.py
+++ b/erpnext/schools/doctype/student/student_dashboard.py
@@ -10,7 +10,7 @@
'items': ['Student Log', 'Student Batch', 'Student Group', 'Program Enrollment']
},
{
- 'items': ['Fees', 'Assessment', 'Student Attendance', 'Student Leave Application']
+ 'items': ['Fees', 'Assessment Result', 'Student Attendance', 'Student Leave Application']
}
]
}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_group/student_group.js b/erpnext/schools/doctype/student_group/student_group.js
index 6f4084b..392793a 100644
--- a/erpnext/schools/doctype/student_group/student_group.js
+++ b/erpnext/schools/doctype/student_group/student_group.js
@@ -10,11 +10,11 @@
frappe.set_route("List", "Course Schedule");
});
- frm.add_custom_button(__("Assessment"), function() {
+ frm.add_custom_button(__("Assessment Plan"), function() {
frappe.route_options = {
student_group: frm.doc.name
}
- frappe.set_route("List", "Assessment");
+ frappe.set_route("List", "Assessment Plan");
});
}
},
diff --git a/erpnext/selling/doctype/customer/customer.js b/erpnext/selling/doctype/customer/customer.js
index ea88e8b..747b31e 100644
--- a/erpnext/selling/doctype/customer/customer.js
+++ b/erpnext/selling/doctype/customer/customer.js
@@ -32,6 +32,8 @@
erpnext.toggle_naming_series();
}
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Customer'}
+
frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
if(!frm.doc.__islocal) {
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 48e2982..d8011af 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -9,7 +9,7 @@
from frappe.utils import flt, cint, cstr
from frappe.desk.reportview import build_match_conditions
from erpnext.utilities.transaction_base import TransactionBase
-from erpnext.utilities.address_and_contact import load_address_and_contact
+from erpnext.utilities.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
@@ -79,9 +79,6 @@
if self.flags.old_lead != self.lead_name:
self.update_lead_status()
- self.update_address()
- self.update_contact()
-
if self.flags.is_new_doc:
self.create_lead_address_contact()
@@ -95,30 +92,26 @@
for d in frappe.get_all(doctype, {'lead': self.lead_name}):
frappe.db.set_value(doctype, d.name, 'customer', self.name, update_modified=False)
- def update_address(self):
- frappe.db.sql("""update `tabAddress` set customer_name=%s, modified=NOW()
- where customer=%s""", (self.customer_name, self.name))
-
- def update_contact(self):
- frappe.db.sql("""update `tabContact` set customer_name=%s, modified=NOW()
- where customer=%s""", (self.customer_name, self.name))
-
def create_lead_address_contact(self):
if self.lead_name:
- if not frappe.db.get_value("Address", {"lead": self.lead_name, "customer": self.name}):
- frappe.db.sql("""update `tabAddress` set customer=%s, customer_name=%s where lead=%s""",
- (self.name, self.customer_name, self.lead_name))
+ # assign lead address to customer (if already not set)
+ address_name = frappe.get_value('Dynamic Link', dict(parenttype='Address', link_doctype='Lead', link_name=self.name))
+ if address_name:
+ address = frappe.get_doc('Address', address_name)
+ if not address.has_link('Customer', self.name):
+ address.append('links', dict(link_doctype='Customer', link_name=self.name))
+ address.save()
lead = frappe.db.get_value("Lead", self.lead_name, ["lead_name", "email_id", "phone", "mobile_no"], as_dict=True)
+ # create contact from lead
c = frappe.new_doc('Contact')
c.first_name = lead.lead_name
c.email_id = lead.email_id
c.phone = lead.phone
c.mobile_no = lead.mobile_no
- c.customer = self.name
- c.customer_name = self.customer_name
c.is_primary_contact = 1
+ c.append('links', dict(link_doctype='Customer', link_name=self.name))
c.flags.ignore_permissions = self.flags.ignore_permissions
c.autoname()
if not frappe.db.exists("Contact", c.name):
@@ -137,40 +130,14 @@
if flt(self.credit_limit) < outstanding_amt:
frappe.throw(_("""New credit limit is less than current outstanding amount for the customer. Credit limit has to be atleast {0}""").format(outstanding_amt))
- def delete_customer_address(self):
- addresses = frappe.db.sql("""select name, lead from `tabAddress`
- where customer=%s""", (self.name,))
-
- for name, lead in addresses:
- if lead:
- frappe.db.sql("""update `tabAddress` set customer=null, customer_name=null
- where name=%s""", name)
- else:
- frappe.db.sql("""delete from `tabAddress` where name=%s""", name)
-
- def delete_customer_contact(self):
- for contact in frappe.db.sql_list("""select name from `tabContact`
- where customer=%s""", self.name):
- frappe.delete_doc("Contact", contact)
-
def on_trash(self):
- self.delete_customer_address()
- self.delete_customer_contact()
+ delete_contact_and_address('Customer', self.name)
if self.lead_name:
frappe.db.sql("update `tabLead` set status='Interested' where name=%s",self.lead_name)
def after_rename(self, olddn, newdn, merge=False):
- set_field = ''
if frappe.defaults.get_global_default('cust_master_name') == 'Customer Name':
frappe.db.set(self, "customer_name", newdn)
- self.update_contact()
- set_field = ", customer_name=%(newdn)s"
- self.update_customer_address(newdn, set_field)
-
- def update_customer_address(self, newdn, set_field):
- frappe.db.sql("""update `tabAddress` set address_title=%(newdn)s
- {set_field} where customer=%(newdn)s"""\
- .format(set_field=set_field), ({"newdn": newdn}))
def get_customer_list(doctype, txt, searchfield, start, page_len, filters):
diff --git a/erpnext/selling/doctype/installation_note/installation_note.js b/erpnext/selling/doctype/installation_note/installation_note.js
index 0334ae7..d4b2179 100644
--- a/erpnext/selling/doctype/installation_note/installation_note.js
+++ b/erpnext/selling/doctype/installation_note/installation_note.js
@@ -32,11 +32,7 @@
}
});
- this.frm.set_query("contact_person", function() {
- return {
- filters: {'customer': me.frm.doc.customer }
- }
- });
+ this.frm.set_query('contact_person', erpnext.queries.contact_query);
this.frm.set_query("customer", function() {
return {
diff --git a/erpnext/selling/doctype/quotation/quotation.js b/erpnext/selling/doctype/quotation/quotation.js
index d111c14..e06f963 100644
--- a/erpnext/selling/doctype/quotation/quotation.js
+++ b/erpnext/selling/doctype/quotation/quotation.js
@@ -16,6 +16,7 @@
},
refresh: function(doc, dt, dn) {
this._super(doc, dt, dn);
+
if(doc.docstatus == 1 && doc.status!=='Lost') {
cur_frm.add_custom_button(__('Make Sales Order'),
cur_frm.cscript['Make Sales Order']);
@@ -66,12 +67,8 @@
this.frm.toggle_reqd("customer", this.frm.doc.quotation_to == "Customer");
// to overwrite the customer_filter trigger from queries.js
- $.each(["customer_address", "shipping_address_name"],
- function(i, opts) {
- me.frm.set_query(opts, me.frm.doc.quotation_to==="Lead"
- ? erpnext.queries["lead_filter"] : erpnext.queries["customer_filter"]);
- }
- );
+ this.frm.set_query('customer_address', erpnext.queries.address_query);
+ this.frm.set_query('shipping_address_name', erpnext.queries.address_query);
},
tc_name: function() {
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index f1eeccc..8a4a47c 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -203,13 +203,6 @@
// for backward compatibility: combine new and previous states
$.extend(cur_frm.cscript, new erpnext.selling.SalesOrderController({frm: cur_frm}));
-cur_frm.cscript.new_contact = function(){
- tn = frappe.model.make_new_doc_and_get_name('Contact');
- locals['Contact'][tn].is_customer = 1;
- if(doc.customer) locals['Contact'][tn].customer = doc.customer;
- frappe.set_route('Form', 'Contact', tn);
-}
-
cur_frm.fields_dict['project'].get_query = function(doc, cdt, cdn) {
return {
query: "erpnext.controllers.queries.get_project_name",
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 7ddf45d..9d9511e 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -26,16 +26,17 @@
this.frm.add_fetch("sales_partner", "commission_rate", "commission_rate");
- $.each([["customer_address", "customer_filter"],
- ["shipping_address_name", "customer_filter"],
- ["contact_person", "customer_filter"],
- ["customer", "customer"],
+ $.each([["customer", "customer"],
["lead", "lead"]],
function(i, opts) {
if(me.frm.fields_dict[opts[0]])
me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
});
+ me.frm.set_query('contact_person', erpnext.queries.contact_query);
+ me.frm.set_query('customer_address', erpnext.queries.address_query);
+ me.frm.set_query('shipping_address_name', erpnext.queries.address_query);
+
if(this.frm.fields_dict.taxes_and_charges) {
this.frm.set_query("taxes_and_charges", function() {
return {
@@ -104,6 +105,9 @@
refresh: function() {
this._super();
+
+ frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+
this.frm.toggle_display("customer_name",
(this.frm.doc.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer));
if(this.frm.fields_dict.packed_items) {
diff --git a/erpnext/setup/doctype/sales_partner/sales_partner.js b/erpnext/setup/doctype/sales_partner/sales_partner.js
index 143bf44..df8d23f 100644
--- a/erpnext/setup/doctype/sales_partner/sales_partner.js
+++ b/erpnext/setup/doctype/sales_partner/sales_partner.js
@@ -1,14 +1,17 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
-cur_frm.cscript.refresh = function(doc,dt,dn){
+frappe.ui.form.on('Sales Partner', {
+ refresh: function(frm) {
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Sales Person'}
- if(doc.__islocal){
- hide_field(['address_html', 'contact_html']);
- erpnext.utils.clear_address_and_contact(cur_frm);
+ if(doc.__islocal){
+ hide_field(['address_html', 'contact_html']);
+ erpnext.utils.clear_address_and_contact(frm);
+ }
+ else{
+ unhide_field(['address_html', 'contact_html']);
+ erpnext.utils.render_address_and_contact(frm);
+ }
}
- else{
- unhide_field(['address_html', 'contact_html']);
- erpnext.utils.render_address_and_contact(cur_frm);
- }
-}
+});
diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py
index 395ea51..664c089 100644
--- a/erpnext/setup/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/setup_wizard/setup_wizard.py
@@ -407,7 +407,7 @@
if args.get("customer_contact_" + str(i)):
create_contact(args.get("customer_contact_" + str(i)),
- "customer", doc.name)
+ "Customer", doc.name)
except frappe.NameError:
pass
@@ -425,7 +425,7 @@
if args.get("supplier_contact_" + str(i)):
create_contact(args.get("supplier_contact_" + str(i)),
- "supplier", doc.name)
+ "Supplier", doc.name)
except frappe.NameError:
pass
@@ -433,12 +433,13 @@
"""Create contact based on given contact name"""
contact = contact.strip().split(" ")
- frappe.get_doc({
+ contact = frappe.get_doc({
"doctype":"Contact",
- party_type: party,
"first_name":contact[0],
"last_name": len(contact) > 1 and contact[1] or ""
- }).insert()
+ })
+ contact.append('links', dict(link_doctype=party_type, link_name=party))
+ contact.insert()
def create_letter_head(args):
if args.get("attach_letterhead"):
diff --git a/erpnext/shopping_cart/cart.py b/erpnext/shopping_cart/cart.py
index d5cde4a..5ca0315 100644
--- a/erpnext/shopping_cart/cart.py
+++ b/erpnext/shopping_cart/cart.py
@@ -6,7 +6,7 @@
from frappe import throw, _
import frappe.defaults
from frappe.utils import cint, flt, get_fullname, cstr
-from erpnext.utilities.doctype.address.address import get_address_display
+from frappe.geo.doctype.address.address import get_address_display
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import get_shopping_cart_settings
from frappe.utils.nestedset import get_root_of
from erpnext.accounts.utils import get_account_name
@@ -182,8 +182,7 @@
(party.doctype.lower()): party.name
})
- qdoc.contact_person = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
- "customer": party.name})
+ qdoc.contact_person = frappe.db.get_value("Contact", {"email_id": frappe.session.user})
qdoc.contact_email = frappe.session.user
qdoc.flags.ignore_permissions = True
@@ -198,8 +197,7 @@
party.customer_name = company_name or fullname
party.customer_type == "Company" if company_name else "Individual"
- contact_name = frappe.db.get_value("Contact", {"email_id": frappe.session.user,
- "customer": party.name})
+ contact_name = frappe.db.get_value("Contact", {"email_id": frappe.session.user})
contact = frappe.get_doc("Contact", contact_name)
contact.first_name = fullname
contact.last_name = None
@@ -291,10 +289,14 @@
if not user:
user = frappe.session.user
- party = frappe.db.get_value("Contact", {"email_id": user}, ["customer", "supplier"], as_dict=1)
- if party:
- party_doctype = 'Customer' if party.customer else 'Supplier'
- party = party.customer or party.supplier
+ contact_name = frappe.db.get_value("Contact", {"email_id": user})
+ party = None
+
+ if contact_name:
+ contact = frappe.get_doc('Contact', contact_name)
+ if contact.links:
+ party_doctype = contact.links[0].link_doctype
+ party = contact.links[0].link_name
cart_settings = frappe.get_doc("Shopping Cart Settings")
@@ -331,10 +333,10 @@
contact = frappe.new_doc("Contact")
contact.update({
- "customer": customer.name,
"first_name": fullname,
"email_id": user
})
+ contact.append('links', dict(link_doctype='Customer', link_name=customer.name))
contact.flags.ignore_mandatory = True
contact.insert(ignore_permissions=True)
@@ -373,26 +375,17 @@
if not party:
return []
- address_docs = frappe.db.sql("""select * from `tabAddress`
- where `{0}`=%s order by name limit {1}, {2}""".format(party.doctype.lower(),
- limit_start, limit_page_length), party.name,
- as_dict=True, update={"doctype": "Address"})
+ address_names = frappe.db.get_all('Dyanamic Link', fields=('parent'),
+ filters=dict(parenttype='Address', link_doctype=party.doctype, link_name=party.name))
- for address in address_docs:
- address.display = get_address_display(address)
+ out = []
- return address_docs
+ for address_name in address_names:
+ address = frappe.get_doc('Address', address_name)
+ address.display = get_address_display(address.as_dict())
+ out.append(address)
-def set_customer_in_address(doc, method=None):
- if doc.flags.linked:
- return
-
- doc.check_if_linked()
-
- if not doc.flags.linked and (frappe.db.get_value("User", frappe.session.user, "user_type") == "Website User"):
- # creates a customer if one does not exist
- get_party()
- doc.link_address()
+ return out
@frappe.whitelist()
def apply_shipping_rule(shipping_rule):
diff --git a/erpnext/shopping_cart/test_shopping_cart.py b/erpnext/shopping_cart/test_shopping_cart.py
index 5282231..698d467 100644
--- a/erpnext/shopping_cart/test_shopping_cart.py
+++ b/erpnext/shopping_cart/test_shopping_cart.py
@@ -25,8 +25,8 @@
# test if lead is created and quotation with new lead is fetched
quotation = _get_cart_quotation()
self.assertEquals(quotation.quotation_to, "Customer")
- self.assertEquals(frappe.db.get_value("Contact", {"customer": quotation.customer}, "email_id"),
- "test_cart_user@example.com")
+ self.assertEquals(frappe.db.get_value("Contact", dict(contact_person="test_cart_user@example.com")),
+ quotation.contact_name)
self.assertEquals(quotation.lead, None)
self.assertEquals(quotation.contact_email, frappe.session.user)
@@ -101,7 +101,7 @@
quotation = self.create_quotation()
from erpnext.accounts.party import set_taxes
-
+
tax_rule_master = set_taxes(quotation.customer, "Customer", \
quotation.transaction_date, quotation.company, None, None, \
quotation.customer_address, quotation.shipping_address_name, 1)
diff --git a/erpnext/shopping_cart/utils.py b/erpnext/shopping_cart/utils.py
index 50ce5cf..3241234 100644
--- a/erpnext/shopping_cart/utils.py
+++ b/erpnext/shopping_cart/utils.py
@@ -31,12 +31,11 @@
def check_customer_or_supplier():
if frappe.session.user:
- contacts = frappe.get_all("Contact", fields=["customer", "supplier", "email_id"],
- filters={"email_id": frappe.session.user})
+ contact_name = frappe.get_value("Contact", {"email_id": frappe.session.user})
+ if contact_name:
+ contact = frappe.get_doc('Contact', contact_name)
+ for link in contact.links:
+ if link.link_doctype in ('Customer', 'Supplier'):
+ return link.link_doctype, link.link_name
- customer = [d.customer for d in contacts if d.customer] or None
- supplier = [d.supplier for d in contacts if d.supplier] or None
-
- if customer: return 'Customer', customer
- if supplier : return 'Supplier', supplier
return 'Customer', None
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.js b/erpnext/stock/doctype/delivery_note/delivery_note.js
index 204e98a..8f87198 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.js
@@ -137,13 +137,6 @@
// for backward compatibility: combine new and previous states
$.extend(cur_frm.cscript, new erpnext.stock.DeliveryNoteController({frm: cur_frm}));
-cur_frm.cscript.new_contact = function(){
- tn = frappe.model.make_new_doc_and_get_name('Contact');
- locals['Contact'][tn].is_customer = 1;
- if(doc.customer) locals['Contact'][tn].customer = doc.customer;
- frappe.set_route('Form', 'Contact', tn);
-}
-
cur_frm.cscript.update_status = function(status) {
frappe.ui.form.is_saving = true;
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 457a7c2..c843d7d 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -26,7 +26,7 @@
]
}
});
-
+
}
});
@@ -122,26 +122,6 @@
})
}
-cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
- return {
- filters: { 'supplier': doc.supplier}
- }
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return {
- filters: { 'supplier': doc.supplier }
- }
-}
-
-cur_frm.cscript.new_contact = function() {
- tn = frappe.model.make_new_doc_and_get_name('Contact');
- locals['Contact'][tn].is_supplier = 1;
- if(doc.supplier)
- locals['Contact'][tn].supplier = doc.supplier;
- frappe.set_route('Form', 'Contact', tn);
-}
-
cur_frm.fields_dict['items'].grid.get_field('project').get_query = function(doc, cdt, cdn) {
return {
filters: [
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index f961cdd..7421e01 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -8,6 +8,7 @@
import frappe.defaults
from frappe.utils import cint, flt, cstr, today
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
+from erpnext import set_perpetual_inventory
class TestPurchaseReceipt(unittest.TestCase):
def test_make_purchase_invoice(self):
@@ -26,10 +27,10 @@
def test_purchase_receipt_no_gl_entry(self):
set_perpetual_inventory(0)
-
+
existing_bin_stock_value = frappe.db.get_value("Bin", {"item_code": "_Test Item",
"warehouse": "_Test Warehouse - _TC"}, "stock_value")
-
+
pr = make_purchase_receipt()
stock_value_difference = frappe.db.get_value("Stock Ledger Entry",
@@ -78,22 +79,22 @@
def test_subcontracting(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
-
+
make_stock_entry(item_code="_Test Item", target="_Test Warehouse 1 - _TC", qty=100, basic_rate=100)
- make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse 1 - _TC",
+ make_stock_entry(item_code="_Test Item Home Desktop 100", target="_Test Warehouse 1 - _TC",
qty=100, basic_rate=100)
-
+
pr = make_purchase_receipt(item_code="_Test FG Item", qty=10, rate=500, is_subcontracted="Yes")
self.assertEquals(len(pr.get("supplied_items")), 2)
-
+
rm_supp_cost = sum([d.amount for d in pr.get("supplied_items")])
self.assertEquals(pr.get("items")[0].rm_supp_cost, flt(rm_supp_cost, 2))
def test_serial_no_supplier(self):
pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1)
- self.assertEquals(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"),
+ self.assertEquals(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "supplier"),
pr.supplier)
-
+
pr.cancel()
self.assertFalse(frappe.db.get_value("Serial No", pr.get("items")[0].serial_no, "warehouse"))
@@ -118,21 +119,21 @@
for serial_no in rejected_serial_nos:
self.assertEquals(frappe.db.get_value("Serial No", serial_no, "warehouse"),
pr.get("items")[0].rejected_warehouse)
-
+
def test_purchase_return(self):
set_perpetual_inventory()
-
+
pr = make_purchase_receipt()
-
+
return_pr = make_purchase_receipt(is_return=1, return_against=pr.name, qty=-2)
# check sle
- outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
+ outgoing_rate = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
"voucher_no": return_pr.name}, "outgoing_rate")
-
+
self.assertEqual(outgoing_rate, 50)
-
-
+
+
# check gl entries for return
gl_entries = get_gl_entries("Purchase Receipt", return_pr.name)
@@ -146,7 +147,7 @@
for gle in gl_entries:
self.assertEquals(expected_values[gle.account][0], gle.debit)
self.assertEquals(expected_values[gle.account][1], gle.credit)
-
+
set_perpetual_inventory(0)
def test_purchase_return_for_rejected_qty(self):
@@ -158,7 +159,7 @@
actual_qty = frappe.db.get_value("Stock Ledger Entry", {"voucher_type": "Purchase Receipt",
"voucher_no": return_pr.name, 'warehouse': return_pr.items[0].rejected_warehouse}, "actual_qty")
-
+
self.assertEqual(actual_qty, -2)
set_perpetual_inventory(0)
@@ -168,87 +169,82 @@
serial_no = frappe.get_doc("Serial No", serial_no)
for field, value in field_values.items():
self.assertEquals(cstr(serial_no.get(field)), value)
-
+
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
-
+
pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=1)
-
+
serial_no = get_serial_nos(pr.get("items")[0].serial_no)[0]
-
+
_check_serial_no_values(serial_no, {
"warehouse": "_Test Warehouse - _TC",
"purchase_document_no": pr.name
})
-
- return_pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=-1,
+
+ return_pr = make_purchase_receipt(item_code="_Test Serialized Item With Series", qty=-1,
is_return=1, return_against=pr.name, serial_no=serial_no)
-
+
_check_serial_no_values(serial_no, {
"warehouse": "",
"purchase_document_no": pr.name,
"delivery_document_no": return_pr.name
})
-
+
def test_closed_purchase_receipt(self):
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import update_purchase_receipt_status
-
+
pr = make_purchase_receipt(do_not_submit=True)
pr.submit()
-
+
update_purchase_receipt_status(pr.name, "Closed")
self.assertEquals(frappe.db.get_value("Purchase Receipt", pr.name, "status"), "Closed")
-
+
def test_pr_billing_status(self):
# PO -> PR1 -> PI and PO -> PI and PO -> PR2
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
from erpnext.buying.doctype.purchase_order.purchase_order \
import make_purchase_receipt, make_purchase_invoice as make_purchase_invoice_from_po
-
+
po = create_purchase_order()
-
+
pr1 = make_purchase_receipt(po.name)
pr1.posting_date = today()
pr1.posting_time = "10:00"
pr1.get("items")[0].received_qty = 2
pr1.get("items")[0].qty = 2
pr1.submit()
-
+
pi1 = make_purchase_invoice(pr1.name)
pi1.submit()
-
+
pr1.load_from_db()
self.assertEqual(pr1.per_billed, 100)
-
+
pi2 = make_purchase_invoice_from_po(po.name)
pi2.get("items")[0].qty = 4
pi2.submit()
-
+
pr2 = make_purchase_receipt(po.name)
pr2.posting_date = today()
pr2.posting_time = "08:00"
pr2.get("items")[0].received_qty = 5
pr2.get("items")[0].qty = 5
pr2.submit()
-
+
pr1.load_from_db()
self.assertEqual(pr1.get("items")[0].billed_amt, 1000)
self.assertEqual(pr1.per_billed, 100)
self.assertEqual(pr1.status, "Completed")
-
+
self.assertEqual(pr2.get("items")[0].billed_amt, 2000)
self.assertEqual(pr2.per_billed, 80)
self.assertEqual(pr2.status, "To Bill")
-
+
def get_gl_entries(voucher_type, voucher_no):
return frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
order by account desc""", (voucher_type, voucher_no), as_dict=1)
-def set_perpetual_inventory(enable=1):
- accounts_settings = frappe.get_doc("Accounts Settings")
- accounts_settings.auto_accounting_for_stock = enable
- accounts_settings.save()
-
def make_purchase_receipt(**args):
pr = frappe.new_doc("Purchase Receipt")
args = frappe._dict(args)
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 1199593..107c85c 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -219,9 +219,9 @@
# validate qty during submit
if d.docstatus==1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty:
- frappe.throw(_("Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})".format(d.idx,
+ frappe.throw(_("Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})").format(d.idx,
frappe.bold(d.s_warehouse), formatdate(self.posting_date),
- format_time(self.posting_time), frappe.bold(d.item_code)))
+ format_time(self.posting_time), frappe.bold(d.item_code))
+ '<br><br>' + _("Available qty is {0}, you need {1}").format(frappe.bold(d.actual_qty),
frappe.bold(d.transfer_qty)),
NegativeStockError, title=_('Insufficient Stock'))
@@ -868,4 +868,4 @@
"basic_rate" : get_incoming_rate(args)
}
- return ret
\ No newline at end of file
+ return ret
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 2caabee..00e3abe 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -27,9 +27,6 @@
self.validate_and_set_fiscal_year()
self.block_transactions_against_group_warehouse()
- from erpnext.accounts.utils import validate_fiscal_year
- validate_fiscal_year(self.posting_date, self.fiscal_year, self.meta.get_label("posting_date"), self)
-
def on_submit(self):
self.check_stock_frozen_date()
self.actual_amt_check()
@@ -117,6 +114,10 @@
def validate_and_set_fiscal_year(self):
if not self.fiscal_year:
self.fiscal_year = get_fiscal_year(self.posting_date, company=self.company)[0]
+ else:
+ from erpnext.accounts.utils import validate_fiscal_year
+ validate_fiscal_year(self.posting_date, self.fiscal_year, self.company,
+ self.meta.get_label("posting_date"), self)
def block_transactions_against_group_warehouse(self):
from erpnext.stock.utils import is_group_warehouse
diff --git a/erpnext/stock/doctype/warehouse/test_warehouse.py b/erpnext/stock/doctype/warehouse/test_warehouse.py
index edc5400..ec64bdd 100644
--- a/erpnext/stock/doctype/warehouse/test_warehouse.py
+++ b/erpnext/stock/doctype/warehouse/test_warehouse.py
@@ -4,59 +4,64 @@
from frappe.model.rename_doc import rename_doc
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
from frappe.utils import cint
-from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
+from erpnext import set_perpetual_inventory
+from frappe.test_runner import make_test_records
import frappe
import unittest
test_records = frappe.get_test_records('Warehouse')
class TestWarehouse(unittest.TestCase):
+ def setUp(self):
+ if not frappe.get_value('Item', '_Test Item'):
+ make_test_records('Item')
+
def test_parent_warehouse(self):
parent_warehouse = frappe.get_doc("Warehouse", "_Test Warehouse Group - _TC")
self.assertEquals(parent_warehouse.is_group, 1)
-
+
def test_warehouse_hierarchy(self):
p_warehouse = frappe.get_doc("Warehouse", "_Test Warehouse Group - _TC")
-
+
child_warehouses = frappe.db.sql("""select name, is_group, parent_warehouse from `tabWarehouse` wh
where wh.lft > %s and wh.rgt < %s""", (p_warehouse.lft, p_warehouse.rgt), as_dict=1)
-
+
for child_warehouse in child_warehouses:
self.assertEquals(p_warehouse.name, child_warehouse.parent_warehouse)
self.assertEquals(child_warehouse.is_group, 0)
-
+
def test_warehouse_renaming(self):
set_perpetual_inventory(1)
create_warehouse("Test Warehouse for Renaming 1")
-
+
self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 1 - _TC"))
- self.assertTrue(frappe.db.get_value("Account",
+ self.assertTrue(frappe.db.get_value("Account",
filters={"warehouse": "Test Warehouse for Renaming 1 - _TC"}))
-
+
# Rename with abbr
if frappe.db.exists("Warehouse", "Test Warehouse for Renaming 2 - _TC"):
frappe.delete_doc("Warehouse", "Test Warehouse for Renaming 2 - _TC")
rename_doc("Warehouse", "Test Warehouse for Renaming 1 - _TC", "Test Warehouse for Renaming 2 - _TC")
-
+
self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 2 - _TC"))
- self.assertTrue(frappe.db.get_value("Account",
+ self.assertTrue(frappe.db.get_value("Account",
filters={"warehouse": "Test Warehouse for Renaming 2 - _TC"}))
-
+ self.assertFalse(frappe.db.get_value("Account",
+ filters={"warehouse": "Test Warehouse for Renaming 1 - _TC"}))
+
# Rename without abbr
if frappe.db.exists("Warehouse", "Test Warehouse for Renaming 3 - _TC"):
frappe.delete_doc("Warehouse", "Test Warehouse for Renaming 3 - _TC")
-
+
rename_doc("Warehouse", "Test Warehouse for Renaming 2 - _TC", "Test Warehouse for Renaming 3")
-
+
self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Renaming 3 - _TC"))
- self.assertTrue(frappe.db.get_value("Account",
+ self.assertTrue(frappe.db.get_value("Account",
filters={"warehouse": "Test Warehouse for Renaming 3 - _TC"}))
-
- set_perpetual_inventory(0)
-
+
def test_warehouse_merging(self):
set_perpetual_inventory(1)
-
+
create_warehouse("Test Warehouse for Merging 1")
create_warehouse("Test Warehouse for Merging 2")
@@ -64,31 +69,29 @@
qty=1, rate=100)
make_stock_entry(item_code="_Test Item", target="Test Warehouse for Merging 2 - _TC",
qty=1, rate=100)
-
+
existing_bin_qty = (
- cint(frappe.db.get_value("Bin",
+ cint(frappe.db.get_value("Bin",
{"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 1 - _TC"}, "actual_qty"))
- + cint(frappe.db.get_value("Bin",
+ + cint(frappe.db.get_value("Bin",
{"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 2 - _TC"}, "actual_qty"))
)
- rename_doc("Warehouse", "Test Warehouse for Merging 1 - _TC",
+ rename_doc("Warehouse", "Test Warehouse for Merging 1 - _TC",
"Test Warehouse for Merging 2 - _TC", merge=True)
self.assertFalse(frappe.db.exists("Warehouse", "Test Warehouse for Merging 1 - _TC"))
bin_qty = frappe.db.get_value("Bin",
{"item_code": "_Test Item", "warehouse": "Test Warehouse for Merging 2 - _TC"}, "actual_qty")
-
+
self.assertEqual(bin_qty, existing_bin_qty)
-
+
self.assertFalse(frappe.db.exists("Account", "Test Warehouse for Merging 1 - _TC"))
self.assertTrue(frappe.db.exists("Account", "Test Warehouse for Merging 2 - _TC"))
- self.assertTrue(frappe.db.get_value("Account",
+ self.assertTrue(frappe.db.get_value("Account",
filters={"warehouse": "Test Warehouse for Merging 2 - _TC"}))
-
- set_perpetual_inventory(0)
-
+
def create_warehouse(warehouse_name):
if not frappe.db.exists("Warehouse", warehouse_name + " - _TC"):
w = frappe.new_doc("Warehouse")
@@ -96,5 +99,7 @@
w.parent_warehouse = "_Test Warehouse Group - _TC"
w.company = "_Test Company"
w.save()
-
-
\ No newline at end of file
+
+ if not frappe.get_value('Account', dict(warehouse=warehouse_name + ' - _TC')):
+ print 'Warehouse {0} not linked'.format(warehouse_name)
+
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index 1d2befa..d99cdf6 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
-import frappe
+import frappe, erpnext
from frappe.utils import cint, validate_email_add
from frappe import throw, msgprint, _
from frappe.utils.nestedset import NestedSet
@@ -53,6 +53,8 @@
self.update_nsm_model()
def create_account_head(self):
+ '''Create new account head if there is no account linked to this Warehouse'''
+ from erpnext.accounts.doctype.account.account import BalanceMismatchError
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
if not self.get_account():
if self.get("__islocal") or not frappe.db.get_value(
@@ -76,10 +78,12 @@
ac_doc.insert()
msgprint(_("Account head {0} created").format(ac_doc.name), indicator='green', alert=True)
- except frappe.DuplicateEntryError, e:
- if not (e.args and e.args[0]=='Account'):
- # if this is not due to creation of Account
- raise
+ except frappe.DuplicateEntryError:
+ msgprint(_("Please create an Account for this Warehouse and link it. This cannot be done automatically as an account with name {0} already exists").format(frappe.bold(self.name)),
+ indicator='orange')
+
+ except BalanceMismatchError:
+ msgprint(_("Cannot automatically create Account as there is already stock balance in the Account. You must create a matching account before you can make an entry on this warehouse"))
def validate_parent_account(self):
if not self.company:
@@ -111,7 +115,7 @@
else:
frappe.db.sql("delete from `tabBin` where name = %s", d['name'])
- warehouse_account = self.get_account(self.name)
+ warehouse_account = self.get_account()
if warehouse_account:
frappe.delete_doc("Account", warehouse_account)
@@ -131,10 +135,9 @@
return frappe.db.sql("""select name from `tabWarehouse`
where parent_warehouse = %s""", self.name)
- def before_rename(self, olddn, newdn, merge=False):
+ def before_rename(self, old_name, new_name, merge=False):
# Add company abbr if not provided
- from erpnext.setup.doctype.company.company import get_name_with_abbr
- new_warehouse = get_name_with_abbr(newdn, self.company)
+ new_warehouse = erpnext.encode_company_abbr(new_name, self.company)
if merge:
if not frappe.db.exists("Warehouse", new_warehouse):
@@ -143,64 +146,54 @@
if self.company != frappe.db.get_value("Warehouse", new_warehouse, "company"):
frappe.throw(_("Both Warehouse must belong to same Company"))
- self.rename_account_for(olddn, new_warehouse, merge)
+ self.rename_account_for(old_name, new_warehouse, merge)
return new_warehouse
- def rename_account_for(self, olddn, newdn, merge):
- if self.is_group:
- old_account = self.get_account()
- else:
- old_account = self.get_account(olddn)
+ def rename_account_for(self, old_name, new_name, merge):
+ old_account_name = frappe.get_value('Account', dict(warehouse=old_name))
- if old_account:
- new_account = None
+ if old_account_name:
if not merge:
- if old_account == self.add_abbr_if_missing(olddn):
- new_account = frappe.rename_doc("Account", old_account, newdn)
+ # old account name is same as old name, so rename the account too
+ if old_account_name == erpnext.encode_company_abbr(old_name, self.company):
+ frappe.rename_doc("Account", old_account_name, new_name)
else:
- existing_new_account = self.get_account(newdn)
- new_account = frappe.rename_doc("Account", old_account,
- existing_new_account or newdn, merge=True if existing_new_account else False)
+ # merge
+ target_account = frappe.get_value('Account', dict(warehouse=new_name))
+ if target_account:
+ # target warehouse has account, merge into target account
+ frappe.rename_doc("Account", old_account_name,
+ target_account, merge=True)
+ else:
+ # target warehouse does not have account, use this account
+ frappe.rename_doc("Account", old_account_name,
+ new_name, merge=False)
- frappe.db.set_value("Account", new_account or old_account, "warehouse", newdn)
+ # rename link
+ frappe.db.set_value('Account', new_name, 'warehouse', new_name)
- def add_abbr_if_missing(self, dn):
- from erpnext.setup.doctype.company.company import get_name_with_abbr
- return get_name_with_abbr(dn, self.company)
+ def get_account(self):
+ return frappe.get_value('Account', dict(warehouse=self.name))
- def get_account(self, warehouse=None):
- filters = {
- "account_type": "Stock",
- "company": self.company,
- "is_group": self.is_group
- }
-
- if warehouse:
- filters.update({"warehouse": warehouse})
- else:
- filters.update({"account_name": self.warehouse_name})
-
- return frappe.db.get_value("Account", filters)
-
- def after_rename(self, olddn, newdn, merge=False):
+ def after_rename(self, old_name, new_name, merge=False):
if merge:
- self.recalculate_bin_qty(newdn)
+ self.recalculate_bin_qty(new_name)
- def recalculate_bin_qty(self, newdn):
+ def recalculate_bin_qty(self, new_name):
from erpnext.stock.stock_balance import repost_stock
frappe.db.auto_commit_on_many_writes = 1
existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
repost_stock_for_items = frappe.db.sql_list("""select distinct item_code
- from tabBin where warehouse=%s""", newdn)
+ from tabBin where warehouse=%s""", new_name)
# Delete all existing bins to avoid duplicate bins for the same item and warehouse
- frappe.db.sql("delete from `tabBin` where warehouse=%s", newdn)
+ frappe.db.sql("delete from `tabBin` where warehouse=%s", new_name)
for item_code in repost_stock_for_items:
- repost_stock(item_code, newdn)
+ repost_stock(item_code, new_name)
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock)
frappe.db.auto_commit_on_many_writes = 0
@@ -231,7 +224,7 @@
if self.check_if_sle_exists():
throw(_("Warehouses with existing transaction can not be converted to group."))
else:
- account_name = self.get_account(self.name)
+ account_name = self.get_account()
if account_name:
doc = frappe.get_doc("Account", account_name)
doc.flags.exclude_account_type_check = True
@@ -269,26 +262,13 @@
@frappe.whitelist()
def add_node():
- doctype = frappe.form_dict.get('doctype')
- company = frappe.form_dict.get('company')
- parent_field = 'parent_' + doctype.lower().replace(' ', '_')
- name_field = doctype.lower().replace(' ', '_') + '_name'
+ from frappe.desk.treeview import make_tree_args
+ args = make_tree_args(**frappe.form_dict)
- doc = frappe.new_doc(doctype)
+ if cint(args.is_root):
+ args.parent_warehouse = None
- parent = frappe.form_dict['parent']
-
- if cint(frappe.form_dict['is_root']):
- parent = None
-
- doc.update({
- name_field: frappe.form_dict['warehouse_name'],
- parent_field: parent,
- "is_group": frappe.form_dict['is_group'],
- "company": company
- })
-
- doc.save()
+ frappe.get_doc(args).insert()
@frappe.whitelist()
def convert_to_group_or_ledger():
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 68b4270..0f1e30d 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -42,9 +42,6 @@
get_party_item_code(args, item_doc, out)
- if out.get("warehouse"):
- out.update(get_bin_details(args.item_code, out.warehouse))
-
if frappe.db.exists("Product Bundle", args.item_code):
valuation_rate = 0.0
bundled_items = frappe.get_doc("Product Bundle", args.item_code)
@@ -65,6 +62,9 @@
if args.customer and cint(args.is_pos):
out.update(get_pos_profile_item_details(args.company, args))
+
+ if out.get("warehouse"):
+ out.update(get_bin_details(args.item_code, out.warehouse))
# update args with out, if key or value not exists
for key, value in out.iteritems():
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index d5d6f9d..a8db4e0 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -102,7 +102,7 @@
"in_qty": 0.0, "in_val": 0.0,
"out_qty": 0.0, "out_val": 0.0,
"bal_qty": 0.0, "bal_val": 0.0,
- "val_rate": 0.0, "uom": None
+ "val_rate": 0.0
})
qty_dict = iwb_map[(d.company, d.item_code, d.warehouse)]
@@ -129,6 +129,24 @@
qty_dict.val_rate = d.valuation_rate
qty_dict.bal_qty += qty_diff
qty_dict.bal_val += value_diff
+
+ iwb_map = filter_items_with_no_transactions(iwb_map)
+
+ return iwb_map
+
+def filter_items_with_no_transactions(iwb_map):
+ for (company, item, warehouse) in sorted(iwb_map):
+ qty_dict = iwb_map[(company, item, warehouse)]
+
+ no_transactions = True
+ for key, val in qty_dict.items():
+ val = flt(val, 3)
+ qty_dict[key] = val
+ if key != "val_rate" and val:
+ no_transactions = False
+
+ if no_transactions:
+ iwb_map.pop((company, item, warehouse))
return iwb_map
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index 36d0876..f2d8bd5 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -33,11 +33,11 @@
if not self.lead:
self.lead = frappe.db.get_value("Lead", {"email_id": email_id})
if not self.contact:
- values = frappe.db.get_value("Contact",
- {"email_id": email_id}, ("name", "customer"))
+ self.contact = frappe.db.get_value("Contact", {"email_id": email_id})
- if values:
- self.contact, self.customer = values
+ if self.contact:
+ contact = frappe.get_doc('Contact', self.contact)
+ self.customer = contact.get_link_for('Customer')
if not self.company:
self.company = frappe.db.get_value("Lead", self.lead, "company") or \
diff --git a/erpnext/support/doctype/warranty_claim/warranty_claim.js b/erpnext/support/doctype/warranty_claim/warranty_claim.js
index 9fed265..2369a8a 100644
--- a/erpnext/support/doctype/warranty_claim/warranty_claim.js
+++ b/erpnext/support/doctype/warranty_claim/warranty_claim.js
@@ -4,6 +4,10 @@
frappe.provide("erpnext.support");
frappe.ui.form.on("Warranty Claim", {
+ setup: function(frm) {
+ frm.set_query('contact_person', erpnext.queries.contact_query);
+ frm.set_query('customer_address', erpnext.queries.address_query);
+ },
customer: function(frm) {
erpnext.utils.get_party_details(frm);
},
@@ -17,6 +21,8 @@
erpnext.support.WarrantyClaim = frappe.ui.form.Controller.extend({
refresh: function() {
+ frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
+
if(!cur_frm.doc.__islocal &&
(cur_frm.doc.status=='Open' || cur_frm.doc.status == 'Work In Progress')) {
cur_frm.add_custom_button(__('Maintenance Visit'),
@@ -40,18 +46,6 @@
set_multiple(cdt,cdn,{status:'Open'});
}
-cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{ 'customer': doc.customer}
- }
-}
-
-cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
- return{
- filters:{ 'customer': doc.customer}
- }
-}
-
cur_frm.fields_dict['serial_no'].get_query = function(doc, cdt, cdn) {
var cond = [];
var filter = [
diff --git a/erpnext/templates/utils.py b/erpnext/templates/utils.py
index 94f9242..c1405c3 100644
--- a/erpnext/templates/utils.py
+++ b/erpnext/templates/utils.py
@@ -34,6 +34,8 @@
if customer:
opportunity.customer = customer
+ elif lead:
+ opportunity.lead = lead
else:
opportunity.lead = new_lead.name
diff --git a/erpnext/utilities/address_and_contact.py b/erpnext/utilities/address_and_contact.py
index 36879d2..f3435ae 100644
--- a/erpnext/utilities/address_and_contact.py
+++ b/erpnext/utilities/address_and_contact.py
@@ -6,17 +6,46 @@
def load_address_and_contact(doc, key):
"""Loads address list and contact list in `__onload`"""
- from erpnext.utilities.doctype.address.address import get_address_display
+ from frappe.geo.doctype.address.address import get_address_display
- doc.get("__onload")["addr_list"] = [a.update({"display": get_address_display(a)}) \
- for a in frappe.get_all("Address",
- fields="*", filters={key: doc.name},
- order_by="is_primary_address desc, modified desc")]
+ address_list = [frappe.get_value('Address', a.parent, '*')
+ for a in frappe.get_all('Dynamic Link', fields='parent',
+ filters=dict(parenttype='Address', link_doctype=doc.doctype, link_name=doc.name))]
+
+ address_list = [a.update({"display": get_address_display(a)})
+ for a in address_list]
+
+ address_list = sorted(address_list,
+ lambda a, b:
+ (int(a.is_primary_address - b.is_primary_address)) or
+ (1 if a.modified - b.modified else 0))
+
+ doc.set_onload('addr_list', address_list)
if doc.doctype != "Lead":
- doc.get("__onload")["contact_list"] = frappe.get_all("Contact",
- fields="*", filters={key: doc.name},
- order_by="is_primary_contact desc, modified desc")
+ contact_list = [frappe.get_value('Contact', a.parent, '*')
+ for a in frappe.get_all('Dynamic Link', fields='parent',
+ filters=dict(parenttype='Contact', link_doctype=doc.doctype, link_name=doc.name))]
+
+ contact_list = sorted(contact_list,
+ lambda a, b:
+ (int(a.is_primary_contact - b.is_primary_contact)) or
+ (1 if a.modified - b.modified else 0))
+
+ doc.set_onload('contact_list', contact_list)
+
+def set_default_role(doc, method):
+ '''Set customer, supplier, student based on email'''
+ contact_name = frappe.get_value('Contact', dict(email_id=doc.email))
+ if contact_name:
+ contact = frappe.get_doc('Contact', contact_name)
+ for link in contact.links:
+ if link.link_doctype=='Customer':
+ doc.add_roles('Customer')
+ elif link.link_doctype=='Supplier':
+ doc.add_roles('Supplier')
+ elif frappe.get_value('Student', dict(student_email_id=doc.email)):
+ doc.add_roles('Student')
def has_permission(doc, ptype, user):
links = get_permitted_and_not_permitted_links(doc.doctype)
@@ -50,15 +79,15 @@
if not links.get("not_permitted_links"):
# when everything is permitted, don't add additional condition
return ""
-
+
elif not links.get("permitted_links"):
conditions = []
-
+
# when everything is not permitted
for df in links.get("not_permitted_links"):
# like ifnull(customer, '')='' and ifnull(supplier, '')=''
conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')=''".format(doctype=doctype, fieldname=df.fieldname))
-
+
return "( " + " and ".join(conditions) + " )"
else:
@@ -66,7 +95,7 @@
for df in links.get("permitted_links"):
# like ifnull(customer, '')!='' or ifnull(supplier, '')!=''
- conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname))
+ conditions.append("ifnull(`tab{doctype}`.`{fieldname}`, '')!=''".format(doctype=doctype, fieldname=df.fieldname))
return "( " + " or ".join(conditions) + " )"
@@ -89,3 +118,14 @@
"permitted_links": permitted_links,
"not_permitted_links": not_permitted_links
}
+
+def delete_contact_and_address(doctype, name):
+ for parenttype in ('Contact', 'Address'):
+ items = frappe.db.sql("""select parent from `tabDynamic Link`
+ where parenttype=%s and link_doctype=%s and link_name=%s""",
+ (parenttype, doctype, name))
+
+ for name in items:
+ doc = frappe.get_doc(parenttype, name)
+ if len(doc.links)==1:
+ doc.delete()
diff --git a/erpnext/utilities/doctype/address/README.md b/erpnext/utilities/doctype/address/README.md
deleted file mode 100644
index a4efda6..0000000
--- a/erpnext/utilities/doctype/address/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Address belonging to a Customer or Supplier.
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/address/__init__.py b/erpnext/utilities/doctype/address/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/utilities/doctype/address/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/utilities/doctype/address/address.js b/erpnext/utilities/doctype/address/address.js
deleted file mode 100644
index 1e874c3..0000000
--- a/erpnext/utilities/doctype/address/address.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-{% include 'erpnext/controllers/js/contact_address_common.js' %};
-
-frappe.ui.form.on("Address", "validate", function(frm) {
- // clear linked customer / supplier / sales partner on saving...
- $.each(["Customer", "Supplier", "Sales Partner", "Lead"], function(i, doctype) {
- var name = frm.doc[doctype.toLowerCase().replace(/ /g, "_")];
- if(name && locals[doctype] && locals[doctype][name])
- frappe.model.remove_from_locals(doctype, name);
- });
-});
diff --git a/erpnext/utilities/doctype/address/address.json b/erpnext/utilities/doctype/address/address.json
deleted file mode 100644
index 329e05f..0000000
--- a/erpnext/utilities/doctype/address/address.json
+++ /dev/null
@@ -1,851 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "beta": 0,
- "creation": "2013-01-10 16:34:32",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "address_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": "",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-map-marker",
- "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,
- "description": "Name of person or organization that this address belongs to.",
- "fieldname": "address_title",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Address Title",
- "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": "address_type",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Address Type",
- "length": 0,
- "no_copy": 0,
- "options": "Billing\nShipping\nOffice\nPersonal\nPlant\nPostal\nShop\nSubsidiary\nWarehouse\nOther",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "address_line1",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Address Line 1",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "address_line2",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Address Line 2",
- "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": "city",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "City/Town",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "county",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "County",
- "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": "state",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "State",
- "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": "country",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Country",
- "length": 0,
- "no_copy": 0,
- "options": "Country",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "pincode",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Postal Code",
- "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": 1,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break0",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0,
- "width": "50%"
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "email_id",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Email Address",
- "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": "phone",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Phone",
- "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": "fax",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Fax",
- "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,
- "default": "0",
- "description": "",
- "fieldname": "is_primary_address",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Preferred Billing Address",
- "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,
- "default": "0",
- "description": "",
- "fieldname": "is_shipping_address",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Preferred Shipping Address",
- "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": "linked_with",
- "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": "Reference",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-pushpin",
- "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,
- "default": "0",
- "fieldname": "is_your_company_address",
- "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 Your Company Address",
- "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:doc.is_your_company_address",
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 1,
- "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:!doc.is_your_company_address",
- "fieldname": "customer",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Customer",
- "length": 0,
- "no_copy": 0,
- "options": "Customer",
- "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": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.is_your_company_address",
- "fieldname": "customer_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Customer Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "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,
- "depends_on": "eval:!doc.is_your_company_address",
- "fieldname": "supplier",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Supplier",
- "length": 0,
- "no_copy": 0,
- "options": "Supplier",
- "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": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.is_your_company_address",
- "fieldname": "supplier_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Supplier Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "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,
- "depends_on": "eval: !doc.is_your_company_address",
- "fieldname": "sales_partner",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sales Partner",
- "length": 0,
- "no_copy": 0,
- "options": "Sales Partner",
- "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,
- "depends_on": "eval:!doc.supplier && !doc.sales_partner && !doc.is_your_company_address",
- "fieldname": "lead",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Lead",
- "length": 0,
- "no_copy": 0,
- "options": "Lead",
- "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,
- "depends_on": "eval:!doc.supplier && !doc.sales_partner && !doc.is_your_company_address",
- "fieldname": "lead_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": "Lead Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "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,
- "icon": "fa fa-map-marker",
- "idx": 5,
- "image_view": 0,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2016-11-07 05:47:06.911933",
- "modified_by": "Administrator",
- "module": "Utilities",
- "name": "Address",
- "owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Sales User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Purchase User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Maintenance User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- }
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "customer, supplier, sales_partner, country, state",
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/address/address.py b/erpnext/utilities/doctype/address/address.py
deleted file mode 100644
index 2952531..0000000
--- a/erpnext/utilities/doctype/address/address.py
+++ /dev/null
@@ -1,181 +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 import throw, _
-from frappe.utils import cstr
-
-from frappe.model.document import Document
-from jinja2 import TemplateSyntaxError
-from frappe.utils.user import is_website_user
-from frappe.model.naming import make_autoname
-
-class Address(Document):
- def __setup__(self):
- self.flags.linked = False
-
- def autoname(self):
- if not self.address_title:
- self.address_title = self.customer \
- or self.supplier or self.sales_partner or self.lead
-
- if self.address_title:
- self.name = (cstr(self.address_title).strip() + "-" + cstr(self.address_type).strip())
- if frappe.db.exists("Address", self.name):
- self.name = make_autoname(cstr(self.address_title).strip() + "-" +
- cstr(self.address_type).strip() + "-.#")
- else:
- throw(_("Address Title is mandatory."))
-
- def validate(self):
- self.link_fields = ("customer", "supplier", "sales_partner", "lead")
- self.link_address()
- self.validate_primary_address()
- self.validate_shipping_address()
- self.validate_reference()
-
- def validate_primary_address(self):
- """Validate that there can only be one primary address for particular customer, supplier"""
- if self.is_primary_address == 1:
- self._unset_other("is_primary_address")
-
- elif self.is_shipping_address != 1:
- for fieldname in self.link_fields:
- if self.get(fieldname):
- if not frappe.db.sql("""select name from `tabAddress` where is_primary_address=1
- and `%s`=%s and name!=%s""" % (frappe.db.escape(fieldname), "%s", "%s"),
- (self.get(fieldname), self.name)):
- self.is_primary_address = 1
- break
-
- def link_address(self):
- """Link address based on owner"""
- if not self.flags.linked:
- self.check_if_linked()
-
- if not self.flags.linked and not self.is_your_company_address:
- contact = frappe.db.get_value("Contact", {"email_id": self.owner},
- ("name", "customer", "supplier"), as_dict = True)
- if contact:
- self.customer = contact.customer
- self.supplier = contact.supplier
-
- self.lead = frappe.db.get_value("Lead", {"email_id": self.owner})
-
- def check_if_linked(self):
- for fieldname in self.link_fields:
- if self.get(fieldname):
- self.flags.linked = True
- break
-
- def validate_shipping_address(self):
- """Validate that there can only be one shipping address for particular customer, supplier"""
- if self.is_shipping_address == 1:
- self._unset_other("is_shipping_address")
-
- def validate_reference(self):
- if self.is_your_company_address:
- if not self.company:
- frappe.throw(_("Company is mandatory, as it is your company address"))
- if self.customer or self.supplier or self.sales_partner or self.lead:
- frappe.throw(_("Remove reference of customer, supplier, sales partner and lead, as it is your company address"))
-
- def _unset_other(self, is_address_type):
- for fieldname in ["customer", "supplier", "sales_partner", "lead"]:
- if self.get(fieldname):
- frappe.db.sql("""update `tabAddress` set `%s`=0 where `%s`=%s and name!=%s""" %
- (is_address_type, fieldname, "%s", "%s"), (self.get(fieldname), self.name))
- break
-
- def get_display(self):
- return get_address_display(self.as_dict())
-
-@frappe.whitelist()
-def get_address_display(address_dict):
- if not address_dict:
- return
-
- if not isinstance(address_dict, dict):
- address_dict = frappe.db.get_value("Address", address_dict, "*", as_dict=True) or {}
-
- name, template = get_address_templates(address_dict)
-
- try:
- return frappe.render_template(template, address_dict)
- except TemplateSyntaxError:
- frappe.throw(_("There is an error in your Address Template {0}").format(name))
-
-
-def get_territory_from_address(address):
- """Tries to match city, state and country of address to existing territory"""
- if not address:
- return
-
- if isinstance(address, basestring):
- address = frappe.get_doc("Address", address)
-
- territory = None
- for fieldname in ("city", "state", "country"):
- territory = frappe.db.get_value("Territory", address.get(fieldname))
- if territory:
- break
-
- return territory
-
-def get_list_context(context=None):
- from erpnext.shopping_cart.cart import get_address_docs
- return {
- "title": _("Addresses"),
- "get_list": get_address_list,
- "row_template": "templates/includes/address_row.html",
- 'no_breadcrumbs': True,
- }
-
-def get_address_list(doctype, txt, filters, limit_start, limit_page_length=20):
- from frappe.www.list import get_list
- user = frappe.session.user
- ignore_permissions = False
- if is_website_user():
- if not filters: filters = []
- filters.append(("Address", "owner", "=", user))
- ignore_permissions = True
-
- return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=ignore_permissions)
-
-def has_website_permission(doc, ptype, user, verbose=False):
- """Returns true if customer or lead matches with user"""
- customer = frappe.db.get_value("Contact", {"email_id": frappe.session.user}, "customer")
- if customer:
- return doc.customer == customer
- else:
- lead = frappe.db.get_value("Lead", {"email_id": frappe.session.user})
- if lead:
- return doc.lead == lead
-
- return False
-
-def get_address_templates(address):
- result = frappe.db.get_value("Address Template", \
- {"country": address.get("country")}, ["name", "template"])
-
- if not result:
- result = frappe.db.get_value("Address Template", \
- {"is_default": 1}, ["name", "template"])
-
- if not result:
- frappe.throw(_("No default Address Template found. Please create a new one from Setup > Printing and Branding > Address Template."))
- else:
- return result
-
-@frappe.whitelist()
-def get_shipping_address(company):
- filters = {"company": company, "is_your_company_address":1}
- fieldname = ["name", "address_line1", "address_line2", "city", "state", "country"]
-
- address_as_dict = frappe.db.get_value("Address", filters=filters, fieldname=fieldname, as_dict=True)
-
- if address_as_dict:
- name, address_template = get_address_templates(address_as_dict)
- return address_as_dict.get("name"), frappe.render_template(address_template, address_as_dict)
diff --git a/erpnext/utilities/doctype/address/test_address.py b/erpnext/utilities/doctype/address/test_address.py
deleted file mode 100644
index 36f2535..0000000
--- a/erpnext/utilities/doctype/address/test_address.py
+++ /dev/null
@@ -1,21 +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
-test_records = frappe.get_test_records('Address')
-
-import unittest
-import frappe
-
-from erpnext.utilities.doctype.address.address import get_address_display
-
-class TestAddress(unittest.TestCase):
- def test_template_works(self):
- address = frappe.get_list("Address")[0].name
- display = get_address_display(frappe.get_doc("Address", address).as_dict())
- self.assertTrue(display)
-
-
-test_dependencies = ["Address Template"]
diff --git a/erpnext/utilities/doctype/address/test_records.json b/erpnext/utilities/doctype/address/test_records.json
deleted file mode 100644
index a7bde9a..0000000
--- a/erpnext/utilities/doctype/address/test_records.json
+++ /dev/null
@@ -1,15 +0,0 @@
-[
- {
- "address_line1": "_Test Address Line 1",
- "address_title": "_Test Address",
- "address_type": "Office",
- "city": "_Test City",
- "state": "Test State",
- "country": "India",
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "doctype": "Address",
- "is_primary_address": 1,
- "phone": "+91 0000000000"
- }
-]
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/address_template/__init__.py b/erpnext/utilities/doctype/address_template/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/utilities/doctype/address_template/__init__.py
+++ /dev/null
diff --git a/erpnext/utilities/doctype/address_template/address_template.js b/erpnext/utilities/doctype/address_template/address_template.js
deleted file mode 100644
index c055bca..0000000
--- a/erpnext/utilities/doctype/address_template/address_template.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Address Template', {
- refresh: function(frm) {
- if(frm.is_new() && !frm.doc.template) {
- // set default template via js so that it is translated
- frappe.call({
- method: 'erpnext.utilities.doctype.address_template.address_template.get_default_address_template',
- callback: function(r) {
- frm.set_value('template', r.message);
- }
- });
- }
- }
-});
diff --git a/erpnext/utilities/doctype/address_template/address_template.json b/erpnext/utilities/doctype/address_template/address_template.json
deleted file mode 100644
index 6ff93d9..0000000
--- a/erpnext/utilities/doctype/address_template/address_template.json
+++ /dev/null
@@ -1,147 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 1,
- "autoname": "field:country",
- "beta": 0,
- "creation": "2014-06-05 02:22:36.029850",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
- "engine": "InnoDB",
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "country",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Country",
- "length": 0,
- "no_copy": 0,
- "options": "Country",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "This format is used if country specific format is not found",
- "fieldname": "is_default",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Is Default",
- "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,
- "default": "",
- "description": "<h4>Default Template</h4>\n<p>Uses <a href=\"http://jinja.pocoo.org/docs/templates/\">Jinja Templating</a> and all the fields of Address (including Custom Fields if any) will be available</p>\n<pre><code>{{ address_line1 }}<br>\n{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}\n{{ city }}<br>\n{% if state %}{{ state }}<br>{% endif -%}\n{% if pincode %} PIN: {{ pincode }}<br>{% endif -%}\n{{ country }}<br>\n{% if phone %}Phone: {{ phone }}<br>{% endif -%}\n{% if fax %}Fax: {{ fax }}<br>{% endif -%}\n{% if email_id %}Email: {{ email_id }}<br>{% endif -%}\n</code></pre>",
- "fieldname": "template",
- "fieldtype": "Code",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Template",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- }
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-map-marker",
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2016-11-07 05:47:11.633848",
- "modified_by": "Administrator",
- "module": "Utilities",
- "name": "Address Template",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 0,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "set_user_permissions": 1,
- "share": 1,
- "submit": 0,
- "write": 1
- }
- ],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/address_template/address_template.py b/erpnext/utilities/doctype/address_template/address_template.py
deleted file mode 100644
index 64aaa45..0000000
--- a/erpnext/utilities/doctype/address_template/address_template.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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
-from frappe.utils.jinja import validate_template
-from frappe import _
-
-class AddressTemplate(Document):
- def validate(self):
- if not self.template:
- self.template = get_default_address_template()
-
- self.defaults = frappe.db.get_values("Address Template", {"is_default":1, "name":("!=", self.name)})
- if not self.is_default:
- if not self.defaults:
- self.is_default = 1
- frappe.msgprint(_("Setting this Address Template as default as there is no other default"))
-
- validate_template(self.template)
-
- def on_update(self):
- if self.is_default and self.defaults:
- for d in self.defaults:
- frappe.db.set_value("Address Template", d[0], "is_default", 0)
-
- def on_trash(self):
- if self.is_default:
- frappe.throw(_("Default Address Template cannot be deleted"))
-
-@frappe.whitelist()
-def get_default_address_template():
- '''Get default address template (translated)'''
- return '''{{ address_line1 }}<br>{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}\
-{{ city }}<br>
-{% if state %}{{ state }}<br>{% endif -%}
-{% if pincode %}{{ pincode }}<br>{% endif -%}
-{{ country }}<br>
-{% if phone %}'''+_('Phone')+''': {{ phone }}<br>{% endif -%}
-{% if fax %}'''+_('Fax')+''': {{ fax }}<br>{% endif -%}
-{% if email_id %}'''+_('Email')+''': {{ email_id }}<br>{% endif -%}'''
diff --git a/erpnext/utilities/doctype/address_template/test_address_template.py b/erpnext/utilities/doctype/address_template/test_address_template.py
deleted file mode 100644
index 9490005..0000000
--- a/erpnext/utilities/doctype/address_template/test_address_template.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: See license.txt
-
-from __future__ import unicode_literals
-
-import frappe
-test_records = frappe.get_test_records('Address Template')
-
-import unittest
-import frappe
-
-class TestAddressTemplate(unittest.TestCase):
- def test_default_is_unset(self):
- a = frappe.get_doc("Address Template", "India")
- a.is_default = 1
- a.save()
-
- b = frappe.get_doc("Address Template", "Brazil")
- b.is_default = 1
- b.save()
-
- self.assertEqual(frappe.db.get_value("Address Template", "India", "is_default"), 0)
-
- def tearDown(self):
- a = frappe.get_doc("Address Template", "India")
- a.is_default = 1
- a.save()
diff --git a/erpnext/utilities/doctype/address_template/test_records.json b/erpnext/utilities/doctype/address_template/test_records.json
deleted file mode 100644
index 412c9e7..0000000
--- a/erpnext/utilities/doctype/address_template/test_records.json
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- {
- "country": "India",
- "is_default": 1,
- "template": "{{ address_title }}<br>\n{{ address_line1 }}<br>\n{% if address_line2 %}{{ address_line2 }}<br>{% endif %}\n{{ city }}<br>\n{% if state %}{{ state }}<br>{% endif %}\n{% if pincode %} PIN / ZIP: {{ pincode }}<br>{% endif %}\n{{ country }}<br>\n{% if phone %}Phone: {{ phone }}<br>{% endif %}\n{% if fax %}Fax: {{ fax }}<br>{% endif %}\n{% if email_id %}Email: {{ email_id }}<br>{% endif %}\n"
- },
- {
- "country": "Brazil",
- "is_default": 0,
- "template": "{{ address_title }}<br>\n{{ address_line1 }}<br>\n{% if address_line2 %}{{ address_line2 }}<br>{% endif %}\n{{ city }}<br>\n{% if state %}{{ state }}<br>{% endif %}\n{% if pincode %} PIN / ZIP: {{ pincode }}<br>{% endif %}\n{{ country }}<br>\n{% if phone %}Phone: {{ phone }}<br>{% endif %}\n{% if fax %}Fax: {{ fax }}<br>{% endif %}\n{% if email_id %}Email: {{ email_id }}<br>{% endif %}\n"
- }
-]
-
diff --git a/erpnext/utilities/doctype/contact/README.md b/erpnext/utilities/doctype/contact/README.md
deleted file mode 100644
index 484522c..0000000
--- a/erpnext/utilities/doctype/contact/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Contact representing a Customer or Supplier.
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/contact/__init__.py b/erpnext/utilities/doctype/contact/__init__.py
deleted file mode 100644
index baffc48..0000000
--- a/erpnext/utilities/doctype/contact/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from __future__ import unicode_literals
diff --git a/erpnext/utilities/doctype/contact/contact.js b/erpnext/utilities/doctype/contact/contact.js
deleted file mode 100644
index 07d9d6f..0000000
--- a/erpnext/utilities/doctype/contact/contact.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-{% include 'erpnext/controllers/js/contact_address_common.js' %};
-
-cur_frm.email_field = "email_id";
-frappe.ui.form.on("Contact", {
- refresh: function(frm) {
- if(!frm.doc.user && !frm.is_new() && frm.perm[0].write) {
- frm.add_custom_button(__("Invite as User"), function() {
- frappe.call({
- method: "erpnext.utilities.doctype.contact.contact.invite_user",
- args: {
- contact: frm.doc.name
- },
- callback: function(r) {
- frm.set_value("user", r.message);
- }
- });
- });
- }
- },
- validate: function(frm) {
- // clear linked customer / supplier / sales partner on saving...
- $.each(["Customer", "Supplier", "Sales Partner"], function(i, doctype) {
- var name = frm.doc[doctype.toLowerCase().replace(/ /g, "_")];
- if(name && locals[doctype] && locals[doctype][name])
- frappe.model.remove_from_locals(doctype, name);
- });
- }
-});
diff --git a/erpnext/utilities/doctype/contact/contact.json b/erpnext/utilities/doctype/contact/contact.json
deleted file mode 100644
index 98061da..0000000
--- a/erpnext/utilities/doctype/contact/contact.json
+++ /dev/null
@@ -1,921 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "beta": 0,
- "creation": "2013-01-10 16:34:32",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
- "engine": "InnoDB",
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "contact_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": "",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-user",
- "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": "first_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": "First Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "first_name",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "last_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": "Last Name",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "last_name",
- "oldfieldtype": "Data",
- "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": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "email_id",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Email Address",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "email_id",
- "oldfieldtype": "Data",
- "options": "Email",
- "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": 1,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cb00",
- "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,
- "default": "Passive",
- "fieldname": "status",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Status",
- "length": 0,
- "no_copy": 0,
- "options": "Passive\nOpen\nReplied",
- "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": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "phone",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Phone",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "contact_no",
- "oldfieldtype": "Data",
- "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": "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": 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,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "contact_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": "Reference",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-pushpin",
- "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": "user",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "User Id",
- "length": 0,
- "no_copy": 0,
- "options": "User",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "customer",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Customer",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "customer",
- "oldfieldtype": "Link",
- "options": "Customer",
- "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": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "customer_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": "Customer Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "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_break1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0,
- "width": "50%"
- },
- {
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "supplier",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Supplier",
- "length": 0,
- "no_copy": 0,
- "options": "Supplier",
- "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": 1,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "",
- "fieldname": "supplier_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": "Supplier Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "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,
- "depends_on": "",
- "fieldname": "sales_partner",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sales Partner",
- "length": 0,
- "no_copy": 0,
- "options": "Sales Partner",
- "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,
- "default": "0",
- "depends_on": "eval:(doc.customer || doc.supplier || doc.sales_partner)",
- "fieldname": "is_primary_contact",
- "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 Primary Contact",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "is_primary_contact",
- "oldfieldtype": "Select",
- "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": "more_info",
- "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 Information",
- "length": 0,
- "no_copy": 0,
- "options": "fa fa-file-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,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "mobile_no",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Mobile No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "mobile_no",
- "oldfieldtype": "Data",
- "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,
- "description": "Enter department to which this Contact belongs",
- "fieldname": "department",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Department",
- "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,
- "description": "Enter designation of this Contact",
- "fieldname": "designation",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Designation",
- "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": "unsubscribed",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Unsubscribed",
- "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
- }
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "fa fa-user",
- "idx": 1,
- "image_field": "image",
- "image_view": 0,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "modified": "2016-11-07 05:30:56.576752",
- "modified_by": "Administrator",
- "module": "Utilities",
- "name": "Contact",
- "owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 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": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Sales Master 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": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Purchase Master Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Sales Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Purchase Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Maintenance Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Sales User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Purchase User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Maintenance User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- },
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 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": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "is_custom": 0,
- "match": "",
- "permlevel": 1,
- "print": 0,
- "read": 1,
- "report": 1,
- "role": "All",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
- "write": 0
- }
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "sort_order": "ASC",
- "track_seen": 0
-}
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/contact/contact.py b/erpnext/utilities/doctype/contact/contact.py
deleted file mode 100644
index be0f985..0000000
--- a/erpnext/utilities/doctype/contact/contact.py
+++ /dev/null
@@ -1,107 +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 cstr, has_gravatar
-from frappe import _
-
-from erpnext.controllers.status_updater import StatusUpdater
-
-class Contact(StatusUpdater):
- def autoname(self):
- # concat first and last name
- self.name = " ".join(filter(None,
- [cstr(self.get(f)).strip() for f in ["first_name", "last_name"]]))
-
- # concat party name if reqd
- for fieldname in ("customer", "supplier", "sales_partner"):
- if self.get(fieldname):
- self.name = self.name + "-" + cstr(self.get(fieldname)).strip()
- break
-
- def validate(self):
- self.set_status()
- self.validate_primary_contact()
- self.set_user()
- if self.email_id:
- self.image = has_gravatar(self.email_id)
-
- def set_user(self):
- if not self.user and self.email_id:
- self.user = frappe.db.get_value("User", {"email": self.email_id})
-
- def validate_primary_contact(self):
- if self.is_primary_contact == 1:
- if self.customer:
- frappe.db.sql("update tabContact set is_primary_contact=0 where customer = %s",
- (self.customer))
- elif self.supplier:
- frappe.db.sql("update tabContact set is_primary_contact=0 where supplier = %s",
- (self.supplier))
- elif self.sales_partner:
- frappe.db.sql("""update tabContact set is_primary_contact=0
- where sales_partner = %s""", (self.sales_partner))
- else:
- if self.customer:
- if not frappe.db.sql("select name from tabContact \
- where is_primary_contact=1 and customer = %s", (self.customer)):
- self.is_primary_contact = 1
- elif self.supplier:
- if not frappe.db.sql("select name from tabContact \
- where is_primary_contact=1 and supplier = %s", (self.supplier)):
- self.is_primary_contact = 1
- elif self.sales_partner:
- if not frappe.db.sql("select name from tabContact \
- where is_primary_contact=1 and sales_partner = %s",
- self.sales_partner):
- self.is_primary_contact = 1
-
- def on_trash(self):
- frappe.db.sql("""update `tabIssue` set contact='' where contact=%s""",
- self.name)
-
-@frappe.whitelist()
-def invite_user(contact):
- contact = frappe.get_doc("Contact", contact)
-
- if not contact.email_id:
- frappe.throw(_("Please set Email Address"))
-
- if contact.has_permission("write"):
- user = frappe.get_doc({
- "doctype": "User",
- "first_name": contact.first_name,
- "last_name": contact.last_name,
- "email": contact.email_id,
- "user_type": "Website User",
- "send_welcome_email": 1
- }).insert(ignore_permissions = True)
-
- return user.name
-
-@frappe.whitelist()
-def get_contact_details(contact):
- contact = frappe.get_doc("Contact", contact)
- out = {
- "contact_person": contact.get("name"),
- "contact_display": " ".join(filter(None,
- [contact.get("first_name"), contact.get("last_name")])),
- "contact_email": contact.get("email_id"),
- "contact_mobile": contact.get("mobile_no"),
- "contact_phone": contact.get("phone"),
- "contact_designation": contact.get("designation"),
- "contact_department": contact.get("department")
- }
- return out
-
-def update_contact(doc, method):
- '''Update contact when user is updated, if contact is found. Called via hooks'''
- contact_name = frappe.db.get_value("Contact", {"email_id": doc.name})
- if contact_name:
- contact = frappe.get_doc("Contact", contact_name)
- for key in ("first_name", "last_name", "phone"):
- if doc.get(key):
- contact.set(key, doc.get(key))
- contact.flags.ignore_mandatory = True
- contact.save(ignore_permissions=True)
diff --git a/erpnext/utilities/doctype/contact/test_contact.py b/erpnext/utilities/doctype/contact/test_contact.py
deleted file mode 100644
index 964c8d7..0000000
--- a/erpnext/utilities/doctype/contact/test_contact.py
+++ /dev/null
@@ -1,7 +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
-test_records = frappe.get_test_records('Contact')
\ No newline at end of file
diff --git a/erpnext/utilities/doctype/contact/test_records.json b/erpnext/utilities/doctype/contact/test_records.json
deleted file mode 100644
index 133a7b6..0000000
--- a/erpnext/utilities/doctype/contact/test_records.json
+++ /dev/null
@@ -1,22 +0,0 @@
-[
- {
- "customer": "_Test Customer",
- "customer_name": "_Test Customer",
- "doctype": "Contact",
- "email_id": "test_contact_customer@example.com",
- "first_name": "_Test Contact For _Test Customer",
- "is_primary_contact": 1,
- "phone": "+91 0000000000",
- "status": "Open"
- },
- {
- "doctype": "Contact",
- "email_id": "test_contact_supplier@example.com",
- "first_name": "_Test Contact For _Test Supplier",
- "is_primary_contact": 1,
- "phone": "+91 0000000000",
- "status": "Open",
- "supplier": "_Test Supplier",
- "supplier_name": "_Test Supplier"
- }
-]
\ No newline at end of file