Merge branch 'develop' into rfq-multi-uom

This commit is contained in:
Marica 2020-06-18 14:44:46 +05:30 committed by GitHub
commit d6906dccfe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 709 additions and 862 deletions

View File

@ -11,4 +11,4 @@ jobs:
- name: curl
run: |
apk add curl bash
curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token ${{ secrets.TRAVIS_CI_TOKEN }}" -d '{"request":{"branch":"master"}}' https://api.travis-ci.org/repo/frappe%2Ffrappe_docker/requests
curl -s -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Travis-API-Version: 3" -H "Authorization: token ${{ secrets.TRAVIS_CI_TOKEN }}" -d '{"request":{"branch":"master"}}' https://api.travis-ci.com/repo/frappe%2Ffrappe_docker/requests

View File

@ -146,7 +146,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2020-04-29 16:09:30.025214",
"modified": "2020-06-17 16:09:30.025214",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cost Center",

View File

@ -102,7 +102,7 @@ def validate_item_attribute_value(attributes_list, attribute, attribute_value, i
frappe.throw(_("{0} is not a valid Value for Attribute {1} of Item {2}.").format(
frappe.bold(attribute_value), frappe.bold(attribute), frappe.bold(item)), InvalidItemAttributeValueError, title=_("Invalid Value"))
else:
msg = _("The value {0} is already assigned to an exisiting Item {1}.").format(
msg = _("The value {0} is already assigned to an existing Item {1}.").format(
frappe.bold(attribute_value), frappe.bold(item))
msg += "<br>" + _("To still proceed with editing this Attribute Value, enable {0} in Item Variant Settings.").format(frappe.bold("Allow Rename Attribute Value"))

View File

@ -227,7 +227,9 @@ class StockController(AccountsController):
def check_expense_account(self, item):
if not item.get("expense_account"):
frappe.throw(_("Expense Account not set for Item {0}. Please set an Expense Account for the item in the Items table").format(item.item_code))
frappe.throw(_("Row #{0}: Expense Account not set for Item {1}. Please set an Expense \
Account in the Items table").format(item.idx, frappe.bold(item.item_code)),
title=_("Expense Account Missing"))
else:
is_expense_account = frappe.db.get_value("Account",

View File

@ -9,6 +9,14 @@ frappe.ui.form.on('Fee Structure', {
},
onload: function(frm) {
frm.set_query("academic_term", function() {
return {
"filters": {
"academic_year": frm.doc.academic_year
}
};
});
frm.set_query("receivable_account", function(doc) {
return {
filters: {

View File

@ -1,4 +1,5 @@
{
"actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "naming_series:",
@ -11,8 +12,8 @@
"program",
"student_category",
"column_break_2",
"academic_term",
"academic_year",
"academic_term",
"section_break_4",
"components",
"section_break_6",
@ -157,7 +158,8 @@
],
"icon": "fa fa-flag",
"is_submittable": 1,
"modified": "2019-05-26 09:04:17.765758",
"links": [],
"modified": "2020-06-16 15:34:57.295010",
"modified_by": "Administrator",
"module": "Education",
"name": "Fee Structure",

View File

@ -1,398 +1,119 @@
{
"allow_copy": 0,
"allow_guest_to_view": 1,
"allow_import": 0,
"allow_rename": 1,
"autoname": "",
"beta": 0,
"creation": "2016-09-13 03:05:27.154713",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 1,
"actions": [],
"allow_guest_to_view": 1,
"allow_rename": 1,
"creation": "2016-09-13 03:05:27.154713",
"doctype": "DocType",
"document_type": "Document",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"title",
"route",
"column_break_3",
"academic_year",
"admission_start_date",
"admission_end_date",
"published",
"enable_admission_application",
"section_break_5",
"program_details",
"introduction"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "title",
"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": "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
},
"fieldname": "title",
"fieldtype": "Data",
"label": "Title"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "",
"fieldname": "route",
"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": "Route",
"length": 0,
"no_copy": 1,
"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,
"fieldname": "route",
"fieldtype": "Data",
"label": "Route",
"no_copy": 1,
"unique": 1
},
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "application_form_route",
"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": "Application Form Route",
"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
},
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "academic_year",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Academic Year",
"no_copy": 1,
"options": "Academic Year",
"reqd": 1
},
{
"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": 1,
"in_standard_filter": 1,
"label": "Academic Year",
"length": 0,
"no_copy": 1,
"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
},
"fieldname": "admission_start_date",
"fieldtype": "Date",
"label": "Admission Start Date",
"no_copy": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "admission_start_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Admission Start Date",
"length": 0,
"no_copy": 1,
"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
},
"fieldname": "admission_end_date",
"fieldtype": "Date",
"label": "Admission End Date",
"no_copy": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "admission_end_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Admission End Date",
"length": 0,
"no_copy": 1,
"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
},
"default": "0",
"fieldname": "published",
"fieldtype": "Check",
"label": "Publish on website"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "published",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Publish on website",
"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
},
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"label": "Eligibility and Details"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Eligibility and Details",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
"fieldname": "program_details",
"fieldtype": "Table",
"label": "Eligibility and Details",
"options": "Student Admission Program"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "program_details",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Eligibility and Details",
"length": 0,
"no_copy": 0,
"options": "Student Admission Program",
"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
},
"fieldname": "introduction",
"fieldtype": "Text Editor",
"label": "Introduction"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "introduction",
"fieldtype": "Text Editor",
"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": "Introduction",
"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
"default": "0",
"fieldname": "enable_admission_application",
"fieldtype": "Check",
"label": "Enable Admission Application"
}
],
"has_web_view": 1,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_published_field": "published",
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2017-11-10 18:57:34.570376",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Admission",
"name_case": "",
"owner": "Administrator",
],
"has_web_view": 1,
"is_published_field": "published",
"links": [],
"modified": "2020-06-15 20:18:38.591626",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Admission",
"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,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Academics User",
"share": 1,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Education",
"route": "admissions",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 0,
"track_seen": 0
],
"restrict_to_domain": "Education",
"route": "admissions",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title"
}

