Merge branch 'develop' into feat-request-for-quotation
This commit is contained in:
commit
458f2fcd62
7
.github/helper/install.sh
vendored
7
.github/helper/install.sh
vendored
@ -2,6 +2,13 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Check for merge conflicts before proceeding
|
||||
python -m compileall -f "${GITHUB_WORKSPACE}"
|
||||
if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
|
||||
then echo "Found merge conflicts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ~ || exit
|
||||
|
||||
sudo apt-get install redis-server libcups2-dev
|
||||
|
2
.github/try-on-f-cloud-button.svg
vendored
2
.github/try-on-f-cloud-button.svg
vendored
@ -1,4 +1,4 @@
|
||||
<svg width="201" height="60" viewBox="0 0 201 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="4 2 193 52">
|
||||
<g filter="url(#filter0_dd)">
|
||||
<rect x="4" y="2" width="193" height="52" rx="6" fill="#2490EF"/>
|
||||
<path d="M28 22.2891H32.8786V35.5H36.2088V22.2891H41.0874V19.5H28V22.2891Z" fill="white"/>
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.3 KiB |
71
README.md
71
README.md
@ -1,5 +1,7 @@
|
||||
<div align="center">
|
||||
<img src="https://raw.githubusercontent.com/frappe/erpnext/develop/erpnext/public/images/erpnext-logo.png" height="128">
|
||||
<a href="https://erpnext.com">
|
||||
<img src="https://raw.githubusercontent.com/frappe/erpnext/develop/erpnext/public/images/erpnext-logo.png" height="128">
|
||||
</a>
|
||||
<h2>ERPNext</h2>
|
||||
<p align="center">
|
||||
<p>ERP made simple</p>
|
||||
@ -32,17 +34,12 @@ ERPNext as a monolith includes the following areas for managing businesses:
|
||||
1. [Customize ERPNext](https://erpnext.com/docs/user/manual/en/customize-erpnext)
|
||||
1. [And More](https://erpnext.com/docs/user/manual/en/)
|
||||
|
||||
ERPNext requires MariaDB.
|
||||
|
||||
ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a full-stack web app framework built with Python & JavaScript.
|
||||
|
||||
- [User Guide](https://erpnext.com/docs/user)
|
||||
- [Discussion Forum](https://discuss.erpnext.com/)
|
||||
|
||||
---
|
||||
## Installation
|
||||
|
||||
<div align="center" style="max-height: 40px;">
|
||||
<a href="https://frappecloud.com/deploy?apps=frappe,erpnext&source=erpnext_readme">
|
||||
<a href="https://frappecloud.com/erpnext/signup">
|
||||
<img src=".github/try-on-f-cloud-button.svg" height="40">
|
||||
</a>
|
||||
<a href="https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/frappe/frappe_docker/main/pwd.yml">
|
||||
@ -56,21 +53,20 @@ ERPNext is built on the [Frappe Framework](https://github.com/frappe/frappe), a
|
||||
|
||||
Use docker to deploy ERPNext in production or for development of [Frappe](https://github.com/frappe/frappe) apps. See https://github.com/frappe/frappe_docker for more details.
|
||||
|
||||
### Full Install
|
||||
### Manual Install
|
||||
|
||||
The Easy Way: our install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench for more details.
|
||||
|
||||
New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt).
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
## Learning and community
|
||||
|
||||
GNU/General Public License (see [license.txt](license.txt))
|
||||
1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community.
|
||||
2. [Official documentation](https://docs.erpnext.com/) - Extensive documentation for ERPNext.
|
||||
3. [Discussion Forum](https://discuss.erpnext.com/) - Engage with community of ERPNext users and service providers.
|
||||
4. [Telegram Group](https://t.me/erpnexthelp) - Get instant help from huge community of users.
|
||||
|
||||
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
@ -78,49 +74,14 @@ The ERPNext code is licensed as GNU General Public License (v3) and the Document
|
||||
1. [Report Security Vulnerabilities](https://erpnext.com/security)
|
||||
1. [Pull Request Requirements](https://github.com/frappe/erpnext/wiki/Contribution-Guidelines)
|
||||
1. [Translations](https://translate.erpnext.com)
|
||||
1. [Chart of Accounts](https://charts.erpnext.com)
|
||||
|
||||
---
|
||||
|
||||
## Learning
|
||||
## License
|
||||
|
||||
1. [Frappe School](https://frappe.school) - Learn Frappe Framework and ERPNext from the various courses by the maintainers or from the community.
|
||||
GNU/General Public License (see [license.txt](license.txt))
|
||||
|
||||
---
|
||||
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
|
||||
|
||||
## Logo and Trademark
|
||||
## Logo and Trademark Policy
|
||||
|
||||
The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd.
|
||||
|
||||
### Introduction
|
||||
|
||||
Frappe Technologies Pvt. Ltd. (Frappe) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
|
||||
|
||||
- We’d like to make it easy for anyone to use the ERPNext name or logo for community-oriented efforts that help spread and improve ERPNext.
|
||||
- We’d like to make it clear how ERPNext-related businesses and projects can (and cannot) use the ERPNext name and logo.
|
||||
- We’d like to make it hard for anyone to use the ERPNext name and logo to unfairly profit from, trick or confuse people who are looking for official ERPNext resources.
|
||||
|
||||
### Frappe Trademark Usage Policy
|
||||
|
||||
Permission from Frappe is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
|
||||
|
||||
We will grant permission to use the ERPNext name and logo for projects that meet the following criteria:
|
||||
|
||||
- The primary purpose of your project is to promote the spread and improvement of the ERPNext software.
|
||||
- Your project is non-commercial in nature (it can make money to cover its costs or contribute to non-profit entities, but it cannot be run as a for-profit project or business).
|
||||
Your project neither promotes nor is associated with entities that currently fail to comply with the GPL license under which ERPNext is distributed.
|
||||
- If your project meets these criteria, you will be permitted to use the ERPNext name and logo to promote your project in any way you see fit with one exception: Please do not use ERPNext as part of a domain name.
|
||||
|
||||
Use of the ERPNext name and logo is additionally allowed in the following situations:
|
||||
|
||||
All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappe Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
|
||||
|
||||
Similarly, it’s OK to use the ERPNext logo as part of a page that describes your products or services, but it is not OK to use it as part of your company or product logo or branding itself. Under no circumstances is it permitted to use ERPNext as part of a top-level domain name.
|
||||
|
||||
We do not allow the use of the trademark in advertising, including AdSense/AdWords.
|
||||
|
||||
Please note that it is not the goal of this policy to limit commercial activity around ERPNext. We encourage ERPNext-based businesses, and we would love to see hundreds of them.
|
||||
|
||||
When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification.
|
||||
|
||||
(inspired by WordPress)
|
||||
Please read our [Logo and Trademark Policy](TRADEMARK_POLICY.md).
|
||||
|
36
TRADEMARK_POLICY.md
Normal file
36
TRADEMARK_POLICY.md
Normal file
@ -0,0 +1,36 @@
|
||||
## Logo and Trademark Policy
|
||||
|
||||
The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd.
|
||||
|
||||
### Introduction
|
||||
|
||||
Frappe Technologies Pvt. Ltd. (Frappe) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
|
||||
|
||||
- We’d like to make it easy for anyone to use the ERPNext name or logo for community-oriented efforts that help spread and improve ERPNext.
|
||||
- We’d like to make it clear how ERPNext-related businesses and projects can (and cannot) use the ERPNext name and logo.
|
||||
- We’d like to make it hard for anyone to use the ERPNext name and logo to unfairly profit from, trick or confuse people who are looking for official ERPNext resources.
|
||||
|
||||
### Frappe Trademark Usage Policy
|
||||
|
||||
Permission from Frappe is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
|
||||
|
||||
We will grant permission to use the ERPNext name and logo for projects that meet the following criteria:
|
||||
|
||||
- The primary purpose of your project is to promote the spread and improvement of the ERPNext software.
|
||||
- Your project is non-commercial in nature (it can make money to cover its costs or contribute to non-profit entities, but it cannot be run as a for-profit project or business).
|
||||
Your project neither promotes nor is associated with entities that currently fail to comply with the GPL license under which ERPNext is distributed.
|
||||
- If your project meets these criteria, you will be permitted to use the ERPNext name and logo to promote your project in any way you see fit with one exception: Please do not use ERPNext as part of a domain name.
|
||||
|
||||
Use of the ERPNext name and logo is additionally allowed in the following situations:
|
||||
|
||||
All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappe Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
|
||||
|
||||
Similarly, it’s OK to use the ERPNext logo as part of a page that describes your products or services, but it is not OK to use it as part of your company or product logo or branding itself. Under no circumstances is it permitted to use ERPNext as part of a top-level domain name.
|
||||
|
||||
We do not allow the use of the trademark in advertising, including AdSense/AdWords.
|
||||
|
||||
Please note that it is not the goal of this policy to limit commercial activity around ERPNext. We encourage ERPNext-based businesses, and we would love to see hundreds of them.
|
||||
|
||||
When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification.
|
||||
|
||||
(inspired by WordPress)
|
@ -539,19 +539,11 @@ def make_gl_entries(
|
||||
frappe.db.commit()
|
||||
except Exception as e:
|
||||
if frappe.flags.in_test:
|
||||
traceback = frappe.get_traceback()
|
||||
frappe.log_error(
|
||||
title=_("Error while processing deferred accounting for Invoice {0}").format(doc.name),
|
||||
message=traceback,
|
||||
)
|
||||
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
||||
raise e
|
||||
else:
|
||||
frappe.db.rollback()
|
||||
traceback = frappe.get_traceback()
|
||||
frappe.log_error(
|
||||
title=_("Error while processing deferred accounting for Invoice {0}").format(doc.name),
|
||||
message=traceback,
|
||||
)
|
||||
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
||||
frappe.flags.deferred_accounting_error = True
|
||||
|
||||
|
||||
@ -632,12 +624,7 @@ def book_revenue_via_journal_entry(
|
||||
frappe.db.commit()
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
traceback = frappe.get_traceback()
|
||||
frappe.log_error(
|
||||
title=_("Error while processing deferred accounting for Invoice {0}").format(doc.name),
|
||||
message=traceback,
|
||||
)
|
||||
|
||||
doc.log_error(f"Error while processing deferred accounting for Invoice {doc.name}")
|
||||
frappe.flags.deferred_accounting_error = True
|
||||
|
||||
|
||||
|
@ -118,6 +118,7 @@ class BankClearance(Document):
|
||||
)
|
||||
.where(loan_repayment.docstatus == 1)
|
||||
.where(loan_repayment.clearance_date.isnull())
|
||||
.where(loan_repayment.repay_from_salary == 0)
|
||||
.where(loan_repayment.posting_date >= self.from_date)
|
||||
.where(loan_repayment.posting_date <= self.to_date)
|
||||
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
|
||||
|
@ -467,6 +467,7 @@ def get_lr_matching_query(bank_account, amount_condition, filters):
|
||||
loan_repayment.posting_date,
|
||||
)
|
||||
.where(loan_repayment.docstatus == 1)
|
||||
.where(loan_repayment.repay_from_salary == 0)
|
||||
.where(loan_repayment.clearance_date.isnull())
|
||||
.where(loan_repayment.payment_account == bank_account)
|
||||
)
|
||||
|
@ -136,7 +136,7 @@ def start_import(
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
data_import.db_set("status", "Error")
|
||||
frappe.log_error(title=data_import.name)
|
||||
data_import.log_error("Bank Statement Import failed")
|
||||
finally:
|
||||
frappe.flags.in_import = False
|
||||
|
||||
|
@ -56,7 +56,7 @@ def create_bank_entries(columns, data, bank_account):
|
||||
bank_transaction.submit()
|
||||
success += 1
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
bank_transaction.log_error("Bank entry creation failed")
|
||||
errors += 1
|
||||
|
||||
return {"success": success, "errors": errors}
|
||||
|
@ -62,7 +62,7 @@ def start_merge(docname):
|
||||
)
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error(title=ledger_merge.name)
|
||||
ledger_merge.log_error("Ledger merge failed")
|
||||
finally:
|
||||
if successful_merges == total:
|
||||
ledger_merge.db_set("status", "Success")
|
||||
|
@ -2,9 +2,6 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import traceback
|
||||
from json import dumps
|
||||
|
||||
import frappe
|
||||
from frappe import _, scrub
|
||||
from frappe.model.document import Document
|
||||
@ -114,10 +111,13 @@ class OpeningInvoiceCreationTool(Document):
|
||||
)
|
||||
or {}
|
||||
)
|
||||
|
||||
default_currency = frappe.db.get_value(row.party_type, row.party, "default_currency")
|
||||
|
||||
if company_details:
|
||||
invoice.update(
|
||||
{
|
||||
"currency": company_details.get("default_currency"),
|
||||
"currency": default_currency or company_details.get("default_currency"),
|
||||
"letter_head": company_details.get("default_letter_head"),
|
||||
}
|
||||
)
|
||||
@ -244,11 +244,7 @@ def start_import(invoices):
|
||||
except Exception:
|
||||
errors += 1
|
||||
frappe.db.rollback()
|
||||
message = "\n".join(
|
||||
["Data:", dumps(d, default=str, indent=4), "--" * 50, "\nException:", traceback.format_exc()]
|
||||
)
|
||||
frappe.log_error(title="Error while creating Opening Invoice", message=message)
|
||||
frappe.db.commit()
|
||||
doc.log_error("Opening invoice creation failed")
|
||||
if errors:
|
||||
frappe.msgprint(
|
||||
_("You had {} errors while creating opening invoices. Check {} for more details").format(
|
||||
|
@ -112,8 +112,6 @@ frappe.ui.form.on('Payment Entry', {
|
||||
var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"];
|
||||
} else if (frm.doc.party_type == "Employee") {
|
||||
var doctypes = ["Expense Claim", "Journal Entry"];
|
||||
} else if (frm.doc.party_type == "Student") {
|
||||
var doctypes = ["Fees"];
|
||||
} else {
|
||||
var doctypes = ["Journal Entry"];
|
||||
}
|
||||
@ -755,8 +753,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if(
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")
|
||||
) {
|
||||
if(total_positive_outstanding > total_negative_outstanding)
|
||||
if (!frm.doc.paid_amount)
|
||||
@ -798,8 +795,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if (
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")
|
||||
) {
|
||||
if(total_positive_outstanding_including_order > paid_amount) {
|
||||
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
|
||||
|
@ -183,9 +183,7 @@ class PaymentEntry(AccountsController):
|
||||
if not self.party:
|
||||
frappe.throw(_("Party is mandatory"))
|
||||
|
||||
_party_name = (
|
||||
"title" if self.party_type in ("Student", "Shareholder") else self.party_type.lower() + "_name"
|
||||
)
|
||||
_party_name = "title" if self.party_type == "Shareholder" else self.party_type.lower() + "_name"
|
||||
self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name)
|
||||
|
||||
if self.party:
|
||||
@ -298,9 +296,7 @@ class PaymentEntry(AccountsController):
|
||||
frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field)))
|
||||
|
||||
def validate_reference_documents(self):
|
||||
if self.party_type == "Student":
|
||||
valid_reference_doctypes = "Fees"
|
||||
elif self.party_type == "Customer":
|
||||
if self.party_type == "Customer":
|
||||
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry", "Dunning")
|
||||
elif self.party_type == "Supplier":
|
||||
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
|
||||
@ -338,8 +334,6 @@ class PaymentEntry(AccountsController):
|
||||
ref_party_account = (
|
||||
get_party_account_based_on_invoice_discounting(d.reference_name) or ref_doc.debit_to
|
||||
)
|
||||
elif self.party_type == "Student":
|
||||
ref_party_account = ref_doc.receivable_account
|
||||
elif self.party_type == "Supplier":
|
||||
ref_party_account = ref_doc.credit_to
|
||||
elif self.party_type == "Employee":
|
||||
@ -1259,20 +1253,19 @@ def get_outstanding_reference_documents(args):
|
||||
|
||||
# Get all SO / PO which are not fully billed or against which full advance not paid
|
||||
orders_to_be_billed = []
|
||||
if args.get("party_type") != "Student":
|
||||
orders_to_be_billed = get_orders_to_be_billed(
|
||||
args.get("posting_date"),
|
||||
args.get("party_type"),
|
||||
args.get("party"),
|
||||
args.get("company"),
|
||||
party_account_currency,
|
||||
company_currency,
|
||||
filters=args,
|
||||
)
|
||||
orders_to_be_billed = get_orders_to_be_billed(
|
||||
args.get("posting_date"),
|
||||
args.get("party_type"),
|
||||
args.get("party"),
|
||||
args.get("company"),
|
||||
party_account_currency,
|
||||
company_currency,
|
||||
filters=args,
|
||||
)
|
||||
|
||||
# Get negative outstanding sales /purchase invoices
|
||||
negative_outstanding_invoices = []
|
||||
if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
|
||||
if args.get("party_type") != "Employee" and not args.get("voucher_no"):
|
||||
negative_outstanding_invoices = get_negative_outstanding_invoices(
|
||||
args.get("party_type"),
|
||||
args.get("party"),
|
||||
@ -1496,9 +1489,7 @@ def get_party_details(company, party_type, party, date, cost_center=None):
|
||||
|
||||
account_currency = get_account_currency(party_account)
|
||||
account_balance = get_balance_on(party_account, date, cost_center=cost_center)
|
||||
_party_name = (
|
||||
"title" if party_type in ("Student", "Shareholder") else party_type.lower() + "_name"
|
||||
)
|
||||
_party_name = "title" if party_type == "Shareholder" else party_type.lower() + "_name"
|
||||
party_name = frappe.db.get_value(party_type, party, _party_name)
|
||||
party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center)
|
||||
if party_type in ["Customer", "Supplier"]:
|
||||
@ -1560,7 +1551,7 @@ def get_company_defaults(company):
|
||||
def get_outstanding_on_journal_entry(name):
|
||||
res = frappe.db.sql(
|
||||
"SELECT "
|
||||
'CASE WHEN party_type IN ("Customer", "Student") '
|
||||
'CASE WHEN party_type IN ("Customer") '
|
||||
"THEN ifnull(sum(debit_in_account_currency - credit_in_account_currency), 0) "
|
||||
"ELSE ifnull(sum(credit_in_account_currency - debit_in_account_currency), 0) "
|
||||
"END as outstanding_amount "
|
||||
@ -1917,8 +1908,6 @@ def set_party_type(dt):
|
||||
party_type = "Supplier"
|
||||
elif dt in ("Expense Claim", "Employee Advance", "Gratuity"):
|
||||
party_type = "Employee"
|
||||
elif dt == "Fees":
|
||||
party_type = "Student"
|
||||
return party_type
|
||||
|
||||
|
||||
|
@ -38,6 +38,15 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
this.frm.set_query("cost_center", () => {
|
||||
return {
|
||||
"filters": {
|
||||
"company": this.frm.doc.company,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
refresh() {
|
||||
|
@ -24,6 +24,7 @@
|
||||
"invoice_limit",
|
||||
"payment_limit",
|
||||
"bank_cash_account",
|
||||
"cost_center",
|
||||
"sec_break1",
|
||||
"invoices",
|
||||
"column_break_15",
|
||||
@ -178,13 +179,19 @@
|
||||
{
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"options": "Cost Center"
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"icon": "icon-resize-horizontal",
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2021-10-04 20:27:11.114194",
|
||||
"modified": "2022-04-29 15:37:10.246831",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Reconciliation",
|
||||
@ -209,5 +216,6 @@
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"track_changes": 1
|
||||
}
|
@ -332,6 +332,9 @@ class PaymentReconciliation(Document):
|
||||
def get_conditions(self, get_invoices=False, get_payments=False, get_return_invoices=False):
|
||||
condition = " and company = '{0}' ".format(self.company)
|
||||
|
||||
if self.get("cost_center") and (get_invoices or get_payments or get_return_invoices):
|
||||
condition = " and cost_center = '{0}' ".format(self.cost_center)
|
||||
|
||||
if get_invoices:
|
||||
condition += (
|
||||
" and posting_date >= {0}".format(frappe.db.escape(self.from_invoice_date))
|
||||
|
@ -1,9 +1,96 @@
|
||||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
from frappe.utils import add_days, getdate
|
||||
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
|
||||
|
||||
class TestPaymentReconciliation(unittest.TestCase):
|
||||
pass
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
make_customer()
|
||||
make_invoice_and_payment()
|
||||
|
||||
def test_payment_reconciliation(self):
|
||||
payment_reco = frappe.get_doc("Payment Reconciliation")
|
||||
payment_reco.company = "_Test Company"
|
||||
payment_reco.party_type = "Customer"
|
||||
payment_reco.party = "_Test Payment Reco Customer"
|
||||
payment_reco.receivable_payable_account = "Debtors - _TC"
|
||||
payment_reco.from_invoice_date = add_days(getdate(), -1)
|
||||
payment_reco.to_invoice_date = getdate()
|
||||
payment_reco.from_payment_date = add_days(getdate(), -1)
|
||||
payment_reco.to_payment_date = getdate()
|
||||
payment_reco.maximum_invoice_amount = 1000
|
||||
payment_reco.maximum_payment_amount = 1000
|
||||
payment_reco.invoice_limit = 10
|
||||
payment_reco.payment_limit = 10
|
||||
payment_reco.bank_cash_account = "_Test Bank - _TC"
|
||||
payment_reco.cost_center = "_Test Cost Center - _TC"
|
||||
payment_reco.get_unreconciled_entries()
|
||||
|
||||
self.assertEqual(len(payment_reco.get("invoices")), 1)
|
||||
self.assertEqual(len(payment_reco.get("payments")), 1)
|
||||
|
||||
payment_entry = payment_reco.get("payments")[0].reference_name
|
||||
invoice = payment_reco.get("invoices")[0].invoice_number
|
||||
|
||||
payment_reco.allocate_entries(
|
||||
{
|
||||
"payments": [payment_reco.get("payments")[0].as_dict()],
|
||||
"invoices": [payment_reco.get("invoices")[0].as_dict()],
|
||||
}
|
||||
)
|
||||
payment_reco.reconcile()
|
||||
|
||||
payment_entry_doc = frappe.get_doc("Payment Entry", payment_entry)
|
||||
self.assertEqual(payment_entry_doc.get("references")[0].reference_name, invoice)
|
||||
|
||||
|
||||
def make_customer():
|
||||
if not frappe.db.get_value("Customer", "_Test Payment Reco Customer"):
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Customer",
|
||||
"customer_name": "_Test Payment Reco Customer",
|
||||
"customer_type": "Individual",
|
||||
"customer_group": "_Test Customer Group",
|
||||
"territory": "_Test Territory",
|
||||
}
|
||||
).insert()
|
||||
|
||||
|
||||
def make_invoice_and_payment():
|
||||
si = create_sales_invoice(
|
||||
customer="_Test Payment Reco Customer", qty=1, rate=690, do_not_save=True
|
||||
)
|
||||
si.cost_center = "_Test Cost Center - _TC"
|
||||
si.save()
|
||||
si.submit()
|
||||
|
||||
pe = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Payment Entry",
|
||||
"payment_type": "Receive",
|
||||
"party_type": "Customer",
|
||||
"party": "_Test Payment Reco Customer",
|
||||
"company": "_Test Company",
|
||||
"paid_from_account_currency": "INR",
|
||||
"paid_to_account_currency": "INR",
|
||||
"source_exchange_rate": 1,
|
||||
"target_exchange_rate": 1,
|
||||
"reference_no": "1",
|
||||
"reference_date": getdate(),
|
||||
"received_amount": 690,
|
||||
"paid_amount": 690,
|
||||
"paid_from": "Debtors - _TC",
|
||||
"paid_to": "_Test Bank - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
}
|
||||
)
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
@ -824,29 +824,6 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
}
|
||||
},
|
||||
|
||||
// Healthcare
|
||||
patient: function(frm) {
|
||||
if (frappe.boot.active_domains.includes("Healthcare")){
|
||||
if(frm.doc.patient){
|
||||
frappe.call({
|
||||
method: "frappe.client.get_value",
|
||||
args:{
|
||||
doctype: "Patient",
|
||||
filters: {
|
||||
"name": frm.doc.patient
|
||||
},
|
||||
fieldname: "customer"
|
||||
},
|
||||
callback:function(r) {
|
||||
if(r && r.message.customer){
|
||||
frm.set_value("customer", r.message.customer);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
project: function(frm) {
|
||||
if (frm.doc.project) {
|
||||
frm.events.add_timesheet_data(frm, {
|
||||
@ -976,25 +953,6 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
if (frm.doc.is_debit_note) {
|
||||
frm.set_df_property('return_against', 'label', __('Adjustment Against'));
|
||||
}
|
||||
|
||||
if (frappe.boot.active_domains.includes("Healthcare")) {
|
||||
frm.set_df_property("patient", "hidden", 0);
|
||||
frm.set_df_property("patient_name", "hidden", 0);
|
||||
frm.set_df_property("ref_practitioner", "hidden", 0);
|
||||
if (cint(frm.doc.docstatus==0) && cur_frm.page.current_view_name!=="pos" && !frm.doc.is_return) {
|
||||
frm.add_custom_button(__('Healthcare Services'), function() {
|
||||
get_healthcare_services_to_invoice(frm);
|
||||
},__("Get Items From"));
|
||||
frm.add_custom_button(__('Prescriptions'), function() {
|
||||
get_drugs_to_invoice(frm);
|
||||
},__("Get Items From"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
frm.set_df_property("patient", "hidden", 1);
|
||||
frm.set_df_property("patient_name", "hidden", 1);
|
||||
frm.set_df_property("ref_practitioner", "hidden", 1);
|
||||
}
|
||||
},
|
||||
|
||||
create_invoice_discounting: function(frm) {
|
||||
|
@ -12,7 +12,10 @@ def get_data():
|
||||
"Sales Invoice": "return_against",
|
||||
"Auto Repeat": "reference_document",
|
||||
},
|
||||
"internal_links": {"Sales Order": ["items", "sales_order"]},
|
||||
"internal_links": {
|
||||
"Sales Order": ["items", "sales_order"],
|
||||
"Timesheet": ["timesheets", "time_sheet"],
|
||||
},
|
||||
"transactions": [
|
||||
{
|
||||
"label": _("Payment"),
|
||||
|
@ -722,9 +722,7 @@ def process(data):
|
||||
frappe.db.commit()
|
||||
except frappe.ValidationError:
|
||||
frappe.db.rollback()
|
||||
frappe.db.begin()
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
frappe.db.commit()
|
||||
subscription.log_error("Subscription failed")
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
@ -203,7 +203,7 @@ def get_loan_entries(filters):
|
||||
posting_date = (loan_doc.posting_date).as_("posting_date")
|
||||
account = loan_doc.payment_account
|
||||
|
||||
entries = (
|
||||
query = (
|
||||
frappe.qb.from_(loan_doc)
|
||||
.select(
|
||||
ConstantColumn(doctype).as_("payment_document"),
|
||||
@ -217,9 +217,12 @@ def get_loan_entries(filters):
|
||||
.where(account == filters.get("account"))
|
||||
.where(posting_date <= getdate(filters.get("report_date")))
|
||||
.where(ifnull(loan_doc.clearance_date, "4000-01-01") > getdate(filters.get("report_date")))
|
||||
.run(as_dict=1)
|
||||
)
|
||||
|
||||
if doctype == "Loan Repayment":
|
||||
query.where(loan_doc.repay_from_salary == 0)
|
||||
|
||||
entries = query.run(as_dict=1)
|
||||
loan_docs.extend(entries)
|
||||
|
||||
return loan_docs
|
||||
|
@ -133,7 +133,7 @@ def set_account_currency(filters):
|
||||
else:
|
||||
account_currency = (
|
||||
None
|
||||
if filters.party_type in ["Employee", "Student", "Shareholder", "Member"]
|
||||
if filters.party_type in ["Employee", "Shareholder", "Member"]
|
||||
else frappe.db.get_value(filters.party_type, filters.party[0], "default_currency")
|
||||
)
|
||||
|
||||
|
@ -23,8 +23,6 @@ def execute(filters=None):
|
||||
def get_data(filters, show_party_name):
|
||||
if filters.get("party_type") in ("Customer", "Supplier", "Employee", "Member"):
|
||||
party_name_field = "{0}_name".format(frappe.scrub(filters.get("party_type")))
|
||||
elif filters.get("party_type") == "Student":
|
||||
party_name_field = "first_name"
|
||||
elif filters.get("party_type") == "Shareholder":
|
||||
party_name_field = "title"
|
||||
else:
|
||||
|
@ -23,6 +23,10 @@
|
||||
"order_confirmation_no",
|
||||
"order_confirmation_date",
|
||||
"amended_from",
|
||||
"accounting_dimensions_section",
|
||||
"cost_center",
|
||||
"dimension_col_break",
|
||||
"project",
|
||||
"drop_ship",
|
||||
"customer",
|
||||
"customer_name",
|
||||
@ -1137,16 +1141,39 @@
|
||||
"fieldtype": "Link",
|
||||
"label": "Tax Withholding Category",
|
||||
"options": "Tax Withholding Category"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "accounting_dimensions_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Accounting Dimensions "
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"fieldtype": "Link",
|
||||
"label": "Cost Center",
|
||||
"options": "Cost Center"
|
||||
},
|
||||
{
|
||||
"fieldname": "dimension_col_break",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"label": "Project",
|
||||
"options": "Project"
|
||||
}
|
||||
],
|
||||
"icon": "fa fa-file-text",
|
||||
"idx": 105,
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2021-09-28 13:10:47.955401",
|
||||
"modified": "2022-04-26 12:16:38.694276",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
"naming_rule": "By \"Naming Series\" field",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
@ -1193,6 +1220,7 @@
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"timeline_field": "supplier",
|
||||
"title_field": "supplier_name",
|
||||
"track_changes": 1
|
||||
|
@ -114,11 +114,11 @@ frappe.query_reports["Supplier Quotation Comparison"] = {
|
||||
onload: (report) => {
|
||||
// Create a button for setting the default supplier
|
||||
report.page.add_inner_button(__("Select Default Supplier"), () => {
|
||||
let reporter = frappe.query_reports["Quoted Item Comparison"];
|
||||
let reporter = frappe.query_reports["Supplier Quotation Comparison"];
|
||||
|
||||
//Always make a new one so that the latest values get updated
|
||||
reporter.make_default_supplier_dialog(report);
|
||||
}, 'Tools');
|
||||
}, __("Tools"));
|
||||
|
||||
},
|
||||
make_default_supplier_dialog: (report) => {
|
||||
@ -126,7 +126,7 @@ frappe.query_reports["Supplier Quotation Comparison"] = {
|
||||
if(!report.data) return;
|
||||
|
||||
let filters = report.get_values();
|
||||
let item_code = filters.item;
|
||||
let item_code = filters.item_code;
|
||||
|
||||
// Get a list of the suppliers (with a blank as well) for the user to select
|
||||
let suppliers = $.map(report.data, (row, idx)=>{ return row.supplier_name })
|
||||
@ -152,7 +152,7 @@ frappe.query_reports["Supplier Quotation Comparison"] = {
|
||||
]
|
||||
});
|
||||
|
||||
dialog.set_primary_action("Set Default Supplier", () => {
|
||||
dialog.set_primary_action(__("Set Default Supplier"), () => {
|
||||
let values = dialog.get_values();
|
||||
if(values) {
|
||||
// Set the default_supplier field of the appropriate Item to the selected supplier
|
||||
|
@ -1,192 +0,0 @@
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_data():
|
||||
return [
|
||||
{
|
||||
"label": _("Student"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Student",
|
||||
"onboard": 1,
|
||||
},
|
||||
{"type": "doctype", "name": "Guardian"},
|
||||
{"type": "doctype", "name": "Student Log"},
|
||||
{"type": "doctype", "name": "Student Group"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Admission"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Student Applicant"},
|
||||
{"type": "doctype", "name": "Web Academy Applicant"},
|
||||
{"type": "doctype", "name": "Student Admission"},
|
||||
{"type": "doctype", "name": "Program Enrollment"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Attendance"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Student Attendance"},
|
||||
{"type": "doctype", "name": "Student Leave Application"},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Absent Student Report",
|
||||
"doctype": "Student Attendance",
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Student Batch-Wise Attendance",
|
||||
"doctype": "Student Attendance",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Tools"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Student Attendance Tool"},
|
||||
{"type": "doctype", "name": "Assessment Result Tool"},
|
||||
{"type": "doctype", "name": "Student Group Creation Tool"},
|
||||
{"type": "doctype", "name": "Program Enrollment Tool"},
|
||||
{"type": "doctype", "name": "Course Scheduling Tool"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Assessment"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Assessment Plan"},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Assessment Group",
|
||||
"link": "Tree/Assessment Group",
|
||||
},
|
||||
{"type": "doctype", "name": "Assessment Result"},
|
||||
{"type": "doctype", "name": "Assessment Criteria"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Assessment Reports"),
|
||||
"items": [
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Course wise Assessment Report",
|
||||
"doctype": "Assessment Result",
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Final Assessment Grades",
|
||||
"doctype": "Assessment Result",
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Assessment Plan Status",
|
||||
"doctype": "Assessment Plan",
|
||||
},
|
||||
{"type": "doctype", "name": "Student Report Generation Tool"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Fees"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Fees"},
|
||||
{"type": "doctype", "name": "Fee Schedule"},
|
||||
{"type": "doctype", "name": "Fee Structure"},
|
||||
{"type": "doctype", "name": "Fee Category"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Schedule"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Course Schedule", "route": "/app/List/Course Schedule/Calendar"},
|
||||
{"type": "doctype", "name": "Course Scheduling Tool"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Masters"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Program",
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Course",
|
||||
"onboard": 1,
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Topic",
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Instructor",
|
||||
"onboard": 1,
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Room",
|
||||
"onboard": 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Content Masters"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Article"},
|
||||
{"type": "doctype", "name": "Video"},
|
||||
{"type": "doctype", "name": "Quiz"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("LMS Activity"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Course Enrollment"},
|
||||
{"type": "doctype", "name": "Course Activity"},
|
||||
{"type": "doctype", "name": "Quiz Activity"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Settings"),
|
||||
"items": [
|
||||
{"type": "doctype", "name": "Student Category"},
|
||||
{"type": "doctype", "name": "Student Batch Name"},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Grading Scale",
|
||||
"onboard": 1,
|
||||
},
|
||||
{"type": "doctype", "name": "Academic Term"},
|
||||
{"type": "doctype", "name": "Academic Year"},
|
||||
{"type": "doctype", "name": "Education Settings"},
|
||||
],
|
||||
},
|
||||
{
|
||||
"label": _("Other Reports"),
|
||||
"items": [
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Student and Guardian Contact Details",
|
||||
"doctype": "Program Enrollment",
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Student Monthly Attendance Sheet",
|
||||
"doctype": "Student Attendance",
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "Student Fee Collection",
|
||||
"doctype": "Fees",
|
||||
"is_query_report": True,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
@ -72,7 +72,7 @@ class LinkedInSettings(Document):
|
||||
if media_id:
|
||||
return self.post_text(text, title, media_id=media_id)
|
||||
else:
|
||||
frappe.log_error("Failed to upload media.", "LinkedIn Upload Error")
|
||||
self.log_error("LinkedIn: Failed to upload media")
|
||||
|
||||
def upload_image(self, media):
|
||||
media = get_file_path(media)
|
||||
|
@ -70,8 +70,7 @@ class SocialMediaPost(Document):
|
||||
|
||||
except Exception:
|
||||
self.db_set("post_status", "Error")
|
||||
title = _("Error while POSTING {0}").format(self.name)
|
||||
frappe.log_error(message=frappe.get_traceback(), title=title)
|
||||
self.log_error("Social posting failed")
|
||||
|
||||
|
||||
def process_scheduled_social_media_posts():
|
||||
|
@ -1,19 +0,0 @@
|
||||
data = {
|
||||
"desktop_icons": [
|
||||
"Student",
|
||||
"Program",
|
||||
"Course",
|
||||
"Student Group",
|
||||
"Instructor",
|
||||
"Fees",
|
||||
"Task",
|
||||
"ToDo",
|
||||
"Education",
|
||||
"Student Attendance Tool",
|
||||
"Student Applicant",
|
||||
],
|
||||
"default_portal_role": "Student",
|
||||
"restricted_roles": ["Student", "Instructor", "Academics User", "Education Manager"],
|
||||
"modules": ["Education"],
|
||||
"on_setup": "erpnext.education.setup.setup_education",
|
||||
}
|
@ -56,8 +56,7 @@ def get_product_filter_data(query_args=None):
|
||||
attribute_filters, field_filters, search_term=search, start=start, item_group=item_group
|
||||
)
|
||||
except Exception:
|
||||
traceback = frappe.get_traceback()
|
||||
frappe.log_error(traceback, frappe._("Product Engine Error"))
|
||||
frappe.log_error("Product query with filter failed")
|
||||
return {"exc": "Something went wrong!"}
|
||||
|
||||
# discount filter data
|
||||
|
@ -245,8 +245,7 @@ def get_fields_indexed():
|
||||
|
||||
def raise_redisearch_error():
|
||||
"Create an Error Log and raise error."
|
||||
traceback = frappe.get_traceback()
|
||||
log = frappe.log_error(traceback, frappe._("Redisearch Error"))
|
||||
log = frappe.log_error("Redisearch Error")
|
||||
log_link = frappe.utils.get_link_to_form("Error Log", log.name)
|
||||
|
||||
frappe.throw(
|
||||
|
@ -1,17 +0,0 @@
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
|
||||
class StudentNotInGroupError(frappe.ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
def validate_student_belongs_to_group(student, student_group):
|
||||
groups = frappe.db.get_all("Student Group Student", ["parent"], dict(student=student, active=1))
|
||||
if not student_group in [d.parent for d in groups]:
|
||||
frappe.throw(
|
||||
_("Student {0} does not belong to group {1}").format(
|
||||
frappe.bold(student), frappe.bold(student_group)
|
||||
),
|
||||
StudentNotInGroupError,
|
||||
)
|
@ -1,444 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.email.doctype.email_group.email_group import add_subscribers
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
from frappe.utils import cstr, flt, getdate
|
||||
|
||||
|
||||
def get_course(program):
|
||||
"""Return list of courses for a particular program
|
||||
:param program: Program
|
||||
"""
|
||||
courses = frappe.db.sql(
|
||||
"""select course, course_name from `tabProgram Course` where parent=%s""", (program), as_dict=1
|
||||
)
|
||||
return courses
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def enroll_student(source_name):
|
||||
"""Creates a Student Record and returns a Program Enrollment.
|
||||
|
||||
:param source_name: Student Applicant.
|
||||
"""
|
||||
frappe.publish_realtime("enroll_student_progress", {"progress": [1, 4]}, user=frappe.session.user)
|
||||
student = get_mapped_doc(
|
||||
"Student Applicant",
|
||||
source_name,
|
||||
{"Student Applicant": {"doctype": "Student", "field_map": {"name": "student_applicant"}}},
|
||||
ignore_permissions=True,
|
||||
)
|
||||
student.save()
|
||||
|
||||
student_applicant = frappe.db.get_value(
|
||||
"Student Applicant", source_name, ["student_category", "program"], as_dict=True
|
||||
)
|
||||
program_enrollment = frappe.new_doc("Program Enrollment")
|
||||
program_enrollment.student = student.name
|
||||
program_enrollment.student_category = student_applicant.student_category
|
||||
program_enrollment.student_name = student.title
|
||||
program_enrollment.program = student_applicant.program
|
||||
frappe.publish_realtime("enroll_student_progress", {"progress": [2, 4]}, user=frappe.session.user)
|
||||
return program_enrollment
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def check_attendance_records_exist(course_schedule=None, student_group=None, date=None):
|
||||
"""Check if Attendance Records are made against the specified Course Schedule or Student Group for given date.
|
||||
|
||||
:param course_schedule: Course Schedule.
|
||||
:param student_group: Student Group.
|
||||
:param date: Date.
|
||||
"""
|
||||
if course_schedule:
|
||||
return frappe.get_list("Student Attendance", filters={"course_schedule": course_schedule})
|
||||
else:
|
||||
return frappe.get_list(
|
||||
"Student Attendance", filters={"student_group": student_group, "date": date}
|
||||
)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def mark_attendance(
|
||||
students_present, students_absent, course_schedule=None, student_group=None, date=None
|
||||
):
|
||||
"""Creates Multiple Attendance Records.
|
||||
|
||||
:param students_present: Students Present JSON.
|
||||
:param students_absent: Students Absent JSON.
|
||||
:param course_schedule: Course Schedule.
|
||||
:param student_group: Student Group.
|
||||
:param date: Date.
|
||||
"""
|
||||
|
||||
if student_group:
|
||||
academic_year = frappe.db.get_value("Student Group", student_group, "academic_year")
|
||||
if academic_year:
|
||||
year_start_date, year_end_date = frappe.db.get_value(
|
||||
"Academic Year", academic_year, ["year_start_date", "year_end_date"]
|
||||
)
|
||||
if getdate(date) < getdate(year_start_date) or getdate(date) > getdate(year_end_date):
|
||||
frappe.throw(
|
||||
_("Attendance cannot be marked outside of Academic Year {0}").format(academic_year)
|
||||
)
|
||||
|
||||
present = json.loads(students_present)
|
||||
absent = json.loads(students_absent)
|
||||
|
||||
for d in present:
|
||||
make_attendance_records(
|
||||
d["student"], d["student_name"], "Present", course_schedule, student_group, date
|
||||
)
|
||||
|
||||
for d in absent:
|
||||
make_attendance_records(
|
||||
d["student"], d["student_name"], "Absent", course_schedule, student_group, date
|
||||
)
|
||||
|
||||
frappe.db.commit()
|
||||
frappe.msgprint(_("Attendance has been marked successfully."))
|
||||
|
||||
|
||||
def make_attendance_records(
|
||||
student, student_name, status, course_schedule=None, student_group=None, date=None
|
||||
):
|
||||
"""Creates/Update Attendance Record.
|
||||
|
||||
:param student: Student.
|
||||
:param student_name: Student Name.
|
||||
:param course_schedule: Course Schedule.
|
||||
:param status: Status (Present/Absent)
|
||||
"""
|
||||
student_attendance = frappe.get_doc(
|
||||
{
|
||||
"doctype": "Student Attendance",
|
||||
"student": student,
|
||||
"course_schedule": course_schedule,
|
||||
"student_group": student_group,
|
||||
"date": date,
|
||||
}
|
||||
)
|
||||
if not student_attendance:
|
||||
student_attendance = frappe.new_doc("Student Attendance")
|
||||
student_attendance.student = student
|
||||
student_attendance.student_name = student_name
|
||||
student_attendance.course_schedule = course_schedule
|
||||
student_attendance.student_group = student_group
|
||||
student_attendance.date = date
|
||||
student_attendance.status = status
|
||||
student_attendance.save()
|
||||
student_attendance.submit()
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_student_guardians(student):
|
||||
"""Returns List of Guardians of a Student.
|
||||
|
||||
:param student: Student.
|
||||
"""
|
||||
guardians = frappe.get_all("Student Guardian", fields=["guardian"], filters={"parent": student})
|
||||
return guardians
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_student_group_students(student_group, include_inactive=0):
|
||||
"""Returns List of student, student_name in Student Group.
|
||||
|
||||
:param student_group: Student Group.
|
||||
"""
|
||||
if include_inactive:
|
||||
students = frappe.get_all(
|
||||
"Student Group Student",
|
||||
fields=["student", "student_name"],
|
||||
filters={"parent": student_group},
|
||||
order_by="group_roll_number",
|
||||
)
|
||||
else:
|
||||
students = frappe.get_all(
|
||||
"Student Group Student",
|
||||
fields=["student", "student_name"],
|
||||
filters={"parent": student_group, "active": 1},
|
||||
order_by="group_roll_number",
|
||||
)
|
||||
return students
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_fee_structure(program, academic_term=None):
|
||||
"""Returns Fee Structure.
|
||||
|
||||
:param program: Program.
|
||||
:param academic_term: Academic Term.
|
||||
"""
|
||||
fee_structure = frappe.db.get_values(
|
||||
"Fee Structure", {"program": program, "academic_term": academic_term}, "name", as_dict=True
|
||||
)
|
||||
return fee_structure[0].name if fee_structure else None
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_fee_components(fee_structure):
|
||||
"""Returns Fee Components.
|
||||
|
||||
:param fee_structure: Fee Structure.
|
||||
"""
|
||||
if fee_structure:
|
||||
fs = frappe.get_all(
|
||||
"Fee Component",
|
||||
fields=["fees_category", "description", "amount"],
|
||||
filters={"parent": fee_structure},
|
||||
order_by="idx",
|
||||
)
|
||||
return fs
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_fee_schedule(program, student_category=None):
|
||||
"""Returns Fee Schedule.
|
||||
|
||||
:param program: Program.
|
||||
:param student_category: Student Category
|
||||
"""
|
||||
fs = frappe.get_all(
|
||||
"Program Fee",
|
||||
fields=["academic_term", "fee_structure", "due_date", "amount"],
|
||||
filters={"parent": program, "student_category": student_category},
|
||||
order_by="idx",
|
||||
)
|
||||
return fs
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def collect_fees(fees, amt):
|
||||
paid_amount = flt(amt) + flt(frappe.db.get_value("Fees", fees, "paid_amount"))
|
||||
total_amount = flt(frappe.db.get_value("Fees", fees, "total_amount"))
|
||||
frappe.db.set_value("Fees", fees, "paid_amount", paid_amount)
|
||||
frappe.db.set_value("Fees", fees, "outstanding_amount", (total_amount - paid_amount))
|
||||
return paid_amount
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_course_schedule_events(start, end, filters=None):
|
||||
"""Returns events for Course Schedule Calendar view rendering.
|
||||
|
||||
:param start: Start date-time.
|
||||
:param end: End date-time.
|
||||
:param filters: Filters (JSON).
|
||||
"""
|
||||
from frappe.desk.calendar import get_event_conditions
|
||||
|
||||
conditions = get_event_conditions("Course Schedule", filters)
|
||||
|
||||
data = frappe.db.sql(
|
||||
"""select name, course, color,
|
||||
timestamp(schedule_date, from_time) as from_time,
|
||||
timestamp(schedule_date, to_time) as to_time,
|
||||
room, student_group, 0 as 'allDay'
|
||||
from `tabCourse Schedule`
|
||||
where ( schedule_date between %(start)s and %(end)s )
|
||||
{conditions}""".format(
|
||||
conditions=conditions
|
||||
),
|
||||
{"start": start, "end": end},
|
||||
as_dict=True,
|
||||
update={"allDay": 0},
|
||||
)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_assessment_criteria(course):
|
||||
"""Returns Assessmemt Criteria and their Weightage from Course Master.
|
||||
|
||||
:param Course: Course
|
||||
"""
|
||||
return frappe.get_all(
|
||||
"Course Assessment Criteria",
|
||||
fields=["assessment_criteria", "weightage"],
|
||||
filters={"parent": course},
|
||||
order_by="idx",
|
||||
)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_assessment_students(assessment_plan, student_group):
|
||||
student_list = get_student_group_students(student_group)
|
||||
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.assessment_criteria: [cstr(d.score), d.grade]})
|
||||
student_result.update(
|
||||
{"total_score": [cstr(result.total_score), result.grade], "comment": result.comment}
|
||||
)
|
||||
student.update(
|
||||
{"assessment_details": student_result, "docstatus": result.docstatus, "name": result.name}
|
||||
)
|
||||
else:
|
||||
student.update({"assessment_details": None})
|
||||
return student_list
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_assessment_details(assessment_plan):
|
||||
"""Returns Assessment Criteria and Maximum Score from Assessment Plan Master.
|
||||
|
||||
:param Assessment Plan: Assessment Plan
|
||||
"""
|
||||
return frappe.get_all(
|
||||
"Assessment Plan Criteria",
|
||||
fields=["assessment_criteria", "maximum_score", "docstatus"],
|
||||
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": ("!=", 2)},
|
||||
)
|
||||
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 = {}
|
||||
if not hasattr(frappe.local, "grading_scale"):
|
||||
grading_scale = frappe.get_all(
|
||||
"Grading Scale Interval", fields=["grade_code", "threshold"], filters={"parent": grading_scale}
|
||||
)
|
||||
frappe.local.grading_scale = grading_scale
|
||||
for d in frappe.local.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(assessment_plan, scores):
|
||||
student_score = json.loads(scores)
|
||||
assessment_details = []
|
||||
for criteria in student_score.get("assessment_details"):
|
||||
assessment_details.append(
|
||||
{"assessment_criteria": criteria, "score": flt(student_score["assessment_details"][criteria])}
|
||||
)
|
||||
assessment_result = get_assessment_result_doc(student_score["student"], assessment_plan)
|
||||
assessment_result.update(
|
||||
{
|
||||
"student": student_score.get("student"),
|
||||
"assessment_plan": assessment_plan,
|
||||
"comment": student_score.get("comment"),
|
||||
"total_score": student_score.get("total_score"),
|
||||
"details": assessment_details,
|
||||
}
|
||||
)
|
||||
assessment_result.save()
|
||||
details = {}
|
||||
for d in assessment_result.details:
|
||||
details.update({d.assessment_criteria: d.grade})
|
||||
assessment_result_dict = {
|
||||
"name": assessment_result.name,
|
||||
"student": assessment_result.student,
|
||||
"total_score": assessment_result.total_score,
|
||||
"grade": assessment_result.grade,
|
||||
"details": details,
|
||||
}
|
||||
return assessment_result_dict
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def submit_assessment_results(assessment_plan, student_group):
|
||||
total_result = 0
|
||||
student_list = get_student_group_students(student_group)
|
||||
for i, student in enumerate(student_list):
|
||||
doc = get_result(student.student, assessment_plan)
|
||||
if doc and doc.docstatus == 0:
|
||||
total_result += 1
|
||||
doc.submit()
|
||||
return total_result
|
||||
|
||||
|
||||
def get_assessment_result_doc(student, assessment_plan):
|
||||
assessment_result = frappe.get_all(
|
||||
"Assessment Result",
|
||||
filters={"student": student, "assessment_plan": assessment_plan, "docstatus": ("!=", 2)},
|
||||
)
|
||||
if assessment_result:
|
||||
doc = frappe.get_doc("Assessment Result", assessment_result[0])
|
||||
if doc.docstatus == 0:
|
||||
return doc
|
||||
elif doc.docstatus == 1:
|
||||
frappe.msgprint(_("Result already Submitted"))
|
||||
return None
|
||||
else:
|
||||
return frappe.new_doc("Assessment Result")
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_email_group(doctype, name):
|
||||
if not frappe.db.exists("Email Group", name):
|
||||
email_group = frappe.new_doc("Email Group")
|
||||
email_group.title = name
|
||||
email_group.save()
|
||||
email_list = []
|
||||
students = []
|
||||
if doctype == "Student Group":
|
||||
students = get_student_group_students(name)
|
||||
for stud in students:
|
||||
for guard in get_student_guardians(stud.student):
|
||||
email = frappe.db.get_value("Guardian", guard.guardian, "email_address")
|
||||
if email:
|
||||
email_list.append(email)
|
||||
add_subscribers(name, email_list)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_current_enrollment(student, academic_year=None):
|
||||
current_academic_year = academic_year or frappe.defaults.get_defaults().academic_year
|
||||
program_enrollment_list = frappe.db.sql(
|
||||
"""
|
||||
select
|
||||
name as program_enrollment, student_name, program, student_batch_name as student_batch,
|
||||
student_category, academic_term, academic_year
|
||||
from
|
||||
`tabProgram Enrollment`
|
||||
where
|
||||
student = %s and academic_year = %s
|
||||
order by creation""",
|
||||
(student, current_academic_year),
|
||||
as_dict=1,
|
||||
)
|
||||
|
||||
if program_enrollment_list:
|
||||
return program_enrollment_list[0]
|
||||
else:
|
||||
return None
|
@ -1,31 +0,0 @@
|
||||
{
|
||||
"based_on": "",
|
||||
"chart_name": "Course wise Enrollment",
|
||||
"chart_type": "Group By",
|
||||
"creation": "2020-07-23 18:24:38.214220",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"document_type": "Course Enrollment",
|
||||
"dynamic_filters_json": "[]",
|
||||
"filters_json": "[[\"Course Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]",
|
||||
"group_by_based_on": "course",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"last_synced_on": "2020-07-27 17:50:32.490587",
|
||||
"modified": "2020-07-27 17:54:09.829206",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Course wise Enrollment",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"source": "",
|
||||
"time_interval": "Yearly",
|
||||
"timeseries": 0,
|
||||
"timespan": "Last Year",
|
||||
"type": "Percentage",
|
||||
"use_report_chart": 0,
|
||||
"value_based_on": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
{
|
||||
"based_on": "",
|
||||
"chart_name": "Course wise Student Count",
|
||||
"chart_type": "Group By",
|
||||
"creation": "2020-07-27 17:24:39.136163",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"document_type": "Course Enrollment",
|
||||
"dynamic_filters_json": "[]",
|
||||
"filters_json": "[[\"Course Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]",
|
||||
"group_by_based_on": "course",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"last_synced_on": "2020-07-27 17:24:56.184236",
|
||||
"modified": "2020-07-27 17:25:46.232846",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Course wise Student Count",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"source": "",
|
||||
"time_interval": "Yearly",
|
||||
"timeseries": 0,
|
||||
"timespan": "Last Year",
|
||||
"type": "Donut",
|
||||
"use_report_chart": 0,
|
||||
"value_based_on": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
{
|
||||
"based_on": "",
|
||||
"chart_name": "Instructor Gender Diversity Ratio",
|
||||
"chart_type": "Group By",
|
||||
"creation": "2020-07-23 18:35:02.544019",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"document_type": "Instructor",
|
||||
"dynamic_filters_json": "[]",
|
||||
"filters_json": "[[\"Instructor\",\"status\",\"=\",\"Active\",false]]",
|
||||
"group_by_based_on": "gender",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"last_synced_on": "2020-07-27 17:50:32.783820",
|
||||
"modified": "2020-07-27 17:55:41.595260",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Instructor Gender Diversity Ratio",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"source": "",
|
||||
"time_interval": "Yearly",
|
||||
"timeseries": 0,
|
||||
"timespan": "Last Year",
|
||||
"type": "Donut",
|
||||
"use_report_chart": 0,
|
||||
"value_based_on": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
{
|
||||
"based_on": "enrollment_date",
|
||||
"chart_name": "Program Enrollments",
|
||||
"chart_type": "Count",
|
||||
"creation": "2020-07-23 18:27:53.641616",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"document_type": "Program Enrollment",
|
||||
"dynamic_filters_json": "[]",
|
||||
"filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false]]",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"last_synced_on": "2020-07-27 17:50:32.203069",
|
||||
"modified": "2020-07-27 17:51:59.022909",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program Enrollments",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"source": "",
|
||||
"time_interval": "Daily",
|
||||
"timeseries": 1,
|
||||
"timespan": "Last Month",
|
||||
"type": "Line",
|
||||
"use_report_chart": 0,
|
||||
"value_based_on": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
{
|
||||
"based_on": "",
|
||||
"chart_name": "Program wise Enrollment",
|
||||
"chart_type": "Group By",
|
||||
"creation": "2020-07-23 18:23:45.192748",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"document_type": "Program Enrollment",
|
||||
"dynamic_filters_json": "[]",
|
||||
"filters_json": "[[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false],[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false]]",
|
||||
"group_by_based_on": "program",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"last_synced_on": "2020-07-27 17:50:32.629321",
|
||||
"modified": "2020-07-27 17:53:36.269098",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program wise Enrollment",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"source": "",
|
||||
"time_interval": "Yearly",
|
||||
"timeseries": 0,
|
||||
"timespan": "Last Year",
|
||||
"type": "Percentage",
|
||||
"use_report_chart": 0,
|
||||
"value_based_on": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"chart_name": "Program wise Fee Collection",
|
||||
"chart_type": "Report",
|
||||
"creation": "2020-08-05 16:19:53.398335",
|
||||
"custom_options": "",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"dynamic_filters_json": "{\"from_date\":\"frappe.datetime.add_months(frappe.datetime.get_today(), -1)\",\"to_date\":\"frappe.datetime.nowdate()\"}",
|
||||
"filters_json": "{}",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"modified": "2020-08-05 16:20:47.436847",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program wise Fee Collection",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"report_name": "Program wise Fee Collection",
|
||||
"time_interval": "Yearly",
|
||||
"timeseries": 0,
|
||||
"timespan": "Last Year",
|
||||
"type": "Bar",
|
||||
"use_report_chart": 1,
|
||||
"x_field": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
{
|
||||
"based_on": "",
|
||||
"chart_name": "Student Category wise Program Enrollments",
|
||||
"chart_type": "Group By",
|
||||
"creation": "2020-07-27 17:37:47.116446",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"document_type": "Program Enrollment",
|
||||
"dynamic_filters_json": "[]",
|
||||
"filters_json": "[[\"Program Enrollment\",\"enrollment_date\",\"Timespan\",\"this year\",false],[\"Program Enrollment\",\"docstatus\",\"=\",\"1\",false]]",
|
||||
"group_by_based_on": "student_category",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"last_synced_on": "2020-07-27 17:46:54.901911",
|
||||
"modified": "2020-07-27 17:47:21.370866",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student Category wise Program Enrollments",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"source": "",
|
||||
"time_interval": "Yearly",
|
||||
"timeseries": 0,
|
||||
"timespan": "Last Year",
|
||||
"type": "Donut",
|
||||
"use_report_chart": 0,
|
||||
"value_based_on": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
{
|
||||
"based_on": "",
|
||||
"chart_name": "Student Gender Diversity Ratio",
|
||||
"chart_type": "Group By",
|
||||
"creation": "2020-07-23 18:12:15.972123",
|
||||
"docstatus": 0,
|
||||
"doctype": "Dashboard Chart",
|
||||
"document_type": "Student",
|
||||
"dynamic_filters_json": "[]",
|
||||
"filters_json": "[[\"Student\",\"enabled\",\"=\",1,false]]",
|
||||
"group_by_based_on": "gender",
|
||||
"group_by_type": "Count",
|
||||
"idx": 0,
|
||||
"is_public": 1,
|
||||
"is_standard": 1,
|
||||
"modified": "2020-07-23 18:12:21.606772",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student Gender Diversity Ratio",
|
||||
"number_of_groups": 0,
|
||||
"owner": "Administrator",
|
||||
"source": "",
|
||||
"time_interval": "Yearly",
|
||||
"timeseries": 0,
|
||||
"timespan": "Last Year",
|
||||
"type": "Donut",
|
||||
"use_report_chart": 0,
|
||||
"value_based_on": "",
|
||||
"y_axis": []
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Academic Term', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
@ -1,216 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
"beta": 0,
|
||||
"creation": "2015-09-08 17:19:19.158228",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"editable_grid": 0,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "academic_year",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Academic Year",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Academic Year",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "term_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Term Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "term_start_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Term Start Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "term_end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Term End Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Title",
|
||||
"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
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:05:58.567627",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Academic Term",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "name",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "title",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import getdate
|
||||
|
||||
|
||||
class AcademicTerm(Document):
|
||||
def autoname(self):
|
||||
self.name = self.academic_year + " ({})".format(self.term_name) if self.term_name else ""
|
||||
|
||||
def validate(self):
|
||||
# Check if entry with same academic_year and the term_name already exists
|
||||
validate_duplication(self)
|
||||
self.title = self.academic_year + " ({})".format(self.term_name) if self.term_name else ""
|
||||
|
||||
# Check that start of academic year is earlier than end of academic year
|
||||
if (
|
||||
self.term_start_date
|
||||
and self.term_end_date
|
||||
and getdate(self.term_start_date) > getdate(self.term_end_date)
|
||||
):
|
||||
frappe.throw(
|
||||
_(
|
||||
"The Term End Date cannot be earlier than the Term Start Date. Please correct the dates and try again."
|
||||
)
|
||||
)
|
||||
|
||||
# Check that the start of the term is not before the start of the academic year
|
||||
# and end of term is not after the end of the academic year"""
|
||||
|
||||
year = frappe.get_doc("Academic Year", self.academic_year)
|
||||
if (
|
||||
self.term_start_date
|
||||
and getdate(year.year_start_date)
|
||||
and (getdate(self.term_start_date) < getdate(year.year_start_date))
|
||||
):
|
||||
frappe.throw(
|
||||
_(
|
||||
"The Term Start Date cannot be earlier than the Year Start Date of the Academic Year to which the term is linked (Academic Year {}). Please correct the dates and try again."
|
||||
).format(self.academic_year)
|
||||
)
|
||||
|
||||
if (
|
||||
self.term_end_date
|
||||
and getdate(year.year_end_date)
|
||||
and (getdate(self.term_end_date) > getdate(year.year_end_date))
|
||||
):
|
||||
frappe.throw(
|
||||
_(
|
||||
"The Term End Date cannot be later than the Year End Date of the Academic Year to which the term is linked (Academic Year {}). Please correct the dates and try again."
|
||||
).format(self.academic_year)
|
||||
)
|
||||
|
||||
|
||||
def validate_duplication(self):
|
||||
term = frappe.db.sql(
|
||||
"""select name from `tabAcademic Term` where academic_year= %s and term_name= %s
|
||||
and docstatus<2 and name != %s""",
|
||||
(self.academic_year, self.term_name, self.name),
|
||||
)
|
||||
if term:
|
||||
frappe.throw(
|
||||
_(
|
||||
"An academic term with this 'Academic Year' {0} and 'Term Name' {1} already exists. Please modify these entries and try again."
|
||||
).format(self.academic_year, self.term_name)
|
||||
)
|
@ -1,13 +0,0 @@
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
"fieldname": "academic_term",
|
||||
"transactions": [
|
||||
{"label": _("Student"), "items": ["Student Applicant", "Student Group", "Student Log"]},
|
||||
{"label": _("Fee"), "items": ["Fees", "Fee Schedule", "Fee Structure"]},
|
||||
{"label": _("Program"), "items": ["Program Enrollment"]},
|
||||
{"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]},
|
||||
],
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Academic Term')
|
||||
|
||||
|
||||
class TestAcademicTerm(unittest.TestCase):
|
||||
pass
|
@ -1,27 +0,0 @@
|
||||
[
|
||||
{
|
||||
"doctype": "Academic Term",
|
||||
"academic_year": "2014-2015",
|
||||
"term_name": "_Test Academic Term"
|
||||
},
|
||||
{
|
||||
"doctype": "Academic Term",
|
||||
"academic_year": "2014-2015",
|
||||
"term_name": "_Test Academic Term 1"
|
||||
},
|
||||
{
|
||||
"doctype": "Academic Term",
|
||||
"academic_year": "2014-2015",
|
||||
"term_name": "_Test Academic Term 2"
|
||||
},
|
||||
{
|
||||
"doctype": "Academic Term",
|
||||
"academic_year": "2017-2018",
|
||||
"term_name": "_Test AT1"
|
||||
},
|
||||
{
|
||||
"doctype": "Academic Term",
|
||||
"academic_year": "2017-2018",
|
||||
"term_name": "_Test AT2"
|
||||
}
|
||||
]
|
@ -1,2 +0,0 @@
|
||||
frappe.ui.form.on("Academic Year", {
|
||||
});
|
@ -1,154 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:academic_year_name",
|
||||
"beta": 0,
|
||||
"creation": "2015-09-07 12:49:51.303026",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "academic_year_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Academic Year Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "year_start_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Year Start Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "year_end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Year End Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:06:08.123090",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Academic Year",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class AcademicYear(Document):
|
||||
def validate(self):
|
||||
# Check that start of academic year is earlier than end of academic year
|
||||
if self.year_start_date and self.year_end_date and self.year_start_date > self.year_end_date:
|
||||
frappe.throw(
|
||||
_(
|
||||
"The Year End Date cannot be earlier than the Year Start Date. Please correct the dates and try again."
|
||||
)
|
||||
)
|
@ -1,16 +0,0 @@
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
"fieldname": "academic_year",
|
||||
"transactions": [
|
||||
{
|
||||
"label": _("Student"),
|
||||
"items": ["Student Admission", "Student Applicant", "Student Group", "Student Log"],
|
||||
},
|
||||
{"label": _("Fee"), "items": ["Fees", "Fee Schedule", "Fee Structure"]},
|
||||
{"label": _("Academic Term and Program"), "items": ["Academic Term", "Program Enrollment"]},
|
||||
{"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]},
|
||||
],
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Academic Year')
|
||||
|
||||
|
||||
class TestAcademicYear(unittest.TestCase):
|
||||
pass
|
@ -1,18 +0,0 @@
|
||||
[
|
||||
{
|
||||
"doctype": "Academic Year",
|
||||
"academic_year_name": "2014-2015"
|
||||
},
|
||||
{
|
||||
"doctype": "Academic Year",
|
||||
"academic_year_name": "2015-2016"
|
||||
},
|
||||
{
|
||||
"doctype": "Academic Year",
|
||||
"academic_year_name": "2016-2017"
|
||||
},
|
||||
{
|
||||
"doctype": "Academic Year",
|
||||
"academic_year_name": "2017-2018"
|
||||
}
|
||||
]
|
@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Article', {
|
||||
refresh: function(frm) {
|
||||
if (!frm.doc.__islocal) {
|
||||
frm.add_custom_button(__('Add to Topics'), function() {
|
||||
frm.trigger('add_article_to_topics');
|
||||
}, __('Action'));
|
||||
}
|
||||
},
|
||||
|
||||
add_article_to_topics: function(frm) {
|
||||
get_topics_without_article(frm.doc.name).then(r => {
|
||||
if (r.message.length) {
|
||||
frappe.prompt([
|
||||
{
|
||||
fieldname: 'topics',
|
||||
label: __('Topics'),
|
||||
fieldtype: 'MultiSelectPills',
|
||||
get_data: function() {
|
||||
return r.message;
|
||||
}
|
||||
}
|
||||
],
|
||||
function(data) {
|
||||
frappe.call({
|
||||
method: 'erpnext.education.doctype.topic.topic.add_content_to_topics',
|
||||
args: {
|
||||
'content_type': 'Article',
|
||||
'content': frm.doc.name,
|
||||
'topics': data.topics,
|
||||
},
|
||||
callback: function(r) {
|
||||
if (!r.exc) {
|
||||
frm.reload_doc();
|
||||
}
|
||||
},
|
||||
freeze: true,
|
||||
freeze_message: __('...Adding Article to Topics')
|
||||
});
|
||||
}, __('Add Article to Topics'), __('Add'));
|
||||
} else {
|
||||
frappe.msgprint(__('This article is already added to the existing topics'));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let get_topics_without_article = function(article) {
|
||||
return frappe.call({
|
||||
type: 'GET',
|
||||
method: 'erpnext.education.doctype.article.article.get_topics_without_article',
|
||||
args: {'article': article}
|
||||
});
|
||||
};
|
@ -1,81 +0,0 @@
|
||||
{
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
"creation": "2018-10-17 05:45:38.471670",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"title",
|
||||
"author",
|
||||
"content",
|
||||
"publish_date"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "title",
|
||||
"fieldtype": "Data",
|
||||
"label": "Title",
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "author",
|
||||
"fieldtype": "Data",
|
||||
"label": "Author"
|
||||
},
|
||||
{
|
||||
"fieldname": "content",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Content"
|
||||
},
|
||||
{
|
||||
"fieldname": "publish_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "Publish Date"
|
||||
}
|
||||
],
|
||||
"modified": "2019-06-12 12:36:58.740340",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Article",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Instructor",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "LMS User",
|
||||
"share": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class Article(Document):
|
||||
def get_article(self):
|
||||
pass
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_topics_without_article(article):
|
||||
data = []
|
||||
for entry in frappe.db.get_all("Topic"):
|
||||
topic = frappe.get_doc("Topic", entry.name)
|
||||
topic_contents = [tc.content for tc in topic.topic_content]
|
||||
if not topic_contents or article not in topic_contents:
|
||||
data.append(topic.name)
|
||||
return data
|
@ -1,8 +0,0 @@
|
||||
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestArticle(unittest.TestCase):
|
||||
pass
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Assessment Criteria', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
@ -1,125 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:assessment_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_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "assessment_criteria",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment 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
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 1,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "assessment_criteria_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment Criteria Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Assessment Criteria 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
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:08:11.311304",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment 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,
|
||||
"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,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
STD_CRITERIA = ["total", "total score", "total grade", "maximum score", "score", "grade"]
|
||||
|
||||
|
||||
class AssessmentCriteria(Document):
|
||||
def validate(self):
|
||||
if self.assessment_criteria.lower() in STD_CRITERIA:
|
||||
frappe.throw(_("Can't create standard criteria. Please rename the criteria"))
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Assessment Criteria')
|
||||
|
||||
|
||||
class TestAssessmentCriteria(unittest.TestCase):
|
||||
pass
|
@ -1,8 +0,0 @@
|
||||
[
|
||||
{
|
||||
"assessment_criteria": "_Test Assessment Criteria"
|
||||
},
|
||||
{
|
||||
"assessment_criteria": "_Test Assessment Criteria 1"
|
||||
}
|
||||
]
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Assessment Criteria Group', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
@ -1,94 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:assessment_criteria_group",
|
||||
"beta": 0,
|
||||
"creation": "2017-01-27 15:17:38.855910",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "assessment_criteria_group",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment Criteria Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:11:45.334917",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Criteria Group",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class AssessmentCriteriaGroup(Document):
|
||||
pass
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Assessment Criteria Group')
|
||||
|
||||
|
||||
class TestAssessmentCriteriaGroup(unittest.TestCase):
|
||||
pass
|
@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Assessment Group', {
|
||||
onload: function(frm) {
|
||||
frm.list_route = "Tree/Assessment Group";
|
||||
}
|
||||
});
|
@ -1,90 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:assessment_group_name",
|
||||
"creation": "2016-08-04 04:42:48.319388",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"field_order": [
|
||||
"assessment_group_name",
|
||||
"is_group",
|
||||
"section_break_2",
|
||||
"parent_assessment_group",
|
||||
"lft",
|
||||
"rgt",
|
||||
"old_parent"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "assessment_group_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Assessment Group Name",
|
||||
"reqd": 1,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_group",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Group"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "parent_assessment_group",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Parent Assessment Group",
|
||||
"options": "Assessment Group",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"label": "lft"
|
||||
},
|
||||
{
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"label": "rgt"
|
||||
},
|
||||
{
|
||||
"fieldname": "old_parent",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "old_parent",
|
||||
"options": "Assessment Group"
|
||||
}
|
||||
],
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2020-03-18 18:01:14.710416",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Group",
|
||||
"nsm_parent_field": "parent_assessment_group",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"restrict_to_domain": "Education",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class AssessmentGroup(Document):
|
||||
pass
|
@ -1,11 +0,0 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
"fieldname": "assessment_group",
|
||||
"transactions": [{"label": _("Assessment"), "items": ["Assessment Plan", "Assessment Result"]}],
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
frappe.treeview_settings["Assessment Group"] = {
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Assessment Group')
|
||||
|
||||
|
||||
class TestAssessmentGroup(unittest.TestCase):
|
||||
pass
|
@ -1,78 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.ui.form.on('Assessment Plan', {
|
||||
onload: function(frm) {
|
||||
frm.set_query('assessment_group', function(doc, cdt, cdn) {
|
||||
return{
|
||||
filters: {
|
||||
'is_group': 0
|
||||
}
|
||||
};
|
||||
});
|
||||
frm.set_query('grading_scale', function(){
|
||||
return {
|
||||
filters: {
|
||||
docstatus: 1
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if (frm.doc.docstatus == 1) {
|
||||
frm.add_custom_button(__('Assessment Result Tool'), function() {
|
||||
frappe.route_options = {
|
||||
assessment_plan: frm.doc.name,
|
||||
student_group: frm.doc.student_group
|
||||
}
|
||||
frappe.set_route('Form', 'Assessment Result Tool');
|
||||
}, __('Tools'));
|
||||
}
|
||||
|
||||
frm.set_query('course', function() {
|
||||
return {
|
||||
query: 'erpnext.education.doctype.program_enrollment.program_enrollment.get_program_courses',
|
||||
filters: {
|
||||
'program': frm.doc.program
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query('academic_term', function() {
|
||||
return {
|
||||
filters: {
|
||||
'academic_year': frm.doc.academic_year
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
course: function(frm) {
|
||||
if (frm.doc.course && frm.doc.maximum_assessment_score) {
|
||||
frappe.call({
|
||||
method: 'erpnext.education.api.get_assessment_criteria',
|
||||
args: {
|
||||
course: frm.doc.course
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
frm.doc.assessment_criteria = [];
|
||||
$.each(r.message, function(i, d) {
|
||||
var row = frappe.model.add_child(frm.doc, 'Assessment Plan Criteria', 'assessment_criteria');
|
||||
row.assessment_criteria = d.assessment_criteria;
|
||||
row.maximum_score = d.weightage / 100 * frm.doc.maximum_assessment_score;
|
||||
});
|
||||
}
|
||||
refresh_field('assessment_criteria');
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
maximum_assessment_score: function(frm) {
|
||||
frm.trigger('course');
|
||||
}
|
||||
});
|
@ -1,227 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"autoname": "EDU-ASP-.YYYY.-.#####",
|
||||
"creation": "2015-11-12 16:34:34.658092",
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"student_group",
|
||||
"assessment_name",
|
||||
"assessment_group",
|
||||
"grading_scale",
|
||||
"column_break_2",
|
||||
"program",
|
||||
"course",
|
||||
"academic_year",
|
||||
"academic_term",
|
||||
"section_break_5",
|
||||
"schedule_date",
|
||||
"room",
|
||||
"examiner",
|
||||
"examiner_name",
|
||||
"column_break_4",
|
||||
"from_time",
|
||||
"to_time",
|
||||
"supervisor",
|
||||
"supervisor_name",
|
||||
"section_break_20",
|
||||
"maximum_assessment_score",
|
||||
"assessment_criteria",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "student_group",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Student Group",
|
||||
"options": "Student Group",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "assessment_name",
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"label": "Assessment Name"
|
||||
},
|
||||
{
|
||||
"fieldname": "assessment_group",
|
||||
"fieldtype": "Link",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Assessment Group",
|
||||
"options": "Assessment Group",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "course.default_grading_scale",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "grading_scale",
|
||||
"fieldtype": "Link",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Grading Scale",
|
||||
"options": "Grading Scale",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fetch_from": "student_group.course",
|
||||
"fetch_if_empty": 1,
|
||||
"fieldname": "course",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Course",
|
||||
"options": "Course",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "student_group.program",
|
||||
"fieldname": "program",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"label": "Program",
|
||||
"options": "Program"
|
||||
},
|
||||
{
|
||||
"fetch_from": "student_group.academic_year",
|
||||
"fieldname": "academic_year",
|
||||
"fieldtype": "Link",
|
||||
"label": "Academic Year",
|
||||
"options": "Academic Year"
|
||||
},
|
||||
{
|
||||
"fetch_from": "student_group.academic_term",
|
||||
"fieldname": "academic_term",
|
||||
"fieldtype": "Link",
|
||||
"label": "Academic Term",
|
||||
"options": "Academic Term"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Schedule"
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"in_list_view": 1,
|
||||
"label": "Schedule Date",
|
||||
"no_copy": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "room",
|
||||
"fieldtype": "Link",
|
||||
"label": "Room",
|
||||
"options": "Room"
|
||||
},
|
||||
{
|
||||
"fieldname": "examiner",
|
||||
"fieldtype": "Link",
|
||||
"label": "Examiner",
|
||||
"options": "Instructor"
|
||||
},
|
||||
{
|
||||
"fetch_from": "examiner.instructor_name",
|
||||
"fieldname": "examiner_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Examiner Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "from_time",
|
||||
"fieldtype": "Time",
|
||||
"label": "From Time",
|
||||
"no_copy": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "to_time",
|
||||
"fieldtype": "Time",
|
||||
"label": "To Time",
|
||||
"no_copy": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "supervisor",
|
||||
"fieldtype": "Link",
|
||||
"label": "Supervisor",
|
||||
"options": "Instructor"
|
||||
},
|
||||
{
|
||||
"fetch_from": "supervisor.instructor_name",
|
||||
"fieldname": "supervisor_name",
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"label": "Supervisor Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_20",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Evaluate"
|
||||
},
|
||||
{
|
||||
"fieldname": "maximum_assessment_score",
|
||||
"fieldtype": "Float",
|
||||
"label": "Maximum Assessment Score",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "assessment_criteria",
|
||||
"fieldtype": "Table",
|
||||
"label": "Assessment Criteria",
|
||||
"options": "Assessment Plan Criteria",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Assessment Plan",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-10-23 15:55:35.076251",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Plan",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"restrict_to_domain": "Education",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "assessment_name"
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class AssessmentPlan(Document):
|
||||
def validate(self):
|
||||
self.validate_overlap()
|
||||
self.validate_max_score()
|
||||
self.validate_assessment_criteria()
|
||||
|
||||
def validate_overlap(self):
|
||||
"""Validates overlap for Student Group, Instructor, Room"""
|
||||
|
||||
from erpnext.education.utils import validate_overlap_for
|
||||
|
||||
# Validate overlapping course schedules.
|
||||
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_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_max_score(self):
|
||||
max_score = 0
|
||||
for d in self.assessment_criteria:
|
||||
max_score += d.maximum_score
|
||||
if self.maximum_assessment_score != max_score:
|
||||
frappe.throw(
|
||||
_("Sum of Scores of Assessment Criteria needs to be {0}.").format(
|
||||
self.maximum_assessment_score
|
||||
)
|
||||
)
|
||||
|
||||
def validate_assessment_criteria(self):
|
||||
assessment_criteria_list = frappe.db.sql_list(
|
||||
""" select apc.assessment_criteria
|
||||
from `tabAssessment Plan` ap , `tabAssessment Plan Criteria` apc
|
||||
where ap.name = apc.parent and ap.course=%s and ap.student_group=%s and ap.assessment_group=%s
|
||||
and ap.name != %s and ap.docstatus=1""",
|
||||
(self.course, self.student_group, self.assessment_group, self.name),
|
||||
)
|
||||
for d in self.assessment_criteria:
|
||||
if d.assessment_criteria in assessment_criteria_list:
|
||||
frappe.throw(
|
||||
_("You have already assessed for the assessment criteria {}.").format(
|
||||
frappe.bold(d.assessment_criteria)
|
||||
)
|
||||
)
|
@ -1,12 +0,0 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
"fieldname": "assessment_plan",
|
||||
"transactions": [{"label": _("Assessment"), "items": ["Assessment Result"]}],
|
||||
"reports": [{"label": _("Report"), "items": ["Assessment Plan Status"]}],
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('Assessment Plan')
|
||||
|
||||
|
||||
class TestAssessmentPlan(unittest.TestCase):
|
||||
pass
|
@ -1,134 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2016-12-14 17:20:27.738226",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "assessment_criteria",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Assessment Criteria",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Assessment 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_bulk_edit": 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_global_search": 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_bulk_edit": 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_global_search": 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": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:10:50.560006",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Plan Criteria",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class AssessmentPlanCriteria(Document):
|
||||
pass
|
@ -1,125 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Assessment Result', {
|
||||
refresh: function(frm) {
|
||||
if (!frm.doc.__islocal) {
|
||||
frm.trigger('setup_chart');
|
||||
}
|
||||
|
||||
frm.get_field('details').grid.cannot_add_rows = true;
|
||||
|
||||
frm.set_query('course', function() {
|
||||
return {
|
||||
query: 'erpnext.education.doctype.program_enrollment.program_enrollment.get_program_courses',
|
||||
filters: {
|
||||
'program': frm.doc.program
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query('academic_term', function() {
|
||||
return {
|
||||
filters: {
|
||||
'academic_year': frm.doc.academic_year
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
frm.set_query('assessment_plan', function() {
|
||||
return {
|
||||
filters: {
|
||||
docstatus: 1
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
assessment_plan: function(frm) {
|
||||
if (frm.doc.assessment_plan) {
|
||||
frappe.call({
|
||||
method: 'erpnext.education.api.get_assessment_details',
|
||||
args: {
|
||||
assessment_plan: frm.doc.assessment_plan
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
frappe.model.clear_table(frm.doc, 'details');
|
||||
$.each(r.message, function(i, d) {
|
||||
var row = frm.add_child('details');
|
||||
row.assessment_criteria = d.assessment_criteria;
|
||||
row.maximum_score = d.maximum_score;
|
||||
});
|
||||
frm.refresh_field('details');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
setup_chart: function(frm) {
|
||||
let labels = [];
|
||||
let maximum_scores = [];
|
||||
let scores = [];
|
||||
$.each(frm.doc.details, function(_i, e) {
|
||||
labels.push(e.assessment_criteria);
|
||||
maximum_scores.push(e.maximum_score);
|
||||
scores.push(e.score);
|
||||
});
|
||||
|
||||
if (labels.length && maximum_scores.length && scores.length) {
|
||||
frm.dashboard.chart_area.empty().removeClass('hidden');
|
||||
new frappe.Chart('.form-graph', {
|
||||
title: 'Assessment Results',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{
|
||||
name: 'Maximum Score',
|
||||
chartType: 'bar',
|
||||
values: maximum_scores,
|
||||
},
|
||||
{
|
||||
name: 'Score Obtained',
|
||||
chartType: 'bar',
|
||||
values: scores,
|
||||
}
|
||||
]
|
||||
},
|
||||
colors: ['#4CA746', '#98D85B'],
|
||||
type: 'bar'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Assessment Result Detail', {
|
||||
score: function(frm, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
|
||||
if (!d.maximum_score || !frm.doc.grading_scale) {
|
||||
d.score = '';
|
||||
frappe.throw(__('Please fill in all the details to generate Assessment Result.'));
|
||||
}
|
||||
|
||||
if (d.score > d.maximum_score) {
|
||||
frappe.throw(__('Score cannot be greater than Maximum Score'));
|
||||
}
|
||||
else {
|
||||
frappe.call({
|
||||
method: 'erpnext.education.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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
@ -1,203 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_import": 1,
|
||||
"autoname": "EDU-RES-.YYYY.-.#####",
|
||||
"creation": "2015-11-13 17:18:06.468332",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"assessment_plan",
|
||||
"program",
|
||||
"course",
|
||||
"academic_year",
|
||||
"academic_term",
|
||||
"column_break_3",
|
||||
"student",
|
||||
"student_name",
|
||||
"student_group",
|
||||
"assessment_group",
|
||||
"grading_scale",
|
||||
"section_break_5",
|
||||
"details",
|
||||
"section_break_8",
|
||||
"maximum_score",
|
||||
"column_break_11",
|
||||
"total_score",
|
||||
"grade",
|
||||
"section_break_13",
|
||||
"comment",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "assessment_plan",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Assessment Plan",
|
||||
"options": "Assessment Plan",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.program",
|
||||
"fieldname": "program",
|
||||
"fieldtype": "Link",
|
||||
"label": "Program",
|
||||
"options": "Program"
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.course",
|
||||
"fieldname": "course",
|
||||
"fieldtype": "Link",
|
||||
"label": "Course",
|
||||
"options": "Course"
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.academic_year",
|
||||
"fieldname": "academic_year",
|
||||
"fieldtype": "Link",
|
||||
"label": "Academic Year",
|
||||
"options": "Academic Year"
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.academic_term",
|
||||
"fieldname": "academic_term",
|
||||
"fieldtype": "Link",
|
||||
"label": "Academic Term",
|
||||
"options": "Academic Term"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "student",
|
||||
"fieldtype": "Link",
|
||||
"in_global_search": 1,
|
||||
"label": "Student",
|
||||
"options": "Student",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "student.title",
|
||||
"fieldname": "student_name",
|
||||
"fieldtype": "Data",
|
||||
"in_global_search": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Student Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.student_group",
|
||||
"fieldname": "student_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Student Group",
|
||||
"options": "Student Group"
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.assessment_group",
|
||||
"fieldname": "assessment_group",
|
||||
"fieldtype": "Link",
|
||||
"label": "Assessment Group",
|
||||
"options": "Assessment Group"
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.grading_scale",
|
||||
"fieldname": "grading_scale",
|
||||
"fieldtype": "Link",
|
||||
"label": "Grading Scale",
|
||||
"options": "Grading Scale",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Result"
|
||||
},
|
||||
{
|
||||
"fieldname": "details",
|
||||
"fieldtype": "Table",
|
||||
"label": "Details",
|
||||
"options": "Assessment Result Detail",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.maximum_assessment_score",
|
||||
"fieldname": "maximum_score",
|
||||
"fieldtype": "Float",
|
||||
"label": "Maximum Score",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fetch_from": "assessment_plan.maximum_assessment_score",
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_score",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Total Score",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "grade",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Grade",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_13",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Summary"
|
||||
},
|
||||
{
|
||||
"fieldname": "comment",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Comment"
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"label": "Amended From",
|
||||
"no_copy": 1,
|
||||
"options": "Assessment Result",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-08-03 11:47:54.119486",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Result",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 1,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Academics User",
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "student_name"
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import flt
|
||||
from frappe.utils.csvutils import getlink
|
||||
|
||||
import erpnext.education
|
||||
from erpnext.education.api import get_assessment_details, get_grade
|
||||
|
||||
|
||||
class AssessmentResult(Document):
|
||||
def validate(self):
|
||||
erpnext.education.validate_student_belongs_to_group(self.student, self.student_group)
|
||||
self.validate_maximum_score()
|
||||
self.validate_grade()
|
||||
self.validate_duplicate()
|
||||
|
||||
def validate_maximum_score(self):
|
||||
assessment_details = get_assessment_details(self.assessment_plan)
|
||||
max_scores = {}
|
||||
for d in assessment_details:
|
||||
max_scores.update({d.assessment_criteria: d.maximum_score})
|
||||
|
||||
for d in self.details:
|
||||
d.maximum_score = max_scores.get(d.assessment_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)
|
||||
|
||||
def validate_duplicate(self):
|
||||
assessment_result = frappe.get_list(
|
||||
"Assessment Result",
|
||||
filters={
|
||||
"name": ("not in", [self.name]),
|
||||
"student": self.student,
|
||||
"assessment_plan": self.assessment_plan,
|
||||
"docstatus": ("!=", 2),
|
||||
},
|
||||
)
|
||||
if assessment_result:
|
||||
frappe.throw(
|
||||
_("Assessment Result record {0} already exists.").format(
|
||||
getlink("Assessment Result", assessment_result[0].name)
|
||||
)
|
||||
)
|
@ -1,12 +0,0 @@
|
||||
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_data():
|
||||
return {
|
||||
"reports": [
|
||||
{"label": _("Reports"), "items": ["Final Assessment Grades", "Course wise Assessment Report"]}
|
||||
]
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
|
||||
import unittest
|
||||
|
||||
from erpnext.education.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.assertEqual("A", grade)
|
||||
|
||||
grade = get_grade("_Test Grading Scale", 70)
|
||||
self.assertEqual("B", grade)
|
@ -1,66 +0,0 @@
|
||||
{
|
||||
"actions": [],
|
||||
"creation": "2016-12-14 17:44:35.583123",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"assessment_criteria",
|
||||
"maximum_score",
|
||||
"column_break_2",
|
||||
"score",
|
||||
"grade"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"columns": 4,
|
||||
"fieldname": "assessment_criteria",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Assessment Criteria",
|
||||
"options": "Assessment Criteria",
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "maximum_score",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Maximum Score",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "score",
|
||||
"fieldtype": "Float",
|
||||
"in_list_view": 1,
|
||||
"label": "Score",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"columns": 2,
|
||||
"fieldname": "grade",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Grade",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2020-07-31 13:27:17.699022",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Result Detail",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"restrict_to_domain": "Education",
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC"
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class AssessmentResultDetail(Document):
|
||||
pass
|
@ -1,162 +0,0 @@
|
||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
|
||||
frappe.ui.form.on('Assessment Result Tool', {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("assessment_plan", "student_group", "student_group");
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if (frappe.route_options) {
|
||||
frm.set_value("student_group", frappe.route_options.student_group);
|
||||
frm.set_value("assessment_plan", frappe.route_options.assessment_plan);
|
||||
frappe.route_options = null;
|
||||
} else {
|
||||
frm.trigger("assessment_plan");
|
||||
}
|
||||
frm.disable_save();
|
||||
frm.page.clear_indicator();
|
||||
},
|
||||
|
||||
assessment_plan: function(frm) {
|
||||
frm.doc.show_submit = false;
|
||||
if(frm.doc.assessment_plan) {
|
||||
if (!frm.doc.student_group)
|
||||
return
|
||||
frappe.call({
|
||||
method: "erpnext.education.api.get_assessment_students",
|
||||
args: {
|
||||
"assessment_plan": frm.doc.assessment_plan,
|
||||
"student_group": frm.doc.student_group
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
frm.doc.students = r.message;
|
||||
frm.events.render_table(frm);
|
||||
for (let value of r.message) {
|
||||
if (!value.docstatus) {
|
||||
frm.doc.show_submit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
frm.events.submit_result(frm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render_table: function(frm) {
|
||||
$(frm.fields_dict.result_html.wrapper).empty();
|
||||
let assessment_plan = frm.doc.assessment_plan;
|
||||
frappe.call({
|
||||
method: "erpnext.education.api.get_assessment_details",
|
||||
args: {
|
||||
assessment_plan: assessment_plan
|
||||
},
|
||||
callback: function(r) {
|
||||
frm.events.get_marks(frm, r.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_marks: function(frm, criteria_list) {
|
||||
let max_total_score = 0;
|
||||
criteria_list.forEach(function(c) {
|
||||
max_total_score += c.maximum_score
|
||||
});
|
||||
var result_table = $(frappe.render_template('assessment_result_tool', {
|
||||
frm: frm,
|
||||
students: frm.doc.students,
|
||||
criteria: criteria_list,
|
||||
max_total_score: max_total_score
|
||||
}));
|
||||
result_table.appendTo(frm.fields_dict.result_html.wrapper);
|
||||
|
||||
result_table.on('change', 'input', function(e) {
|
||||
let $input = $(e.target);
|
||||
let student = $input.data().student;
|
||||
let max_score = $input.data().maxScore;
|
||||
let value = $input.val();
|
||||
if(value < 0) {
|
||||
$input.val(0);
|
||||
} else if(value > max_score) {
|
||||
$input.val(max_score);
|
||||
}
|
||||
let total_score = 0;
|
||||
let student_scores = {};
|
||||
student_scores["assessment_details"] = {}
|
||||
result_table.find(`input[data-student=${student}].student-result-data`)
|
||||
.each(function(el, input) {
|
||||
let $input = $(input);
|
||||
let criteria = $input.data().criteria;
|
||||
let value = parseFloat($input.val());
|
||||
if (!Number.isNaN(value)) {
|
||||
student_scores["assessment_details"][criteria] = value;
|
||||
}
|
||||
total_score += value;
|
||||
});
|
||||
if(!Number.isNaN(total_score)) {
|
||||
result_table.find(`span[data-student=${student}].total-score`).html(total_score);
|
||||
}
|
||||
if (Object.keys(student_scores["assessment_details"]).length === criteria_list.length) {
|
||||
student_scores["student"] = student;
|
||||
student_scores["total_score"] = total_score;
|
||||
result_table.find(`[data-student=${student}].result-comment`)
|
||||
.each(function(el, input){
|
||||
student_scores["comment"] = $(input).val();
|
||||
});
|
||||
frappe.call({
|
||||
method: "erpnext.education.api.mark_assessment_result",
|
||||
args: {
|
||||
"assessment_plan": frm.doc.assessment_plan,
|
||||
"scores": student_scores
|
||||
},
|
||||
callback: function(r) {
|
||||
let assessment_result = r.message;
|
||||
if (!frm.doc.show_submit) {
|
||||
frm.doc.show_submit = true;
|
||||
frm.events.submit_result;
|
||||
}
|
||||
for (var criteria of Object.keys(assessment_result.details)) {
|
||||
result_table.find(`[data-criteria=${criteria}][data-student=${assessment_result
|
||||
.student}].student-result-grade`).each(function(e1, input) {
|
||||
$(input).html(assessment_result.details[criteria]);
|
||||
});
|
||||
}
|
||||
result_table.find(`span[data-student=${assessment_result.student}].total-score-grade`).html(assessment_result.grade);
|
||||
let link_span = result_table.find(`span[data-student=${assessment_result.student}].total-result-link`);
|
||||
$(link_span).css("display", "block");
|
||||
$(link_span).find("a").attr("href", "/app/assessment-result/"+assessment_result.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
submit_result: function(frm) {
|
||||
if (frm.doc.show_submit) {
|
||||
frm.page.set_primary_action(__("Submit"), function() {
|
||||
frappe.call({
|
||||
method: "erpnext.education.api.submit_assessment_results",
|
||||
args: {
|
||||
"assessment_plan": frm.doc.assessment_plan,
|
||||
"student_group": frm.doc.student_group
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
frappe.msgprint(__("{0} Result submittted", [r.message]));
|
||||
} else {
|
||||
frappe.msgprint(__("No Result to submit"));
|
||||
}
|
||||
frm.events.assessment_plan(frm);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
frm.page.clear_primary_action();
|
||||
}
|
||||
}
|
||||
});
|
@ -1,235 +0,0 @@
|
||||
{
|
||||
"allow_copy": 1,
|
||||
"allow_guest_to_view": 0,
|
||||
"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_bulk_edit": 0,
|
||||
"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_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"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_bulk_edit": 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_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "student_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Student 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": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "assessment_plan",
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "result_html",
|
||||
"fieldtype": "HTML",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "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
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 1,
|
||||
"hide_toolbar": 1,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-27 09:36:37.155890",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Result Tool",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Academics User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Instructor",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"restrict_to_domain": "Education",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user