View File

@ -43,8 +43,8 @@
<thead>
<tr class="active">
<th style="width: 90px">Program/Std.</th>
<th style="width: 170px">Minumum Age(DOB)</th>
<th style="width: 170px">Maximum Age(DOB)</th>
<th style="width: 170px">Minumum Age</th>
<th style="width: 170px">Maximum Age</th>
<th style="width: 100px">Application Fee</th>
</tr>
</thead>
@ -52,8 +52,8 @@
{% for row in program_details %}
<tr>
<td>{{ row.program }}</td>
<td>{{ row.minimum_age }}</td>
<td>{{ row.maximum_age }}</td>
<td>{{ row.min_age }}</td>
<td>{{ row.max_age }}</td>
<td>{{ row.application_fee }}</td>
</tr>
{% endfor %}
@ -61,12 +61,11 @@
</table>
</div>
{% endif %}
{%- if application_form_route -%}
{%- if doc.enable_admission_application -%}
<br>
<p>
<a class='btn btn-primary'
href='/{{ doc.application_form_route }}?new=1'>
href='/student-applicant?new=1&student_admission={{doc.name}}'>
{{ _("Apply Now") }}</a>
</p>
{% endif %}

View File

@ -11,7 +11,7 @@ QUnit.test('Test: Student Admission', function(assert) {
{admission_start_date: '2016-04-20'},
{admission_end_date: '2016-05-31'},
{title: '2016-17 Admissions'},
{application_form_route: 'student-applicant'},
{enable_admission_application: 1},
{introduction: 'Test intro'},
{program_details: [
[
@ -28,7 +28,7 @@ QUnit.test('Test: Student Admission', function(assert) {
assert.ok(cur_frm.doc.admission_start_date == '2016-04-20');
assert.ok(cur_frm.doc.admission_end_date == '2016-05-31');
assert.ok(cur_frm.doc.title == '2016-17 Admissions');
assert.ok(cur_frm.doc.application_form_route == 'student-applicant');
assert.ok(cur_frm.doc.enable_admission_application == 1);
assert.ok(cur_frm.doc.introduction == 'Test intro');
assert.ok(cur_frm.doc.program_details[0].program == 'Standard Test', 'Program correctly selected');
assert.ok(cur_frm.doc.program_details[0].application_fee == 1000);

View File

@ -1,237 +1,77 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"autoname": "",
"beta": 0,
"creation": "2017-09-15 12:59:43.207923",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"actions": [],
"creation": "2017-09-15 12:59:43.207923",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"program",
"min_age",
"max_age",
"column_break_4",
"application_fee",
"applicant_naming_series"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "program",
"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": "Program",
"length": 0,
"no_copy": 0,
"options": "Program",
"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,
"translatable": 0,
"unique": 0
},
"fieldname": "program",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Program",
"options": "Program",
"show_days": 1,
"show_seconds": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "minimum_age",
"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": "Minimum Age",
"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,
"translatable": 0,
"unique": 0
},
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "maximum_age",
"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": "Maximum Age",
"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,
"translatable": 0,
"unique": 0
},
"fieldname": "application_fee",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Application Fee",
"show_days": 1,
"show_seconds": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_4",
"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,
"translatable": 0,
"unique": 0
},
"fieldname": "applicant_naming_series",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Naming Series (for Student Applicant)",
"show_days": 1,
"show_seconds": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "application_fee",
"fieldtype": "Currency",
"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": "Application Fee",
"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,
"translatable": 0,
"unique": 0
},
"fieldname": "min_age",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Minimum Age",
"show_days": 1,
"show_seconds": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "applicant_naming_series",
"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": "Naming Series (for Student Applicant)",
"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,
"translatable": 0,
"unique": 0
"fieldname": "max_age",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Maximum Age",
"show_days": 1,
"show_seconds": 1
}
],
"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": "2018-11-04 03:37:17.408427",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Admission Program",
"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": 1,
"track_seen": 0,
"track_views": 0
],
"istable": 1,
"links": [],
"modified": "2020-06-10 23:06:30.037404",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Admission Program",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"restrict_to_domain": "Education",
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@ -6,7 +6,7 @@ from __future__ import print_function, unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import getdate
from frappe.utils import getdate, add_years, nowdate, date_diff
class StudentApplicant(Document):
def autoname(self):
@ -31,6 +31,7 @@ class StudentApplicant(Document):
def validate(self):
self.validate_dates()
self.title = " ".join(filter(None, [self.first_name, self.middle_name, self.last_name]))
if self.student_admission and self.program and self.date_of_birth:
self.validation_from_student_admission()
@ -48,16 +49,16 @@ class StudentApplicant(Document):
frappe.throw(_("Please select Student Admission which is mandatory for the paid student applicant"))
def validation_from_student_admission(self):
student_admission = get_student_admission_data(self.student_admission, self.program)
# different validation for minimum and maximum age so that either min/max can also work independently.
if student_admission and student_admission.minimum_age and \
getdate(student_admission.minimum_age) < getdate(self.date_of_birth):
frappe.throw(_("Not eligible for the admission in this program as per DOB"))
if student_admission and student_admission.min_age and \
date_diff(nowdate(), add_years(getdate(self.date_of_birth), student_admission.min_age)) < 0:
frappe.throw(_("Not eligible for the admission in this program as per Date Of Birth"))
if student_admission and student_admission.maximum_age and \
getdate(student_admission.maximum_age) > getdate(self.date_of_birth):
frappe.throw(_("Not eligible for the admission in this program as per DOB"))
if student_admission and student_admission.max_age and \
date_diff(nowdate(), add_years(getdate(self.date_of_birth), student_admission.max_age)) > 0:
frappe.throw(_("Not eligible for the admission in this program as per Date Of Birth"))
def on_payment_authorized(self, *args, **kwargs):
@ -65,10 +66,12 @@ class StudentApplicant(Document):
def get_student_admission_data(student_admission, program):
student_admission = frappe.db.sql("""select sa.admission_start_date, sa.admission_end_date,
sap.program, sap.minimum_age, sap.maximum_age, sap.applicant_naming_series
sap.program, sap.min_age, sap.max_age, sap.applicant_naming_series
from `tabStudent Admission` sa, `tabStudent Admission Program` sap
where sa.name = sap.parent and sa.name = %s and sap.program = %s""", (student_admission, program), as_dict=1)
if student_admission:
return student_admission[0]
else:

View File

@ -1,200 +1,248 @@
{
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 1,
"allow_incomplete": 0,
"allow_multiple": 1,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"creation": "2016-09-22 13:10:10.792735",
"doc_type": "Student Applicant",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2017-02-21 05:44:46.022738",
"modified_by": "Administrator",
"module": "Education",
"name": "student-applicant",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "student-applicant",
"show_sidebar": 1,
"sidebar_items": [],
"success_url": "/student-applicant",
"title": "Student Applicant",
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 1,
"allow_incomplete": 0,
"allow_multiple": 1,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"creation": "2016-09-22 13:10:10.792735",
"doc_type": "Student Applicant",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2020-06-11 22:53:45.875310",
"modified_by": "Administrator",
"module": "Education",
"name": "student-applicant",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "student-applicant",
"route_to_success_link": 0,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 1,
"sidebar_items": [],
"success_url": "/student-applicant",
"title": "Student Applicant",
"web_form_fields": [
{
"fieldname": "first_name",
"fieldtype": "Data",
"hidden": 0,
"label": "First Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1
},
"allow_read_on_all_link_options": 0,
"fieldname": "first_name",
"fieldtype": "Data",
"hidden": 0,
"label": "First Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"fieldname": "middle_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Middle Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "middle_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Middle Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "last_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Last Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "last_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Last Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "image",
"fieldtype": "Data",
"hidden": 0,
"label": "Image",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "image",
"fieldtype": "Data",
"hidden": 0,
"label": "Image",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "program",
"fieldtype": "Link",
"hidden": 0,
"label": "Program",
"max_length": 0,
"max_value": 0,
"options": "Program",
"read_only": 0,
"reqd": 1
},
"allow_read_on_all_link_options": 0,
"fieldname": "program",
"fieldtype": "Link",
"hidden": 0,
"label": "Program",
"max_length": 0,
"max_value": 0,
"options": "Program",
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"fieldname": "academic_year",
"fieldtype": "Link",
"hidden": 0,
"label": "Academic Year",
"max_length": 0,
"max_value": 0,
"options": "Academic Year",
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "academic_year",
"fieldtype": "Link",
"hidden": 0,
"label": "Academic Year",
"max_length": 0,
"max_value": 0,
"options": "Academic Year",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "date_of_birth",
"fieldtype": "Date",
"hidden": 0,
"label": "Date of Birth",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "date_of_birth",
"fieldtype": "Date",
"hidden": 0,
"label": "Date of Birth",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "blood_group",
"fieldtype": "Select",
"hidden": 0,
"label": "Blood Group",
"max_length": 0,
"max_value": 0,
"options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-",
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "blood_group",
"fieldtype": "Select",
"hidden": 0,
"label": "Blood Group",
"max_length": 0,
"max_value": 0,
"options": "\nA+\nA-\nB+\nB-\nO+\nO-\nAB+\nAB-",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "student_email_id",
"fieldtype": "Data",
"hidden": 0,
"label": "Student Email ID",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "student_email_id",
"fieldtype": "Data",
"hidden": 0,
"label": "Student Email ID",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "student_mobile_number",
"fieldtype": "Data",
"hidden": 0,
"label": "Student Mobile Number",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "student_mobile_number",
"fieldtype": "Data",
"hidden": 0,
"label": "Student Mobile Number",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"default": "INDIAN",
"fieldname": "nationality",
"fieldtype": "Data",
"hidden": 0,
"label": "Nationality",
"max_length": 0,
"max_value": 0,
"options": "",
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"default": "INDIAN",
"fieldname": "nationality",
"fieldtype": "Data",
"hidden": 0,
"label": "Nationality",
"max_length": 0,
"max_value": 0,
"options": "",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "address_line_1",
"fieldtype": "Data",
"hidden": 0,
"label": "Address Line 1",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "address_line_1",
"fieldtype": "Data",
"hidden": 0,
"label": "Address Line 1",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "address_line_2",
"fieldtype": "Data",
"hidden": 0,
"label": "Address Line 2",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "address_line_2",
"fieldtype": "Data",
"hidden": 0,
"label": "Address Line 2",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "pincode",
"fieldtype": "Data",
"hidden": 0,
"label": "Pincode",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "pincode",
"fieldtype": "Data",
"hidden": 0,
"label": "Pincode",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "guardians",
"fieldtype": "Table",
"hidden": 0,
"label": "Guardians",
"max_length": 0,
"max_value": 0,
"options": "Student Guardian",
"read_only": 0,
"reqd": 0
},
"allow_read_on_all_link_options": 0,
"fieldname": "guardians",
"fieldtype": "Table",
"hidden": 0,
"label": "Guardians",
"max_length": 0,
"max_value": 0,
"options": "Student Guardian",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"fieldname": "siblings",
"fieldtype": "Table",
"hidden": 0,
"label": "Siblings",
"max_length": 0,
"max_value": 0,
"options": "Student Sibling",
"read_only": 0,
"reqd": 0
"allow_read_on_all_link_options": 0,
"fieldname": "siblings",
"fieldtype": "Table",
"hidden": 0,
"label": "Siblings",
"max_length": 0,
"max_value": 0,
"options": "Student Sibling",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "student_admission",
"fieldtype": "Link",
"hidden": 0,
"label": "Student Admission",
"max_length": 0,
"max_value": 0,
"options": "Student Admission",
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
}
]
}

View File

@ -8,6 +8,7 @@ import json
from frappe import _
from frappe.model.document import Document
from frappe.utils import get_request_session
from requests.exceptions import HTTPError
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from erpnext.erpnext_integrations.utils import get_webhook_address
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import make_shopify_log
@ -29,19 +30,24 @@ class ShopifySettings(Document):
webhooks = ["orders/create", "orders/paid", "orders/fulfilled"]
# url = get_shopify_url('admin/webhooks.json', self)
created_webhooks = [d.method for d in self.webhooks]
url = get_shopify_url('admin/api/2019-04/webhooks.json', self)
url = get_shopify_url('admin/api/2020-04/webhooks.json', self)
for method in webhooks:
session = get_request_session()
try:
d = session.post(url, data=json.dumps({
res = session.post(url, data=json.dumps({
"webhook": {
"topic": method,
"address": get_webhook_address(connector_name='shopify_connection', method='store_request_data'),
"format": "json"
}
}), headers=get_header(self))
d.raise_for_status()
self.update_webhook_table(method, d.json())
res.raise_for_status()
self.update_webhook_table(method, res.json())
except HTTPError as e:
error_message = res.json().get('errors', e)
make_shopify_log(status="Warning", exception=error_message, rollback=True)
except Exception as e:
make_shopify_log(status="Warning", exception=e, rollback=True)
@ -50,13 +56,18 @@ class ShopifySettings(Document):
deleted_webhooks = []
for d in self.webhooks:
url = get_shopify_url('admin/api/2019-04/webhooks/{0}.json'.format(d.webhook_id), self)
url = get_shopify_url('admin/api/2020-04/webhooks/{0}.json'.format(d.webhook_id), self)
try:
res = session.delete(url, headers=get_header(self))
res.raise_for_status()
deleted_webhooks.append(d)
except HTTPError as e:
error_message = res.json().get('errors', e)
make_shopify_log(status="Warning", exception=error_message, rollback=True)
except Exception as e:
frappe.log_error(message=frappe.get_traceback(), title=e)
frappe.log_error(message=e, title='Shopify Webhooks Issue')
for d in deleted_webhooks:
self.remove(d)
@ -125,4 +136,3 @@ def setup_custom_fields():
}
create_custom_fields(custom_fields)

View File

@ -8,7 +8,7 @@ from erpnext.erpnext_integrations.doctype.shopify_settings.shopify_settings impo
shopify_variants_attr_list = ["option1", "option2", "option3"]
def sync_item_from_shopify(shopify_settings, item):
url = get_shopify_url("admin/api/2019-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
url = get_shopify_url("admin/api/2020-04/products/{0}.json".format(item.get("product_id")), shopify_settings)
session = get_request_session()
try:

View File

@ -70,6 +70,7 @@ def validate_service_item(item, msg):
if frappe.db.get_value('Item', item, 'is_stock_item'):
frappe.throw(_(msg))
@frappe.whitelist()
def get_practitioner_list(doctype, txt, searchfield, start, page_len, filters=None):
fields = ['name', 'practitioner_name', 'mobile_phone']

View File

@ -93,7 +93,7 @@
"idx": 0,
"is_standard": 1,
"label": "HR",
"modified": "2020-06-10 12:41:41.695669",
"modified": "2020-06-16 19:20:50.976045",
"modified_by": "Administrator",
"module": "HR",
"name": "HR",
@ -126,7 +126,7 @@
},
{
"label": "Salary Structure",
"link_to": "Payroll Entry",
"link_to": "Salary Structure",
"type": "DocType"
},
{

View File

@ -119,6 +119,7 @@ class BOM(WebsiteGenerator):
"description": d.description,
"time_in_mins": d.time_in_mins,
"batch_size": d.batch_size,
"operating_cost": d.operating_cost,
"idx": d.idx
})
child.hour_rate = flt(d.hour_rate / self.conversion_rate, 2)

View File

@ -78,6 +78,7 @@
"read_only": 1
},
{
"depends_on": "eval:parent.doctype == 'BOM'",
"fieldname": "base_hour_rate",
"fieldtype": "Currency",
"label": "Base Hour Rate(Company Currency)",
@ -87,6 +88,7 @@
},
{
"default": "5",
"depends_on": "eval:parent.doctype == 'BOM'",
"fieldname": "base_operating_cost",
"fieldtype": "Currency",
"label": "Operating Cost(Company Currency)",
@ -108,12 +110,12 @@
],
"idx": 1,
"istable": 1,
"modified": "2019-07-16 22:35:55.374037",
"modified_by": "govindsmenokee@gmail.com",
"modified": "2020-06-16 17:01:11.128420",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Operation",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC"
}
}

View File

@ -44,7 +44,6 @@ frappe.ui.form.on('BOM Operation', {
name: d.workstation
},
callback: function (data) {
frappe.model.set_value(d.doctype, d.name, "base_hour_rate", data.message.hour_rate);
frappe.model.set_value(d.doctype, d.name, "hour_rate", data.message.hour_rate);
frm.events.calculate_operating_cost(frm, d);
}

View File

@ -698,4 +698,5 @@ erpnext.patches.v12_0.update_uom_conversion_factor
erpnext.patches.v13_0.delete_old_purchase_reports
erpnext.patches.v12_0.set_italian_import_supplier_invoice_permissions
erpnext.patches.v13_0.update_sla_enhancements
erpnext.patches.v12_0.update_address_template_for_india
erpnext.patches.v12_0.set_multi_uom_in_rfq

View File

@ -6,4 +6,6 @@ import frappe
def execute():
''' Move from due_advance_amount to pending_amount '''
frappe.db.sql(''' UPDATE `tabEmployee Advance` SET pending_amount=due_advance_amount ''')
if frappe.db.has_column("Employee Advance", "due_advance_amount"):
frappe.db.sql(''' UPDATE `tabEmployee Advance` SET pending_amount=due_advance_amount ''')

View File

@ -0,0 +1,12 @@
# Copyright (c) 2020, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from erpnext.regional.address_template.setup import set_up_address_templates
def execute():
if frappe.db.get_value('Company', {'country': 'India'}, 'name'):
address_template = frappe.db.get_value('Address Template', 'India', 'template')
if not address_template or "gstin" not in address_template:
set_up_address_templates(default_country='India')

View File

@ -1,4 +1,5 @@
import frappe
from frappe.utils import cint
from erpnext.portal.product_configurator.item_variants_cache import ItemVariantsCacheManager
def get_field_filter_data():
@ -243,6 +244,8 @@ def get_next_attribute_and_values(item_code, selected_attributes):
else:
product_info = None
product_info["allow_items_not_in_stock"] = cint(data.cart_settings.allow_items_not_in_stock)
return {
'next_attribute': next_attribute,
'valid_options_for_attributes': valid_options_for_attributes,

View File

@ -13,7 +13,7 @@ from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.hr.doctype.salary_structure.test_salary_structure \
import make_salary_structure, create_salary_structure_assignment
from erpnext.hr.doctype.employee.test_employee import make_employee
class TestTimesheet(unittest.TestCase):
def setUp(self):
@ -25,8 +25,10 @@ class TestTimesheet(unittest.TestCase):
def test_timesheet_billing_amount(self):
make_salary_structure_for_timesheet("_T-Employee-00001")
timesheet = make_timesheet("_T-Employee-00001", simulate=True, billable=1)
emp = make_employee("test_employee_6@salary.com")
make_salary_structure_for_timesheet(emp)
timesheet = make_timesheet(emp, simulate=True, billable=1)
self.assertEqual(timesheet.total_hours, 2)
self.assertEqual(timesheet.total_billable_hours, 2)
@ -35,8 +37,10 @@ class TestTimesheet(unittest.TestCase):
self.assertEqual(timesheet.total_billable_amount, 100)
def test_timesheet_billing_amount_not_billable(self):
make_salary_structure_for_timesheet("_T-Employee-00001")
timesheet = make_timesheet("_T-Employee-00001", simulate=True, billable=0)
emp = make_employee("test_employee_6@salary.com")
make_salary_structure_for_timesheet(emp)
timesheet = make_timesheet(emp, simulate=True, billable=0)
self.assertEqual(timesheet.total_hours, 2)
self.assertEqual(timesheet.total_billable_hours, 0)
@ -45,8 +49,10 @@ class TestTimesheet(unittest.TestCase):
self.assertEqual(timesheet.total_billable_amount, 0)
def test_salary_slip_from_timesheet(self):
salary_structure = make_salary_structure_for_timesheet("_T-Employee-00001")
timesheet = make_timesheet("_T-Employee-00001", simulate = True, billable=1)
emp = make_employee("test_employee_6@salary.com")
salary_structure = make_salary_structure_for_timesheet(emp)
timesheet = make_timesheet(emp, simulate = True, billable=1)
salary_slip = make_salary_slip(timesheet.name)
salary_slip.submit()
@ -65,7 +71,9 @@ class TestTimesheet(unittest.TestCase):
self.assertEqual(timesheet.status, 'Submitted')
def test_sales_invoice_from_timesheet(self):
timesheet = make_timesheet("_T-Employee-00001", simulate=True, billable=1)
emp = make_employee("test_employee_6@salary.com")
timesheet = make_timesheet(emp, simulate=True, billable=1)
sales_invoice = make_sales_invoice(timesheet.name, '_Test Item', '_Test Customer')
sales_invoice.due_date = nowdate()
sales_invoice.submit()
@ -80,7 +88,9 @@ class TestTimesheet(unittest.TestCase):
self.assertEqual(item.rate, 50.00)
def test_timesheet_billing_based_on_project(self):
timesheet = make_timesheet("_T-Employee-00001", simulate=True, billable=1, project = '_Test Project', company='_Test Company')
emp = make_employee("test_employee_6@salary.com")
timesheet = make_timesheet(emp, simulate=True, billable=1, project = '_Test Project', company='_Test Company')
sales_invoice = create_sales_invoice(do_not_save=True)
sales_invoice.project = '_Test Project'
sales_invoice.submit()
@ -90,6 +100,8 @@ class TestTimesheet(unittest.TestCase):
self.assertEqual(ts.time_logs[0].sales_invoice, sales_invoice.name)
def test_timesheet_time_overlap(self):
emp = make_employee("test_employee_6@salary.com")
settings = frappe.get_single('Projects Settings')
initial_setting = settings.ignore_employee_time_overlap
settings.ignore_employee_time_overlap = 0
@ -97,7 +109,7 @@ class TestTimesheet(unittest.TestCase):
update_activity_type("_Test Activity Type")
timesheet = frappe.new_doc("Timesheet")
timesheet.employee = "_T-Employee-00001"
timesheet.employee = emp
timesheet.append(
'time_logs',
{
@ -129,12 +141,14 @@ class TestTimesheet(unittest.TestCase):
settings.save()
def test_timesheet_std_working_hours(self):
emp = make_employee("test_employee_6@salary.com")
company = frappe.get_doc('Company', "_Test Company")
company.standard_working_hours = 8
company.save()
timesheet = frappe.new_doc("Timesheet")
timesheet.employee = "_T-Employee-00001"
timesheet.employee = emp
timesheet.company = '_Test Company'
timesheet.append(
'time_logs',
@ -156,7 +170,7 @@ class TestTimesheet(unittest.TestCase):
company.save()
timesheet = frappe.new_doc("Timesheet")
timesheet.employee = "_T-Employee-00001"
timesheet.employee = emp
timesheet.company = '_Test Company'
timesheet.append(
'time_logs',

View File

@ -81,4 +81,10 @@
.place-order-container {
text-align: right;
}
.kb-card {
.card-body > .card-title {
line-height: 1.3;
}
}

View File

@ -1,7 +1,7 @@
{{ address_line1 }}<br>{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}{{ city }}<br>
{% if gst_state %}{{ gst_state }}{% endif -%}
{% if gst_state_number %}, State Code: {{ gst_state_number }}<br>{% endif -%}
{% if pincode %}PIN: {{ pincode }}<br>{% endif -%}
{% if pincode %}Postal Code: {{ pincode }}<br>{% endif -%}
{{ country }}<br>
{% if phone %}Phone: {{ phone }}<br>{% endif -%}
{% if fax %}Fax: {{ fax }}<br>{% endif -%}

View File

@ -339,6 +339,7 @@ def get_loyalty_programs(doc):
return lp_details
@frappe.whitelist()
def get_customer_list(doctype, txt, searchfield, start, page_len, filters=None):
from erpnext.controllers.queries import get_fields

View File

@ -5,7 +5,7 @@ from __future__ import unicode_literals
import calendar
import frappe
from frappe import _
from frappe.utils import cint, cstr
from frappe.utils import cint, cstr, getdate
def execute(filters=None):
common_columns = [
@ -160,7 +160,7 @@ def get_data_by_territory(filters, common_columns):
return columns, data, None, None, None, 1
def get_customer_stats(filters, tree_view=False):
""" Calculates number of new and repeated customers. """
""" Calculates number of new and repeated customers and revenue. """
company_condition = ''
if filters.get('company'):
company_condition = ' and company=%(company)s'
@ -174,14 +174,14 @@ def get_customer_stats(filters, tree_view=False):
filters, as_dict=1):
key = si.territory if tree_view else si.posting_date.strftime('%Y-%m')
new_or_repeat = 'new' if si.customer not in customers else 'repeat'
customers_in.setdefault(key, {'new': [0, 0.0], 'repeat': [0, 0.0]})
if not si.customer in customers:
customers_in[key]['new'][0] += 1
customers_in[key]['new'][1] += si.base_grand_total
# if filters.from_date <= si.posting_date.strftime('%Y-%m-%d'):
if getdate(filters.from_date) <= getdate(si.posting_date):
customers_in[key][new_or_repeat][0] += 1
customers_in[key][new_or_repeat][1] += si.base_grand_total
if new_or_repeat == 'new':
customers.append(si.customer)
else:
customers_in[key]['repeat'][0] += 1
customers_in[key]['repeat'][1] += si.base_grand_total
return customers_in

View File

@ -1,4 +1,5 @@
{
"actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:title",
@ -49,7 +50,7 @@
"fieldname": "terms_and_conditions_help",
"fieldtype": "HTML",
"label": "Terms and Conditions Help",
"options": "<h4>Standard Terms and Conditions Example</h4>\n\n<pre>Delivery Terms for Order number {{ name }}\n\n-Order Date : {{ transaction_date }} \n-Expected Delivery Date : {{ delivery_date }}\n</pre>\n\n<h4>How to get fieldnames</h4>\n\n<p>The fieldnames you can use in your email template are the fields in the document from which you are sending the email. You can find out the fields of any documents via Setup &gt; Customize Form View and selecting the document type (e.g. Sales Invoice)</p>\n\n<h4>Templating</h4>\n\n<p>Templates are compiled using the Jinja Templating Langauge. To learn more about Jinja, <a class=\"strong\" href=\"http://jinja.pocoo.org/docs/dev/templates/\">read this documentation.</a></p>"
"options": "<h4>Standard Terms and Conditions Example</h4>\n\n<pre>Delivery Terms for Order number {{ name }}\n\n-Order Date : {{ transaction_date }} \n-Expected Delivery Date : {{ delivery_date }}\n</pre>\n\n<h4>How to get fieldnames</h4>\n\n<p>The fieldnames you can use in your email template are the fields in the document from which you are sending the email. You can find out the fields of any documents via Setup &gt; Customize Form View and selecting the document type (e.g. Sales Invoice)</p>\n\n<h4>Templating</h4>\n\n<p>Templates are compiled using the Jinja Templating Language. To learn more about Jinja, <a class=\"strong\" href=\"http://jinja.pocoo.org/docs/dev/templates/\">read this documentation.</a></p>"
},
{
"fieldname": "applicable_modules_section",
@ -81,7 +82,8 @@
],
"icon": "icon-legal",
"idx": 1,
"modified": "2019-07-04 13:31:30.393425",
"links": [],
"modified": "2020-06-16 22:54:38.094844",
"modified_by": "Administrator",
"module": "Setup",
"name": "Terms and Conditions",

View File

@ -42,9 +42,9 @@ def get_cart_quotation(doc=None):
return {
"doc": decorate_quotation_doc(doc),
"shipping_addresses": [{"name": address.name, "display": address.display}
"shipping_addresses": [{"name": address.name, "title": address.address_title, "display": address.display}
for address in addresses if address.address_type == "Shipping"],
"billing_addresses": [{"name": address.name, "display": address.display}
"billing_addresses": [{"name": address.name, "title": address.address_title, "display": address.display}
for address in addresses if address.address_type == "Billing"],
"shipping_rules": get_applicable_shipping_rules(party),
"cart_settings": frappe.get_cached_doc("Shopping Cart Settings")
@ -78,8 +78,10 @@ def place_order():
if is_stock_item:
item_stock = get_qty_in_stock(item.item_code, "website_warehouse")
if not cint(item_stock.in_stock):
throw(_("{1} Not in Stock").format(item.item_code))
if item.qty > item_stock.stock_qty[0][0]:
throw(_("Only {0} in stock for item {1}").format(item_stock.stock_qty[0][0], item.item_code))
throw(_("Only {0} in Stock for item {1}").format(item_stock.stock_qty[0][0], item.item_code))
sales_order.flags.ignore_permissions = True
sales_order.insert()

View File

@ -5,7 +5,7 @@ from __future__ import unicode_literals
import frappe
import unittest
from erpnext.support.doctype.service_level_agreement.test_service_level_agreement import create_service_level_agreements_for_issues
from frappe.utils import now_datetime, get_datetime
from frappe.utils import now_datetime, get_datetime, flt
import datetime
from datetime import timedelta
@ -120,7 +120,7 @@ class TestIssue(unittest.TestCase):
create_communication(issue.name, "test@example.com", "Received", creation)
issue.reload()
self.assertEqual(issue.total_hold_time, 2700)
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
self.assertEqual(issue.resolution_by, datetime.datetime(2020, 3, 4, 16, 45))
creation = datetime.datetime(2020, 3, 4, 5, 5)
@ -132,7 +132,7 @@ class TestIssue(unittest.TestCase):
issue.save()
issue.reload()
self.assertEqual(issue.total_hold_time, 2700)
self.assertEqual(flt(issue.total_hold_time, 2), 2700)
def make_issue(creation=None, customer=None, index=0):

View File

@ -1,5 +1,5 @@
{
"actions": [],
"actions": "",
"creation": "2017-02-17 13:07:35.686409",
"doctype": "DocType",
"editable_grid": 1,
@ -22,6 +22,10 @@
"post_description_key",
"post_route_key",
"post_route_string",
"greetings_section_section",
"greeting_title",
"column_break_19",
"greeting_subtitle",
"search_apis_sb",
"search_apis"
],
@ -127,11 +131,40 @@
"fieldname": "allow_resetting_service_level_agreement",
"fieldtype": "Check",
"label": "Allow Resetting Service Level Agreement"
},
{
"default": "We're here to help",
"fieldname": "greeting_title",
"fieldtype": "Data",
"label": "Greeting Title",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"show_days": 1,
"show_seconds": 1
},
{
"default": "Browse help topics",
"fieldname": "greeting_subtitle",
"fieldtype": "Data",
"label": "Greeting Subtitle",
"show_days": 1,
"show_seconds": 1
},
{
"fieldname": "greetings_section_section",
"fieldtype": "Section Break",
"label": "Greetings Section",
"show_days": 1,
"show_seconds": 1
}
],
"issingle": 1,
"links": [],
"modified": "2020-06-05 17:56:17.491684",
"modified": "2020-06-11 13:08:38.473616",
"modified_by": "Administrator",
"module": "Support",
"name": "Support Settings",

View File

@ -193,14 +193,17 @@ class ItemConfigure {
filtered_items_count === 1 ?
filtered_items[0] : '';
// Allow Add to Cart if adding out of stock items enabled in Shopping Cart else check stock.
const in_stock = product_info.allow_items_not_in_stock ? 1 : product_info.in_stock;
const add_to_cart = `<a href data-action="btn_add_to_cart" data-item-code="${one_item}">${__('Add to cart')}</a>`;
const product_action = in_stock ? add_to_cart : `<a style="color:#74808b;">${__('Not in Stock')}</a>`;
const item_add_to_cart = one_item ? `
<div class="alert alert-success d-flex justify-content-between align-items-center" role="alert">
<div>
<div>${one_item} ${product_info && product_info.price ? '(' + product_info.price.formatted_price_sales_uom + ')' : ''}</div>
</div>
<a href data-action="btn_add_to_cart" data-item-code="${one_item}">
${__('Add to cart')}
</a>
${product_action}
</div>
`: '';

View File

@ -14,12 +14,12 @@
{%- if introduction -%}
<div>{{ introduction }}</div>
{% endif %}
{% endif %}
{%- if application_form_route -%}
{%- if doc.enable_admission_application -%}
<p>
<a class='btn btn-primary'
href='/{{ doc.application_form_route }}'>
href='/student-applicant'>
{{ _("Apply Now") }}</a>
</p>
{% endif %}

View File

@ -3,7 +3,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg>
</div>
<div class="card-body">
<h5 class="card-title">{{ address.name }}</h5>
<h5 class="card-title">{{ address.title }}</h5>
<p class="card-text text-muted">
{{ address.display }}
</p>

View File

@ -109,7 +109,7 @@ frappe.ready(() => {
reqd: 1
},
{
label: __('Pin Code'),
label: __('Postal Code'),
fieldname: 'pincode',
fieldtype: 'Data'
},

View File

View File

@ -0,0 +1,58 @@
{% extends "templates/web.html" %}
{% block content %}
<section class="section section-padding-top section-padding-bottom">
<div class='container'>
<div class="hero-content">
<h1 class="hero-title">{{ greeting_title or _("We're here to help!") }}</h1>
{% if greeting_subtitle %}
<p class="hero-subtitle">{{ greeting_subtitle }}</p>
{% endif %}
</div>
</div>
</section>
{% if favorite_article_list %}
<section class="section section-padding-top section-padding-bottom bg-light">
<div class='container'>
<h2>{{ _("Frequently Read Articles") }}</h2>
<div class="row">
{% for favorite_article in favorite_article_list %}
<div class="mt-4 col-12 col-sm-6 col-lg-4">
<div class="card card-md h-100 kb-card">
<div class="card-body">
<h6 class="card-subtitle mb-2 text-uppercase small text-muted">
{{ favorite_article['category'] }}</h6>
<h3 class="card-title">{{ favorite_article['title'] }}</h3>
<p class="card-text">{{ favorite_article['description'] }}</p>
</div>
<a href="{{ favorite_article['route'] }}" class="stretched-link"></a>
</div>
</div>
{% endfor %}
</div>
</div>
</section>
{% endif %}
{% if help_article_list %}
<section class="section section-padding-top section-padding-bottom">
<div class='container'>
<h2>{{ _("Help Articles") }}</h2>
<div class="row">
{% for item in help_article_list %}
<div class="mt-5 col-12 col-sm-6 col-lg-4">
<h5>{{ item['category'].name }}</h5>
<div>
{% for article in item['articles'] %}
<a href="{{ article.route }}" class="mt-2 d-block">{{ article.title }}</a>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
</section>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,74 @@
from __future__ import unicode_literals
import frappe
def get_context(context):
context.no_cache = 1
context.align_greeting = ''
setting = frappe.get_doc("Support Settings")
context.greeting_title = setting.greeting_title
context.greeting_subtitle = setting.greeting_subtitle
# Support content
favorite_articles = get_favorite_articles_by_page_view()
if len(favorite_articles) < 6:
name_list = []
if favorite_articles:
for article in favorite_articles:
name_list.append(article.name)
for record in (frappe.get_all("Help Article",
fields=["title", "content", "route", "category"],
filters={"name": ['not in', tuple(name_list)], "published": 1},
order_by="creation desc", limit=(6-len(favorite_articles)))):
favorite_articles.append(record)
context.favorite_article_list = get_favorite_articles(favorite_articles)
context.help_article_list = get_help_article_list()
def get_favorite_articles_by_page_view():
return frappe.db.sql(
"""
SELECT
t1.name as name,
t1.title as title,
t1.content as content,
t1.route as route,
t1.category as category,
count(t1.route) as count
FROM `tabHelp Article` AS t1
INNER JOIN
`tabWeb Page View` AS t2
ON t1.route = t2.path
WHERE t1.published = 1
GROUP BY route
ORDER BY count DESC
LIMIT 6;
""", as_dict=True)
def get_favorite_articles(favorite_articles):
favorite_article_list=[]
for article in favorite_articles:
description = frappe.utils.strip_html(article.content)
if len(description) > 120:
description = description[:120] + '...'
favorite_article_dict = {
'title': article.title,
'description': description,
'route': article.route,
'category': article.category,
}
favorite_article_list.append(favorite_article_dict)
return favorite_article_list
def get_help_article_list():
help_article_list=[]
category_list = frappe.get_all("Help Category", fields="name")
for category in category_list:
help_articles = frappe.get_all("Help Article", fields="*", filters={"category": category.name, "published": 1}, order_by="modified desc", limit=5)
if help_articles:
help_aricles_per_caetgory = {
'category': category,
'articles': help_articles,
}
help_article_list.append(help_aricles_per_caetgory)
return help_article_list