Merge branch 'develop' into payroll_entry
diff --git a/.travis.yml b/.travis.yml
index d57b2d8..602144c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,7 +29,7 @@
- cp -r $TRAVIS_BUILD_DIR/test_sites/test_site ~/frappe-bench/sites/
before_script:
- - wget http://chromedriver.storage.googleapis.com/2.32/chromedriver_linux64.zip
+ - wget http://chromedriver.storage.googleapis.com/2.33/chromedriver_linux64.zip
- unzip chromedriver_linux64.zip
- sudo apt-get install libnss3
- sudo apt-get --only-upgrade install google-chrome-stable
@@ -66,8 +66,13 @@
env: Client Side Test
- # stage
script:
+ - bench --verbose run-setup-wizard-ui-test
+ - bench execute erpnext.setup.utils.enable_all_roles_and_domains
+ - bench run-ui-tests --app erpnext --test-list erpnext/tests/ui/agriculture.txt
+ env: Agriculture Client Side Test
+ - # stage
+ script:
- wget http://build.erpnext.com/20171108_190013_955977f8_database.sql.gz
- bench --force restore ~/frappe-bench/20171108_190013_955977f8_database.sql.gz --mariadb-root-password travis
- bench migrate
env: Patch Testing
-
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 4679a4a..29e81f1 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -3,8 +3,9 @@
import inspect
import frappe
from erpnext.hooks import regional_overrides
+from frappe.utils import getdate
-__version__ = '9.2.19'
+__version__ = '9.2.20'
def get_default_company(user=None):
'''Get default company for user'''
@@ -108,3 +109,16 @@
return caller
+def get_last_membership():
+ '''Returns last membership if exists'''
+ last_membership = frappe.get_all('Membership', 'name,to_date,membership_type',
+ dict(member=frappe.session.user, paid=1), order_by='to_date desc', limit=1)
+
+ return last_membership and last_membership[0]
+
+def is_member():
+ '''Returns true if the user is still a member'''
+ last_membership = get_last_membership()
+ if last_membership and getdate(last_membership.to_date) > getdate():
+ return True
+ return False
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index d8995a9..8ecedb5 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -512,7 +512,7 @@
c.outstanding_amount = d.outstanding_amount;
c.bill_no = d.bill_no;
- if(!in_list(["Sales Order", "Purchase Order", "Expense Claim"], d.voucher_type)) {
+ if(!in_list(["Sales Order", "Purchase Order", "Expense Claim", "Fees"], d.voucher_type)) {
if(flt(d.outstanding_amount) > 0)
total_positive_outstanding += flt(d.outstanding_amount);
else
@@ -527,7 +527,7 @@
} else {
c.exchange_rate = 1;
}
- if (in_list(['Sales Invoice', 'Purchase Invoice', "Expense Claim"], d.reference_doctype)){
+ if (in_list(['Sales Invoice', 'Purchase Invoice', "Expense Claim", "Fees"], d.reference_doctype)){
c.due_date = d.due_date;
}
});
@@ -535,7 +535,8 @@
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=="Pay" && frm.doc.party_type=="Employee") ||
+ (frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
) {
if(total_positive_outstanding > total_negative_outstanding)
frm.set_value("paid_amount",
@@ -579,13 +580,16 @@
})
var allocated_negative_outstanding = 0;
- if ((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
+ 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")) {
- if(total_positive_outstanding_including_order > paid_amount) {
- var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
- allocated_negative_outstanding = total_negative_outstanding < remaining_outstanding ?
- total_negative_outstanding : remaining_outstanding;
+ (frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee") ||
+ (frm.doc.payment_type=="Receive" && frm.doc.party_type=="Student")
+ ) {
+ if(total_positive_outstanding_including_order > paid_amount) {
+ var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
+ allocated_negative_outstanding = total_negative_outstanding < remaining_outstanding ?
+ total_negative_outstanding : remaining_outstanding;
}
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index 36ff0ac..99ff295 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -310,9 +310,10 @@
self.difference_amount = flt(self.difference_amount - total_deductions,
self.precision("difference_amount"))
+ # Paid amount is auto allocated in the reference document by default.
+ # Clear the reference document which doesn't have allocated amount on validate so that form can be loaded fast
def clear_unallocated_reference_document_rows(self):
self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]}))
-
frappe.db.sql("""delete from `tabPayment Entry Reference`
where parent = %s and allocated_amount = 0""", self.name)
diff --git a/erpnext/accounts/doctype/payment_request/payment_request.json b/erpnext/accounts/doctype/payment_request/payment_request.json
index 5a6292b..1042071 100644
--- a/erpnext/accounts/doctype/payment_request/payment_request.json
+++ b/erpnext/accounts/doctype/payment_request/payment_request.json
@@ -26,7 +26,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
- "in_list_view": 0,
+ "in_list_view": 1,
"in_standard_filter": 0,
"label": "Series",
"length": 0,
@@ -432,7 +432,7 @@
"options": "<pre><h5>Message Example</h5>\n\n<p>Dear {{ doc.contact_person }},</p>\n\n<p>Requesting payment for {{ doc.doctype }}, {{ doc.name }} for {{ doc.grand_total }}.</p>\n\n<a href=\"{{ payment_url }}\"> click here to pay </a>\n\n</pre>\n",
"permlevel": 0,
"precision": "",
- "print_hide": 0,
+ "print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -728,7 +728,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-06-13 14:29:20.388372",
+ "modified": "2017-12-02 15:50:41.775006",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",
diff --git a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
index 2b7fe77..e620065 100644
--- a/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
+++ b/erpnext/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.json
@@ -19,7 +19,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "Valuation and Total",
+ "default": "Total",
"fieldname": "category",
"fieldtype": "Select",
"hidden": 0,
@@ -679,7 +679,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-11-15 19:26:57.074345",
+ "modified": "2017-12-06 13:37:44.483509",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Taxes and Charges",
diff --git a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
index 890833b..67112b6 100644
--- a/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
+++ b/erpnext/accounts/report/asset_depreciations_and_balances/asset_depreciations_and_balances.py
@@ -86,17 +86,20 @@
for d in assets:
asset = frappe.get_doc("Asset", d.name)
- asset_depreciations.setdefault(d.asset_category, frappe._dict({
- "accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
- "depreciation_amount_during_the_period": 0,
- "depreciation_eliminated_during_the_period": 0
- }))
+ if d.asset_category in asset_depreciations:
+ asset_depreciations[d.asset_category]['accumulated_depreciation_as_on_from_date'] += asset.opening_accumulated_depreciation
+ else:
+ asset_depreciations.setdefault(d.asset_category, frappe._dict({
+ "accumulated_depreciation_as_on_from_date": asset.opening_accumulated_depreciation,
+ "depreciation_amount_during_the_period": 0,
+ "depreciation_eliminated_during_the_period": 0
+ }))
depr = asset_depreciations[d.asset_category]
for schedule in asset.get("schedules"):
if getdate(schedule.schedule_date) < getdate(filters.from_date):
- if not asset.disposal_date and getdate(asset.disposal_date) >= getdate(filters.from_date):
+ if not asset.disposal_date or getdate(asset.disposal_date) >= getdate(filters.from_date):
depr.accumulated_depreciation_as_on_from_date += flt(schedule.depreciation_amount)
elif getdate(schedule.schedule_date) <= getdate(filters.to_date):
depr.depreciation_amount_during_the_period += flt(schedule.depreciation_amount)
diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py
index 9eea472..5df2a65 100644
--- a/erpnext/accounts/report/trial_balance/trial_balance.py
+++ b/erpnext/accounts/report/trial_balance/trial_balance.py
@@ -134,8 +134,12 @@
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
+ "opening_debit": 0.0,
+ "opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
+ "closing_debit": 0.0,
+ "closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
@@ -156,7 +160,10 @@
total_row["debit"] += d["debit"]
total_row["credit"] += d["credit"]
-
+ total_row["opening_debit"] += d["opening_debit"]
+ total_row["opening_credit"] += d["opening_credit"]
+ total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
+ total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
return total_row
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index ba5d8b3..abdadb3 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -576,14 +576,13 @@
outstanding_invoices = []
precision = frappe.get_precision("Sales Invoice", "outstanding_amount")
- if party_type == "Customer":
+ if party_type == "Customer" or party_type == "Student":
dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
payment_dr_or_cr = "payment_gl_entry.credit_in_account_currency - payment_gl_entry.debit_in_account_currency"
else:
dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency"
- invoice = 'Sales Invoice' if party_type == 'Customer' else 'Purchase Invoice'
invoice_list = frappe.db.sql("""
select
voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount, due_date,
@@ -613,7 +612,6 @@
having (invoice_amount - payment_amount) > 0.005
order by posting_date, name, due_date""".format(
dr_or_cr=dr_or_cr,
- invoice=invoice,
payment_dr_or_cr=payment_dr_or_cr,
condition=condition or ""
), {
diff --git a/erpnext/agriculture/__init__.py b/erpnext/agriculture/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/__init__.py
diff --git a/erpnext/agriculture/doctype/__init__.py b/erpnext/agriculture/doctype/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/__init__.py
diff --git a/erpnext/agriculture/doctype/agriculture_analysis_criteria/__init__.py b/erpnext/agriculture/doctype/agriculture_analysis_criteria/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_analysis_criteria/__init__.py
diff --git a/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.js b/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.js
new file mode 100644
index 0000000..e236cc6
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Agriculture Analysis Criteria', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.json b/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.json
new file mode 100644
index 0000000..a53bffd
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.json
@@ -0,0 +1,155 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:title",
+ "beta": 0,
+ "creation": "2017-12-05 16:37:46.599982",
+ "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": "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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "standard",
+ "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": "Standard",
+ "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": "linked_doctype",
+ "fieldtype": "Select",
+ "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": "Linked Doctype",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nWater Analysis\nSoil Analysis\nPlant Analysis\nFertilizer\nSoil Texture\nWeather",
+ "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-12-05 18:54:26.250707",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Agriculture Analysis 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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.py b/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.py
new file mode 100644
index 0000000..3bd3d7d
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_analysis_criteria/agriculture_analysis_criteria.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class AgricultureAnalysisCriteria(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.js b/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.js
new file mode 100644
index 0000000..f70dcd2
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Agriculture Analysis Criteria", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Agriculture Analysis Criteria
+ () => frappe.tests.make('Agriculture Analysis Criteria', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.py b/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.py
new file mode 100644
index 0000000..d79970b
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_analysis_criteria/test_agriculture_analysis_criteria.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestAgricultureAnalysisCriteria(unittest.TestCase):
+ pass
diff --git a/erpnext/agriculture/doctype/agriculture_task/__init__.py b/erpnext/agriculture/doctype/agriculture_task/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_task/__init__.py
diff --git a/erpnext/agriculture/doctype/agriculture_task/agriculture_task.js b/erpnext/agriculture/doctype/agriculture_task/agriculture_task.js
new file mode 100644
index 0000000..4d6b959
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_task/agriculture_task.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Agriculture Task', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/agriculture/doctype/agriculture_task/agriculture_task.json b/erpnext/agriculture/doctype/agriculture_task/agriculture_task.json
new file mode 100644
index 0000000..11c691c
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_task/agriculture_task.json
@@ -0,0 +1,199 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "ATask.########",
+ "beta": 0,
+ "creation": "2017-10-26 15:51:19.602452",
+ "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": "task_name",
+ "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": "Task Name",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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,
+ "default": "",
+ "fieldname": "start_day",
+ "fieldtype": "Int",
+ "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": "Start Day",
+ "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,
+ "default": "",
+ "fieldname": "end_day",
+ "fieldtype": "Int",
+ "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": "End Day",
+ "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,
+ "default": "Ignore holidays",
+ "fieldname": "holiday_management",
+ "fieldtype": "Select",
+ "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": "Holiday Management",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Ignore holidays\nPrevious Business Day\nNext Business Day",
+ "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,
+ "default": "Low",
+ "fieldname": "priority",
+ "fieldtype": "Select",
+ "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": "Priority",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Low\nMedium\nHigh\nUrgent",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-06 01:13:14.512609",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Agriculture Task",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/agriculture_task/agriculture_task.py b/erpnext/agriculture/doctype/agriculture_task/agriculture_task.py
new file mode 100644
index 0000000..ce39368
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_task/agriculture_task.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class AgricultureTask(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.js b/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.js
new file mode 100644
index 0000000..a012c4b
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Agriculture Task", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Agriculture Task
+ () => frappe.tests.make('Agriculture Task', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.py b/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.py
new file mode 100644
index 0000000..e828151
--- /dev/null
+++ b/erpnext/agriculture/doctype/agriculture_task/test_agriculture_task.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestAgricultureTask(unittest.TestCase):
+ pass
diff --git a/erpnext/agriculture/doctype/crop/__init__.py b/erpnext/agriculture/doctype/crop/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/__init__.py
diff --git a/erpnext/agriculture/doctype/crop/crop.js b/erpnext/agriculture/doctype/crop/crop.js
new file mode 100644
index 0000000..587727c
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/crop.js
@@ -0,0 +1,7 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Crop', {
+ validate: (frm) => {
+ }
+});
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop/crop.json b/erpnext/agriculture/doctype/crop/crop.json
new file mode 100644
index 0000000..8e6807f
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/crop.json
@@ -0,0 +1,1045 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:title",
+ "beta": 0,
+ "creation": "2017-10-20 01:16:17.606174",
+ "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": "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": 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": "section_break_2",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "crop_name",
+ "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": "Crop 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": "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,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "scientific_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": "Scientific Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "You can define all the tasks which need to carried out for this crop here. The day field is used to mention the day on which the task needs to be carried out, 1 being the 1st day, etc.. ",
+ "fieldname": "section_break_20",
+ "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": "Tasks",
+ "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": "agriculture_task",
+ "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": "Agriculture Task",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Task",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fieldname": "period",
+ "fieldtype": "Int",
+ "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": "Period",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_9",
+ "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": "crop_spacing",
+ "fieldtype": "Float",
+ "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": "Crop Spacing",
+ "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": "crop_spacing_uom",
+ "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": "Crop Spacing UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "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": "column_break_12",
+ "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": "row_spacing",
+ "fieldtype": "Float",
+ "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": "Row Spacing",
+ "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": "row_spacing_uom",
+ "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": "Row Spacing UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_4",
+ "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": "type",
+ "fieldtype": "Select",
+ "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": "Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Annual\nPerennial\nBiennial",
+ "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": "column_break_6",
+ "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": "category",
+ "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": "Category",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_8",
+ "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": "target_warehouse",
+ "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": "Target Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_12",
+ "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": "planting_uom",
+ "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": "Planting UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "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": "planting_area",
+ "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": "Planting Area",
+ "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": "column_break_14",
+ "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": "yield_uom",
+ "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": "Yield UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_16",
+ "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": "section_break_17",
+ "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": "Materials Required",
+ "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": "materials_required",
+ "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": "Materials Required",
+ "length": 0,
+ "no_copy": 0,
+ "options": "BOM Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_19",
+ "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": "Produced Items",
+ "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": "produce",
+ "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": "Produce",
+ "length": 0,
+ "no_copy": 0,
+ "options": "BOM Item",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_18",
+ "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": "Byproducts",
+ "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": "byproducts",
+ "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": "Byproducts",
+ "length": 0,
+ "no_copy": 0,
+ "options": "BOM Item",
+ "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-12-06 11:00:06.333894",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Crop",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop/crop.py b/erpnext/agriculture/doctype/crop/crop.py
new file mode 100644
index 0000000..29b9823
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/crop.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class Crop(Document):
+ def validate(self):
+ max_period = 0
+ for task in self.agriculture_task:
+ # validate start_day is not > end_day
+ if task.start_day > task.end_day:
+ frappe.throw("Start day is greater than end day in task '{0}'".format(task.subject))
+ # to calculate the period of the Crop Cycle
+ if task.end_day > max_period: max_period = task.end_day
+ if max_period > self.period: self.period = max_period
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop/crop_dashboard.py b/erpnext/agriculture/doctype/crop/crop_dashboard.py
new file mode 100644
index 0000000..715f92b
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/crop_dashboard.py
@@ -0,0 +1,11 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'transactions': [
+ {
+ 'label': _('Crop Cycle'),
+ 'items': ['Crop Cycle']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop/test_crop.js b/erpnext/agriculture/doctype/crop/test_crop.js
new file mode 100644
index 0000000..138acbf
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/test_crop.js
@@ -0,0 +1,116 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Crop", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(2);
+
+ frappe.run_serially([
+ // insert a new Item
+ () => frappe.tests.make('Item', [
+ // values to be set
+ {item_code: 'Basil Seeds'},
+ {item_name: 'Basil Seeds'},
+ {item_group: 'Seed'}
+ ]),
+ // insert a new Item
+ () => frappe.tests.make('Item', [
+ // values to be set
+ {item_code: 'Twigs'},
+ {item_name: 'Twigs'},
+ {item_group: 'By-product'}
+ ]),
+ // insert a new Item
+ () => frappe.tests.make('Item', [
+ // values to be set
+ {item_code: 'Basil Leaves'},
+ {item_name: 'Basil Leaves'},
+ {item_group: 'Produce'}
+ ]),
+ // insert a new Crop
+ () => frappe.tests.make('Crop', [
+ // values to be set
+ {title: 'Basil from seed'},
+ {crop_name: 'Basil'},
+ {scientific_name: 'Ocimum basilicum'},
+ {materials_required: [
+ [
+ {item_code: 'Basil Seeds'},
+ {qty: '25'},
+ {uom: 'Nos'},
+ {rate: '1'}
+ ],
+ [
+ {item_code: 'Urea'},
+ {qty: '5'},
+ {uom: 'Kg'},
+ {rate: '10'}
+ ]
+ ]},
+ {byproducts: [
+ [
+ {item_code: 'Twigs'},
+ {qty: '25'},
+ {uom: 'Nos'},
+ {rate: '1'}
+ ]
+ ]},
+ {produce: [
+ [
+ {item_code: 'Basil Leaves'},
+ {qty: '100'},
+ {uom: 'Nos'},
+ {rate: '1'}
+ ]
+ ]},
+ {agriculture_task: [
+ [
+ {task_name: "Plough the field"},
+ {start_day: 1},
+ {end_day: 1},
+ {holiday_management: "Ignore holidays"}
+ ],
+ [
+ {task_name: "Plant the seeds"},
+ {start_day: 2},
+ {end_day: 3},
+ {holiday_management: "Ignore holidays"}
+ ],
+ [
+ {task_name: "Water the field"},
+ {start_day: 4},
+ {end_day: 4},
+ {holiday_management: "Ignore holidays"}
+ ],
+ [
+ {task_name: "First harvest"},
+ {start_day: 8},
+ {end_day: 8},
+ {holiday_management: "Ignore holidays"}
+ ],
+ [
+ {task_name: "Add the fertilizer"},
+ {start_day: 10},
+ {end_day: 12},
+ {holiday_management: "Ignore holidays"}
+ ],
+ [
+ {task_name: "Final cut"},
+ {start_day: 15},
+ {end_day: 15},
+ {holiday_management: "Ignore holidays"}
+ ]
+ ]}
+ ]),
+ // agriculture task list
+ () => {
+ assert.equal(cur_frm.doc.name, 'Basil from seed');
+ assert.equal(cur_frm.doc.period, 15);
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/crop/test_crop.py b/erpnext/agriculture/doctype/crop/test_crop.py
new file mode 100644
index 0000000..5c992ea
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/test_crop.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+test_dependencies = ["Fertilizer"]
+
+class TestCrop(unittest.TestCase):
+ def test_crop_period(self):
+ basil = frappe.get_doc('Crop', 'Basil from seed')
+ self.assertEquals(basil.period, 15)
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop/test_records.json b/erpnext/agriculture/doctype/crop/test_records.json
new file mode 100644
index 0000000..41ddb9a
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop/test_records.json
@@ -0,0 +1,80 @@
+[
+ {
+ "doctype": "Item",
+ "item_code": "Basil Seeds",
+ "item_name": "Basil Seeds",
+ "item_group": "Seed"
+ },
+ {
+ "doctype": "Item",
+ "item_code": "Twigs",
+ "item_name": "Twigs",
+ "item_group": "By-product"
+ },
+ {
+ "doctype": "Item",
+ "item_code": "Basil Leaves",
+ "item_name": "Basil Leaves",
+ "item_group": "Produce"
+ },
+ {
+ "doctype": "Crop",
+ "title": "Basil from seed",
+ "crop_name": "Basil",
+ "scientific_name": "Ocimum basilicum",
+ "materials_required": [{
+ "item_code": "Basil Seeds",
+ "qty": "25",
+ "uom": "Nos",
+ "rate": "1"
+ }, {
+ "item_code": "Urea",
+ "qty": "5",
+ "uom": "Kg",
+ "rate": "10"
+ }],
+ "byproducts": [{
+ "item_code": "Twigs",
+ "qty": "25",
+ "uom": "Nos",
+ "rate": "1"
+ }],
+ "produce": [{
+ "item_code": "Basil Leaves",
+ "qty": "100",
+ "uom": "Nos",
+ "rate": "1"
+ }],
+ "agriculture_task": [{
+ "task_name": "Plough the field",
+ "start_day": 1,
+ "end_day": 1,
+ "holiday_management": "Ignore holidays"
+ }, {
+ "task_name": "Plant the seeds",
+ "start_day": 2,
+ "end_day": 3,
+ "holiday_management": "Ignore holidays"
+ }, {
+ "task_name": "Water the field",
+ "start_day": 4,
+ "end_day": 4,
+ "holiday_management": "Ignore holidays"
+ }, {
+ "task_name": "First harvest",
+ "start_day": 8,
+ "end_day": 8,
+ "holiday_management": "Ignore holidays"
+ }, {
+ "task_name": "Add the fertilizer",
+ "start_day": 10,
+ "end_day": 12,
+ "holiday_management": "Ignore holidays"
+ }, {
+ "task_name": "Final cut",
+ "start_day": 15,
+ "end_day": 15,
+ "holiday_management": "Ignore holidays"
+ }]
+ }
+]
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop_cycle/__init__.py b/erpnext/agriculture/doctype/crop_cycle/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop_cycle/__init__.py
diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.js b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.js
new file mode 100644
index 0000000..98dd056
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.js
@@ -0,0 +1,48 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Crop Cycle', {
+ refresh: (frm) => {
+ if (!frm.doc.__islocal)
+ frm.add_custom_button(__('Reload Linked Analysis'), () => frm.call("reload_linked_analysis"));
+
+ frappe.realtime.on("List of Linked Docs", (output) => {
+ let analysis_doctypes = ['Soil Texture', 'Plant Analysis', 'Soil Analysis'];
+ let analysis_doctypes_docs = ['soil_texture', 'plant_analysis', 'soil_analysis'];
+ let obj_to_append = {soil_analysis: [], soil_texture: [], plant_analysis: []};
+ output['Land Unit'].forEach( (land_doc) => {
+ analysis_doctypes.forEach( (doctype) => {
+ output[doctype].forEach( (analysis_doc) => {
+ let point_to_be_tested = JSON.parse(analysis_doc.location).features[0].geometry.coordinates;
+ let poly_of_land = JSON.parse(land_doc.location).features[0].geometry.coordinates[0];
+ if (test_analysis_position(point_to_be_tested, poly_of_land)){
+ obj_to_append[analysis_doctypes_docs[analysis_doctypes.indexOf(doctype)]].push(analysis_doc.name);
+ }
+ });
+ });
+ });
+ frm.call('append_to_child', {
+ obj_to_append: obj_to_append
+ });
+ });
+ }
+});
+
+function test_analysis_position(point, vs) {
+ // ray-casting algorithm based on
+ // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
+
+ var x = point[0], y = point[1];
+
+ var inside = false;
+ for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
+ var xi = vs[i][0], yi = vs[i][1];
+ var xj = vs[j][0], yj = vs[j][1];
+
+ var intersect = ((yi > y) != (yj > y))
+ && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
+ if (intersect) inside = !inside;
+ }
+
+ return inside;
+};
diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.json b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.json
new file mode 100644
index 0000000..410a0d4
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.json
@@ -0,0 +1,849 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:title",
+ "beta": 0,
+ "creation": "2017-11-02 03:09:35.449880",
+ "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": "title",
+ "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": "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": 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": "crop",
+ "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": "Crop",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Crop",
+ "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,
+ "description": "",
+ "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,
+ "label": "Linked Land Unit",
+ "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,
+ "description": "A link to all the Land Units in which the Crop is growing",
+ "fieldname": "linked_land_unit",
+ "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": "Linked Land Unit",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Linked Land Unit",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_3",
+ "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,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "project",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Project",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Project",
+ "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": "column_break_12",
+ "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,
+ "description": "This will be day 1 of the crop cycle",
+ "fieldname": "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": "Start Date",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": "end_date",
+ "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": "End Date",
+ "length": 0,
+ "no_copy": 0,
+ "options": "project.expected_end_date",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_7",
+ "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": "iso_8016_standard",
+ "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": "ISO 8016 standard",
+ "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": "column_break_5",
+ "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": "cycle_type",
+ "fieldtype": "Select",
+ "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": "Cycle Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Yearly\nLess than a 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": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_12",
+ "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,
+ "description": "The minimum length between each plant in the field for optimum growth",
+ "fieldname": "crop_spacing",
+ "fieldtype": "Float",
+ "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": "Crop Spacing",
+ "length": 0,
+ "no_copy": 0,
+ "options": "crop.crop_spacing",
+ "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": "crop_spacing_uom",
+ "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": "Crop Spacing UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "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": "column_break_11",
+ "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,
+ "description": "The minimum distance between rows of plants for optimum growth",
+ "fieldname": "row_spacing",
+ "fieldtype": "Float",
+ "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": "Row Spacing",
+ "length": 0,
+ "no_copy": 0,
+ "options": "crop.row_spacing",
+ "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": "row_spacing_uom",
+ "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": "Row Spacing UOM",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "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,
+ "description": "List of diseases detected on the field. When selected it'll automatically add a list of tasks to deal with the disease ",
+ "fieldname": "section_break_14",
+ "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": "Detected Diseases",
+ "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": "detected_disease",
+ "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": "Detected Disease",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Detected Disease",
+ "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": 1,
+ "collapsible_depends_on": "eval:false",
+ "columns": 0,
+ "fieldname": "section_break_22",
+ "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": "LInked Analysis",
+ "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": "soil_texture",
+ "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": "Soil Texture",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Linked Soil Texture",
+ "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": "soil_analysis",
+ "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": "Soil Analysis",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Linked Soil Analysis",
+ "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": "plant_analysis",
+ "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": "Plant Analysis",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Linked Plant Analysis",
+ "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-12-06 01:47:26.656870",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Crop Cycle",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
new file mode 100644
index 0000000..8912f59
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+import ast
+
+class CropCycle(Document):
+ def validate(self):
+ if self.is_new():
+ crop = frappe.get_doc('Crop', self.crop)
+ self.create_project(crop.period, crop.agriculture_task)
+ if not self.project:
+ self.project = self.name
+ for detected_disease in self.detected_disease:
+ disease = frappe.get_doc('Disease', detected_disease.disease)
+ self.create_task(disease.treatment_task, self.name, detected_disease.start_date)
+
+ def create_project(self, period, crop_tasks):
+ project = frappe.new_doc("Project")
+ project.project_name = self.title
+ project.expected_start_date = self.start_date
+ project.expected_end_date = frappe.utils.data.add_days(self.start_date, period-1)
+ project.insert()
+ self.create_task(crop_tasks, project.as_dict.im_self.name, self.start_date)
+ return project.as_dict.im_self.name
+
+ def create_task(self, crop_tasks, project_name, start_date):
+ for crop_task in crop_tasks:
+ task = frappe.new_doc("Task")
+ task.subject = crop_task.get("task_name")
+ task.priority = crop_task.get("priority")
+ task.project = project_name
+ task.exp_start_date = frappe.utils.data.add_days(start_date, crop_task.get("start_day")-1)
+ task.exp_end_date = frappe.utils.data.add_days(start_date, crop_task.get("end_day")-1)
+ task.insert()
+
+ def reload_linked_analysis(self):
+ linked_doctypes = ['Soil Texture', 'Soil Analysis', 'Plant Analysis']
+ required_fields = ['location', 'name', 'collection_datetime']
+ output = {}
+ for doctype in linked_doctypes:
+ output[doctype] = frappe.get_all(doctype, fields=required_fields)
+ output['Land Unit'] = []
+ for land in self.linked_land_unit:
+ output['Land Unit'].append(frappe.get_doc('Land Unit', land.land_unit))
+
+ frappe.publish_realtime("List of Linked Docs", output, user=frappe.session.user)
+
+ def append_to_child(self, obj_to_append):
+ for doctype in obj_to_append:
+ for doc_name in set(obj_to_append[doctype]):
+ self.append(doctype, {doctype: doc_name})
+ self.save()
+
+ def get_coordinates(self, doc):
+ return ast.literal_eval(doc.location).get('features')[0].get('geometry').get('coordinates')
+
+ def get_geometry_type(self, doc):
+ return ast.literal_eval(doc.location).get('features')[0].get('geometry').get('type')
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.js b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.js
new file mode 100644
index 0000000..464a368
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.js
@@ -0,0 +1,34 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Crop Cycle", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Crop Cycle
+ () => frappe.tests.make('Crop Cycle', [
+ // values to be set
+ {title: 'Basil from seed 2017'},
+ {detected_disease: [
+ [
+ {start_date: '2017-11-21'},
+ {disease: 'Aphids'}
+ ]
+ ]},
+ {linked_land_unit: [
+ [
+ {land_unit: 'Basil Farm'}
+ ]
+ ]},
+ {crop: 'Basil from seed'},
+ {start_date: '2017-11-11'},
+ {cycle_type: 'Less than a year'}
+ ]),
+ () => assert.equal(cur_frm.doc.name, 'Basil from seed 2017'),
+ () => done()
+ ]);
+});
diff --git a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
new file mode 100644
index 0000000..0c3db73
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+test_dependencies = ["Crop", "Fertilizer", "Land Unit", "Disease"]
+
+class TestCropCycle(unittest.TestCase):
+ def test_crop_cycle_creation(self):
+ cycle = frappe.get_doc('Crop Cycle', 'Basil from seed 2017')
+ self.assertEquals(frappe.db.exists('Crop Cycle', 'Basil from seed 2017'), 'Basil from seed 2017')
+
+ # check if the tasks were created
+ self.assertEquals(check_task_creation(), True)
+ self.assertEquals(check_project_creation(), True)
+
+def check_task_creation():
+ all_task_dict = {
+ "Survey and find the aphid locations": {
+ "exp_start_date": frappe.utils.datetime.date(2017,11,21),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,22)
+ },
+ "Apply Pesticides": {
+ "exp_start_date": frappe.utils.datetime.date(2017,11,23),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,23)
+ },
+ "Plough the field": {
+ "exp_start_date": frappe.utils.datetime.date(2017,11,11),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,11)
+ },
+ "Plant the seeds": {
+ "exp_start_date": frappe.utils.datetime.date(2017,11,12),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,13)
+ },
+ "Water the field": {
+ "exp_start_date": frappe.utils.datetime.date(2017,11,14),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,14)
+ },
+ "First harvest": {
+ "exp_start_date": frappe.utils.datetime.date(2017,11,18),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,18)
+ },
+ "Add the fertilizer": {
+ "exp_start_date": frappe.utils.datetime.date(2017,11,20),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,22)
+ },
+ "Final cut":{
+ "exp_start_date": frappe.utils.datetime.date(2017,11,25),
+ "exp_end_date": frappe.utils.datetime.date(2017,11,25)
+ }
+ }
+ all_tasks = frappe.get_all('Task')
+ for task in all_tasks:
+ sample_task = frappe.get_doc('Task', task.name)
+ if sample_task.subject in all_task_dict.keys():
+ if sample_task.exp_start_date != all_task_dict[sample_task.subject]['exp_start_date'] or sample_task.exp_end_date != all_task_dict[sample_task.subject]['exp_end_date']:
+ return False
+ all_task_dict.pop(sample_task.subject)
+ if all_task_dict != {}:
+ return False
+ return True
+
+def check_project_creation():
+ if frappe.db.exists('Project', 'Basil from seed 2017'): return True
+ else: return False
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/crop_cycle/test_records.json b/erpnext/agriculture/doctype/crop_cycle/test_records.json
new file mode 100644
index 0000000..fade7a0
--- /dev/null
+++ b/erpnext/agriculture/doctype/crop_cycle/test_records.json
@@ -0,0 +1,15 @@
+[
+ {
+ "doctype": "Crop Cycle",
+ "title": "Basil from seed 2017",
+ "linked_land_unit": [{
+ "land_unit": "Basil Farm"
+ }],
+ "crop": "Basil from seed",
+ "start_date": "2017-11-11",
+ "detected_disease": [{
+ "disease": "Aphids",
+ "start_date": "2017-11-21"
+ }]
+ }
+]
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/detected_disease/__init__.py b/erpnext/agriculture/doctype/detected_disease/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/detected_disease/__init__.py
diff --git a/erpnext/agriculture/doctype/detected_disease/detected_disease.json b/erpnext/agriculture/doctype/detected_disease/detected_disease.json
new file mode 100644
index 0000000..cf44149
--- /dev/null
+++ b/erpnext/agriculture/doctype/detected_disease/detected_disease.json
@@ -0,0 +1,102 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-11-20 17:31:30.772779",
+ "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": "disease",
+ "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": "Disease",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Disease",
+ "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": "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": "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": 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-26 21:10:14.753511",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Detected Disease",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/detected_disease/detected_disease.py b/erpnext/agriculture/doctype/detected_disease/detected_disease.py
new file mode 100644
index 0000000..8c90b83
--- /dev/null
+++ b/erpnext/agriculture/doctype/detected_disease/detected_disease.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class DetectedDisease(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/disease/__init__.py b/erpnext/agriculture/doctype/disease/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/disease/__init__.py
diff --git a/erpnext/agriculture/doctype/disease/disease.js b/erpnext/agriculture/doctype/disease/disease.js
new file mode 100644
index 0000000..f6b678c
--- /dev/null
+++ b/erpnext/agriculture/doctype/disease/disease.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Disease', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/agriculture/doctype/disease/disease.json b/erpnext/agriculture/doctype/disease/disease.json
new file mode 100644
index 0000000..e10b1ca
--- /dev/null
+++ b/erpnext/agriculture/doctype/disease/disease.json
@@ -0,0 +1,293 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:common_name",
+ "beta": 0,
+ "creation": "2017-11-20 17:16:54.496355",
+ "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": "common_name",
+ "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": "Common 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": "scientific_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": "Scientific Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_3",
+ "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": "description",
+ "fieldtype": "Long Text",
+ "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": "Description",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_2",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Treatment Task",
+ "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": "treatment_task",
+ "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": "Treatment Task",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Task",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "treatment_period",
+ "fieldtype": "Int",
+ "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": "Treatment Period",
+ "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-12-04 19:20:19.352479",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Disease",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/disease/disease.py b/erpnext/agriculture/doctype/disease/disease.py
new file mode 100644
index 0000000..42005d6
--- /dev/null
+++ b/erpnext/agriculture/doctype/disease/disease.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class Disease(Document):
+ def validate(self):
+ max_period = 0
+ for task in self.treatment_task:
+ # validate start_day is not > end_day
+ if task.start_day > task.end_day:
+ frappe.throw("Start day is greater than end day in task '{0}'".format(task.task_name))
+ # to calculate the period of the Crop Cycle
+ if task.end_day > max_period: max_period = task.end_day
+ self.treatment_period = max_period
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/disease/test_disease.js b/erpnext/agriculture/doctype/disease/test_disease.js
new file mode 100644
index 0000000..57d62c1
--- /dev/null
+++ b/erpnext/agriculture/doctype/disease/test_disease.js
@@ -0,0 +1,39 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Disease", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Disease
+ () => frappe.tests.make('Disease', [
+ // values to be set
+ {common_name: 'Aphids'},
+ {scientific_name: 'Aphidoidea'},
+ {treatment_task: [
+ [
+ {task_name: "Survey and find the aphid locations"},
+ {start_day: 1},
+ {end_day: 2},
+ {holiday_management: "Ignore holidays"}
+ ],
+ [
+ {task_name: "Apply Pesticides"},
+ {start_day: 3},
+ {end_day: 3},
+ {holiday_management: "Ignore holidays"}
+ ]
+ ]}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.treatment_period, 3);
+ },
+ () => done()
+ ]);
+
+});
+
diff --git a/erpnext/agriculture/doctype/disease/test_disease.py b/erpnext/agriculture/doctype/disease/test_disease.py
new file mode 100644
index 0000000..a040358
--- /dev/null
+++ b/erpnext/agriculture/doctype/disease/test_disease.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestDisease(unittest.TestCase):
+ def test_treatment_period(self):
+ disease = frappe.get_doc('Disease', 'Aphids')
+ self.assertEquals(disease.treatment_period, 3)
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/disease/test_records.json b/erpnext/agriculture/doctype/disease/test_records.json
new file mode 100644
index 0000000..e91a611
--- /dev/null
+++ b/erpnext/agriculture/doctype/disease/test_records.json
@@ -0,0 +1,18 @@
+[
+ {
+ "doctype": "Disease",
+ "common_name": "Aphids",
+ "scientific_name": "Aphidoidea",
+ "treatment_task": [{
+ "task_name": "Survey and find the aphid locations",
+ "start_day": 1,
+ "end_day": 2,
+ "holiday_management": "Ignore holidays"
+ }, {
+ "task_name": "Apply Pesticides",
+ "start_day": 3,
+ "end_day": 3,
+ "holiday_management": "Ignore holidays"
+ }]
+ }
+]
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/fertilizer/__init__.py b/erpnext/agriculture/doctype/fertilizer/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer/__init__.py
diff --git a/erpnext/agriculture/doctype/fertilizer/fertilizer.js b/erpnext/agriculture/doctype/fertilizer/fertilizer.js
new file mode 100644
index 0000000..357e089
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer/fertilizer.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Fertilizer', {
+ onload: (frm) => {
+ if (frm.doc.fertilizer_contents == undefined) frm.call('load_contents');
+ }
+});
diff --git a/erpnext/agriculture/doctype/fertilizer/fertilizer.json b/erpnext/agriculture/doctype/fertilizer/fertilizer.json
new file mode 100644
index 0000000..b2a1b81
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer/fertilizer.json
@@ -0,0 +1,292 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:fertilizer_name",
+ "beta": 0,
+ "creation": "2017-10-17 18:17:06.175062",
+ "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": "fertilizer_name",
+ "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": "Fertilizer 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": "item",
+ "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": "Item",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Item",
+ "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": "section_break_2",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "density",
+ "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": "Density (if liquid)",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_4",
+ "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": "section_break_28",
+ "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": "Fertilizer Contents",
+ "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": "fertilizer_contents",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "options": "Fertilizer Content",
+ "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-12-05 19:13:42.471667",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Fertilizer",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/fertilizer/fertilizer.py b/erpnext/agriculture/doctype/fertilizer/fertilizer.py
new file mode 100644
index 0000000..dc2781c
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer/fertilizer.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class Fertilizer(Document):
+ def load_contents(self):
+ docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Fertilizer'})
+ for doc in docs:
+ self.append('fertilizer_contents', {'title': str(doc.name)})
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/fertilizer/test_fertilizer.js b/erpnext/agriculture/doctype/fertilizer/test_fertilizer.js
new file mode 100644
index 0000000..5dd7313
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer/test_fertilizer.js
@@ -0,0 +1,31 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Fertilizer", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Item
+ () => frappe.tests.make('Item', [
+ // values to be set
+ {item_code: 'Urea'},
+ {item_name: 'Urea'},
+ {item_group: 'Fertilizer'}
+ ]),
+ // insert a new Fertilizer
+ () => frappe.tests.make('Fertilizer', [
+ // values to be set
+ {fertilizer_name: 'Urea'},
+ {item: 'Urea'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.name, 'Urea');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/fertilizer/test_fertilizer.py b/erpnext/agriculture/doctype/fertilizer/test_fertilizer.py
new file mode 100644
index 0000000..3b34e4f
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer/test_fertilizer.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestFertilizer(unittest.TestCase):
+ def test_fertilizer_creation(self):
+ self.assertEquals(frappe.db.exists('Fertilizer', 'Urea'), 'Urea')
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/fertilizer/test_records.json b/erpnext/agriculture/doctype/fertilizer/test_records.json
new file mode 100644
index 0000000..ba735cd
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer/test_records.json
@@ -0,0 +1,13 @@
+[
+ {
+ "doctype": "Item",
+ "item_code": "Urea",
+ "item_name": "Urea",
+ "item_group": "Fertilizer"
+ },
+ {
+ "doctype": "Fertilizer",
+ "fertilizer_name": "Urea",
+ "item": "Urea"
+ }
+]
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/fertilizer_content/__init__.py b/erpnext/agriculture/doctype/fertilizer_content/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer_content/__init__.py
diff --git a/erpnext/agriculture/doctype/fertilizer_content/fertilizer_content.json b/erpnext/agriculture/doctype/fertilizer_content/fertilizer_content.json
new file mode 100644
index 0000000..bf222ab
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer_content/fertilizer_content.json
@@ -0,0 +1,103 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-05 16:54:17.071914",
+ "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": "title",
+ "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": "Title",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Analysis 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": "value",
+ "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": "Value",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-05 19:20:38.892231",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Fertilizer Content",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Agriculture",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/fertilizer_content/fertilizer_content.py b/erpnext/agriculture/doctype/fertilizer_content/fertilizer_content.py
new file mode 100644
index 0000000..d385242
--- /dev/null
+++ b/erpnext/agriculture/doctype/fertilizer_content/fertilizer_content.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class FertilizerContent(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/land_unit/__init__.py b/erpnext/agriculture/doctype/land_unit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/__init__.py
diff --git a/erpnext/agriculture/doctype/land_unit/land_unit.js b/erpnext/agriculture/doctype/land_unit/land_unit.js
new file mode 100644
index 0000000..c9ab348
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/land_unit.js
@@ -0,0 +1,31 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+// Code for finding the area of editable features drawn on the geolocation control
+
+
+
+frappe.ui.form.on('Land Unit', {
+ setup: function(frm) {
+ frm.add_fetch("parent_land_unit", "latitude", "latitude");
+ frm.add_fetch("parent_land_unit", "longitude", "longitude");
+ },
+
+ onload_post_render(frm){
+ if(!frm.doc.location && frm.doc.latitude && frm.doc.longitude) {
+ frm.fields_dict.location.map.setView([frm.doc.latitude, frm.doc.longitude],13);
+ }
+ else {
+ frm.doc.latitude = frm.fields_dict.location.map.getCenter()['lat'];
+ frm.doc.longitude = frm.fields_dict.location.map.getCenter()['lng'];
+ }
+ },
+ refresh: function(frm) {
+ if(!frm.doc.parent_land_unit) {
+ frm.set_read_only();
+ frm.set_intro(__("This is a root land unit and cannot be edited."));
+ } else {
+ frm.set_intro(null);
+ }
+ },
+});
diff --git a/erpnext/agriculture/doctype/land_unit/land_unit.json b/erpnext/agriculture/doctype/land_unit/land_unit.json
new file mode 100644
index 0000000..9ed3d03
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/land_unit.json
@@ -0,0 +1,690 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:land_unit_name",
+ "beta": 0,
+ "creation": "2017-10-21 05:35:34.508529",
+ "custom": 0,
+ "description": "Land Unit describing various land assets",
+ "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": "land_unit_name",
+ "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": "Land Unit Name",
+ "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": 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": "parent_land_unit",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Parent Land Unit",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Land Unit",
+ "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": "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,
+ "description": "Check if it is a hydroponic unit",
+ "fieldname": "is_container",
+ "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": "Is Container",
+ "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": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "is_group",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Is Group",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "tree_details",
+ "fieldtype": "Section Break",
+ "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": "Tree Details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "lft",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "lft",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "rgt",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "rgt",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "old_parent",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "old_parent",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Land Unit",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 1,
+ "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": "land_unit_details",
+ "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": "Land Unit Details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "latitude",
+ "fieldtype": "Float",
+ "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": "Latitude",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": "longitude",
+ "fieldtype": "Float",
+ "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": "Longitude",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": "latlong",
+ "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": "area",
+ "fieldtype": "Float",
+ "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": "Area",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_13",
+ "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": "location",
+ "fieldtype": "Geolocation",
+ "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": "Location",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_17",
+ "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": "linked_soil_texture",
+ "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": "Linked Soil Texture",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Linked Soil Texture",
+ "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": "linked_soil_analysis",
+ "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": "Linked Soil Analysis",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Linked Soil Analysis",
+ "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": "linked_plant_analysis",
+ "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": "Linked Plant Analysis",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Linked Plant Analysis",
+ "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-12-05 10:57:33.108504",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Land Unit",
+ "name_case": "Title 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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 0,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/land_unit/land_unit.py b/erpnext/agriculture/doctype/land_unit/land_unit.py
new file mode 100644
index 0000000..634cb75
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/land_unit.py
@@ -0,0 +1,165 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import json
+import math
+
+from frappe import _
+
+from frappe.utils.nestedset import NestedSet
+# from frappe.model.document import Document
+
+RADIUS = 6378137
+FLATTENING_DENOM = 298.257223563
+FLATTENING = 1/FLATTENING_DENOM
+POLAR_RADIUS = RADIUS*(1-FLATTENING)
+
+class LandUnit(NestedSet):
+ # pass
+ nsm_parent_field = 'parent_land_unit'
+
+ def on_trash(self):
+ ancestors = self.get_ancestors()
+ for ancestor in ancestors:
+ ancestor_doc = frappe.get_doc('Land Unit', ancestor)
+ ancestor_child_features, ancestor_non_child_features = ancestor_doc.feature_seperator(child_feature = self.get('land_unit_name'))
+ ancestor_features = ancestor_non_child_features
+ for index,feature in enumerate(ancestor_features):
+ ancestor_features[index] = json.loads(feature)
+ ancestor_doc.set_location_value(features = ancestor_features)
+ ancestor_doc.db_set(fieldname='area', value=ancestor_doc.get('area')-self.get('area'),commit=True)
+
+ def validate(self):
+ if not self.is_new():
+ if not self.get('location'):
+ features = ''
+ else:
+ features = json.loads(self.get('location')).get('features')
+ new_area = compute_area(features)
+ self.area_difference = new_area - self.area
+ self.area = new_area
+
+ if self.get('parent'):
+ ancestors = self.get_ancestors()
+ self_features = self.add_child_property()
+ self_features = set(self_features)
+
+ for ancestor in ancestors:
+ ancestor_doc = frappe.get_doc('Land Unit', ancestor)
+ ancestor_child_features, ancestor_non_child_features = ancestor_doc.feature_seperator(child_feature = self.get('land_unit_name'))
+ ancestor_features = list(set(ancestor_non_child_features))
+ child_features = set(ancestor_child_features)
+
+ if not (self_features.issubset(child_features) and child_features.issubset(self_features)):
+ features_to_be_appended = self_features - child_features
+ features_to_be_discarded = child_features - self_features
+ for feature in features_to_be_discarded:
+ child_features.discard(feature)
+ for feature in features_to_be_appended:
+ child_features.add(feature)
+ child_features = list(child_features)
+
+ ancestor_features.extend(child_features)
+ for index,feature in enumerate(ancestor_features):
+ ancestor_features[index] = json.loads(feature)
+ ancestor_doc.set_location_value(features = ancestor_features)
+ ancestor_doc.db_set(fieldname='area', value=ancestor_doc.get('area')+\
+ self.get('area_difference'),commit=True)
+
+ def set_location_value(self, features):
+ if not self.get('location'):
+ self.location = '{"type":"FeatureCollection","features":[]}'
+ location = json.loads(self.location)
+ location['features'] = features
+ self.db_set(fieldname='location', value=json.dumps(location), commit=True)
+
+ def on_update(self):
+ super(LandUnit, self).on_update()
+ self.validate_one_root()
+
+ def add_child_property(self):
+ location = self.get('location')
+ if location:
+ features = json.loads(location).get('features')
+ if type(features) != list:
+ features = json.loads(features)
+ filter_features = [feature for feature in features if feature.get('properties').get('child_feature') != True]
+ for index,feature in enumerate(filter_features):
+ feature['properties'].update({'child_feature': True, 'feature_of': self.land_unit_name})
+ filter_features[index] = json.dumps(filter_features[index])
+ return filter_features
+ return []
+
+ def feature_seperator(self, child_feature=None):
+ doc = self
+ child_features = []
+ non_child_features = []
+ location = doc.get('location')
+ if location:
+ features = json.loads(location).get('features')
+ if type(features) != list:
+ features = json.loads(features)
+ for feature in features:
+ if feature.get('properties').get('feature_of') == child_feature:
+ child_features.extend([json.dumps(feature)])
+ else:
+ non_child_features.extend([json.dumps(feature)])
+
+ return child_features, non_child_features
+
+
+def compute_area(features):
+ layer_area = 0
+ for feature in features:
+ if feature.get('geometry').get('type') == 'Polygon':
+ layer_area += polygon_area(coords = feature.get('geometry').get('coordinates'))
+ elif feature.get('geometry').get('type') == 'Point' and feature.get('properties').get('point_type') == 'circle':
+ layer_area += math.pi * math.pow(feature.get('properties').get('radius'), 2)
+ return layer_area
+
+def rad(angle_in_degrees):
+ return angle_in_degrees*math.pi/180
+
+def polygon_area(coords):
+ area = 0
+ if coords and len(coords) > 0:
+ area += math.fabs(ring_area(coords[0]));
+ for i in range(1, len(coords)):
+ area -= math.fabs(ring_area(coords[i]));
+ return area;
+
+def ring_area(coords):
+ p1 = 0
+ p2 = 0
+ p3 = 0
+ lower_index = 0
+ middle_index = 0
+ upper_index = 0
+ i = 0
+ area = 0
+ coords_length = len(coords)
+ if coords_length > 2:
+ for i in range(0, coords_length):
+ if i == coords_length - 2: # i = N-2
+ lower_index = coords_length - 2;
+ middle_index = coords_length -1;
+ upper_index = 0;
+ elif i == coords_length - 1: # i = N-1
+ lower_index = coords_length - 1;
+ middle_index = 0;
+ upper_index = 1;
+ else: # i = 0 to N-3
+ lower_index = i;
+ middle_index = i+1;
+ upper_index = i+2;
+ p1 = coords[lower_index];
+ p2 = coords[middle_index];
+ p3 = coords[upper_index];
+ area += ( rad(p3[0]) - rad(p1[0]) ) * math.sin( rad(p2[1]));
+
+ area = area * RADIUS * RADIUS / 2
+ return area
+
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/land_unit/land_unit_tree.js b/erpnext/agriculture/doctype/land_unit/land_unit_tree.js
new file mode 100644
index 0000000..0d7a53e
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/land_unit_tree.js
@@ -0,0 +1,15 @@
+frappe.treeview_settings["Land Unit"] = {
+ ignore_fields:["parent_land_unit"],
+ disable_add_node: true,
+ toolbar: [
+ { toggle_btn: true },
+ {
+ label:__("Add Child"),
+ click: function(node) {
+ var lu = frappe.new_doc("Land Unit", {
+ "parent_land_unit": node.label
+ })
+ }
+ }
+ ],
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/land_unit/test_land_unit.js b/erpnext/agriculture/doctype/land_unit/test_land_unit.js
new file mode 100644
index 0000000..c23db77
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/test_land_unit.js
@@ -0,0 +1,24 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Land Unit", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Land Unit
+ () => frappe.tests.make('Land Unit', [
+ // values to be set
+ {parent_land_unit: 'All Land Units'},
+ {land_unit_name: 'Basil Farm'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.name, 'Basil Farm');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/land_unit/test_land_unit.py b/erpnext/agriculture/doctype/land_unit/test_land_unit.py
new file mode 100644
index 0000000..cf08f98
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/test_land_unit.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+import json
+import frappe
+import unittest
+
+class TestLandUnit(unittest.TestCase):
+
+ def runTest(self):
+ land_units = ['Basil Farm', 'Division 1', 'Field 1', 'Block 1']
+ area = 0
+ formatted_land_units = []
+ for land_unit in land_units:
+ doc = frappe.get_doc('Land Unit', land_unit)
+ doc.save()
+ area += doc.area
+ temp = json.loads(doc.location)
+ temp['features'][0]['properties']['child_feature'] = True
+ temp['features'][0]['properties']['feature_of'] = land_unit
+ formatted_land_units.extend(temp['features'])
+ formatted_land_unit_string = str(formatted_land_units)
+ all_land_units = frappe.get_doc('Land Unit', 'All Land Units')
+ self.assertEquals(formatted_land_unit_string, str(json.loads(all_land_units.get('location'))['features']))
+ self.assertEquals(area, all_land_units.get('area'))
diff --git a/erpnext/agriculture/doctype/land_unit/test_records.json b/erpnext/agriculture/doctype/land_unit/test_records.json
new file mode 100644
index 0000000..6baaf27
--- /dev/null
+++ b/erpnext/agriculture/doctype/land_unit/test_records.json
@@ -0,0 +1,38 @@
+[
+ {
+ "doctype": "Land Unit",
+ "land_unit_name": "Basil Farm",
+ "location": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"point_type\":\"circle\",\"radius\":884.5625420736483},\"geometry\":{\"type\":\"Point\",\"coordinates\":[72.875834,19.100566]}}]}",
+ "parent_land_unit": "All Land Units",
+ "parent": "All Land Units",
+ "is_group": 1,
+ "is_container": 1
+ },
+ {
+ "doctype": "Land Unit",
+ "land_unit_name": "Division 1",
+ "location": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"point_type\":\"circle\",\"radius\":542.3424997060739},\"geometry\":{\"type\":\"Point\",\"coordinates\":[72.852359,19.11557]}}]}",
+ "parent_land_unit": "Basil Farm",
+ "parent": "Basil Farm",
+ "is_group": 1,
+ "is_container": 1
+ },
+ {
+ "doctype": "Land Unit",
+ "land_unit_name": "Field 1",
+ "location": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[72.846758,19.118287],[72.846758,19.121206],[72.850535,19.121206],[72.850535,19.118287],[72.846758,19.118287]]]}}]}",
+ "parent_land_unit": "Division 1",
+ "parent": "Division 1",
+ "is_group": 1,
+ "is_container": 1
+ },
+ {
+ "doctype": "Land Unit",
+ "land_unit_name": "Block 1",
+ "location": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[72.921495,19.073313],[72.924929,19.068121],[72.934713,19.06585],[72.929392,19.05579],[72.94158,19.056926],[72.951365,19.095213],[72.921495,19.073313]]]}}]}",
+ "parent_land_unit": "Field 1",
+ "parent": "Field 1",
+ "is_group": 0,
+ "is_container": 1
+ }
+]
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/linked_land_unit/__init__.py b/erpnext/agriculture/doctype/linked_land_unit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_land_unit/__init__.py
diff --git a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json b/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json
new file mode 100644
index 0000000..63816b8
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json
@@ -0,0 +1,72 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-11-22 14:34:59.461273",
+ "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": "land_unit",
+ "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": "Land Unit",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Land Unit",
+ "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-12-04 13:25:50.856991",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Linked Land Unit",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py b/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py
new file mode 100644
index 0000000..266edb9
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class LinkedLandUnit(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/linked_plant_analysis/__init__.py b/erpnext/agriculture/doctype/linked_plant_analysis/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_plant_analysis/__init__.py
diff --git a/erpnext/agriculture/doctype/linked_plant_analysis/linked_plant_analysis.json b/erpnext/agriculture/doctype/linked_plant_analysis/linked_plant_analysis.json
new file mode 100644
index 0000000..e136d61
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_plant_analysis/linked_plant_analysis.json
@@ -0,0 +1,72 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-11-22 15:04:25.180446",
+ "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": "plant_analysis",
+ "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": "Plant Analysis",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Plant Analysis",
+ "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-12-04 13:25:30.437597",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Linked Plant Analysis",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/linked_plant_analysis/linked_plant_analysis.py b/erpnext/agriculture/doctype/linked_plant_analysis/linked_plant_analysis.py
new file mode 100644
index 0000000..daea54b
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_plant_analysis/linked_plant_analysis.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class LinkedPlantAnalysis(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/linked_soil_analysis/__init__.py b/erpnext/agriculture/doctype/linked_soil_analysis/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_soil_analysis/__init__.py
diff --git a/erpnext/agriculture/doctype/linked_soil_analysis/linked_soil_analysis.json b/erpnext/agriculture/doctype/linked_soil_analysis/linked_soil_analysis.json
new file mode 100644
index 0000000..a248ed0
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_soil_analysis/linked_soil_analysis.json
@@ -0,0 +1,72 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-11-22 15:00:37.259063",
+ "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": "soil_analysis",
+ "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": "Soil Analysis",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Soil Analysis",
+ "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-12-04 13:26:18.682109",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Linked Soil Analysis",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/linked_soil_analysis/linked_soil_analysis.py b/erpnext/agriculture/doctype/linked_soil_analysis/linked_soil_analysis.py
new file mode 100644
index 0000000..c4e9245
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_soil_analysis/linked_soil_analysis.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class LinkedSoilAnalysis(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/linked_soil_texture/__init__.py b/erpnext/agriculture/doctype/linked_soil_texture/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_soil_texture/__init__.py
diff --git a/erpnext/agriculture/doctype/linked_soil_texture/linked_soil_texture.json b/erpnext/agriculture/doctype/linked_soil_texture/linked_soil_texture.json
new file mode 100644
index 0000000..5df1812
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_soil_texture/linked_soil_texture.json
@@ -0,0 +1,72 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-11-22 14:58:52.818040",
+ "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": "soil_texture",
+ "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": "Soil Texture",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Soil Texture",
+ "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-12-04 13:26:07.773314",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Linked Soil Texture",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/linked_soil_texture/linked_soil_texture.py b/erpnext/agriculture/doctype/linked_soil_texture/linked_soil_texture.py
new file mode 100644
index 0000000..1b75892
--- /dev/null
+++ b/erpnext/agriculture/doctype/linked_soil_texture/linked_soil_texture.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class LinkedSoilTexture(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/plant_analysis/__init__.py b/erpnext/agriculture/doctype/plant_analysis/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis/__init__.py
diff --git a/erpnext/agriculture/doctype/plant_analysis/plant_analysis.js b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.js
new file mode 100644
index 0000000..3914f83
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.js
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Plant Analysis', {
+ onload: (frm) => {
+ if (frm.doc.plant_analysis_criteria == undefined) frm.call('load_contents');
+ },
+ refresh: (frm) => {
+ let map_tools = ["a.leaflet-draw-draw-polyline",
+ "a.leaflet-draw-draw-polygon",
+ "a.leaflet-draw-draw-rectangle",
+ "a.leaflet-draw-draw-circle",
+ "a.leaflet-draw-draw-circlemarker"];
+
+ map_tools.forEach((element) => $(element).hide());
+ }
+});
diff --git a/erpnext/agriculture/doctype/plant_analysis/plant_analysis.json b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.json
new file mode 100644
index 0000000..cb66103
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.json
@@ -0,0 +1,353 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "PANA.#####",
+ "beta": 0,
+ "creation": "2017-10-18 12:45:13.575986",
+ "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": "crop",
+ "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": "Crop",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Crop",
+ "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": "section_break_1",
+ "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": "location",
+ "fieldtype": "Geolocation",
+ "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": "Location",
+ "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": "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": "collection_datetime",
+ "fieldtype": "Datetime",
+ "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": "Collection Datetime",
+ "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": "laboratory_testing_datetime",
+ "fieldtype": "Datetime",
+ "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": "Laboratory Testing Datetime",
+ "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_datetime",
+ "fieldtype": "Datetime",
+ "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": "Result Datetime",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_2",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Plant Analysis Criterias",
+ "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": "plant_analysis_criteria",
+ "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": "",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Plant Analysis Criteria",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "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-12-05 19:29:58.612659",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Plant Analysis",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/plant_analysis/plant_analysis.py b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.py
new file mode 100644
index 0000000..304727e
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis/plant_analysis.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.naming import make_autoname
+from frappe.model.document import Document
+
+class PlantAnalysis(Document):
+ def load_contents(self):
+ docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Plant Analysis'})
+ for doc in docs:
+ self.append('plant_analysis_criteria', {'title': str(doc.name)})
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.js b/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.js
new file mode 100644
index 0000000..786c047
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Plant Analysis", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Plant Analysis
+ () => frappe.tests.make('Plant Analysis', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.py b/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.py
new file mode 100644
index 0000000..cbd2fd7
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis/test_plant_analysis.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestPlantAnalysis(unittest.TestCase):
+ pass
diff --git a/erpnext/agriculture/doctype/plant_analysis_criteria/__init__.py b/erpnext/agriculture/doctype/plant_analysis_criteria/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis_criteria/__init__.py
diff --git a/erpnext/agriculture/doctype/plant_analysis_criteria/plant_analysis_criteria.json b/erpnext/agriculture/doctype/plant_analysis_criteria/plant_analysis_criteria.json
new file mode 100644
index 0000000..9b07a8a
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis_criteria/plant_analysis_criteria.json
@@ -0,0 +1,162 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-05 19:23:52.481348",
+ "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": "title",
+ "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": "Title",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Analysis 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": "value",
+ "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": "Value",
+ "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": "minimum_permissible_value",
+ "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": "Minimum Permissible Value",
+ "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_permissible_value",
+ "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": "Maximum Permissible Value",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-05 19:37:02.289320",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Plant Analysis Criteria",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/plant_analysis_criteria/plant_analysis_criteria.py b/erpnext/agriculture/doctype/plant_analysis_criteria/plant_analysis_criteria.py
new file mode 100644
index 0000000..c173184
--- /dev/null
+++ b/erpnext/agriculture/doctype/plant_analysis_criteria/plant_analysis_criteria.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class PlantAnalysisCriteria(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/soil_analysis/__init__.py b/erpnext/agriculture/doctype/soil_analysis/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis/__init__.py
diff --git a/erpnext/agriculture/doctype/soil_analysis/soil_analysis.js b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.js
new file mode 100644
index 0000000..12829be
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.js
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Soil Analysis', {
+ onload: (frm) => {
+ if (frm.doc.soil_analysis_criteria == undefined) frm.call('load_contents');
+ },
+ refresh: (frm) => {
+ let map_tools = ["a.leaflet-draw-draw-polyline",
+ "a.leaflet-draw-draw-polygon",
+ "a.leaflet-draw-draw-rectangle",
+ "a.leaflet-draw-draw-circle",
+ "a.leaflet-draw-draw-circlemarker"];
+
+ map_tools.forEach((element) => $(element).hide());
+ }
+});
diff --git a/erpnext/agriculture/doctype/soil_analysis/soil_analysis.json b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.json
new file mode 100644
index 0000000..e92cc3e
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.json
@@ -0,0 +1,560 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "SANA.#####",
+ "beta": 0,
+ "creation": "2017-10-17 19:12:16.728395",
+ "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": "location",
+ "fieldtype": "Geolocation",
+ "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": "Location",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": "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": "collection_datetime",
+ "fieldtype": "Datetime",
+ "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": "Collection Datetime",
+ "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": "laboratory_testing_datetime",
+ "fieldtype": "Datetime",
+ "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": "Laboratory Testing Datetime",
+ "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_datetime",
+ "fieldtype": "Datetime",
+ "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 Datetime",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_3",
+ "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": "ca_per_k",
+ "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": "Ca/K",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "ca_per_mg",
+ "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": "Ca/Mg",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "mg_per_k",
+ "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": "Mg/K",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_31",
+ "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": "ca_mg_per_k",
+ "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": "(Ca+Mg)/K",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "ca_per_k_ca_mg",
+ "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": "Ca/(K+Ca+Mg)",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_28",
+ "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": "invoice_number",
+ "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": "Invoice Number",
+ "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": "soil_analysis_criterias",
+ "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": "Soil Analysis Criterias",
+ "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": "soil_analysis_criteria",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "options": "Soil Analysis Criteria",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "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-12-05 19:43:05.543080",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Soil Analysis",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_analysis/soil_analysis.py b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.py
new file mode 100644
index 0000000..17b96a0
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis/soil_analysis.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class SoilAnalysis(Document):
+ def load_contents(self):
+ docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Soil Analysis'})
+ for doc in docs:
+ self.append('soil_analysis_criteria', {'title': str(doc.name)})
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.js b/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.js
new file mode 100644
index 0000000..29128eb
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Soil Analysis", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Soil Analysis
+ () => frappe.tests.make('Soil Analysis', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.py b/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.py
new file mode 100644
index 0000000..b89d756
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis/test_soil_analysis.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestSoilAnalysis(unittest.TestCase):
+ pass
diff --git a/erpnext/agriculture/doctype/soil_analysis_criteria/__init__.py b/erpnext/agriculture/doctype/soil_analysis_criteria/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis_criteria/__init__.py
diff --git a/erpnext/agriculture/doctype/soil_analysis_criteria/soil_analysis_criteria.json b/erpnext/agriculture/doctype/soil_analysis_criteria/soil_analysis_criteria.json
new file mode 100644
index 0000000..d2627e4
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis_criteria/soil_analysis_criteria.json
@@ -0,0 +1,162 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-05 19:36:05.300770",
+ "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": "title",
+ "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": "Title",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Analysis 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": "value",
+ "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": "Value",
+ "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": "minimum_permissible_value",
+ "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": "Minimum Permissible Value",
+ "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_permissible_value",
+ "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": "Maximum Permissible Value",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-05 23:35:34.569482",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Soil Analysis Criteria",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_analysis_criteria/soil_analysis_criteria.py b/erpnext/agriculture/doctype/soil_analysis_criteria/soil_analysis_criteria.py
new file mode 100644
index 0000000..b073c20
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_analysis_criteria/soil_analysis_criteria.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class SoilAnalysisCriteria(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/soil_texture/__init__.py b/erpnext/agriculture/doctype/soil_texture/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture/__init__.py
diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.js b/erpnext/agriculture/doctype/soil_texture/soil_texture.js
new file mode 100644
index 0000000..1cb8408
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.js
@@ -0,0 +1,59 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.provide('agriculture');
+
+frappe.ui.form.on('Soil Texture', {
+ refresh: (frm) => {
+ let map_tools = ["a.leaflet-draw-draw-polyline",
+ "a.leaflet-draw-draw-polygon",
+ "a.leaflet-draw-draw-rectangle",
+ "a.leaflet-draw-draw-circle",
+ "a.leaflet-draw-draw-circlemarker"];
+
+ map_tools.forEach((element) => $(element).hide());
+ },
+ onload: function(frm) {
+ if (frm.doc.soil_texture_criteria == undefined) frm.call('load_contents');
+ if (this.ternary_plot) return;
+ this.ternary_plot = new agriculture.TernaryPlot({
+ parent: frm.get_field("ternary_plot").$wrapper,
+ clay: frm.doc.clay_composition,
+ sand: frm.doc.sand_composition,
+ silt: frm.doc.silt_composition,
+ });
+ },
+ soil_type: (frm) => {
+ let composition_types = ['clay_composition', 'sand_composition', 'silt_composition'];
+ composition_types.forEach((composition_type) => {
+ frm.doc[composition_type] = 0;
+ frm.refresh_field(composition_type);
+ });
+ },
+ clay_composition: function(frm) {
+ frm.call("update_soil_edit", {
+ soil_type: 'clay_composition'
+ }, () => {
+ refresh_ternary_plot(frm, this);
+ });
+ },
+ sand_composition: function(frm) {
+ frm.call("update_soil_edit", {
+ soil_type: 'sand_composition'
+ }, () => {
+ refresh_ternary_plot(frm, this);
+ });
+ },
+ silt_composition: function(frm) {
+ frm.call("update_soil_edit", {
+ soil_type: 'silt_composition'
+ }, () => {
+ refresh_ternary_plot(frm, this);
+ });
+ }
+});
+
+let refresh_ternary_plot = (frm, me) => {
+ me.ternary_plot.remove_blip();
+ me.ternary_plot.mark_blip({clay: frm.doc.clay_composition, sand: frm.doc.sand_composition, silt: frm.doc.silt_composition});
+};
diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.json b/erpnext/agriculture/doctype/soil_texture/soil_texture.json
new file mode 100644
index 0000000..308039b
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.json
@@ -0,0 +1,504 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "STEXT.#####",
+ "beta": 0,
+ "creation": "2017-10-18 13:06:47.506762",
+ "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": "location",
+ "fieldtype": "Geolocation",
+ "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": "Location",
+ "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": "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": "collection_datetime",
+ "fieldtype": "Datetime",
+ "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": "Collection Datetime",
+ "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": "laboratory_testing_datetime",
+ "fieldtype": "Datetime",
+ "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": "Laboratory Testing Datetime",
+ "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_datetime",
+ "fieldtype": "Datetime",
+ "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": "Result Datetime",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_4",
+ "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": "soil_type",
+ "fieldtype": "Select",
+ "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": "Soil Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Select\nSand\nLoamy Sand\nSandy Loam\nLoam\nSilt Loam\nSilt\nSandy Clay Loam\nClay Loam\nSilty Clay Loam\nSandy Clay\nSilty Clay\nClay",
+ "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,
+ "default": "0",
+ "fieldname": "clay_composition",
+ "fieldtype": "Percent",
+ "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": "Clay Composition (%)",
+ "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,
+ "default": "0",
+ "fieldname": "sand_composition",
+ "fieldtype": "Percent",
+ "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": "Sand Composition (%)",
+ "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,
+ "default": "0",
+ "fieldname": "silt_composition",
+ "fieldtype": "Percent",
+ "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": "Silt Composition (%)",
+ "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": "column_break_6",
+ "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": "ternary_plot",
+ "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": "Ternary Plot",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_15",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Soil Texture 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": 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": "soil_texture_criteria",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "options": "Soil Texture Criteria",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "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-12-05 23:57:10.725578",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Soil Texture",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_texture/soil_texture.py b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
new file mode 100644
index 0000000..7345e86
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture/soil_texture.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from frappe.utils import flt, cint
+
+class SoilTexture(Document):
+ soil_edit_order = [2, 1, 0]
+ soil_types = ['clay_composition', 'sand_composition', 'silt_composition']
+
+ def load_contents(self):
+ docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Soil Texture'})
+ for doc in docs:
+ self.append('soil_texture_criteria', {'title': str(doc.name)})
+
+ def validate(self):
+ self.update_soil_edit('sand_composition')
+ for soil_type in self.soil_types:
+ if self.get(soil_type) > 100 or self.get(soil_type) < 0:
+ frappe.throw("{0} should be a value between 0 and 100".format(soil_type))
+ if sum(self.get(soil_type) for soil_type in self.soil_types) != 100:
+ frappe.throw('Soil compositions do not add up to 100')
+
+ def update_soil_edit(self, soil_type):
+ self.soil_edit_order[self.soil_types.index(soil_type)] = max(self.soil_edit_order)+1
+ self.soil_type = self.get_soil_type()
+
+ def get_soil_type(self):
+ # update the last edited soil type
+ if sum(self.soil_edit_order) < 5: return
+ last_edit_index = self.soil_edit_order.index(min(self.soil_edit_order))
+
+ # set composition of the last edited soil
+ self.set( self.soil_types[last_edit_index],
+ 100 - sum(cint(self.get(soil_type)) for soil_type in self.soil_types) + cint(self.get(self.soil_types[last_edit_index])))
+
+ # calculate soil type
+ c, sa, si = flt(self.clay_composition), flt(self.sand_composition), flt(self.silt_composition)
+
+ if si + (1.5 * c) < 15:
+ return 'Sand'
+ elif si + 1.5 * c >= 15 and si + 2 * c < 30:
+ return 'Loamy Sand'
+ elif ((c >= 7 and c < 20) or (sa > 52) and ((si + 2*c) >= 30) or (c < 7 and si < 50 and (si+2*c) >= 30)):
+ return 'Sandy Loam'
+ elif ((c >= 7 and c < 27) and (si >= 28 and si < 50) and (sa <= 52)):
+ return 'Loam'
+ elif ((si >= 50 and (c >= 12 and c < 27)) or ((si >= 50 and si < 80) and c < 12)):
+ return 'Silt Loam'
+ elif (si >= 80 and c < 12):
+ return 'Silt'
+ elif ((c >= 20 and c < 35) and (si < 28) and (sa > 45)):
+ return 'Sandy Clay Loam'
+ elif ((c >= 27 and c < 40) and (sa > 20 and sa <= 45)):
+ return 'Clay Loam'
+ elif ((c >= 27 and c < 40) and (sa <= 20)):
+ return 'Silty Clay Loam'
+ elif (c >= 35 and sa > 45):
+ return 'Sandy Clay'
+ elif (c >= 40 and si >= 40):
+ return 'Silty Clay'
+ elif (c >= 40 and sa <= 45 and si < 40):
+ return 'Clay'
+ else:
+ return 'Select'
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_texture/test_records.json b/erpnext/agriculture/doctype/soil_texture/test_records.json
new file mode 100644
index 0000000..dcac7ad
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture/test_records.json
@@ -0,0 +1,9 @@
+[
+ {
+ "doctype": "Soil Texture",
+ "location": "{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[72.861242,19.079153]}}]}",
+ "collection_datetime": "2017-11-08",
+ "clay_composition": 20,
+ "sand_composition": 30
+ }
+]
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_texture/test_soil_texture.js b/erpnext/agriculture/doctype/soil_texture/test_soil_texture.js
new file mode 100644
index 0000000..d93f852
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture/test_soil_texture.js
@@ -0,0 +1,26 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Soil Texture", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(2);
+
+ frappe.run_serially([
+ // insert a new Soil Texture
+ () => frappe.tests.make('Soil Texture', [
+ // values to be set
+ {location: '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[72.882185,19.076395]}}]}'},
+ {collection_datetime: '2017-11-08'},
+ {clay_composition: 20},
+ {sand_composition: 30}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.silt_composition, 50);
+ assert.equal(cur_frm.doc.soil_type, 'Silt Loam');
+ },
+ () => done()
+ ]);
+});
diff --git a/erpnext/agriculture/doctype/soil_texture/test_soil_texture.py b/erpnext/agriculture/doctype/soil_texture/test_soil_texture.py
new file mode 100644
index 0000000..3f20e19
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture/test_soil_texture.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestSoilTexture(unittest.TestCase):
+ def test_texture_selection(self):
+ soil_tex = frappe.get_all('Soil Texture', fields=['name'], filters={'collection_datetime': '2017-11-08'})
+ doc = frappe.get_doc('Soil Texture', soil_tex[0].name)
+ self.assertEquals(doc.silt_composition, 50)
+ self.assertEquals(doc.soil_type, 'Silt Loam')
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_texture_criteria/__init__.py b/erpnext/agriculture/doctype/soil_texture_criteria/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture_criteria/__init__.py
diff --git a/erpnext/agriculture/doctype/soil_texture_criteria/soil_texture_criteria.json b/erpnext/agriculture/doctype/soil_texture_criteria/soil_texture_criteria.json
new file mode 100644
index 0000000..e48a34b
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture_criteria/soil_texture_criteria.json
@@ -0,0 +1,162 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-05 23:45:17.419610",
+ "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": "title",
+ "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": "Title",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Analysis 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": "value",
+ "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": "Value",
+ "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": "minimum_permissible_value",
+ "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": "Minimum Permissible Value",
+ "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_permissible_value",
+ "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": "Maximum Permissible Value",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-05 23:45:17.419610",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Soil Texture Criteria",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/soil_texture_criteria/soil_texture_criteria.py b/erpnext/agriculture/doctype/soil_texture_criteria/soil_texture_criteria.py
new file mode 100644
index 0000000..a7525ae
--- /dev/null
+++ b/erpnext/agriculture/doctype/soil_texture_criteria/soil_texture_criteria.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class SoilTextureCriteria(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/water_analysis/__init__.py b/erpnext/agriculture/doctype/water_analysis/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis/__init__.py
diff --git a/erpnext/agriculture/doctype/water_analysis/test_water_analysis.js b/erpnext/agriculture/doctype/water_analysis/test_water_analysis.js
new file mode 100644
index 0000000..bb01cb3
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis/test_water_analysis.js
@@ -0,0 +1,25 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Water Analysis", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Water Analysis
+ () => frappe.tests.make('Water Analysis', [
+ // values to be set
+ {location: '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[72.882185,19.076395]}}]}'},
+ {collection_datetime: '2017-11-08 18:43:57'},
+ {laboratory_testing_datetime: '2017-11-10 18:43:57'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.result_datetime, '2017-11-10 18:43:57');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/water_analysis/test_water_analysis.py b/erpnext/agriculture/doctype/water_analysis/test_water_analysis.py
new file mode 100644
index 0000000..b6467b7
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis/test_water_analysis.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestWaterAnalysis(unittest.TestCase):
+ pass
diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.js b/erpnext/agriculture/doctype/water_analysis/water_analysis.js
new file mode 100644
index 0000000..13fe3ad
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Water Analysis', {
+ onload: (frm) => {
+ if (frm.doc.water_analysis_criteria == undefined) frm.call('load_contents');
+ },
+ refresh: (frm) => {
+ let map_tools = ["a.leaflet-draw-draw-polyline",
+ "a.leaflet-draw-draw-polygon",
+ "a.leaflet-draw-draw-rectangle",
+ "a.leaflet-draw-draw-circle",
+ "a.leaflet-draw-draw-circlemarker"];
+
+ map_tools.forEach((element) => $(element).hide());
+ },
+ laboratory_testing_datetime: (frm) => frm.call("update_lab_result_date")
+});
diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.json b/erpnext/agriculture/doctype/water_analysis/water_analysis.json
new file mode 100644
index 0000000..467dde4
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.json
@@ -0,0 +1,561 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "WANA.#####",
+ "beta": 0,
+ "creation": "2017-10-17 18:51:19.946950",
+ "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": "location",
+ "fieldtype": "Geolocation",
+ "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": "Location",
+ "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": "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": "collection_datetime",
+ "fieldtype": "Datetime",
+ "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": "Collection Datetime",
+ "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": "laboratory_testing_datetime",
+ "fieldtype": "Datetime",
+ "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": "Laboratory Testing Datetime",
+ "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_datetime",
+ "fieldtype": "Datetime",
+ "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 Datetime",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_4",
+ "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": "type_of_sample",
+ "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": "Type of Sample",
+ "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": "container",
+ "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": "Container",
+ "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": "origin",
+ "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": "Origin",
+ "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": "column_break_8",
+ "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": "collection_temperature",
+ "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": "Collection Temperature ",
+ "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": "storage_temperature",
+ "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": "Storage Temperature",
+ "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": "appearance",
+ "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": "Appearance",
+ "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": "person_responsible",
+ "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": "Person Responsible",
+ "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": "column_break_29",
+ "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": "Water Analysis 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": 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": "water_analysis_criteria",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "options": "Water Analysis Criteria",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "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-12-05 23:42:50.684183",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Water Analysis",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/water_analysis/water_analysis.py b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
new file mode 100644
index 0000000..81fdf14
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis/water_analysis.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class WaterAnalysis(Document):
+ def load_contents(self):
+ docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Water Analysis'})
+ for doc in docs:
+ self.append('water_analysis_criteria', {'title': str(doc.name)})
+
+ def update_lab_result_date(self):
+ if not self.result_datetime:
+ self.result_datetime = self.laboratory_testing_datetime
+
+ def validate(self):
+ if self.collection_datetime > self.laboratory_testing_datetime:
+ frappe.throw('Lab testing datetime cannot be before collection datetime')
+ if self.laboratory_testing_datetime > self.result_datetime:
+ frappe.throw('Lab result datetime cannot be before testing datetime')
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/water_analysis_criteria/__init__.py b/erpnext/agriculture/doctype/water_analysis_criteria/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis_criteria/__init__.py
diff --git a/erpnext/agriculture/doctype/water_analysis_criteria/water_analysis_criteria.json b/erpnext/agriculture/doctype/water_analysis_criteria/water_analysis_criteria.json
new file mode 100644
index 0000000..395669a
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis_criteria/water_analysis_criteria.json
@@ -0,0 +1,162 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-05 23:36:22.723558",
+ "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": "title",
+ "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": "Title",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Analysis 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": "value",
+ "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": "Value",
+ "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": "minimum_permissible_value",
+ "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": "Minimum Permissible Value",
+ "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_permissible_value",
+ "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": "Maximum Permissible Value",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-05 23:36:45.836858",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Water Analysis Criteria",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/water_analysis_criteria/water_analysis_criteria.py b/erpnext/agriculture/doctype/water_analysis_criteria/water_analysis_criteria.py
new file mode 100644
index 0000000..6833f90
--- /dev/null
+++ b/erpnext/agriculture/doctype/water_analysis_criteria/water_analysis_criteria.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class WaterAnalysisCriteria(Document):
+ pass
diff --git a/erpnext/agriculture/doctype/weather/__init__.py b/erpnext/agriculture/doctype/weather/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather/__init__.py
diff --git a/erpnext/agriculture/doctype/weather/test_weather.js b/erpnext/agriculture/doctype/weather/test_weather.js
new file mode 100644
index 0000000..b5009a4
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather/test_weather.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Weather", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Weather
+ () => frappe.tests.make('Weather', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/agriculture/doctype/weather/test_weather.py b/erpnext/agriculture/doctype/weather/test_weather.py
new file mode 100644
index 0000000..b4ab3ae
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather/test_weather.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestWeather(unittest.TestCase):
+ pass
diff --git a/erpnext/agriculture/doctype/weather/weather.js b/erpnext/agriculture/doctype/weather/weather.js
new file mode 100644
index 0000000..dadb1d8
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather/weather.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Weather', {
+ onload: (frm) => {
+ if (frm.doc.weather_parameter == undefined) frm.call('load_contents');
+ }
+});
diff --git a/erpnext/agriculture/doctype/weather/weather.json b/erpnext/agriculture/doctype/weather/weather.json
new file mode 100644
index 0000000..8f54957
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather/weather.json
@@ -0,0 +1,261 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:date",
+ "beta": 0,
+ "creation": "2017-10-17 19:01:05.095598",
+ "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": "source",
+ "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": "Source",
+ "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": "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": "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": "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": 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": "section_break_3",
+ "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": "section_break_9",
+ "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": "Weather Parameter",
+ "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": "weather_parameter",
+ "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,
+ "length": 0,
+ "no_copy": 0,
+ "options": "Weather Parameter",
+ "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-12-06 11:04:36.977755",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Weather",
+ "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": "Agriculture Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Agriculture User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/weather/weather.py b/erpnext/agriculture/doctype/weather/weather.py
new file mode 100644
index 0000000..938daa2
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather/weather.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class Weather(Document):
+ def load_contents(self):
+ docs = frappe.get_all("Agriculture Analysis Criteria", filters={'linked_doctype':'Weather'})
+ for doc in docs:
+ self.append('weather_parameter', {'title': str(doc.name)})
diff --git a/erpnext/agriculture/doctype/weather_parameter/__init__.py b/erpnext/agriculture/doctype/weather_parameter/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather_parameter/__init__.py
diff --git a/erpnext/agriculture/doctype/weather_parameter/weather_parameter.json b/erpnext/agriculture/doctype/weather_parameter/weather_parameter.json
new file mode 100644
index 0000000..724ead9
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather_parameter/weather_parameter.json
@@ -0,0 +1,162 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-12-06 00:19:15.967334",
+ "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": "title",
+ "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": "Title",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Agriculture Analysis 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": "value",
+ "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": "Value",
+ "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": "minimum_permissible_value",
+ "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": "Minimum Permissible Value",
+ "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_permissible_value",
+ "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": "Maximum Permissible Value",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-06 00:26:48.887975",
+ "modified_by": "Administrator",
+ "module": "Agriculture",
+ "name": "Weather Parameter",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/agriculture/doctype/weather_parameter/weather_parameter.py b/erpnext/agriculture/doctype/weather_parameter/weather_parameter.py
new file mode 100644
index 0000000..89db74c
--- /dev/null
+++ b/erpnext/agriculture/doctype/weather_parameter/weather_parameter.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class WeatherParameter(Document):
+ pass
diff --git a/erpnext/agriculture/setup.py b/erpnext/agriculture/setup.py
new file mode 100644
index 0000000..b3b136a
--- /dev/null
+++ b/erpnext/agriculture/setup.py
@@ -0,0 +1,434 @@
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from erpnext.setup.utils import insert_record
+
+def setup_agriculture():
+ records = [
+ dict(
+ doctype="Land Unit",
+ land_unit_name="All Land Units",
+ is_group=1,
+ is_container=1),
+ dict(
+ doctype='Item Group',
+ item_group_name='Fertilizer',
+ is_group=0,
+ parent_item_group=_('All Item Groups')),
+ dict(
+ doctype='Item Group',
+ item_group_name='Seed',
+ is_group=0,
+ parent_item_group=_('All Item Groups')),
+ dict(
+ doctype='Item Group',
+ item_group_name='By-product',
+ is_group=0,
+ parent_item_group=_('All Item Groups')),
+ dict(
+ doctype='Item Group',
+ item_group_name='Produce',
+ is_group=0,
+ parent_item_group=_('All Item Groups')),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Nitrogen Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Phosphorous Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Potassium Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Calcium Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Sulphur Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Magnesium Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Iron Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Copper Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Zinc Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Boron Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Manganese Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Chlorine Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Molybdenum Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Sodium Content',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Humic Acid',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Fulvic Acid',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Inert',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Others',
+ standard=1,
+ linked_doctype='Fertilizer'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Nitrogen',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Phosphorous',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Potassium',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Calcium',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Magnesium',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Sulphur',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Boron',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Copper',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Iron',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Manganese',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Zinc',
+ standard=1,
+ linked_doctype='Plant Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Depth (in cm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='pH',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Salt Concentration (%)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Organic Matter (%)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='CEC (Cation Exchange Capacity) (MAQ/100mL)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Potassium Saturation (%)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Calcium Saturation (%)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Manganese Saturation (%)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Nirtogen (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Phosphorous (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Potassium (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Calcium (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Magnesium (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Sulphur (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Copper (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Iron (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Manganese (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Zinc (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Aluminium (ppm)',
+ standard=1,
+ linked_doctype='Soil Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='pH',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Conductivity (mS/cm)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Hardness (mg/CaCO3)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Turbidity (NTU)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Odor',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Color',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Nitrate (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Nirtite (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Calcium (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Magnesium (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Sulphate (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Boron (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Copper (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Iron (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Manganese (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Zinc (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Chlorine (mg/L)',
+ standard=1,
+ linked_doctype='Water Analysis'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Bulk Density',
+ standard=1,
+ linked_doctype='Soil Texture'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Field Capacity',
+ standard=1,
+ linked_doctype='Soil Texture'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Wilting Point',
+ standard=1,
+ linked_doctype='Soil Texture'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Hydraulic Conductivity',
+ standard=1,
+ linked_doctype='Soil Texture'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Organic Matter',
+ standard=1,
+ linked_doctype='Soil Texture'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Temperature High',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Temperature Low',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Temperature Average',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Dew Point',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Precipitation Received',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Humidity',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Pressure',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Insolation/ PAR (Photosynthetically Active Radiation)',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Degree Days',
+ standard=1,
+ linked_doctype='Weather'),
+ dict(
+ doctype='Agriculture Analysis Criteria',
+ title='Degree Days',
+ standard=1,
+ linked_doctype='Water Analysis')
+ ]
+ insert_record(records)
diff --git a/erpnext/config/agriculture.py b/erpnext/config/agriculture.py
new file mode 100644
index 0000000..20ee7cf
--- /dev/null
+++ b/erpnext/config/agriculture.py
@@ -0,0 +1,65 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return [
+ {
+ "label": _("Crops & Lands"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Crop",
+ },
+ {
+ "type": "doctype",
+ "name": "Crop Cycle",
+ },
+ {
+ "type": "doctype",
+ "name": "Land Unit",
+ }
+ ]
+ },
+ {
+ "label": _("Diseases & Fertilizers"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Disease",
+ },
+ {
+ "type": "doctype",
+ "name": "Fertilizer",
+ }
+ ]
+ },
+ {
+ "label": _("Analytics"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Plant Analysis",
+ },
+ {
+ "type": "doctype",
+ "name": "Soil Analysis",
+ },
+ {
+ "type": "doctype",
+ "name": "Water Analysis",
+ },
+ {
+ "type": "doctype",
+ "name": "Soil Texture",
+ },
+ {
+ "type": "doctype",
+ "name": "Weather",
+ },
+ {
+ "type": "doctype",
+ "name": "Agriculture Analysis Criteria",
+ }
+ ]
+ },
+ ]
\ No newline at end of file
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index fde19b4..e913c46 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -164,7 +164,8 @@
"color": "#FF888B",
"icon": "octicon octicon-tools",
"type": "module",
- "label": _("Maintenance")
+ "label": _("Maintenance"),
+ "hidden": 1
},
{
"module_name": "Student",
@@ -173,7 +174,8 @@
"label": _("Student"),
"link": "List/Student",
"_doctype": "Student",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Student Group",
@@ -182,7 +184,8 @@
"label": _("Student Group"),
"link": "List/Student Group",
"_doctype": "Student Group",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Course Schedule",
@@ -191,7 +194,8 @@
"label": _("Course Schedule"),
"link": "Calendar/Course Schedule",
"_doctype": "Course Schedule",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Student Attendance Tool",
@@ -200,7 +204,8 @@
"label": _("Student Attendance Tool"),
"link": "List/Student Attendance Tool",
"_doctype": "Student Attendance Tool",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Course",
@@ -209,7 +214,8 @@
"label": _("Course"),
"link": "List/Course",
"_doctype": "Course",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Program",
@@ -218,7 +224,8 @@
"label": _("Program"),
"link": "List/Program",
"_doctype": "Program",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Student Applicant",
@@ -227,7 +234,8 @@
"label": _("Student Applicant"),
"link": "List/Student Applicant",
"_doctype": "Student Applicant",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Fees",
@@ -236,7 +244,8 @@
"label": _("Fees"),
"link": "List/Fees",
"_doctype": "Fees",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Instructor",
@@ -245,7 +254,8 @@
"label": _("Instructor"),
"link": "List/Instructor",
"_doctype": "Instructor",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Room",
@@ -254,14 +264,16 @@
"label": _("Room"),
"link": "List/Room",
"_doctype": "Room",
- "type": "list"
+ "type": "list",
+ "hidden": 1
},
{
"module_name": "Education",
"color": "#428B46",
"icon": "octicon octicon-mortar-board",
"type": "module",
- "label": _("Education")
+ "label": _("Education"),
+ "hidden": 1
},
{
"module_name": "Healthcare",
@@ -269,6 +281,7 @@
"icon": "octicon octicon-plus",
"type": "module",
"label": _("Healthcare"),
+ "hidden": 1
},
{
"module_name": "Hub",
@@ -292,12 +305,177 @@
"icon": "🍔",
"_doctype": "Restaurant",
"link": "List/Restaurant",
- "label": _("Restaurant")
+ "label": _("Restaurant"),
+ "hidden": 1
+ },
+ {
+ "module_name": "Agriculture",
+ "color": "#8BC34A",
+ "icon": "octicon octicon-globe",
+ "type": "module",
+ "label": _("Agriculture"),
+ "hidden": 1
+ },
+ {
+ "module_name": "Crop",
+ "_doctype": "Crop",
+ "label": _("Crop"),
+ "color": "#8BC34A",
+ "icon": "fa fa-tree",
+ "type": "link",
+ "link": "List/Crop",
+ "hidden": 1
+ },
+ {
+ "module_name": "Crop Cycle",
+ "_doctype": "Crop Cycle",
+ "label": _("Crop Cycle"),
+ "color": "#8BC34A",
+ "icon": "fa fa-circle-o-notch",
+ "type": "link",
+ "link": "List/Crop Cycle",
+ "hidden": 1
+ },
+ {
+ "module_name": "Fertilizer",
+ "_doctype": "Fertilizer",
+ "label": _("Fertilizer"),
+ "color": "#8BC34A",
+ "icon": "fa fa-leaf",
+ "type": "link",
+ "link": "List/Fertilizer",
+ "hidden": 1
+ },
+ {
+ "module_name": "Land Unit",
+ "_doctype": "Land Unit",
+ "label": _("Land Unit"),
+ "color": "#8BC34A",
+ "icon": "fa fa-map",
+ "type": "link",
+ "link": "List/Land Unit",
+ "hidden": 1
+ },
+ {
+ "module_name": "Disease",
+ "_doctype": "Disease",
+ "label": _("Disease"),
+ "color": "#8BC34A",
+ "icon": "octicon octicon-bug",
+ "type": "link",
+ "link": "List/Disease",
+ "hidden": 1
+ },
+ {
+ "module_name": "Plant Analysis",
+ "_doctype": "Plant Analysis",
+ "label": _("Plant Analysis"),
+ "color": "#8BC34A",
+ "icon": "fa fa-pagelines",
+ "type": "link",
+ "link": "List/Plant Analysis",
+ "hidden": 1
+ },
+ {
+ "module_name": "Soil Analysis",
+ "_doctype": "Soil Analysis",
+ "label": _("Soil Analysis"),
+ "color": "#8BC34A",
+ "icon": "fa fa-flask",
+ "type": "link",
+ "link": "List/Soil Analysis",
+ "hidden": 1
+ },
+ {
+ "module_name": "Soil Texture",
+ "_doctype": "Soil Texture",
+ "label": _("Soil Texture"),
+ "color": "#8BC34A",
+ "icon": "octicon octicon-beaker",
+ "type": "link",
+ "link": "List/Soil Texture",
+ "hidden": 1
+ },
+ {
+ "module_name": "Water Analysis",
+ "_doctype": "Water Analysis",
+ "label": _("Water Analysis"),
+ "color": "#8BC34A",
+ "icon": "fa fa-tint",
+ "type": "link",
+ "link": "List/Water Analysis",
+ "hidden": 1
+ },
+ {
+ "module_name": "Weather",
+ "_doctype": "Weather",
+ "label": _("Weather"),
+ "color": "#8BC34A",
+ "icon": "fa fa-sun-o",
+ "type": "link",
+ "link": "List/Weather",
+ "hidden": 1
},
{
"module_name": "Assets",
"color": "#4286f4",
"icon": "octicon octicon-database",
+ "hidden": 1,
+ "label": _("Assets"),
"type": "module"
},
+ {
+ "module_name": "Grant Application",
+ "color": "#E9AB17",
+ "icon": "fa fa-gift",
+ "_doctype": "Grant Application",
+ "link": "List/Grant Application",
+ "label": _("Grant Application"),
+ "hidden": 1
+
+ },
+ {
+ "module_name": "Donor",
+ "color": "#7F5A58",
+ "icon": "fa fa-tint",
+ "_doctype": "Donor",
+ "link": "List/Donor",
+ "label": _("Donor"),
+ "hidden": 1
+ },
+ {
+ "module_name": "Volunteer",
+ "color": "#7E587E",
+ "icon": "fa fa-angellist",
+ "_doctype": "Volunteer",
+ "link": "List/Volunteer",
+ "label": _("Volunteer"),
+ "hidden": 1
+ },
+ {
+ "module_name": "Member",
+ "color": "#79BAEC",
+ "icon": "fa fa-users",
+ "_doctype": "Member",
+ "link": "List/Member",
+ "label": _("Member"),
+ "hidden": 1
+ },
+ {
+ "module_name": "Chapter",
+ "color": "#3B9C9C",
+ "icon": "fa fa-handshake-o",
+ "_doctype": "Chapter",
+ "link": "List/Chapter",
+ "label": _("Chapter"),
+ "hidden": 1
+ },
+ {
+ "module_name": "Non Profit",
+ "color": "#DE2B37",
+ "icon": "octicon octicon-heart",
+ "type": "module",
+ "label": _("Non Profit"),
+ "hidden": 1
+ }
]
diff --git a/erpnext/config/non_profit.py b/erpnext/config/non_profit.py
new file mode 100644
index 0000000..60ca80e
--- /dev/null
+++ b/erpnext/config/non_profit.py
@@ -0,0 +1,77 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return [
+ {
+ "label": _("Chapter"),
+ "icon": "fa fa-star",
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Chapter",
+ "description": _("Chapter information."),
+ }
+ ]
+ },
+ {
+ "label": _("Membership"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Member",
+ "description": _("Member information."),
+ },
+ {
+ "type": "doctype",
+ "name": "Membership",
+ "description": _("Memebership Details"),
+ },
+ {
+ "type": "doctype",
+ "name": "Membership Type",
+ "description": _("Memebership Type Details"),
+ },
+ ]
+ },
+ {
+ "label": _("Volunteer"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Volunteer",
+ "description": _("Volunteer information."),
+ },
+ {
+ "type": "doctype",
+ "name": "Volunteer Type",
+ "description": _("Volunteer Type information."),
+ }
+ ]
+ },
+ {
+ "label": _("Donor"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Donor",
+ "description": _("Donor information."),
+ },
+ {
+ "type": "doctype",
+ "name": "Donor Type",
+ "description": _("Donor Type information."),
+ }
+ ]
+ },
+ {
+ "label": _("Grant Application"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Grant Application",
+ "description": _("Grant information."),
+ }
+ ]
+ }
+ ]
diff --git a/erpnext/demo/domains.py b/erpnext/demo/domains.py
index 456eb5d..5ad3e04 100644
--- a/erpnext/demo/domains.py
+++ b/erpnext/demo/domains.py
@@ -18,5 +18,11 @@
},
'Healthcare': {
'company_name': 'ABC Hospital Ltd.'
+ },
+ 'Agriculture': {
+ 'company_name': 'Schrute Farms'
+ },
+ 'Non Profit': {
+ 'company_name': 'Erpnext Foundation'
}
}
\ No newline at end of file
diff --git a/erpnext/docs/assets/img/education/fees/fee-structure.png b/erpnext/docs/assets/img/education/fees/fee-structure.png
index 81f3e20..cd1edaf 100644
--- a/erpnext/docs/assets/img/education/fees/fee-structure.png
+++ b/erpnext/docs/assets/img/education/fees/fee-structure.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/__init__.py b/erpnext/docs/assets/img/non_profit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/__init__.py
diff --git a/erpnext/docs/assets/img/non_profit/chapter/chapter.png b/erpnext/docs/assets/img/non_profit/chapter/chapter.png
new file mode 100644
index 0000000..794f808
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/chapter/chapter.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/chapter/online_chapter.png b/erpnext/docs/assets/img/non_profit/chapter/online_chapter.png
new file mode 100644
index 0000000..95ebd81
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/chapter/online_chapter.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/chapter/online_chapter_join.png b/erpnext/docs/assets/img/non_profit/chapter/online_chapter_join.png
new file mode 100644
index 0000000..7ea56ec
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/chapter/online_chapter_join.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/donor/donor.png b/erpnext/docs/assets/img/non_profit/donor/donor.png
new file mode 100644
index 0000000..681dcc7
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/donor/donor.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/donor/donor_type.png b/erpnext/docs/assets/img/non_profit/donor/donor_type.png
new file mode 100644
index 0000000..9fedb9b
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/donor/donor_type.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/grant_application/grant_application.png b/erpnext/docs/assets/img/non_profit/grant_application/grant_application.png
new file mode 100644
index 0000000..f00ba32
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/grant_application/grant_application.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/grant_application/grant_application_row.png b/erpnext/docs/assets/img/non_profit/grant_application/grant_application_row.png
new file mode 100644
index 0000000..81cf2c6
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/grant_application/grant_application_row.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/grant_application/grant_portal.png b/erpnext/docs/assets/img/non_profit/grant_application/grant_portal.png
new file mode 100644
index 0000000..ef46bd4
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/grant_application/grant_portal.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/grant_application/online_grant_application_1.png b/erpnext/docs/assets/img/non_profit/grant_application/online_grant_application_1.png
new file mode 100644
index 0000000..899c257
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/grant_application/online_grant_application_1.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/membership/member.png b/erpnext/docs/assets/img/non_profit/membership/member.png
new file mode 100644
index 0000000..d5518ff
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/membership/member.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/membership/membership.png b/erpnext/docs/assets/img/non_profit/membership/membership.png
new file mode 100644
index 0000000..01c3ca4
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/membership/membership.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/membership/membership_type.png b/erpnext/docs/assets/img/non_profit/membership/membership_type.png
new file mode 100644
index 0000000..6711d77
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/membership/membership_type.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/module.png b/erpnext/docs/assets/img/non_profit/module.png
new file mode 100644
index 0000000..fa1d3e8
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/module.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/non_profit_domain.png b/erpnext/docs/assets/img/non_profit/non_profit_domain.png
new file mode 100644
index 0000000..8c102e8
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/non_profit_domain.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/volunteer/volunteer.png b/erpnext/docs/assets/img/non_profit/volunteer/volunteer.png
new file mode 100644
index 0000000..0ada095
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/volunteer/volunteer.png
Binary files differ
diff --git a/erpnext/docs/assets/img/non_profit/volunteer/volunteer_type.png b/erpnext/docs/assets/img/non_profit/volunteer/volunteer_type.png
new file mode 100644
index 0000000..729a0b7
--- /dev/null
+++ b/erpnext/docs/assets/img/non_profit/volunteer/volunteer_type.png
Binary files differ
diff --git a/erpnext/docs/assets/img/setup/barcode-1.png b/erpnext/docs/assets/img/setup/barcode-1.png
deleted file mode 100644
index c200a13..0000000
--- a/erpnext/docs/assets/img/setup/barcode-1.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/docs/assets/img/setup/barcode-2.png b/erpnext/docs/assets/img/setup/barcode-2.png
deleted file mode 100644
index 6ea4529..0000000
--- a/erpnext/docs/assets/img/setup/barcode-2.png
+++ /dev/null
Binary files differ
diff --git a/erpnext/docs/assets/img/stock/material-receipt-sample.png b/erpnext/docs/assets/img/stock/material-receipt-sample.png
new file mode 100644
index 0000000..f893424
--- /dev/null
+++ b/erpnext/docs/assets/img/stock/material-receipt-sample.png
Binary files differ
diff --git a/erpnext/docs/assets/img/stock/material-transfer-sample.png b/erpnext/docs/assets/img/stock/material-transfer-sample.png
new file mode 100644
index 0000000..6191156
--- /dev/null
+++ b/erpnext/docs/assets/img/stock/material-transfer-sample.png
Binary files differ
diff --git a/erpnext/docs/assets/img/stock/retain-sample.png b/erpnext/docs/assets/img/stock/retain-sample.png
new file mode 100644
index 0000000..675339f
--- /dev/null
+++ b/erpnext/docs/assets/img/stock/retain-sample.png
Binary files differ
diff --git a/erpnext/docs/assets/img/stock/sample-warehouse.png b/erpnext/docs/assets/img/stock/sample-warehouse.png
new file mode 100644
index 0000000..fc6fee1
--- /dev/null
+++ b/erpnext/docs/assets/img/stock/sample-warehouse.png
Binary files differ
diff --git a/erpnext/docs/user/manual/de/setting-up/bar-code.md b/erpnext/docs/user/manual/de/setting-up/bar-code.md
deleted file mode 100644
index e85c698..0000000
--- a/erpnext/docs/user/manual/de/setting-up/bar-code.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Barcode
-<span class="text-muted contributed-by">Beigetragen von CWT Connector & Wire Technology GmbH</span>
-
-Ein Barcode ist ein maschinenlesbarer Code und besteht aus Nummern und Mustern von parallelen Linien mit unterschiedlicher Breite, die auf eine Ware aufgedruckt werden. Barcodes werden speziell zur Lagerverwaltung verwendet.
-
-Wenn Sie einen Artikel bei einem beliebigen Geschäft kaufen, dann werden Sie einen Aufkleber mit dünnen Linien erkennen, versehen mit einer Kombination von verschiedenen Zahlen. Dieser Aufkleber wird dann vom Kassierer eingescannt und die Beschreibung und der Preis werden automatisch übernommen. Diese Anordnung von Linien und Zahlen bezeichnet man als Barcode.
-
-Ein Barcode-Lesegerät liest die Nummer des Aufklebers eines Artikels ein. Um mit ERPNext Barcodes zu nutzen, verbinden Sie den Barcodeleser mit Ihrer Hardware. Gehen Sie dann zu den ERPNext-Einstellungen und aktivieren Sie "Barcode" indem Sie zu den Werkzeugen gehen und auf die Funktion "verbergen / anzeigen" klicken. Kreuzen Sie dann das Feld "Artikel-Barcode" an.
-
-> Einstellungen > Anpassen > Funktionen einstellen > Artikelbarcode
-
-### Abbildung 1: Markieren Sie das Feld "Artikelbarcode"
-
-<img class="screenshot" alt="Barcode" src="/docs/assets/img/setup/barcode-1.png">
-
-Wenn Sie einen Barcode einlesen wollen, gehen Sie zu:
-
-> Rechnungswesen > Dokumente > Eingangsrechnung
-
-Klicken Sie unter dem Artikel auf "Neue Zeile einfügen". Die Artikelzeile erweitert sich um neue Felder anzuzeigen. Positionieren Sie Ihre Schreibmarke im Barcodefeld und beginnen Sie mit dem Einlesen. Der Barcode wird im entsprechenden Feld aktualisiert. Nachdem der Barcode eingelesen wurd, holt das System automatisch alle Artikeldetails aus dem System.
-
-Aktivieren Sie der Einfachheit halber die POS-Ansicht in ERPNext. Der Aktivierungsprozess ist der selbe wie bei der Barcodeaktivierung. Gehen Sie in die Einstellungen und klicken Sie auf "Funktionen einstellen". Aktivieren Sie dann das Feld "Ist POS".
-
-Gehen Sie dann zu "Rechnungswesen" und klicken Sie auf Ausgangsrechnung. Aktivieren Sie das Feld "Ist POS".
-
-### Abbildung 2: Aktivieren Sie das Feld "Ist POS"
-
-<img class="screenshot" alt="Barcode" src="/docs/assets/img/setup/barcode-2.png">
-
-Gehen Sie zu "Artikel" und klicken Sie auf "Neue Zeile einfügen".
-
-Die Schreibmarke wird automatisch im Barcodefeld positioniert. So können Sie sofort den Barcode einlesen und mit Ihren Arbeiten fortfahren.
-
-{next}
diff --git a/erpnext/docs/user/manual/de/setting-up/index.txt b/erpnext/docs/user/manual/de/setting-up/index.txt
index a607ca2..fff1665 100644
--- a/erpnext/docs/user/manual/de/setting-up/index.txt
+++ b/erpnext/docs/user/manual/de/setting-up/index.txt
@@ -13,7 +13,6 @@
territory
third-party-backups
workflows
-bar-code
company-setup
setting-company-sales-goal
calculate-incentive-for-sales-team
diff --git a/erpnext/docs/user/manual/en/education/fees/fee-structure.md b/erpnext/docs/user/manual/en/education/fees/fee-structure.md
index b1cc36d..2131c4a 100644
--- a/erpnext/docs/user/manual/en/education/fees/fee-structure.md
+++ b/erpnext/docs/user/manual/en/education/fees/fee-structure.md
@@ -1,7 +1,23 @@
# Fee Structure
-A Fee Structure is a template that can be used while making fee records.
+A Fee Structure is a template that can be used while making Fees records or generating them via the Fee Schedule. In the Accounts section, you can set also the different accounts as for the Fees is an accounting transaction.
+
+You can create the Fee Structure directly from
+
+> Education > Fees > Fee Structure > New Fee Structure
+
+or you can create the Fee Structure from Program also.
<img class="screenshot" alt="Fees Structure" src="/docs/assets/img/education/fees/fee-structure.png">
+#### Academic Year Impact
+
+If the Fee amount doesn't change every academic year then Fee Structure can be created without the Acadamic year. In doing so, the same Fee Structure can be used every academic year until the Fees for that particular program doesn't change. Still you can set the academic year and term while creating the Fees or Fee Schedule records.
+
+#### Accounting Impact
+
+You can set the "Income Account" and "Receivable Account" in the Accounts section which refers to an Account of you [Chart of Accounts](/docs/user/manual/en/accounts/chart-of-accounts.md). You must also mention the Cost Center in which your income will be booked.
+
+If you are going to use this in the Fee Schedule, you must select the Accounts carefully as Fee Schedule updates the respected Accounts in bulk.
+
{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Chapter/__init__.py b/erpnext/docs/user/manual/en/non_profit/Chapter/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Chapter/__init__.py
diff --git a/erpnext/docs/user/manual/en/non_profit/Chapter/chapter.md b/erpnext/docs/user/manual/en/non_profit/Chapter/chapter.md
new file mode 100644
index 0000000..0078f6c
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Chapter/chapter.md
@@ -0,0 +1,27 @@
+#Chapter
+
+The Chapter doctype allows you to record the Chapter details.
+
+Chapter Head or System User can create Chapter.
+
+To Create Chapter:
+
+> Non Profit > Chapter > New
+
+<img class="screenshot" alt="Chapter" src="/docs/assets/img/non_profit/chapter/chapter.png">
+
+System User or Chapter Head can add chapter Member directly from the desk or
+User can join directly by visiting chapter page on website
+
+to join chapter online
+
+> My Account on website > Chapter from sidebar > Select Available chapter and click on join chapter button
+
+<img class="screenshot" alt="online Chapter" src="/docs/assets/img/non_profit/chapter/online_chapter.png">
+
+<img class="screenshot" alt="online Chapter" src="/docs/assets/img/non_profit/chapter/online_chapter_join.png">
+
+
+To leave chapter click on leave chapter button
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Chapter/index.md b/erpnext/docs/user/manual/en/non_profit/Chapter/index.md
new file mode 100644
index 0000000..1c5e132
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Chapter/index.md
@@ -0,0 +1,10 @@
+# Chapter
+
+This section contains Chapter related documents.
+
+Chapter doctype is for people to organize or join offline group meetings in various cities around the world. user/members can find and join groups with a common interest.
+
+
+### Topics
+
+{index}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Chapter/index.txt b/erpnext/docs/user/manual/en/non_profit/Chapter/index.txt
new file mode 100644
index 0000000..9eb7bdd
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Chapter/index.txt
@@ -0,0 +1 @@
+chapter
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Donor/__init__.py b/erpnext/docs/user/manual/en/non_profit/Donor/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Donor/__init__.py
diff --git a/erpnext/docs/user/manual/en/non_profit/Donor/donor.md b/erpnext/docs/user/manual/en/non_profit/Donor/donor.md
new file mode 100644
index 0000000..7958755
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Donor/donor.md
@@ -0,0 +1,21 @@
+#Donor
+
+The Donor doctype allows you to record the Donor details.
+
+Donor are simply contacts in your ERPNext database with one or more Donation. The contact may be an individual, a household, an organisation, or some other contact sub-type, but it is always a contact to which a donation is applied.
+
+To create new Donor go to:
+
+> Non Profit > Donor > New
+
+<img class="screenshot" alt="Student" src="/docs/assets/img/non_profit/donor/donor.png">
+
+**Email:** Email field is the id of Member doctype.
+
+**Donor Type:** DonorType is link field to Donor Type Doctype. Member can select Available Doctype.
+
+**Address and Contact Section:** This Section linked to address and contact doctypes.
+
+**Accounting Section:** This section allowed to set member accounting details such as Account Receivable.
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Donor/donor_type.md b/erpnext/docs/user/manual/en/non_profit/Donor/donor_type.md
new file mode 100644
index 0000000..ba74c17
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Donor/donor_type.md
@@ -0,0 +1,17 @@
+#Donor Type
+
+The Donor Type doctype allows you to Create different Donor Profile for the Donor.
+
+Donor Types are a basic building block for Donor and contribution management. Typically an organization will set up a donor type for each of the different donation that they offer. For example, an organisation may define three donation types for 'regular', 'Organization', and 'honorary' donor.
+
+In this chapter we will cover the most common set-up for donor types.
+
+To create new donor Type go to:
+
+> Non Profit > Donor Type > New
+
+<img class="screenshot" alt="donor type" src="/docs/assets/img/non_profit/donor/donor_type.png">
+
+**Donor Type:** The Donor Type is displayed throughout the system, on both public and backend pages so spend some time thinking about a donor type name that is appropriate to both audiences. It can be changed at a later date
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Donor/index.md b/erpnext/docs/user/manual/en/non_profit/Donor/index.md
new file mode 100644
index 0000000..9b7b14f
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Donor/index.md
@@ -0,0 +1,9 @@
+# Donor
+
+This section contains Donors and Donors Contribution related documents.
+
+A donor in general is a person, organization or government who donates something voluntarily. The term is usually used to represent a form of pure altruism but sometimes used when the payment for a service is recognized by all parties as representing less than the value of the donation and that the motivation is altruistic. In business law, a donor is someone who is giving the gift (law), and a donee the person receiving the gift.
+
+### Topics
+
+{index}
diff --git a/erpnext/docs/user/manual/en/non_profit/Donor/index.txt b/erpnext/docs/user/manual/en/non_profit/Donor/index.txt
new file mode 100644
index 0000000..7f36f92
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Donor/index.txt
@@ -0,0 +1,2 @@
+donor_type
+donor
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Grant Application/__init__.py b/erpnext/docs/user/manual/en/non_profit/Grant Application/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Grant Application/__init__.py
diff --git a/erpnext/docs/user/manual/en/non_profit/Grant Application/grant_application.md b/erpnext/docs/user/manual/en/non_profit/Grant Application/grant_application.md
new file mode 100644
index 0000000..3b07d35
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Grant Application/grant_application.md
@@ -0,0 +1,43 @@
+#Grant Application
+
+The Grant Application doctype allows you to record the Grant Applicants details.
+
+To Generate Online Grant Application go to:
+
+> My Account on website > Grant Application from sidebar > Apply for new Grant Application.
+
+
+<img class="screenshot" alt="Online Grant Application row" src="/docs/assets/img/non_profit/grant_application/grant_application_row.png">
+
+<img class="screenshot" alt="Online Grant Application" src="/docs/assets/img/non_profit/grant_application/online_grant_application_1.png">
+
+<img class="screenshot" alt="Online Grant Application" src="/docs/assets/img/non_profit/grant_application/grant_portal.png">
+
+
+To Generate Grant Application go to:
+
+> Non Profit > Grant Application > New.
+
+
+<img class="screenshot" alt="Grant Application" src="/docs/assets/img/non_profit/grant_application/grant_application.png">
+
+
+**Email:** Email is a mandatory field.
+
+**Organization:** Organization is data field contain organizaion name set as name field in erpnext.
+
+
+**Address and Contact Section:** This Section linked to address and contact doctypes.
+
+**Grant Application Details Section:** This section contains information about grant description.
+
+**Amount:** Amount field describe requested amount by an applicant.
+
+**Route:** Route field leave blank it will automatically create route path grant-application/organization_name
+
+**Assessment Result Section:** In This section when status field selected as received, send Grant Review Email button appear on the top right corner which sends grant URL to Assessment Manager.
+
+After reviewing grant. Grant Assessment Manager scale application at 0 - 9 point and left a note about a grant.
+
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Grant Application/index.md b/erpnext/docs/user/manual/en/non_profit/Grant Application/index.md
new file mode 100644
index 0000000..a665440
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Grant Application/index.md
@@ -0,0 +1,16 @@
+# Grant Application
+
+Grant Application is designed to be used by organisations that distribute funds to others, for example grant seeker, etc.
+
+Grants are non-repayable funds or products disbursed or gifted by one party (grantmakers), often a government department, corporation, foundation or trust, to a recipient, often (but not always) a nonprofit entity, educational institution, business or an individual. In order to receive a grant, some form of "Grant Writing" often referred to as either a proposal or an application is required.
+
+Most grants are made to fund a specific project and require some level of compliance and reporting.
+
+The grant writing process involves an applicant submitting a proposal (or submission) to a potential funder, either on the applicant's own initiative or in response to a Request for Proposal from the funder. Other grants can be given to individuals, such as victims of natural disasters or individuals who seek to open a small business. Sometimes grant makers require grant seekers to have some form of tax-exempt status, be a registered nonprofit organization or a local government.
+
+Grant Application is grant writing process which can be review by assessment manager and then decided by the organization to disburse grant amount to the applicant or not.
+
+
+### Topics
+
+{index}
diff --git a/erpnext/docs/user/manual/en/non_profit/Grant Application/index.txt b/erpnext/docs/user/manual/en/non_profit/Grant Application/index.txt
new file mode 100644
index 0000000..5d997e8
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Grant Application/index.txt
@@ -0,0 +1 @@
+grant_application
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Membership/__init__.py b/erpnext/docs/user/manual/en/non_profit/Membership/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Membership/__init__.py
diff --git a/erpnext/docs/user/manual/en/non_profit/Membership/index.md b/erpnext/docs/user/manual/en/non_profit/Membership/index.md
new file mode 100644
index 0000000..1241451
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Membership/index.md
@@ -0,0 +1,9 @@
+# Membership
+
+This section contains Member and Membership related documents.
+
+How to set up one or more membership types that you can use to manage your organization's members. It also explains the concept of membership statuses and how your organisation can use them to define a membership life-cycle.
+
+### Topics
+
+{index}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Membership/index.txt b/erpnext/docs/user/manual/en/non_profit/Membership/index.txt
new file mode 100644
index 0000000..f1d9bf3
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Membership/index.txt
@@ -0,0 +1,3 @@
+membership_type
+member
+membership
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Membership/member.md b/erpnext/docs/user/manual/en/non_profit/Membership/member.md
new file mode 100644
index 0000000..c9dc9c6
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Membership/member.md
@@ -0,0 +1,21 @@
+#Member
+
+The Member doctype allows you to record the Member details for a **Membership**.
+
+Members are simply contacts in your ERPNext database with one or more memberships. The contact may be an individual, a household, an organisation, or some other contact sub-type, but it is always a contact to which a membership is applied.
+
+To create new Member go to:
+
+> Non Profit > Member > New
+
+<img class="screenshot" alt="Student" src="/docs/assets/img/non_profit/membership/member.png">
+
+**Email:** Email field is the id of Member doctype.
+
+**Membership Type:** Membership Type is link field to Membership Type Doctype. Member can select Available Doctype.
+
+**Membership Expiry Date:** This Field fetch membership end date details from membership doctype.
+
+**Address and Contact Section:** This Section linked to address and contact doctypes.
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Membership/membership.md b/erpnext/docs/user/manual/en/non_profit/Membership/membership.md
new file mode 100644
index 0000000..f101b86
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Membership/membership.md
@@ -0,0 +1,23 @@
+#Membership
+
+The Membership doctype allows you to record membership details for the **Member**.
+
+Membership is a term which refers to any organization that allows people to subscribe, and often requires them to pay a membership fee or "subscription".
+
+
+To create new Membership go to:
+
+> Non Profit > Membership > New
+
+<img class="screenshot" alt="Membership" src="/docs/assets/img/non_profit/membership/membership.png">
+
+**Member:** Member is a link field fetch member details from Member doctype.
+
+**Membership Status:** Membership Status is a select field which contains New, Current, Expired, Pending and Cancelled.
+
+**Membership Date Details section:** This section contain information related to Membership start date, end date and member since date.
+
+**Payment Details:** This section contains payment related details. If the person paid for membership checkbox paid is marked as checked else unmarked.
+Amount fetch based on membership type.
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Membership/membership_type.md b/erpnext/docs/user/manual/en/non_profit/Membership/membership_type.md
new file mode 100644
index 0000000..eb7a09e
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Membership/membership_type.md
@@ -0,0 +1,18 @@
+#Membership Type
+
+Membership Types are a basic building block for membership management. Typically an organization will set up a membership type for each of the different memberships that they offer. For the simplest membership structures, one membership type may be enough. For more complex membership structures, more membership types may be required. For example, an organisation may define three membership types for 'regular', 'student', and 'honorary' members. Or an organization may choose to use membership types as subcriptions to their different publications, either free or paying ones.
+
+In this chapter we will cover the most common set-up for membership types.
+
+To create new Membership Type go to:
+
+> Non Profit > Membership Type > New
+
+
+<img class="screenshot" alt="Student" src="/docs/assets/img/non_profit/membership/membership_type.png">
+
+**Membership Type:** The Membership Type is displayed throughout the system, on both public and backend pages so spend some time thinking about a membership type name that is appropriate to both audiences. It can be changed at a later date
+
+**Amount:** If your memberships are free you should enter 0 (zero) in this field. Otherwise you should enter the amount that must be paid for this membership type.
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Volunteer/__init__.py b/erpnext/docs/user/manual/en/non_profit/Volunteer/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Volunteer/__init__.py
diff --git a/erpnext/docs/user/manual/en/non_profit/Volunteer/index.md b/erpnext/docs/user/manual/en/non_profit/Volunteer/index.md
new file mode 100644
index 0000000..77a8289
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Volunteer/index.md
@@ -0,0 +1,9 @@
+# Volunteer
+
+This section contains Volunteer and Volunteer Type related documents.
+
+Volunteer is the practice of people working on behalf of others without being motivated by financial or material gain.
+
+### Topics
+
+{index}
diff --git a/erpnext/docs/user/manual/en/non_profit/Volunteer/index.txt b/erpnext/docs/user/manual/en/non_profit/Volunteer/index.txt
new file mode 100644
index 0000000..3d93d06
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Volunteer/index.txt
@@ -0,0 +1,2 @@
+volunteer_type
+volunteer
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Volunteer/volunteer.md b/erpnext/docs/user/manual/en/non_profit/Volunteer/volunteer.md
new file mode 100644
index 0000000..6b875ee
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Volunteer/volunteer.md
@@ -0,0 +1,24 @@
+#Volunteer
+
+The Volunteer doctype allows you to record the Volunter details.
+
+Volunteer are simply contacts in your ERPNext database with one or more volunteering program. The contact may be an individual, a household, an organisation, or some other contact sub-type
+
+To create new Volunteer go to:
+
+> Non Profit > Volunteer > New
+
+<img class="screenshot" alt="Volunteer" src="/docs/assets/img/non_profit/volunteer/volunteer.png">
+
+**Email:** Email field is the id of Member doctype.
+
+**Volunteer Type:** Volunteer Type is link field to Volunteer Type Doctype. Volunteer can select available Doctype.
+
+**Address and Contact Section:** This Section linked to address and contact doctypes.
+
+**Volunteer Availability Section:** This section is child table which contains select field about volunteer availability. a volunteer can select availability such as weekly, morning etc
+
+**Volunteer Skills Section:** This section is child table which contains data field about the volunteer skills. a volunteer can add multiple skill for eg. Desk Job,
+Hospitality, Food management, computer operator etc.
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/Volunteer/volunteer_type.md b/erpnext/docs/user/manual/en/non_profit/Volunteer/volunteer_type.md
new file mode 100644
index 0000000..95b4c81
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/Volunteer/volunteer_type.md
@@ -0,0 +1,18 @@
+#Volunteer Type
+
+Volunteer Types are a basic building block for Volunteering management. Typically an organization will set up a volunteer type for each of the different donation that they offer. For example, an organisation may define three volunteer types for 'regular', 'Student', and 'Member' donor.
+
+In this chapter we will cover the most common set-up for volunteer types.
+
+To create new volunteer Type go to:
+
+> Non Profit > Volunteer Type > New
+
+<img class="screenshot" alt="Volunteer" src="/docs/assets/img/non_profit/volunteer/volunteer_type.png">
+
+
+**Volunteer Type:** The Volunteer Type is displayed throughout the system, on both public and backend pages so spend some time thinking about a membership type name that is appropriate to both audiences. It can be changed at a later date
+
+**Amount:** If your Volunteering are free you should enter 0 (zero) in this field. Otherwise you should enter the amount that must be paid to the volunteer.
+
+{next}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/__init__.py b/erpnext/docs/user/manual/en/non_profit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/__init__.py
diff --git a/erpnext/docs/user/manual/en/non_profit/index.md b/erpnext/docs/user/manual/en/non_profit/index.md
new file mode 100644
index 0000000..546581f
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/index.md
@@ -0,0 +1,23 @@
+# Non Profit
+
+
+The Non Profit Modules in ERPNext is designed to meet requirements of NGO and Non Profit Organization. This is a centralized system, which maintains and updates all the activities related to an Organization.
+
+This will track all activity related to Memberships, Chapters, Volunteer Management,
+Donor Management, Event and Grant etc
+
+
+### Desk Page
+<img class="screenshot" >
+
+<div class="section" style="padding-top: 0px; margin-top: -30px;">
+ <div class="fake-browser-frame">
+ <img class="img-responsive browser-image feature-image" alt="Non Profit Domain"
+ src="/docs/assets/img/non_profit/non_profit_domain.png">
+ </div>
+</div>
+
+### Non Profit Domain
+<img class="screenshot" alt="Non Profit" src="/docs/assets/img/non_profit/module.png">
+
+{index}
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/non_profit/index.txt b/erpnext/docs/user/manual/en/non_profit/index.txt
new file mode 100644
index 0000000..9f5e13a
--- /dev/null
+++ b/erpnext/docs/user/manual/en/non_profit/index.txt
@@ -0,0 +1,5 @@
+Membership
+Chapter
+Volunteer
+Donor
+Grant Application
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/setting-up/bar-code.md b/erpnext/docs/user/manual/en/setting-up/bar-code.md
deleted file mode 100644
index e317628..0000000
--- a/erpnext/docs/user/manual/en/setting-up/bar-code.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Bar Code
-
-A Barcode is a machine-readable code in the form of numbers and a pattern of
-parallel lines of varying widths, printed on a commodity and used especially
-for stock control.
-
-When you purchase an item from any store, you will notice a label with thin,
-black lines across it, along with a variation of different numbers. This label
-is then scanned by the cashier, and the item's description and price
-automatically comes up. This set of lines and numbers on the label are termed
-as bar-code.
-
-A bar-code machine scans the number from the label of an Item. To work with
-ERPNext and the bar-code mechanism, connect the bar-code machine to your
-operating hardware. Then go to ERPNext setup and activate bar-code by going to
-tools and clicking on 'hide / unhide features'. Under Materials, feature
-setup, check the box that says Item Barcode.
-
-> Setup > Customize > Hide/ Unhide Features > Item Barcode.
-
-#### Figure 1: Check the box 'Item Barcode'
-
-<img class="screenshot" alt="Barcode" src="/docs/assets/img/setup/barcode-1.png">
-
-
-To start scanning with a bar-code, go to
-
-> Accounts > Sales Invoice
-
-Under Item, click on Add new row. The item row will expand to show new fields.
-Place your cursor on the bar-code field and begin scanning. The bar-code will
-be updated in the field. Once the bar-code is entered, all the Item details
-will be fetched automatically by the system.
-
-For more ease, activate the POS view in ERPnext. The activation process is
-same as the bar-code activation. Go to Setup and click on 'hide/unhide
-features'. Check the 'POS view' box.
-
-Then go to Accounts and click on Sales Invoice. Check the box 'Is POS'
-
-
-#### Figure 2: Check the box 'Is POS'
-
-<img class="screenshot" alt="Barcode" src="/docs/assets/img/setup/barcode-2.png">
-
-
-Go to Item and click on Add new row.
-
-The cursor will automatically be placed in the bar-code field. Thus you can
-immediately scan the bar-code and proceed with your operations.
-
-{next}
diff --git a/erpnext/docs/user/manual/en/setting-up/index.txt b/erpnext/docs/user/manual/en/setting-up/index.txt
index 129876e..2733e91 100644
--- a/erpnext/docs/user/manual/en/setting-up/index.txt
+++ b/erpnext/docs/user/manual/en/setting-up/index.txt
@@ -13,6 +13,5 @@
territory
third-party-backups
workflows
-bar-code
company-setup
articles
diff --git a/erpnext/docs/user/manual/en/stock/index.txt b/erpnext/docs/user/manual/en/stock/index.txt
index b89abe1..f807e73 100644
--- a/erpnext/docs/user/manual/en/stock/index.txt
+++ b/erpnext/docs/user/manual/en/stock/index.txt
@@ -16,3 +16,4 @@
articles
opening-stock
stock-how-to
+retain-sample-stock
\ No newline at end of file
diff --git a/erpnext/docs/user/manual/en/stock/retain-sample-stock.md b/erpnext/docs/user/manual/en/stock/retain-sample-stock.md
new file mode 100644
index 0000000..0f8199a
--- /dev/null
+++ b/erpnext/docs/user/manual/en/stock/retain-sample-stock.md
@@ -0,0 +1,26 @@
+# Retain Sample Stock
+
+A sample of a batch of starting material, packaging material or finished product is stored for the purpose of being analyzed should the need arise later.
+
+### Set Sample Retention Warehouse in Stock Settings
+
+It is advised to create a new warehouse just for retaining samples and not use it in production.
+
+<img class="screenshot" alt="Sample Retention Warehouse" src="/docs/assets/img/stock/sample-warehouse.png">
+
+### Enable Retain Sample in Item master
+
+Check Retain Sample and Maximum allowed samples in Item Master for a batch. Please note that Retain Sample is based
+on Batch hence Has Batch No should be enabled as well.
+
+<img class="screenshot" alt="Retain Sample" src="/docs/assets/img/stock/retain-sample.png">
+
+### Stock Entry
+
+Whenever a Stock Entry is created with the purpose as Material Receipt, for items which have Retain Sample enabled, the Sample Quantity can be set during that Stock Entry. Sample quantity cannot be more than the Maximum sample quantity set in Item Master.
+
+<img class="screenshot" alt="Retain Sample" src="/docs/assets/img/stock/material-receipt-sample.png">
+
+On submission of this Stock Entry, button 'Make Retention Stock Entry' will be available to make another Stock Entry for the transfer of sample items from the mentioned batch to the retention warehouse set in Stock Settings. On clicking this button it will direct you to new Stock Entry with all the information, verify the information and click Submit.
+
+<img class="screenshot" alt="Retain Sample" src="/docs/assets/img/stock/material-transfer-sample.png">
\ No newline at end of file
diff --git a/erpnext/domains/agriculture.py b/erpnext/domains/agriculture.py
new file mode 100644
index 0000000..378c5f1
--- /dev/null
+++ b/erpnext/domains/agriculture.py
@@ -0,0 +1,22 @@
+data = {
+ 'desktop_icons': [
+ 'Agriculture Task',
+ 'Crop',
+ 'Crop Cycle',
+ 'Fertilizer',
+ 'Item',
+ 'Land Unit',
+ 'Disease',
+ 'Plant Analysis',
+ 'Soil Analysis',
+ 'Soil Texture',
+ 'Task',
+ 'Water Analysis',
+ 'Weather'
+ ],
+ 'modules': [
+ 'Agriculture'
+ ],
+ 'default_portal_role': 'System Manager',
+ 'on_setup': 'erpnext.agriculture.setup.setup_agriculture'
+}
\ No newline at end of file
diff --git a/erpnext/domains/non_profit.py b/erpnext/domains/non_profit.py
new file mode 100644
index 0000000..b9683bd
--- /dev/null
+++ b/erpnext/domains/non_profit.py
@@ -0,0 +1,17 @@
+data = {
+ 'desktop_icons': [
+ 'Non Profit',
+ 'Member',
+ 'Donor',
+ 'Volunteer',
+ 'Grant Application',
+ 'Accounts',
+ 'Buying',
+ 'HR',
+ 'ToDo'
+ ],
+ 'modules': [
+ 'Non Profit'
+ ],
+ 'default_portal_role': 'Non Profit Manager'
+}
\ No newline at end of file
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.js b/erpnext/education/doctype/fee_schedule/fee_schedule.js
index a560ea7..a36b9cb 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.js
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.js
@@ -30,6 +30,7 @@
frm.set_query("student_group", "student_groups", function() {
return {
"program": frm.doc.program,
+ "academic_term": frm.doc.academic_term,
"academic_year": frm.doc.academic_year
};
});
@@ -95,19 +96,21 @@
frappe.ui.form.on("Fee Schedule Student Group", {
student_group: function(frm, cdt, cdn) {
var row = locals[cdt][cdn];
- frappe.call({
- method: "erpnext.education.doctype.fee_schedule.fee_schedule.get_total_students",
- args: {
- "student_group": row.student_group,
- "academic_year": frm.doc.academic_year,
- "academic_term": frm.doc.academic_term,
- "student_category": frm.doc.student_category
- },
- callback: function(r) {
- if(!r.exc) {
- frappe.model.set_value(cdt, cdn, "total_students", r.message);
+ if (row.student_group && frm.doc.academic_year) {
+ frappe.call({
+ method: "erpnext.education.doctype.fee_schedule.fee_schedule.get_total_students",
+ args: {
+ "student_group": row.student_group,
+ "academic_year": frm.doc.academic_year,
+ "academic_term": frm.doc.academic_term,
+ "student_category": frm.doc.student_category
+ },
+ callback: function(r) {
+ if(!r.exc) {
+ frappe.model.set_value(cdt, cdn, "total_students", r.message);
+ }
}
- }
- });
+ });
+ }
}
})
\ No newline at end of file
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.json b/erpnext/education/doctype/fee_schedule/fee_schedule.json
index a1ea9bd..a77cc59 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.json
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.json
@@ -280,10 +280,10 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 1,
+ "read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -311,7 +311,7 @@
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 1,
+ "read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -1029,7 +1029,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-11-10 18:56:46.330631",
+ "modified": "2017-12-04 13:08:27.727709",
"modified_by": "Administrator",
"module": "Education",
"name": "Fee Schedule",
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.py b/erpnext/education/doctype/fee_schedule/fee_schedule.py
index 3e1dd0c..59acf46 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.py
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.py
@@ -34,15 +34,21 @@
return info
def validate(self):
- self.calculate_total()
+ self.calculate_total_and_program()
- def calculate_total(self):
+ def calculate_total_and_program(self):
no_of_students = 0
for d in self.student_groups:
# if not d.total_students:
d.total_students = get_total_students(d.student_group, self.academic_year,
self.academic_term, self.student_category)
no_of_students += cint(d.total_students)
+
+ # validate the program of fee structure and student groups
+ student_group_program = frappe.db.get_value("Student Group", d.student_group, "program")
+ if self.program and student_group_program and self.program != student_group_program:
+ frappe.msgprint(_("Program in the Fee Structure and Student Group {0} are different.")
+ .format(d.student_group))
self.grand_total = no_of_students*self.total_amount
self.grand_total_in_words = money_in_words(self.grand_total)
diff --git a/erpnext/education/doctype/fee_structure/fee_structure.json b/erpnext/education/doctype/fee_structure/fee_structure.json
index 428b1b1..98b8faa 100644
--- a/erpnext/education/doctype/fee_structure/fee_structure.json
+++ b/erpnext/education/doctype/fee_structure/fee_structure.json
@@ -50,37 +50,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "student_category",
- "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": "Student Category",
- "length": 0,
- "no_copy": 0,
- "options": "Student Category",
- "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": "program",
"fieldtype": "Link",
"hidden": 0,
@@ -114,6 +83,37 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "student_category",
+ "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": "Student Category",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Student Category",
+ "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": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -197,7 +197,7 @@
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -577,7 +577,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-11-10 18:56:59.698192",
+ "modified": "2017-12-04 12:51:06.864660",
"modified_by": "Administrator",
"module": "Education",
"name": "Fee Structure",
diff --git a/erpnext/education/doctype/fees/fees.json b/erpnext/education/doctype/fees/fees.json
index 85c2471..c4e1f82 100644
--- a/erpnext/education/doctype/fees/fees.json
+++ b/erpnext/education/doctype/fees/fees.json
@@ -1263,35 +1263,6 @@
"search_index": 0,
"set_only_once": 0,
"unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "data_42",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
}
],
"has_web_view": 0,
@@ -1305,7 +1276,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-11-10 18:57:12.021112",
+ "modified": "2017-12-06 05:55:10.502567",
"modified_by": "Administrator",
"module": "Education",
"name": "Fees",
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 65953ec..bf6894c 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -54,6 +54,7 @@
domains = {
+ 'Agriculture': 'erpnext.domains.agriculture',
'Distribution': 'erpnext.domains.distribution',
'Education': 'erpnext.domains.education',
'Healthcare': 'erpnext.domains.healthcare',
@@ -125,6 +126,8 @@
{"from_route": "/admissions", "to_route": "Student Admission"},
{"from_route": "/boms", "to_route": "BOM"},
{"from_route": "/timesheets", "to_route": "Timesheet"},
+ {"from_route": "/grant-application", "to_route": "Grant Application"},
+ {"from_route": "/chapters", "to_route": "Chapter"},
]
standard_portal_menu_items = [
@@ -144,7 +147,9 @@
{"title": _("Patient Appointment"), "route": "/patient-appointments", "reference_doctype": "Patient Appointment", "role":"Patient"},
{"title": _("Fees"), "route": "/fees", "reference_doctype": "Fees", "role":"Student"},
{"title": _("Newsletter"), "route": "/newsletters", "reference_doctype": "Newsletter"},
- {"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission"}
+ {"title": _("Admission"), "route": "/admissions", "reference_doctype": "Student Admission"},
+ {"title": _("Grant Application"), "route": "/grant-application", "reference_doctype": "Grant Application", "role": "Non Profit Portal User"},
+ {"title": _("Chapter"), "route": "/chapters", "reference_doctype": "Chapter"}
]
default_roles = [
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index 23e804e..42f0f0b 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -18,4 +18,6 @@
Regional
Healthcare
Restaurant
-ERPNext Integrations
\ No newline at end of file
+Agriculture
+ERPNext Integrations
+Non Profit
\ No newline at end of file
diff --git a/erpnext/non_profit/__init__.py b/erpnext/non_profit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/__init__.py
diff --git a/erpnext/non_profit/doctype/__init__.py b/erpnext/non_profit/doctype/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/__init__.py
diff --git a/erpnext/non_profit/doctype/chapter/__init__.py b/erpnext/non_profit/doctype/chapter/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/__init__.py
diff --git a/erpnext/non_profit/doctype/chapter/chapter.js b/erpnext/non_profit/doctype/chapter/chapter.js
new file mode 100644
index 0000000..c8b6d4a
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/chapter.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Chapter', {
+ refresh: function() {
+
+ }
+});
diff --git a/erpnext/non_profit/doctype/chapter/chapter.json b/erpnext/non_profit/doctype/chapter/chapter.json
new file mode 100644
index 0000000..b5f6ad5
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/chapter.json
@@ -0,0 +1,397 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 1,
+ "allow_import": 0,
+ "allow_rename": 1,
+ "autoname": "prompt",
+ "beta": 0,
+ "creation": "2017-09-14 13:36:03.904702",
+ "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": "chapter_head",
+ "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": "Chapter Head",
+ "length": 0,
+ "no_copy": 0,
+ "options": "User",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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_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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "region",
+ "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": "Region",
+ "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": "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": "introduction",
+ "fieldtype": "Text Editor",
+ "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": "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": 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": "meetup_embed_html",
+ "fieldtype": "Code",
+ "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": "Meetup Embed 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "address",
+ "fieldtype": "Text",
+ "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": "Address",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "chapters/chapter_name\nleave blank automatically set after saving chapter.",
+ "fieldname": "route",
+ "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": "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": 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": "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": "Published",
+ "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": 1,
+ "columns": 0,
+ "fieldname": "chapter_members",
+ "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": "Chapter Members",
+ "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": "members",
+ "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": "Members",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Chapter Member",
+ "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": 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-12-06 11:45:54.559482",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Chapter",
+ "name_case": "Title 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": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "route": "chapters",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/chapter/chapter.py b/erpnext/non_profit/doctype/chapter/chapter.py
new file mode 100644
index 0000000..d484882
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/chapter.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.website.website_generator import WebsiteGenerator
+
+class Chapter(WebsiteGenerator):
+ _website = frappe._dict(
+ condition_field = "published",
+ )
+
+ def get_context(self, context):
+ context.no_cache = True
+ context.show_sidebar = True
+ context.parents = [dict(label='View All Chapters',
+ route='chapters', title='View Chapters')]
+
+ def validate(self):
+ if not self.route: #pylint: disable=E0203
+ self.route = 'chapters/' + self.scrub(self.name)
+
+ def enable(self):
+ chapter = frappe.get_doc('Chapter', frappe.form_dict.name)
+ chapter.append('members', dict(enable=self.value))
+ chapter.save(ignore_permissions=1)
+ frappe.db.commit()
+
+
+def get_list_context(context):
+ context.allow_guest = True
+ context.no_cache = True
+ context.show_sidebar = True
+ context.title = 'All Chapters'
+ context.no_breadcrumbs = True
+ context.order_by = 'creation desc'
+ context.introduction = '<p>All Chapters</p>'
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/chapter/templates/chapter.html b/erpnext/non_profit/doctype/chapter/templates/chapter.html
new file mode 100644
index 0000000..8953481
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/templates/chapter.html
@@ -0,0 +1,66 @@
+{% extends "templates/web.html" %}
+
+{% block page_content %}
+<h1>{{ title }}</h1>
+<h3>Details</h3>
+<p>{{ introduction }}</p>
+{% if meetup_embed_html %}
+{{ meetup_embed_html }}
+{% endif %}
+<h3>List of Members</h3>
+{% if members %}
+ <table class="table table-bordered small" style="max-width: 500px;">
+ <tr>
+ <th width="15%" ></th>
+ <th>Member Details</th>
+ </tr>
+ {% for user in members %}
+ <tr>
+ <td>{{ loop.index }}</td>
+ <td>
+ <div class="row">
+ <div class="col-lg-6 col-md-6 col-sm-6">{{ frappe.db.get_value('User', user.user, 'full_name') }}</div>
+ <div class="col-lg-6 col-md-6 col-sm-6 text-right">
+ {% if user.website_url %}
+ <a href="{{ user.website_url }}">{{ user.website_url or '' }}</a>
+ {% endif %}
+ </div>
+ <div class="col-lg-12">
+ {% if user.introduction %}
+ {{ user.introduction }}
+ {% endif %}
+ </div>
+ </div>
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+{% else %}
+ <p>No member yet.</p>
+{% endif %}
+
+<h3>Chapter Head</h3>
+<table class="table table-bordered small" style="max-width: 500px;">
+ <tr>
+ <td style='width: 15%'>Name</td>
+ <td>{{ frappe.db.get_value('User', chapter_head, 'full_name') }}</td>
+ </tr>
+ <tr>
+ <td>Email</td>
+ <td>{{ frappe.db.get_value('User', chapter_head, 'email') or '' }}</td>
+ </tr>
+ <tr>
+ <td>Phone</td>
+ <td>{{ frappe.db.get_value('User', chapter_head, 'phone') or '' }}</td>
+ </tr>
+</table>
+<h3>Address</h3>
+<p>{{ address }}</p>
+
+<p style="margin: 20px 0 30px;"><a href="/non_profit/join-chapter?name={{ name }}" class='btn btn-primary'>Join this Chapter</a></p>
+<p style="margin: 20px 0 30px;"><a href="/non_profit/leave-chapter?name={{ name }}" class=''>Leave this Chapter</a></p>
+
+
+{% endblock %}
+
+<!-- this is a sample default web page template -->
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/chapter/templates/chapter_row.html b/erpnext/non_profit/doctype/chapter/templates/chapter_row.html
new file mode 100644
index 0000000..67fb0c5
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/templates/chapter_row.html
@@ -0,0 +1,60 @@
+{% if doc.published %}
+ <div style="margin-bottom: 30px; max-width: 600px" class="with-border clickable">
+ <a href="/{{ doc.route }}">
+ <h3>{{ doc.name }}</h3>
+ <p>
+ <span class="label">{{ frappe.db.get_value('User', chapter_head, 'full_name') }}</span>
+ <span class="label">
+ {% if members %}
+ Members: {{ members|length }}
+ {% else %}
+ Members: 0
+ {% endif %}
+ </span>
+ </p>
+ <p>{{ html2text(doc.introduction[:200]) }}{% if introduction|len > 200 %}...{% endif %}</p>
+ </a>
+ </div>
+{% endif %}
+<style type="text/css">
+
+.label {
+ font-weight: normal;
+ background-color: #d1d8dd;
+ font-size: 13px;
+ padding: 3px 7px;
+ margin-right: 10px;
+}
+
+
+.with-border {
+ border: 1px solid #d1d8dd;
+ border-radius: 3px;
+ padding: 15px;
+ margin-bottom: 30px;
+}
+
+.with-border h3 {
+ margin-top: 0px;
+}
+
+a {
+ color: #5E64FF;
+}
+
+.clickable a {
+ color: #161c23;
+}
+
+.with-border.clickable:hover {
+ border-color: #36414C;
+ background-color: #fafbfc;
+
+}
+
+.with-border a, .with-border a:hover {
+ text-decoration: none;
+}
+
+
+</style>
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/chapter/test_chapter.js b/erpnext/non_profit/doctype/chapter/test_chapter.js
new file mode 100644
index 0000000..e30d6a5
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/test_chapter.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Chapter", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Chapter
+ () => frappe.tests.make('Chapter', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/chapter/test_chapter.py b/erpnext/non_profit/doctype/chapter/test_chapter.py
new file mode 100644
index 0000000..d757a1f
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter/test_chapter.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestChapter(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/chapter_member/__init__.py b/erpnext/non_profit/doctype/chapter_member/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter_member/__init__.py
diff --git a/erpnext/non_profit/doctype/chapter_member/chapter_member.json b/erpnext/non_profit/doctype/chapter_member/chapter_member.json
new file mode 100644
index 0000000..ba78a67
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter_member/chapter_member.json
@@ -0,0 +1,163 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-09-14 13:38:04.296375",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "user",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "User",
+ "length": 0,
+ "no_copy": 0,
+ "options": "User",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "introduction",
+ "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": "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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "website_url",
+ "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": "Website URL",
+ "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": "enabled",
+ "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": "Enabled",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-06 11:33:34.300252",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Chapter Member",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/chapter_member/chapter_member.py b/erpnext/non_profit/doctype/chapter_member/chapter_member.py
new file mode 100644
index 0000000..c4b8999
--- /dev/null
+++ b/erpnext/non_profit/doctype/chapter_member/chapter_member.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class ChapterMember(Document):
+ pass
+
+
diff --git a/erpnext/non_profit/doctype/donor/__init__.py b/erpnext/non_profit/doctype/donor/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor/__init__.py
diff --git a/erpnext/non_profit/doctype/donor/donor.js b/erpnext/non_profit/doctype/donor/donor.js
new file mode 100644
index 0000000..090d5af
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor/donor.js
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Donor', {
+ refresh: function(frm) {
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Donor'};
+
+ frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
+
+ if(!frm.doc.__islocal) {
+ frappe.contacts.render_address_and_contact(frm);
+ } else {
+ frappe.contacts.clear_address_and_contact(frm);
+ }
+
+ }
+});
diff --git a/erpnext/non_profit/doctype/donor/donor.json b/erpnext/non_profit/doctype/donor/donor.json
new file mode 100644
index 0000000..c940bda
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor/donor.json
@@ -0,0 +1,335 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:email",
+ "beta": 0,
+ "creation": "2017-09-19 16:20:27.510196",
+ "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": "donor_name",
+ "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": "Donor 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": "column_break_5",
+ "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": "donor_type",
+ "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": "Donor Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Donor Type",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "email",
+ "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": "Email",
+ "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": "image",
+ "fieldtype": "Attach Image",
+ "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": "Image",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "address_contacts",
+ "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": "Address and Contact",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-map-marker",
+ "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": "address_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": "Address 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_9",
+ "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": "contact_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": "Contact 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": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_field": "image",
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-05 07:02:06.690416",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Donor",
+ "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": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/donor/donor.py b/erpnext/non_profit/doctype/donor/donor.py
new file mode 100644
index 0000000..9121d0c
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor/donor.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+from frappe.contacts.address_and_contact import load_address_and_contact
+
+class Donor(Document):
+ def onload(self):
+ """Load address and contacts in `__onload`"""
+ load_address_and_contact(self)
+
diff --git a/erpnext/non_profit/doctype/donor/donor_list.js b/erpnext/non_profit/doctype/donor/donor_list.js
new file mode 100644
index 0000000..31d4d29
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor/donor_list.js
@@ -0,0 +1,3 @@
+frappe.listview_settings['Donor'] = {
+ add_fields: ["donor_name", "donor_type", "image"],
+};
diff --git a/erpnext/non_profit/doctype/donor/test_donor.js b/erpnext/non_profit/doctype/donor/test_donor.js
new file mode 100644
index 0000000..e478b34
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor/test_donor.js
@@ -0,0 +1,27 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Donor", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(3);
+
+ frappe.run_serially([
+ // insert a new Member
+ () => frappe.tests.make('Donor', [
+ // values to be set
+ {donor_name: 'Test Donor'},
+ {donor_type: 'Test Organization'},
+ {email: 'test@example.com'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.donor_name, 'Test Donor');
+ assert.equal(cur_frm.doc.donor_type, 'Test Organization');
+ assert.equal(cur_frm.doc.email, 'test@example.com');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/donor/test_donor.py b/erpnext/non_profit/doctype/donor/test_donor.py
new file mode 100644
index 0000000..3b6724e
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor/test_donor.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestDonor(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/donor_type/__init__.py b/erpnext/non_profit/doctype/donor_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor_type/__init__.py
diff --git a/erpnext/non_profit/doctype/donor_type/donor_type.js b/erpnext/non_profit/doctype/donor_type/donor_type.js
new file mode 100644
index 0000000..7b1fd4f
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor_type/donor_type.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Donor Type', {
+ refresh: function() {
+
+ }
+});
diff --git a/erpnext/non_profit/doctype/donor_type/donor_type.json b/erpnext/non_profit/doctype/donor_type/donor_type.json
new file mode 100644
index 0000000..07118fd
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor_type/donor_type.json
@@ -0,0 +1,94 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:donor_type",
+ "beta": 0,
+ "creation": "2017-09-19 16:19:16.639635",
+ "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": "donor_type",
+ "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": 1,
+ "label": "Donor Type",
+ "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-12-05 07:04:36.757595",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Donor Type",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/donor_type/donor_type.py b/erpnext/non_profit/doctype/donor_type/donor_type.py
new file mode 100644
index 0000000..e9262ac
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor_type/donor_type.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class DonorType(Document):
+ pass
diff --git a/erpnext/non_profit/doctype/donor_type/test_donor_type.js b/erpnext/non_profit/doctype/donor_type/test_donor_type.js
new file mode 100644
index 0000000..22dc18e
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor_type/test_donor_type.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Donor Type", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Member
+ () => frappe.tests.make('Donor Type', [
+ // values to be set
+ {donor_type: 'Test Organization'},
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.donor_type, 'Test Organization');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/donor_type/test_donor_type.py b/erpnext/non_profit/doctype/donor_type/test_donor_type.py
new file mode 100644
index 0000000..e793913
--- /dev/null
+++ b/erpnext/non_profit/doctype/donor_type/test_donor_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+
+import unittest
+
+class TestDonorType(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/grant_application/__init__.py b/erpnext/non_profit/doctype/grant_application/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/__init__.py
diff --git a/erpnext/non_profit/doctype/grant_application/grant_application.js b/erpnext/non_profit/doctype/grant_application/grant_application.js
new file mode 100644
index 0000000..70f319b
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/grant_application.js
@@ -0,0 +1,27 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Grant Application', {
+ refresh: function(frm) {
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Grant Application'};
+
+ frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
+
+ if(!frm.doc.__islocal) {
+ frappe.contacts.render_address_and_contact(frm);
+ } else {
+ frappe.contacts.clear_address_and_contact(frm);
+ }
+
+ if(frm.doc.status == 'Received' && !frm.doc.email_notification_sent){
+ frm.add_custom_button(__("Send Grant Review Email"), function() {
+ frappe.call({
+ method: "erpnext.non_profit.doctype.grant_application.grant_application.send_grant_review_emails",
+ args: {
+ grant_application: frm.doc.name
+ }
+ });
+ });
+ }
+ }
+});
diff --git a/erpnext/non_profit/doctype/grant_application/grant_application.json b/erpnext/non_profit/doctype/grant_application/grant_application.json
new file mode 100644
index 0000000..2eb2087
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/grant_application.json
@@ -0,0 +1,851 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 1,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "",
+ "beta": 0,
+ "creation": "2017-09-21 12:02:01.206913",
+ "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": "applicant_type",
+ "fieldtype": "Select",
+ "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": "Applicant Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Individual\nOrganization",
+ "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": "applicant_name",
+ "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": "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,
+ "depends_on": "eval:doc.applicant_type=='Organization'",
+ "fieldname": "contact_person",
+ "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": "Contact Person",
+ "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": "email",
+ "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": "Email",
+ "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": "column_break_5",
+ "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,
+ "default": "Open",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "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": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Open\nReceived\nIn Progress\nApproved\nRejected\nExpired\nWithdrawn",
+ "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": "website_url",
+ "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": "Website URL",
+ "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": "company",
+ "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": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 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": "address_contacts",
+ "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": "Address and Contact",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-map-marker",
+ "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": "address_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": "Address 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_9",
+ "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": "contact_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": "Contact 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "grant_application_details",
+ "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": "Grant Application Details ",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "grant_description",
+ "fieldtype": "Long Text",
+ "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": "Grant Description",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "section_break_15",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "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": "amount",
+ "fieldtype": "Currency",
+ "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": "Requested Amount",
+ "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": "has_any_past_grant_record",
+ "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": "Has any past Grant Record",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": "column_break_17",
+ "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": "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": 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": "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": "Show 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "assessment_result",
+ "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": "Assessment Result",
+ "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": "assessment_mark",
+ "fieldtype": "Float",
+ "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 Mark (Out of 10)",
+ "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": "note",
+ "fieldtype": "Small Text",
+ "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": "Note",
+ "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": "column_break_24",
+ "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": "assessment_manager",
+ "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 Manager",
+ "length": 0,
+ "no_copy": 0,
+ "options": "User",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "email_notification_sent",
+ "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": "Email Notification Sent",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 1,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_field": "",
+ "image_view": 0,
+ "in_create": 0,
+ "is_published_field": "published",
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-06 12:39:57.677899",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Grant Application",
+ "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": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "route": "grant-application",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "applicant_name",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/grant_application/grant_application.py b/erpnext/non_profit/doctype/grant_application/grant_application.py
new file mode 100644
index 0000000..f0123b2
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/grant_application.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.website.website_generator import WebsiteGenerator
+from frappe.contacts.address_and_contact import load_address_and_contact
+from frappe.utils import get_url
+
+class GrantApplication(WebsiteGenerator):
+ _website = frappe._dict(
+ condition_field = "published",
+ )
+
+ def validate(self):
+ if not self.route: #pylint: disable=E0203
+ self.route = 'grant-application/' + self.scrub(self.name)
+
+ def onload(self):
+ """Load address and contacts in `__onload`"""
+ load_address_and_contact(self)
+
+ def get_context(self, context):
+ context.no_cache = True
+ context.show_sidebar = True
+ context.parents = [dict(label='View All Grant Applications',
+ route='grant-application', title='View Grants')]
+
+def get_list_context(context):
+ context.allow_guest = True
+ context.no_cache = True
+ context.no_breadcrumbs = True
+ context.show_sidebar = True
+ context.order_by = 'creation desc'
+ context.introduction ='''<a class="btn btn-primary" href="/my-grant?new=1">
+ Apply for new Grant Application</a>'''
+
+@frappe.whitelist()
+def send_grant_review_emails(grant_application):
+ grant = frappe.get_doc("Grant Application", grant_application)
+ url = get_url('grant-application/{0}'.format(grant_application))
+ frappe.sendmail(
+ recipients= grant.assessment_manager,
+ sender=frappe.session.user,
+ subject='Grant Application for {0}'.format(grant.applicant_name),
+ message='<p> Please Review this grant application</p><br>' + url,
+ reference_doctype=grant.doctype,
+ reference_name=grant.name
+ )
+
+ grant.status = 'In Progress'
+ grant.email_notification_sent = 1
+ grant.save()
+ frappe.db.commit()
+
+ frappe.msgprint(_("Review Invitation Sent"))
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/grant_application/templates/grant_application.html b/erpnext/non_profit/doctype/grant_application/templates/grant_application.html
new file mode 100644
index 0000000..8fecdad
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/templates/grant_application.html
@@ -0,0 +1,62 @@
+{% extends "templates/web.html" %}
+
+{% block page_content %}
+ <h1>{{ applicant_name }}</h1>
+ {% if frappe.user == owner %}
+ <p><a class='btn btn-primary btn-sm' href="/my-grant?name={{ name }}">Edit Grant</a></p>
+ {% endif %}
+ <br>
+ <table class='table table-bordered small' style='max-width: 400px; margin-bottom: 0px;'>
+ <tr>
+ <td style='width: 38.2%'>Organization/Indvidual</td>
+ <td>{{ applicant_type }}</td>
+ </tr>
+ <tr>
+ <td>Grant Applicant Name</td>
+ <td>{{ applicant_name}}</td>
+ </tr>
+ <tr>
+ <td>Date</td>
+ <td>{{ frappe.format_date(creation) }}</td>
+ </tr>
+ <tr>
+ <td>Status</td>
+ <td>{{ status }}</td>
+ </tr>
+ <tr>
+ <td>Email</td>
+ <td>{{ email }}</td>
+ </tr>
+ </table>
+ <h2>Q. Please outline your current situation and why you are applying for a grant?</h2>
+ <p> {{ grant_description }}</p>
+ <h2>Q. Requested grant amount</h2>
+ <p>{{ amount }}</p>
+ <h2>Q. Have you recevied grant from us before?</h2>
+ <p>{{ has_any_past_grant_record }}</p>
+ <h3>Contact</h3>
+ {% if frappe.user != 'Guest' %}
+ <table class='table table-bordered small' style='max-width: 400px; margin-bottom: 0px;'>
+ {% if contact_person %}
+ <tr>
+ <td style='width: 38.2%'>Contact Person</td>
+ <td>{{ contact_person }}</td>
+ </tr>
+ {% endif %}
+ <tr>
+ <td style='width: 38.2%'>Email</td>
+ <td>{{ email }}</td>
+ </tr>
+ </table>
+ {% else %}
+ <p><a href="/login">You must register and login to view contact details</a></p>
+ {% endif %}
+ <br>
+ {% if frappe.session.user == assessment_manager %}
+ {% if assessment_scale %}
+ <p> Assessment Review done </p>
+ {% endif %}
+ {% else %}
+ <p><br><a href="/my-grant?new=1" class='btn btn-primary'>Post a New Grant</a></p>
+ {% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/grant_application/templates/grant_application_row.html b/erpnext/non_profit/doctype/grant_application/templates/grant_application_row.html
new file mode 100644
index 0000000..c374959
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/templates/grant_application_row.html
@@ -0,0 +1,51 @@
+{% if doc.published %}
+ <div style='margin-bottom: 30px; max-width: 600px;'
+ class='with-border clickable'>
+ <a href="/{{ doc.route }}">
+ <h3 style='margin-top: 0px;'>{{ doc.name }}</h3>
+ <p>
+ <span class='label'>{{ frappe.format_date(doc.creation) }}</span>
+ </p>
+ </a>
+ </div>
+{% endif %}
+
+<style type="text/css">
+.label {
+ font-weight: normal;
+ background-color: #d1d8dd;
+ font-size: 13px;
+ padding: 3px 7px;
+ margin-right: 10px;
+}
+
+
+.with-border {
+ border: 1px solid #d1d8dd;
+ border-radius: 3px;
+ padding: 15px;
+ margin-bottom: 30px;
+}
+
+.with-border h3 {
+ margin-top: 0px;
+}
+
+a {
+ color: #5E64FF;
+}
+
+.clickable a {
+ color: #161c23;
+}
+
+.with-border.clickable:hover {
+ border-color: #36414C;
+ background-color: #fafbfc;
+
+}
+
+.with-border a, .with-border a:hover {
+ text-decoration: none;
+}
+</style>
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/grant_application/test_grant_application.js b/erpnext/non_profit/doctype/grant_application/test_grant_application.js
new file mode 100644
index 0000000..47230a5
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/test_grant_application.js
@@ -0,0 +1,30 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Grant Application", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(4);
+
+ frappe.run_serially([
+ // insert a new Member
+ () => frappe.tests.make('Grant Application', [
+ // values to be set
+ {applicant_name: 'Test Organization'},
+ {contact_person:'Test Applicant'},
+ {email: 'test@example.com'},
+ {grant_description:'Test message'},
+ {amount: 150000}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.applicant_name, 'Test Organization');
+ assert.equal(cur_frm.doc.contact_person, 'Test Applicant');
+ assert.equal(cur_frm.doc.email, 'test@example.com');
+ assert.equal(cur_frm.doc.amount, 150000);
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/grant_application/test_grant_application.py b/erpnext/non_profit/doctype/grant_application/test_grant_application.py
new file mode 100644
index 0000000..da16acf
--- /dev/null
+++ b/erpnext/non_profit/doctype/grant_application/test_grant_application.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestGrantApplication(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/member/__init__.py b/erpnext/non_profit/doctype/member/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/__init__.py
diff --git a/erpnext/non_profit/doctype/member/member.js b/erpnext/non_profit/doctype/member/member.js
new file mode 100644
index 0000000..c0468a7
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/member.js
@@ -0,0 +1,45 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Member', {
+ refresh: function(frm) {
+
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Member'};
+
+ frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
+
+ if(!frm.doc.__islocal) {
+ frappe.contacts.render_address_and_contact(frm);
+
+ // custom buttons
+ frm.add_custom_button(__('Accounting Ledger'), function() {
+ frappe.set_route('query-report', 'General Ledger',
+ {party_type:'Member', party:frm.doc.name});
+ });
+
+ frm.add_custom_button(__('Accounts Receivable'), function() {
+ frappe.set_route('query-report', 'Accounts Receivable', {member:frm.doc.name});
+ });
+
+ // indicator
+ erpnext.utils.set_party_dashboard_indicators(frm);
+
+ } else {
+ frappe.contacts.clear_address_and_contact(frm);
+ }
+
+ frappe.call({
+ method:"frappe.client.get_value",
+ args:{
+ 'doctype':"Membership",
+ 'filters':{'member': frm.doc.name},
+ 'fieldname':[
+ 'to_date'
+ ]
+ },
+ callback: function (data) {
+ frappe.model.set_value(frm.doctype,frm.docname, "membership_expiry_date", data.message.to_date);
+ }
+ });
+ }
+});
diff --git a/erpnext/non_profit/doctype/member/member.json b/erpnext/non_profit/doctype/member/member.json
new file mode 100644
index 0000000..1c6b9fc
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/member.json
@@ -0,0 +1,385 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:email",
+ "beta": 0,
+ "creation": "2017-09-11 09:24:52.898356",
+ "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": "member_name",
+ "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": "Member 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": "membership_expiry_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": "Membership Expiry 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": "column_break_5",
+ "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": "membership_type",
+ "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": "Membership Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Membership Type",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "email",
+ "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": "Email",
+ "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": "image",
+ "fieldtype": "Attach Image",
+ "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": "Image",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "address_contacts",
+ "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": "Address and Contact",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-map-marker",
+ "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": "address_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": "Address 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_9",
+ "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": "contact_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": "Contact 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": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_field": "image",
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-05 07:03:21.606732",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Member",
+ "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": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Member",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py
new file mode 100644
index 0000000..cc617b5
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/member.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+from frappe.contacts.address_and_contact import load_address_and_contact
+
+STANDARD_USERS = ("Guest", "Administrator")
+
+class Member(Document):
+ def onload(self):
+ """Load address and contacts in `__onload`"""
+ load_address_and_contact(self)
+
+
+ def validate(self):
+ if self.name not in STANDARD_USERS:
+ self.validate_email_type(self.email)
+ self.validate_email_type(self.name)
+
+
+ def validate_email_type(self, email):
+ from frappe.utils import validate_email_add
+ validate_email_add(email.strip(), True)
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member_dashboard.py b/erpnext/non_profit/doctype/member/member_dashboard.py
new file mode 100644
index 0000000..658647c
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/member_dashboard.py
@@ -0,0 +1,14 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'heatmap': True,
+ 'heatmap_message': _('Memeber Activity'),
+ 'fieldname': 'member',
+ 'transactions': [
+ {
+ 'label': _('Membership Details'),
+ 'items': ['Membership']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member_list.js b/erpnext/non_profit/doctype/member/member_list.js
new file mode 100644
index 0000000..8e41e7f
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/member_list.js
@@ -0,0 +1,3 @@
+frappe.listview_settings['Member'] = {
+ add_fields: ["member_name", "membership_type", "image"],
+};
diff --git a/erpnext/non_profit/doctype/member/test_member.js b/erpnext/non_profit/doctype/member/test_member.js
new file mode 100644
index 0000000..f7cca97
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/test_member.js
@@ -0,0 +1,26 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Member", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(2);
+
+ frappe.run_serially([
+ // insert a new Member
+ () => frappe.tests.make('Member', [
+ // values to be set
+ {member_name: 'Test Member'},
+ {membership_type: 'Gold'},
+ {email: 'test@example.com'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.membership_type, 'Gold');
+ assert.equal(cur_frm.doc.email, 'test@example.com');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/member/test_member.py b/erpnext/non_profit/doctype/member/test_member.py
new file mode 100644
index 0000000..748a500
--- /dev/null
+++ b/erpnext/non_profit/doctype/member/test_member.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestMember(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/membership/__init__.py b/erpnext/non_profit/doctype/membership/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership/__init__.py
diff --git a/erpnext/non_profit/doctype/membership/membership.js b/erpnext/non_profit/doctype/membership/membership.js
new file mode 100644
index 0000000..4210879
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership/membership.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Membership', {
+ onload:function(frm) {
+ frm.add_fetch('membership_type', 'amount', 'amount');
+ }
+});
diff --git a/erpnext/non_profit/doctype/membership/membership.json b/erpnext/non_profit/doctype/membership/membership.json
new file mode 100644
index 0000000..42e084d
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership/membership.json
@@ -0,0 +1,476 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "M-.YY.-.####",
+ "beta": 0,
+ "creation": "2017-09-11 11:39:18.492184",
+ "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": "member",
+ "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": "Member",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Member",
+ "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": "membership_type",
+ "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": "Membership Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Membership Type",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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_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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "membership_status",
+ "fieldtype": "Select",
+ "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": "Membership Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "New\nCurrent\nExpired\nPending\nCancelled",
+ "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": "membership_validaty_section",
+ "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": "membership validaty section",
+ "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": "from_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": "From",
+ "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": "to_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": "To",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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_8",
+ "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": "member_since_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": "Member Since",
+ "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": "payment_details",
+ "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": "Payment Details",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "paid",
+ "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": "Paid",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "currency",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "USD\nINR",
+ "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": "amount",
+ "fieldtype": "Float",
+ "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": "Amount",
+ "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-12-05 07:02:56.859408",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership",
+ "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": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Member",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
new file mode 100644
index 0000000..a6be164
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from frappe.utils import add_days, add_years, nowdate, getdate
+from frappe import _
+import erpnext
+
+
+class Membership(Document):
+ def validate(self):
+
+ # get last membership (if active)
+ last_membership = erpnext.get_last_membership()
+
+ # if person applied for offline membership
+ if last_membership and not frappe.session.user == "Administrator":
+ # if last membership does not expire in 30 days, then do not allow to renew
+ if getdate(add_days(last_membership.to_date, -30)) > getdate(nowdate()) :
+ frappe.throw(_('You can only renew if your membership expires within 30 days'))
+
+ self.from_date = add_days(last_membership.to_date, 1)
+ elif frappe.session.user == "Administrator":
+ self.from_date = self.from_date
+ else:
+ self.from_date = nowdate()
+
+ self.to_date = add_years(self.from_date, 1)
+
+ def on_payment_authorized(self, status_changed_to=None):
+ if status_changed_to in ("Completed", "Authorized"):
+ self.load_from_db()
+ self.db_set('paid', 1)
+
+
diff --git a/erpnext/non_profit/doctype/membership/test_membership.js b/erpnext/non_profit/doctype/membership/test_membership.js
new file mode 100644
index 0000000..24c85c6
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership/test_membership.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Membership", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Membership
+ () => frappe.tests.make('Membership', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/membership/test_membership.py b/erpnext/non_profit/doctype/membership/test_membership.py
new file mode 100644
index 0000000..b23f406
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership/test_membership.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestMembership(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/membership_type/__init__.py b/erpnext/non_profit/doctype/membership_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_type/__init__.py
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.js b/erpnext/non_profit/doctype/membership_type/membership_type.js
new file mode 100644
index 0000000..3ef39ae
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Membership Type', {
+ refresh: function() {
+
+ }
+});
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.json b/erpnext/non_profit/doctype/membership_type/membership_type.json
new file mode 100644
index 0000000..35a7902
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.json
@@ -0,0 +1,124 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:membership_type",
+ "beta": 0,
+ "creation": "2017-09-18 12:56:56.343999",
+ "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": "membership_type",
+ "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": 1,
+ "label": "Membership Type",
+ "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": "amount",
+ "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": "Amount",
+ "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-12-05 07:03:45.860757",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership Type",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.py b/erpnext/non_profit/doctype/membership_type/membership_type.py
new file mode 100644
index 0000000..ed6b549
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class MembershipType(Document):
+ pass
diff --git a/erpnext/non_profit/doctype/membership_type/test_membership_type.js b/erpnext/non_profit/doctype/membership_type/test_membership_type.js
new file mode 100644
index 0000000..6440df8
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_type/test_membership_type.js
@@ -0,0 +1,25 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Membership Type", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(2);
+
+ frappe.run_serially([
+ // insert a new Member
+ () => frappe.tests.make('Membership Type', [
+ // values to be set
+ {membership_type: 'Gold'},
+ {amount:50000}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.membership_type, 'Gold');
+ assert.equal(cur_frm.doc.amount, '50000');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/membership_type/test_membership_type.py b/erpnext/non_profit/doctype/membership_type/test_membership_type.py
new file mode 100644
index 0000000..d2c9bee
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_type/test_membership_type.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestMembershipType(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/volunteer/__init__.py b/erpnext/non_profit/doctype/volunteer/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer/__init__.py
diff --git a/erpnext/non_profit/doctype/volunteer/test_volunteer.js b/erpnext/non_profit/doctype/volunteer/test_volunteer.js
new file mode 100644
index 0000000..45eb281
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer/test_volunteer.js
@@ -0,0 +1,34 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Volunteer", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(4);
+
+ frappe.run_serially([
+ // insert a new Member
+ () => frappe.tests.make('Volunteer', [
+ // values to be set
+ {volunteer_name: 'Test Volunteer'},
+ {volunteer_type:'Test Work'},
+ {email:'test@example.com'},
+ {'availability': 'Weekends'},
+ {volunteer_skills:[
+ [
+ {'volunteer_skills': 'Fundraiser'},
+ ]
+ ]},
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.volunteer_name, 'Test Volunteer');
+ assert.equal(cur_frm.doc.volunteer_type, 'Test Work');
+ assert.equal(cur_frm.doc.email, 'test@example.com');
+ assert.equal(cur_frm.doc.availability, 'Weekends');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/volunteer/test_volunteer.py b/erpnext/non_profit/doctype/volunteer/test_volunteer.py
new file mode 100644
index 0000000..6f3bee0
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer/test_volunteer.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestVolunteer(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/volunteer/volunteer.js b/erpnext/non_profit/doctype/volunteer/volunteer.js
new file mode 100644
index 0000000..ac93d8c
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer/volunteer.js
@@ -0,0 +1,17 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Volunteer', {
+ refresh: function(frm) {
+
+ frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Volunteer'};
+
+ frm.toggle_display(['address_html','contact_html'], !frm.doc.__islocal);
+
+ if(!frm.doc.__islocal) {
+ frappe.contacts.render_address_and_contact(frm);
+ } else {
+ frappe.contacts.clear_address_and_contact(frm);
+ }
+ }
+});
diff --git a/erpnext/non_profit/doctype/volunteer/volunteer.json b/erpnext/non_profit/doctype/volunteer/volunteer.json
new file mode 100644
index 0000000..703230c
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer/volunteer.json
@@ -0,0 +1,545 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "field:email",
+ "beta": 0,
+ "creation": "2017-09-19 16:16:45.676019",
+ "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": "volunteer_name",
+ "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": "Volunteer 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": "column_break_5",
+ "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": "volunteer_type",
+ "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": "Volunteer Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Volunteer Type",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "email",
+ "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": "Email",
+ "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": "image",
+ "fieldtype": "Attach Image",
+ "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": "Image",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "address_contacts",
+ "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": "Address and Contact",
+ "length": 0,
+ "no_copy": 0,
+ "options": "fa fa-map-marker",
+ "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": "address_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": "Address 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_9",
+ "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": "contact_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": "Contact 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "volunteer_availability_and_skills_details",
+ "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": "Availability and Skills",
+ "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": "availability",
+ "fieldtype": "Select",
+ "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": "Availability",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nWeekly\nWeekdays\nWeekends",
+ "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": "availability_timeslot",
+ "fieldtype": "Select",
+ "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": "Availability Timeslot",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nMorning\nAfternoon\nEvening\nAnytime",
+ "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": "column_break_12",
+ "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": "volunteer_skills",
+ "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": "Volunteer Skills",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Volunteer Skill",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_15",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "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": "note",
+ "fieldtype": "Long Text",
+ "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": "Note",
+ "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_field": "image",
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2017-12-06 12:03:08.624579",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Volunteer",
+ "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": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/volunteer/volunteer.py b/erpnext/non_profit/doctype/volunteer/volunteer.py
new file mode 100644
index 0000000..699868a
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer/volunteer.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+from frappe.contacts.address_and_contact import load_address_and_contact
+
+class Volunteer(Document):
+ def onload(self):
+ """Load address and contacts in `__onload`"""
+ load_address_and_contact(self)
diff --git a/erpnext/non_profit/doctype/volunteer_skill/__init__.py b/erpnext/non_profit/doctype/volunteer_skill/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_skill/__init__.py
diff --git a/erpnext/non_profit/doctype/volunteer_skill/volunteer_skill.json b/erpnext/non_profit/doctype/volunteer_skill/volunteer_skill.json
new file mode 100644
index 0000000..7d210aa
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_skill/volunteer_skill.json
@@ -0,0 +1,73 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2017-09-20 15:26:26.453435",
+ "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": "volunteer_skill",
+ "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": "Volunteer Skill",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": 1,
+ "max_attachments": 0,
+ "modified": "2017-12-06 11:54:14.396354",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Volunteer Skill",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/volunteer_skill/volunteer_skill.py b/erpnext/non_profit/doctype/volunteer_skill/volunteer_skill.py
new file mode 100644
index 0000000..dc9f823
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_skill/volunteer_skill.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class VolunteerSkill(Document):
+ pass
diff --git a/erpnext/non_profit/doctype/volunteer_type/__init__.py b/erpnext/non_profit/doctype/volunteer_type/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_type/__init__.py
diff --git a/erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.js b/erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.js
new file mode 100644
index 0000000..6c29fb5
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.js
@@ -0,0 +1,25 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Volunteer Type", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(2);
+
+ frappe.run_serially([
+ // insert a new Member
+ () => frappe.tests.make('Volunteer Type', [
+ // values to be set
+ {volunteer_type: 'Test Work'},
+ {amount: 500}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.volunteer_type, 'Test Work');
+ assert.equal(cur_frm.doc.amount, 500);
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.py b/erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.py
new file mode 100644
index 0000000..78f65c7
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import unittest
+
+class TestVolunteerType(unittest.TestCase):
+ pass
diff --git a/erpnext/non_profit/doctype/volunteer_type/volunteer_type.js b/erpnext/non_profit/doctype/volunteer_type/volunteer_type.js
new file mode 100644
index 0000000..5c17505
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_type/volunteer_type.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Volunteer Type', {
+ refresh: function() {
+
+ }
+});
diff --git a/erpnext/non_profit/doctype/volunteer_type/volunteer_type.json b/erpnext/non_profit/doctype/volunteer_type/volunteer_type.json
new file mode 100644
index 0000000..256b25f
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_type/volunteer_type.json
@@ -0,0 +1,94 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "prompt",
+ "beta": 0,
+ "creation": "2017-09-19 16:13:07.763273",
+ "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": "amount",
+ "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": "Amount",
+ "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-12-06 11:52:08.800425",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Volunteer Type",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Non Profit Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Non Profit",
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/volunteer_type/volunteer_type.py b/erpnext/non_profit/doctype/volunteer_type/volunteer_type.py
new file mode 100644
index 0000000..9776402
--- /dev/null
+++ b/erpnext/non_profit/doctype/volunteer_type/volunteer_type.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class VolunteerType(Document):
+ pass
diff --git a/erpnext/non_profit/web_form/__init__.py b/erpnext/non_profit/web_form/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/web_form/__init__.py
diff --git a/erpnext/non_profit/web_form/grant_application/__init__.py b/erpnext/non_profit/web_form/grant_application/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/non_profit/web_form/grant_application/__init__.py
diff --git a/erpnext/non_profit/web_form/grant_application/grant_application.js b/erpnext/non_profit/web_form/grant_application/grant_application.js
new file mode 100644
index 0000000..7da3f1f
--- /dev/null
+++ b/erpnext/non_profit/web_form/grant_application/grant_application.js
@@ -0,0 +1,3 @@
+frappe.ready(function() {
+ // bind events here
+});
\ No newline at end of file
diff --git a/erpnext/non_profit/web_form/grant_application/grant_application.json b/erpnext/non_profit/web_form/grant_application/grant_application.json
new file mode 100644
index 0000000..73c9445
--- /dev/null
+++ b/erpnext/non_profit/web_form/grant_application/grant_application.json
@@ -0,0 +1,108 @@
+{
+ "accept_payment": 0,
+ "allow_comments": 0,
+ "allow_delete": 1,
+ "allow_edit": 1,
+ "allow_incomplete": 0,
+ "allow_multiple": 1,
+ "allow_print": 0,
+ "amount": 0.0,
+ "amount_based_on_field": 0,
+ "creation": "2017-10-30 15:57:10.825188",
+ "currency": "INR",
+ "doc_type": "Grant Application",
+ "docstatus": 0,
+ "doctype": "Web Form",
+ "idx": 0,
+ "introduction_text": "Share as many details as you can to get quick response from organization",
+ "is_standard": 1,
+ "login_required": 1,
+ "max_attachment_size": 0,
+ "modified": "2017-12-06 12:32:16.893289",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "grant-application",
+ "owner": "Administrator",
+ "payment_button_label": "Buy Now",
+ "published": 1,
+ "route": "my-grant",
+ "show_sidebar": 1,
+ "sidebar_items": [],
+ "success_url": "/grant-application",
+ "title": "Grant Application",
+ "web_form_fields": [
+ {
+ "fieldname": "applicant_type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "label": "Applicant Type",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "Individual\nOrganization",
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "applicant_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Name",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "email",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Email Address",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "description": "",
+ "fieldname": "grant_description",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "label": "Please outline your current situation and why you are applying for a grant?",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 1
+ },
+ {
+ "fieldname": "amount",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "label": "Requested Amount",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "has_any_past_grant_record",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Have you received any grant from us before?",
+ "max_length": 0,
+ "max_value": 0,
+ "options": "",
+ "read_only": 0,
+ "reqd": 0
+ },
+ {
+ "fieldname": "published",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Show on Website",
+ "max_length": 0,
+ "max_value": 0,
+ "read_only": 0,
+ "reqd": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/web_form/grant_application/grant_application.py b/erpnext/non_profit/web_form/grant_application/grant_application.py
new file mode 100644
index 0000000..7666ef6
--- /dev/null
+++ b/erpnext/non_profit/web_form/grant_application/grant_application.py
@@ -0,0 +1,8 @@
+from __future__ import unicode_literals
+
+def get_context(context):
+ context.no_cache = True
+ context.parents = [dict(label='View All ',
+ route='grant-application', title='View All')]
+
+
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 1755ec0..f6988ab 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -449,7 +449,8 @@
erpnext.patches.v8_9.delete_gst_doctypes_for_outside_india_accounts
erpnext.patches.v8_9.set_default_fields_in_variant_settings
erpnext.patches.v8_9.update_billing_gstin_for_indian_account
-erpnext.patches.v9_0.add_user_to_child_table_in_pos_profile #2017-11-28
+erpnext.patches.v8_9.set_member_party_type
+erpnext.patches.v9_0.add_user_to_child_table_in_pos_profile
erpnext.patches.v9_0.set_schedule_date_for_material_request_and_purchase_order
erpnext.patches.v9_0.student_admission_childtable_migrate
erpnext.patches.v9_0.fix_subscription_next_date #2017-10-23
@@ -476,3 +477,5 @@
erpnext.patches.v10_0.update_lft_rgt_for_employee
erpnext.patches.v9_2.rename_net_weight_in_item_master
erpnext.patches.v9_2.delete_process_payroll
+erpnext.patches.v10_0.add_agriculture_domain
+erpnext.patches.v10_0.add_non_profit_domain
diff --git a/erpnext/patches/v10_0/add_agriculture_domain.py b/erpnext/patches/v10_0/add_agriculture_domain.py
new file mode 100644
index 0000000..c18e69f
--- /dev/null
+++ b/erpnext/patches/v10_0/add_agriculture_domain.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ domain = 'Agriculture'
+ if not frappe.db.exists('Domain', domain):
+ frappe.get_doc({
+ 'doctype': 'Domain',
+ 'domain': domain
+ }).insert(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/patches/v10_0/add_non_profit_domain.py b/erpnext/patches/v10_0/add_non_profit_domain.py
new file mode 100644
index 0000000..b03d669
--- /dev/null
+++ b/erpnext/patches/v10_0/add_non_profit_domain.py
@@ -0,0 +1,20 @@
+# Copyright (c) 2017, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ domain = 'Non Profit'
+ if not frappe.db.exists('Domain', domain):
+ frappe.get_doc({
+ 'doctype': 'Domain',
+ 'domain': domain
+ }).insert(ignore_permissions=True)
+
+ frappe.get_doc({
+ 'doctype': 'Role',
+ 'role_name': 'Non Profit Portal User',
+ 'desk_access': 0,
+ 'restrict_to_domain': domain
+ }).insert(ignore_permissions=True)
\ No newline at end of file
diff --git a/erpnext/patches/v7_2/make_all_assessment_group.py b/erpnext/patches/v7_2/make_all_assessment_group.py
index 769e503..f3ec628 100644
--- a/erpnext/patches/v7_2/make_all_assessment_group.py
+++ b/erpnext/patches/v7_2/make_all_assessment_group.py
@@ -6,6 +6,7 @@
def execute():
if not frappe.db.exists({"doctype": "Assessment Group","assessment_group_name": "All Assessment Groups"}):
+ frappe.reload_doc("education", "doctype", "assessment_group")
doc = frappe.new_doc("Assessment Group")
doc.assessment_group_name = "All Assessment Groups"
doc.is_group = 1
diff --git a/erpnext/patches/v8_9/set_member_party_type.py b/erpnext/patches/v8_9/set_member_party_type.py
new file mode 100644
index 0000000..2934c70
--- /dev/null
+++ b/erpnext/patches/v8_9/set_member_party_type.py
@@ -0,0 +1,8 @@
+import frappe
+
+def execute():
+ if not frappe.db.exists("Party Type", "Member"):
+ frappe.reload_doc("non_profit", "doctype", "member")
+ party = frappe.new_doc("Party Type")
+ party.party_type = "Member"
+ party.save()
diff --git a/erpnext/patches/v9_0/add_healthcare_domain.py b/erpnext/patches/v9_0/add_healthcare_domain.py
index 45fceb1..3c0433b 100644
--- a/erpnext/patches/v9_0/add_healthcare_domain.py
+++ b/erpnext/patches/v9_0/add_healthcare_domain.py
@@ -3,10 +3,9 @@
from __future__ import unicode_literals
import frappe
-from frappe import _
def execute():
- domain = _('Healthcare')
+ domain = 'Healthcare'
if not frappe.db.exists('Domain', domain):
frappe.get_doc({
'doctype': 'Domain',
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 0bcbf71..a7114a9 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -31,6 +31,9 @@
"public/js/templates/item_selector.html",
"public/js/utils/item_selector.js",
"public/js/help_links.js",
+ "public/js/schools/student_button.html",
+ "public/js/schools/assessment_result_tool.html",
+ "public/js/agriculture/ternary_plot.js",
"public/js/templates/item_quick_entry.html",
"public/js/utils/item_quick_entry.js",
"public/js/education/student_button.html",
diff --git a/erpnext/public/css/leaflet/leaflet.css b/erpnext/public/css/leaflet/leaflet.css
new file mode 100755
index 0000000..979a8bd
--- /dev/null
+++ b/erpnext/public/css/leaflet/leaflet.css
@@ -0,0 +1,611 @@
+/* required styles */
+
+.leaflet-pane,
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-tile-container,
+.leaflet-map-pane svg,
+.leaflet-map-pane canvas,
+.leaflet-zoom-box,
+.leaflet-image-layer,
+.leaflet-layer {
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+
+.leaflet-container {
+ overflow: hidden;
+ -ms-touch-action: none;
+ touch-action: none;
+}
+
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+}
+
+
+/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
+
+.leaflet-safari .leaflet-tile {
+ image-rendering: -webkit-optimize-contrast;
+}
+
+
+/* hack that prevents hw layers "stretching" when loading new tiles */
+
+.leaflet-safari .leaflet-tile-container {
+ width: 1600px;
+ height: 1600px;
+ -webkit-transform-origin: 0 0;
+}
+
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+ display: block;
+}
+
+
+/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
+
+
+/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
+
+.leaflet-container .leaflet-overlay-pane svg,
+.leaflet-container .leaflet-marker-pane img,
+.leaflet-container .leaflet-tile-pane img,
+.leaflet-container img.leaflet-image-layer {
+ max-width: none !important;
+}
+
+.leaflet-tile {
+ filter: inherit;
+ visibility: hidden;
+}
+
+.leaflet-tile-loaded {
+ visibility: inherit;
+}
+
+.leaflet-zoom-box {
+ width: 0;
+ height: 0;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ z-index: 800;
+}
+
+
+/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
+
+.leaflet-overlay-pane svg {
+ -moz-user-select: none;
+}
+
+.leaflet-pane {
+ z-index: 400;
+}
+
+.leaflet-tile-pane {
+ z-index: 200;
+}
+
+.leaflet-overlay-pane {
+ z-index: 400;
+}
+
+.leaflet-shadow-pane {
+ z-index: 500;
+}
+
+.leaflet-marker-pane {
+ z-index: 600;
+}
+
+.leaflet-popup-pane {
+ z-index: 700;
+}
+
+.leaflet-map-pane canvas {
+ z-index: 100;
+}
+
+.leaflet-map-pane svg {
+ z-index: 200;
+}
+
+.leaflet-vml-shape {
+ width: 1px;
+ height: 1px;
+}
+
+.lvml {
+ behavior: url(#default#VML);
+ display: inline-block;
+ position: absolute;
+}
+
+
+/* control positioning */
+
+.leaflet-control {
+ position: relative;
+ z-index: 800;
+ pointer-events: auto;
+}
+
+.leaflet-top,
+.leaflet-bottom {
+ position: absolute;
+ z-index: 1000;
+ pointer-events: none;
+}
+
+.leaflet-top {
+ top: 0;
+}
+
+.leaflet-right {
+ right: 0;
+}
+
+.leaflet-bottom {
+ bottom: 0;
+}
+
+.leaflet-left {
+ left: 0;
+}
+
+.leaflet-control {
+ float: left;
+ clear: both;
+}
+
+.leaflet-right .leaflet-control {
+ float: right;
+}
+
+.leaflet-top .leaflet-control {
+ margin-top: 10px;
+}
+
+.leaflet-bottom .leaflet-control {
+ margin-bottom: 10px;
+}
+
+.leaflet-left .leaflet-control {
+ margin-left: 10px;
+}
+
+.leaflet-right .leaflet-control {
+ margin-right: 10px;
+}
+
+
+/* zoom and fade animations */
+
+.leaflet-fade-anim .leaflet-tile {
+ will-change: opacity;
+}
+
+.leaflet-fade-anim .leaflet-popup {
+ opacity: 0;
+ -webkit-transition: opacity 0.2s linear;
+ -moz-transition: opacity 0.2s linear;
+ -o-transition: opacity 0.2s linear;
+ transition: opacity 0.2s linear;
+}
+
+.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
+ opacity: 1;
+}
+
+.leaflet-zoom-animated {
+ -webkit-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ transform-origin: 0 0;
+}
+
+.leaflet-zoom-anim .leaflet-zoom-animated {
+ will-change: transform;
+}
+
+.leaflet-zoom-anim .leaflet-zoom-animated {
+ -webkit-transition: -webkit-transform 0.25s cubic-bezier(0, 0, 0.25, 1);
+ -moz-transition: -moz-transform 0.25s cubic-bezier(0, 0, 0.25, 1);
+ -o-transition: -o-transform 0.25s cubic-bezier(0, 0, 0.25, 1);
+ transition: transform 0.25s cubic-bezier(0, 0, 0.25, 1);
+}
+
+.leaflet-zoom-anim .leaflet-tile,
+.leaflet-pan-anim .leaflet-tile {
+ -webkit-transition: none;
+ -moz-transition: none;
+ -o-transition: none;
+ transition: none;
+}
+
+.leaflet-zoom-anim .leaflet-zoom-hide {
+ visibility: hidden;
+}
+
+
+/* cursors */
+
+.leaflet-interactive {
+ cursor: pointer;
+}
+
+.leaflet-grab {
+ cursor: -webkit-grab;
+ cursor: -moz-grab;
+}
+
+.leaflet-crosshair,
+.leaflet-crosshair .leaflet-interactive {
+ cursor: crosshair;
+}
+
+.leaflet-popup-pane,
+.leaflet-control {
+ cursor: auto;
+}
+
+.leaflet-dragging .leaflet-grab,
+.leaflet-dragging .leaflet-grab .leaflet-interactive,
+.leaflet-dragging .leaflet-marker-draggable {
+ cursor: move;
+ cursor: -webkit-grabbing;
+ cursor: -moz-grabbing;
+}
+
+
+/* visual tweaks */
+
+.leaflet-container {
+ background: #ddd;
+ outline: 0;
+}
+
+.leaflet-container a {
+ color: #0078A8;
+}
+
+.leaflet-container a.leaflet-active {
+ outline: 2px solid orange;
+}
+
+.leaflet-zoom-box {
+ border: 2px dotted #38f;
+ background: rgba(255, 255, 255, 0.5);
+}
+
+
+/* general typography */
+
+.leaflet-container {
+ font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+}
+
+
+/* general toolbar styles */
+
+.leaflet-bar {
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
+ border-radius: 4px;
+}
+
+.leaflet-bar a,
+.leaflet-bar a:hover {
+ background-color: #fff;
+ border-bottom: 1px solid #ccc;
+ width: 26px;
+ height: 26px;
+ line-height: 26px;
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ color: black;
+}
+
+.leaflet-bar a,
+.leaflet-control-layers-toggle {
+ background-position: 50% 50%;
+ background-repeat: no-repeat;
+ display: block;
+}
+
+.leaflet-bar a:hover {
+ background-color: #f4f4f4;
+}
+
+.leaflet-bar a:first-child {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+
+.leaflet-bar a:last-child {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom: none;
+}
+
+.leaflet-bar a.leaflet-disabled {
+ cursor: default;
+ background-color: #f4f4f4;
+ color: #bbb;
+}
+
+.leaflet-touch .leaflet-bar a {
+ width: 30px;
+ height: 30px;
+ line-height: 30px;
+}
+
+
+/* zoom control */
+
+.leaflet-control-zoom-in,
+.leaflet-control-zoom-out {
+ font: bold 18px 'Lucida Console', Monaco, monospace;
+ text-indent: 1px;
+}
+
+.leaflet-control-zoom-out {
+ font-size: 20px;
+}
+
+.leaflet-touch .leaflet-control-zoom-in {
+ font-size: 22px;
+}
+
+.leaflet-touch .leaflet-control-zoom-out {
+ font-size: 24px;
+}
+
+
+/* layers control */
+
+.leaflet-control-layers {
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
+ background: #fff;
+ border-radius: 5px;
+}
+
+.leaflet-control-layers-toggle {
+ background-image: url('assets/erpnext/images/leaflet/layers.png');
+ width: 36px;
+ height: 36px;
+}
+
+.leaflet-retina .leaflet-control-layers-toggle {
+ background-image: url('assets/erpnext/images/leaflet/layers-2x.png');
+ background-size: 26px 26px;
+}
+
+.leaflet-touch .leaflet-control-layers-toggle {
+ width: 44px;
+ height: 44px;
+}
+
+.leaflet-control-layers .leaflet-control-layers-list,
+.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
+ display: none;
+}
+
+.leaflet-control-layers-expanded .leaflet-control-layers-list {
+ display: block;
+ position: relative;
+}
+
+.leaflet-control-layers-expanded {
+ padding: 6px 10px 6px 6px;
+ color: #333;
+ background: #fff;
+}
+
+.leaflet-control-layers-scrollbar {
+ overflow-y: scroll;
+ padding-right: 5px;
+}
+
+.leaflet-control-layers-selector {
+ margin-top: 2px;
+ position: relative;
+ top: 1px;
+}
+
+.leaflet-control-layers label {
+ display: block;
+}
+
+.leaflet-control-layers-separator {
+ height: 0;
+ border-top: 1px solid #ddd;
+ margin: 5px -10px 5px -6px;
+}
+
+
+/* attribution and scale controls */
+
+.leaflet-container .leaflet-control-attribution {
+ background: #fff;
+ background: rgba(255, 255, 255, 0.7);
+ margin: 0;
+}
+
+.leaflet-control-attribution,
+.leaflet-control-scale-line {
+ padding: 0 5px;
+ color: #333;
+}
+
+.leaflet-control-attribution a {
+ text-decoration: none;
+}
+
+.leaflet-control-attribution a:hover {
+ text-decoration: underline;
+}
+
+.leaflet-container .leaflet-control-attribution,
+.leaflet-container .leaflet-control-scale {
+ font-size: 11px;
+}
+
+.leaflet-left .leaflet-control-scale {
+ margin-left: 5px;
+}
+
+.leaflet-bottom .leaflet-control-scale {
+ margin-bottom: 5px;
+}
+
+.leaflet-control-scale-line {
+ border: 2px solid #777;
+ border-top: none;
+ line-height: 1.1;
+ padding: 2px 5px 1px;
+ font-size: 11px;
+ white-space: nowrap;
+ overflow: hidden;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ background: #fff;
+ background: rgba(255, 255, 255, 0.5);
+}
+
+.leaflet-control-scale-line:not(:first-child) {
+ border-top: 2px solid #777;
+ border-bottom: none;
+ margin-top: -2px;
+}
+
+.leaflet-control-scale-line:not(:first-child):not(:last-child) {
+ border-bottom: 2px solid #777;
+}
+
+.leaflet-touch .leaflet-control-attribution,
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+ box-shadow: none;
+}
+
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+ border: 2px solid rgba(0, 0, 0, 0.2);
+ background-clip: padding-box;
+}
+
+
+/* popup */
+
+.leaflet-popup {
+ position: absolute;
+ text-align: center;
+}
+
+.leaflet-popup-content-wrapper {
+ padding: 1px;
+ text-align: left;
+ border-radius: 12px;
+}
+
+.leaflet-popup-content {
+ margin: 13px 19px;
+ line-height: 1.4;
+}
+
+.leaflet-popup-content p {
+ margin: 18px 0;
+}
+
+.leaflet-popup-tip-container {
+ margin: 0 auto;
+ width: 40px;
+ height: 20px;
+ position: relative;
+ overflow: hidden;
+}
+
+.leaflet-popup-tip {
+ width: 17px;
+ height: 17px;
+ padding: 1px;
+ margin: -10px auto 0;
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg);
+}
+
+.leaflet-popup-content-wrapper,
+.leaflet-popup-tip {
+ background: white;
+ color: #333;
+ box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
+}
+
+.leaflet-container a.leaflet-popup-close-button {
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 4px 4px 0 0;
+ border: none;
+ text-align: center;
+ width: 18px;
+ height: 14px;
+ font: 16px/14px Tahoma, Verdana, sans-serif;
+ color: #c3c3c3;
+ text-decoration: none;
+ font-weight: bold;
+ background: transparent;
+}
+
+.leaflet-container a.leaflet-popup-close-button:hover {
+ color: #999;
+}
+
+.leaflet-popup-scrolled {
+ overflow: auto;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+}
+
+.leaflet-oldie .leaflet-popup-content-wrapper {
+ zoom: 1;
+}
+
+.leaflet-oldie .leaflet-popup-tip {
+ width: 24px;
+ margin: 0 auto;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
+ filter: progid: DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
+}
+
+.leaflet-oldie .leaflet-popup-tip-container {
+ margin-top: -1px;
+}
+
+.leaflet-oldie .leaflet-control-zoom,
+.leaflet-oldie .leaflet-control-layers,
+.leaflet-oldie .leaflet-popup-content-wrapper,
+.leaflet-oldie .leaflet-popup-tip {
+ border: 1px solid #999;
+}
+
+
+/* div icon */
+
+.leaflet-div-icon {
+ background: #fff;
+ border: 1px solid #666;
+}
\ No newline at end of file
diff --git a/erpnext/public/css/leaflet/leaflet.draw.css b/erpnext/public/css/leaflet/leaflet.draw.css
new file mode 100755
index 0000000..6fb7db0
--- /dev/null
+++ b/erpnext/public/css/leaflet/leaflet.draw.css
@@ -0,0 +1,316 @@
+/* ================================================================== */
+
+
+/* Toolbars
+/* ================================================================== */
+
+.leaflet-draw-section {
+ position: relative;
+}
+
+.leaflet-draw-toolbar {
+ margin-top: 12px;
+}
+
+.leaflet-draw-toolbar-top {
+ margin-top: 0;
+}
+
+.leaflet-draw-toolbar-notop a:first-child {
+ border-top-right-radius: 0;
+}
+
+.leaflet-draw-toolbar-nobottom a:last-child {
+ border-bottom-right-radius: 0;
+}
+
+.leaflet-draw-toolbar a {
+ background-image: url('assets/erpnext/images/leaflet/spritesheet.png');
+ background-repeat: no-repeat;
+}
+
+.leaflet-retina .leaflet-draw-toolbar a {
+ background-image: url('assets/erpnext/images/leaflet/spritesheet-2x.png');
+ background-size: 270px 30px;
+}
+
+.leaflet-draw a {
+ display: block;
+ text-align: center;
+ text-decoration: none;
+}
+
+
+/* ================================================================== */
+
+
+/* Toolbar actions menu
+/* ================================================================== */
+
+.leaflet-draw-actions {
+ display: none;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ position: absolute;
+ left: 26px;
+ /* leaflet-draw-toolbar.left + leaflet-draw-toolbar.width */
+ top: 0;
+ white-space: nowrap;
+}
+
+.leaflet-right .leaflet-draw-actions {
+ right: 26px;
+ left: auto;
+}
+
+.leaflet-draw-actions li {
+ display: inline-block;
+}
+
+.leaflet-draw-actions li:first-child a {
+ border-left: none;
+}
+
+.leaflet-draw-actions li:last-child a {
+ -webkit-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.leaflet-right .leaflet-draw-actions li:last-child a {
+ -webkit-border-radius: 0;
+ border-radius: 0;
+}
+
+.leaflet-right .leaflet-draw-actions li:first-child a {
+ -webkit-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.leaflet-draw-actions a {
+ background-color: #919187;
+ border-left: 1px solid #AAA;
+ color: #FFF;
+ font: 11px/19px "Helvetica Neue", Arial, Helvetica, sans-serif;
+ line-height: 28px;
+ text-decoration: none;
+ padding-left: 10px;
+ padding-right: 10px;
+ height: 28px;
+}
+
+.leaflet-draw-actions-bottom {
+ margin-top: 0;
+}
+
+.leaflet-draw-actions-top {
+ margin-top: 1px;
+}
+
+.leaflet-draw-actions-top a,
+.leaflet-draw-actions-bottom a {
+ height: 27px;
+ line-height: 27px;
+}
+
+.leaflet-draw-actions a:hover {
+ background-color: #A0A098;
+}
+
+.leaflet-draw-actions-top.leaflet-draw-actions-bottom a {
+ height: 26px;
+ line-height: 26px;
+}
+
+
+/* ================================================================== */
+
+
+/* Draw toolbar
+/* ================================================================== */
+
+.leaflet-draw-toolbar .leaflet-draw-draw-polyline {
+ background-position: -2px -2px;
+}
+
+.leaflet-draw-toolbar .leaflet-draw-draw-polygon {
+ background-position: -31px -2px;
+}
+
+.leaflet-draw-toolbar .leaflet-draw-draw-rectangle {
+ background-position: -62px -2px;
+}
+
+.leaflet-draw-toolbar .leaflet-draw-draw-circle {
+ background-position: -92px -2px;
+}
+
+.leaflet-draw-toolbar .leaflet-draw-draw-marker {
+ background-position: -122px -2px;
+}
+
+
+/* ================================================================== */
+
+
+/* Edit toolbar
+/* ================================================================== */
+
+.leaflet-draw-toolbar .leaflet-draw-edit-edit {
+ background-position: -152px -2px;
+}
+
+.leaflet-draw-toolbar .leaflet-draw-edit-remove {
+ background-position: -182px -2px;
+}
+
+.leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled {
+ background-position: -212px -2px;
+}
+
+.leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled {
+ background-position: -242px -2px;
+}
+
+
+/* ================================================================== */
+
+
+/* Drawing styles
+/* ================================================================== */
+
+.leaflet-mouse-marker {
+ background-color: #fff;
+ cursor: crosshair;
+}
+
+.leaflet-draw-tooltip {
+ background: rgb(54, 54, 54);
+ background: rgba(0, 0, 0, 0.5);
+ border: 1px solid transparent;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ color: #fff;
+ font: 12px/18px "Helvetica Neue", Arial, Helvetica, sans-serif;
+ margin-left: 20px;
+ margin-top: -21px;
+ padding: 4px 8px;
+ position: absolute;
+ visibility: hidden;
+ white-space: nowrap;
+ z-index: 6;
+}
+
+.leaflet-draw-tooltip:before {
+ border-right: 6px solid black;
+ border-right-color: rgba(0, 0, 0, 0.5);
+ border-top: 6px solid transparent;
+ border-bottom: 6px solid transparent;
+ content: "";
+ position: absolute;
+ top: 7px;
+ left: -7px;
+}
+
+.leaflet-error-draw-tooltip {
+ background-color: #F2DEDE;
+ border: 1px solid #E6B6BD;
+ color: #B94A48;
+}
+
+.leaflet-error-draw-tooltip:before {
+ border-right-color: #E6B6BD;
+}
+
+.leaflet-draw-tooltip-single {
+ margin-top: -12px
+}
+
+.leaflet-draw-tooltip-subtext {
+ color: #f8d5e4;
+}
+
+.leaflet-draw-guide-dash {
+ font-size: 1%;
+ opacity: 0.6;
+ position: absolute;
+ width: 5px;
+ height: 5px;
+}
+
+
+/* ================================================================== */
+
+
+/* Edit styles
+/* ================================================================== */
+
+.leaflet-edit-marker-selected {
+ background: rgba(254, 87, 161, 0.1);
+ border: 4px dashed rgba(254, 87, 161, 0.6);
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.leaflet-edit-move {
+ cursor: move;
+}
+
+.leaflet-edit-resize {
+ cursor: pointer;
+}
+
+
+/* ================================================================== */
+
+
+/* Old IE styles
+/* ================================================================== */
+
+.leaflet-oldie .leaflet-draw-toolbar {
+ border: 3px solid #999;
+}
+
+.leaflet-oldie .leaflet-draw-toolbar a {
+ background-color: #eee;
+}
+
+.leaflet-oldie .leaflet-draw-toolbar a:hover {
+ background-color: #fff;
+}
+
+.leaflet-oldie .leaflet-draw-actions {
+ left: 32px;
+ margin-top: 3px;
+}
+
+.leaflet-oldie .leaflet-draw-actions li {
+ display: inline;
+ zoom: 1;
+}
+
+.leaflet-oldie .leaflet-edit-marker-selected {
+ border: 4px dashed #fe93c2;
+}
+
+.leaflet-oldie .leaflet-draw-actions a {
+ background-color: #999;
+}
+
+.leaflet-oldie .leaflet-draw-actions a:hover {
+ background-color: #a5a5a5;
+}
+
+.leaflet-oldie .leaflet-draw-actions-top a {
+ margin-top: 1px;
+}
+
+.leaflet-oldie .leaflet-draw-actions-bottom a {
+ height: 28px;
+ line-height: 28px;
+}
+
+.leaflet-oldie .leaflet-draw-actions-top.leaflet-draw-actions-bottom a {
+ height: 27px;
+ line-height: 27px;
+}
\ No newline at end of file
diff --git a/erpnext/public/images/leaflet/farmer.png b/erpnext/public/images/leaflet/farmer.png
new file mode 100644
index 0000000..03e42ff
--- /dev/null
+++ b/erpnext/public/images/leaflet/farmer.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/layers-2x.png b/erpnext/public/images/leaflet/layers-2x.png
new file mode 100644
index 0000000..200c333
--- /dev/null
+++ b/erpnext/public/images/leaflet/layers-2x.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/layers.png b/erpnext/public/images/leaflet/layers.png
new file mode 100644
index 0000000..1a72e57
--- /dev/null
+++ b/erpnext/public/images/leaflet/layers.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/marker-icon-2x.png b/erpnext/public/images/leaflet/marker-icon-2x.png
new file mode 100644
index 0000000..e4abba3
--- /dev/null
+++ b/erpnext/public/images/leaflet/marker-icon-2x.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/marker-icon.png b/erpnext/public/images/leaflet/marker-icon.png
new file mode 100644
index 0000000..950edf2
--- /dev/null
+++ b/erpnext/public/images/leaflet/marker-icon.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/marker-shadow.png b/erpnext/public/images/leaflet/marker-shadow.png
new file mode 100644
index 0000000..9fd2979
--- /dev/null
+++ b/erpnext/public/images/leaflet/marker-shadow.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/spritesheet-2x.png b/erpnext/public/images/leaflet/spritesheet-2x.png
new file mode 100644
index 0000000..c45231a
--- /dev/null
+++ b/erpnext/public/images/leaflet/spritesheet-2x.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/spritesheet.png b/erpnext/public/images/leaflet/spritesheet.png
new file mode 100644
index 0000000..97d71c6
--- /dev/null
+++ b/erpnext/public/images/leaflet/spritesheet.png
Binary files differ
diff --git a/erpnext/public/images/leaflet/spritesheet.svg b/erpnext/public/images/leaflet/spritesheet.svg
new file mode 100644
index 0000000..3c00f30
--- /dev/null
+++ b/erpnext/public/images/leaflet/spritesheet.svg
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ viewBox="0 0 600 60"
+ height="60"
+ width="600"
+ id="svg4225"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="spritesheet.svg"
+ inkscape:export-filename="/home/fpuga/development/upstream/icarto.Leaflet.draw/src/images/spritesheet-2x.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <metadata
+ id="metadata4258">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs4256" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1056"
+ id="namedview4254"
+ showgrid="false"
+ inkscape:zoom="1.3101852"
+ inkscape:cx="237.56928"
+ inkscape:cy="7.2419621"
+ inkscape:window-x="1920"
+ inkscape:window-y="24"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4225" />
+ <g
+ id="enabled"
+ style="fill:#464646;fill-opacity:1">
+ <g
+ id="polyline"
+ style="fill:#464646;fill-opacity:1">
+ <path
+ d="m 18,36 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
+ id="path4229"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ d="m 36,18 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
+ id="path4231"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ d="m 23.142,39.145 -2.285,-2.29 16,-15.998 2.285,2.285 z"
+ id="path4233"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ </g>
+ <path
+ id="polygon"
+ d="M 100,24.565 97.904,39.395 83.07,42 76,28.773 86.463,18 Z"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ id="rectangle"
+ d="m 140,20 20,0 0,20 -20,0 z"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ id="circle"
+ d="m 221,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ id="marker"
+ d="m 270,19 c -4.971,0 -9,4.029 -9,9 0,4.971 5.001,12 9,14 4.001,-2 9,-9.029 9,-14 0,-4.971 -4.029,-9 -9,-9 z m 0,12.5 c -2.484,0 -4.5,-2.014 -4.5,-4.5 0,-2.484 2.016,-4.5 4.5,-4.5 2.485,0 4.5,2.016 4.5,4.5 0,2.486 -2.015,4.5 -4.5,4.5 z"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <g
+ id="edit"
+ style="fill:#464646;fill-opacity:1">
+ <path
+ d="m 337,30.156 0,0.407 0,5.604 c 0,1.658 -1.344,3 -3,3 l -10,0 c -1.655,0 -3,-1.342 -3,-3 l 0,-10 c 0,-1.657 1.345,-3 3,-3 l 6.345,0 3.19,-3.17 -9.535,0 c -3.313,0 -6,2.687 -6,6 l 0,10 c 0,3.313 2.687,6 6,6 l 10,0 c 3.314,0 6,-2.687 6,-6 l 0,-8.809 -3,2.968"
+ id="path4240"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ d="m 338.72,24.637 -8.892,8.892 -2.828,0 0,-2.829 8.89,-8.89 z"
+ id="path4242"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ d="m 338.697,17.826 4,0 0,4 -4,0 z"
+ transform="matrix(-0.70698336,-0.70723018,0.70723018,-0.70698336,567.55917,274.78273)"
+ id="path4244"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ </g>
+ <g
+ id="remove"
+ style="fill:#464646;fill-opacity:1">
+ <path
+ d="m 381,42 18,0 0,-18 -18,0 0,18 z m 14,-16 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z"
+ id="path4247"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ <path
+ d="m 395,20 0,-4 -10,0 0,4 -6,0 0,2 22,0 0,-2 -6,0 z m -2,0 -6,0 0,-2 6,0 0,2 z"
+ id="path4249"
+ inkscape:connector-curvature="0"
+ style="fill:#464646;fill-opacity:1" />
+ </g>
+ </g>
+ <g
+ id="disabled"
+ transform="translate(120,0)"
+ style="fill:#bbbbbb">
+ <use
+ xlink:href="#edit"
+ id="edit-disabled"
+ x="0"
+ y="0"
+ width="100%"
+ height="100%" />
+ <use
+ xlink:href="#remove"
+ id="remove-disabled"
+ x="0"
+ y="0"
+ width="100%"
+ height="100%" />
+ </g>
+ <path
+ style="fill:none;stroke:#464646;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="circle-3"
+ d="m 581.65725,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/erpnext/public/js/agriculture/ternary_plot.js b/erpnext/public/js/agriculture/ternary_plot.js
new file mode 100644
index 0000000..6f06585
--- /dev/null
+++ b/erpnext/public/js/agriculture/ternary_plot.js
@@ -0,0 +1,232 @@
+frappe.provide('agriculture');
+
+agriculture.TernaryPlot = class TernaryPlot {
+ constructor(opts) {
+ Object.assign(this, opts);
+
+ frappe.require('assets/frappe/js/lib/snap.svg-min.js', () => {
+ this.make_svg();
+ this.init_snap();
+ this.init_config();
+ this.make_plot();
+ this.make_plot_marking();
+ this.make_legend();
+ this.mark_blip();
+ });
+ }
+
+ make_svg() {
+ this.$svg = $('<svg height="350" width="400">');
+ $(this.parent).append(this.$svg);
+ }
+
+ init_snap() {
+ this.paper = new Snap(this.$svg.get(0));
+ }
+
+ init_config() {
+ this.config = {
+ triangle_side: 300,
+ spacing: 50,
+ strokeWidth: 1,
+ stroke: frappe.ui.color.get('black')
+ };
+ this.config.scaling_factor = this.config.triangle_side / 100;
+ let { triangle_side: t, spacing: s, scaling_factor: p } = this.config;
+
+ this.coords = {
+ sand: {
+ points: [
+ s + t * Snap.cos(60), s,
+ s, s + t * Snap.cos(30),
+ s + t, s + t * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('peach')
+ },
+ loamy_sand: {
+ points: [
+ s + 15 * p * Snap.cos(60), s + (100 - 15) * p * Snap.cos(30),
+ s + 10 * p * Snap.cos(60), s + (100 - 10) * p * Snap.cos(30),
+ s + (100 - 85) * p, s + t * Snap.cos(30),
+ s + (100 - 70) * p, s + t * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('pink')
+ },
+ sandy_loam: {
+ points: [
+ s + 20 * p * Snap.cos(60) + 27.5 * p, s + (100 - 20) * p * Snap.cos(30),
+ s + 20 * p * Snap.cos(60), s + (100 - 20) * p * Snap.cos(30),
+ s + 15 * p * Snap.cos(60), s + (100 - 15) * p * Snap.cos(30),
+ s + (100 - 75) * p, s + t * Snap.cos(30),
+ s + (100 - 50) * p, s + t * Snap.cos(30),
+ s + (100 - 50) * p + 7.5 * p * Snap.cos(60), s + t * Snap.cos(30) - 7.5 * p * Snap.cos(30),
+ s + (100 - 50) * p + 7.5 * p * Snap.cos(60) - 10 * p, s + t * Snap.cos(30) - 7.5 * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('pink', 'light')
+ },
+ loam: {
+ points: [
+ s + (100 - 50) * p + 27.5 * p * Snap.cos(60), s + t * Snap.cos(30) - 27.5 * p * Snap.cos(30),
+ s + (100 - 50) * p + 27.5 * p * Snap.cos(60) - 22.5 * p, s + t * Snap.cos(30) - 27.5 * p * Snap.cos(30),
+ s + 20 * p * Snap.cos(60) + 27.5 * p, s + (100 - 20) * p * Snap.cos(30),
+ s + (100 - 50) * p + 7.5 * p * Snap.cos(60) - 10 * p, s + t * Snap.cos(30) - 7.5 * p * Snap.cos(30),
+ s + (100 - 50) * p + 7.5 * p * Snap.cos(60), s + t * Snap.cos(30) - 7.5 * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('brown')
+ },
+ silt_loam: {
+ points: [
+ s + t - 27.5 * p * Snap.cos(60), s + 72.5 * p * Snap.cos(30),
+ s + (100 - 50) * p + 27.5 * p * Snap.cos(60), s + t * Snap.cos(30) - 27.5 * p * Snap.cos(30),
+ s + (100 - 50) * p, s + t * Snap.cos(30),
+ s + (100 - 20) * p, s + t * Snap.cos(30),
+ s + (100 - 20) * p + 12.5 * p * Snap.cos(60), s + 90 * p * Snap.cos(30),
+ s + t - 12.5 * p * Snap.cos(60), s + (100 - 12.5) * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('green', 'dark')
+ },
+ silt: {
+ points: [
+ s + t - 12.5 * p * Snap.cos(60), s + (100 - 12.5) * p * Snap.cos(30),
+ s + (100 - 20) * p + 12.5 * p * Snap.cos(60), s + 90 * p * Snap.cos(30),
+ s + (100 - 20) * p, s + t * Snap.cos(30),
+ s + t, s + t * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('green')
+ },
+ silty_clay_loam: {
+ points: [
+ s + t - 40 * p * Snap.cos(60), s + 60 * p * Snap.cos(30),
+ s + t - 40 * p * Snap.cos(60) - 20 * p, s + 60 * p * Snap.cos(30),
+ s + t - 27.5 * p * Snap.cos(60) - 20 * p, s + 72.5 * p * Snap.cos(30),
+ s + t - 27.5 * p * Snap.cos(60), s + 72.5 * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('cyan', 'dark')
+ },
+ silty_clay: {
+ points: [
+ s + t - 60 * p * Snap.cos(60), s + 40 * p * Snap.cos(30),
+ s + t - 40 * p * Snap.cos(60) - 20 * p, s + 60 * p * Snap.cos(30),
+ s + t - 40 * p * Snap.cos(60), s + 60 * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('cyan')
+ },
+ clay_loam: {
+ points: [
+ s + t - 40 * p * Snap.cos(60) - 20 * p, s + 60 * p * Snap.cos(30),
+ s + t - 40 * p * Snap.cos(60) - 45 * p, s + 60 * p * Snap.cos(30),
+ s + t - 27.5 * p * Snap.cos(60) - 45 * p, s + 72.5 * p * Snap.cos(30),
+ s + t - 27.5 * p * Snap.cos(60) - 20 * p, s + 72.5 * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('green', 'light')
+ },
+ sandy_clay_loam: {
+ points: [
+ s + 35 * p * Snap.cos(60) + 20 * p, s + (100 - 35) * p * Snap.cos(30),
+ s + 35 * p * Snap.cos(60), s + (100 - 35) * p * Snap.cos(30),
+ s + 20 * p * Snap.cos(60), s + (100 - 20) * p * Snap.cos(30),
+ s + 20 * p * Snap.cos(60) + 27.5 * p, s + (100 - 20) * p * Snap.cos(30),
+ s + t - 27.5 * p * Snap.cos(60) - 45 * p, s + 72.5 * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('pink', 'dark')
+ },
+ sandy_clay: {
+ points: [
+ s + 55 * p * Snap.cos(60), s + (100 - 55) * p * Snap.cos(30),
+ s + 35 * p * Snap.cos(60), s + (100 - 35) * p * Snap.cos(30),
+ s + 35 * p * Snap.cos(60) + 20 * p, s + (100 - 35) * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('red')
+ },
+ clay: {
+ points: [
+ s + t * Snap.cos(60), s,
+ s + 55 * p * Snap.cos(60), s + (100 - 55) * p * Snap.cos(30),
+ s + t - 40 * p * Snap.cos(60) - 45 * p, s + 60 * p * Snap.cos(30),
+ s + t - 40 * p * Snap.cos(60) - 20 * p, s + 60 * p * Snap.cos(30),
+ s + t - 60 * p * Snap.cos(60), s + 40 * p * Snap.cos(30)
+ ],
+ color: frappe.ui.color.get('yellow')
+ },
+ };
+ }
+
+ get_coords(soil_type) {
+ return this.coords[soil_type].points;
+ }
+
+ get_color(soil_type) {
+ return this.coords[soil_type].color;
+ }
+
+ make_plot() {
+ for (let soil_type in this.coords) {
+ this.paper.polygon(this.get_coords(soil_type)).attr({
+ fill: this.get_color(soil_type),
+ stroke: this.config.stroke,
+ strokeWidth: this.config.strokeWidth
+ });
+ }
+ }
+
+ make_plot_marking() {
+ let { triangle_side: t, spacing: s, scaling_factor: p } = this.config;
+
+ let clay = this.paper.text(t * Snap.cos(60) / 2, s + t * Snap.cos(30) / 2, "Clay").attr({
+ fill: frappe.ui.color.get('black')
+ });
+ clay.transform("r300");
+
+ let silt = this.paper.text(t, s + t * Snap.cos(30) / 2, "Silt").attr({
+ fill: frappe.ui.color.get('black')
+ });
+ silt.transform("r60");
+
+ let sand = this.paper.text(35 + t * Snap.cos(60), 90 + t * Snap.cos(30), "Sand").attr({
+ fill: frappe.ui.color.get('black')
+ });
+ sand.transform("r0");
+ }
+
+ make_legend() {
+ // let side = len(this.coords)/2;
+ let index = 1;
+ let offset = 0;
+ let exec_once = true;
+ for (let soil_type in this.coords) {
+ if (index > 6 && exec_once){
+ offset = 300;
+ index = 1;
+ exec_once = false;
+ }
+ let rect = this.paper.rect(0+offset, 0+index*20, 100, 19, 5, 5).attr({
+ fill: this.get_color(soil_type),
+ stroke: frappe.ui.color.get('black')
+ });
+ let text = this.paper.text(5+offset, 16+index*20, soil_type).attr({
+ fill: frappe.ui.color.get('black'),
+ 'font-size': 12
+ });
+ index++;
+ }
+ }
+
+ mark_blip({clay, sand, silt} = this) {
+ if (clay + sand + silt != 0){
+ let { triangle_side: t, spacing: s, scaling_factor: p } = this.config;
+
+ let x_blip = s + clay * p * Snap.cos(60) + silt * p;
+ let y_blip = s + silt * p * Snap.cos(30) + sand * p * Snap.sin(60);
+ this.blip = this.paper.circle(x_blip, y_blip, 4).attr({
+ fill: frappe.ui.color.get("orange"),
+ stroke: frappe.ui.color.get("orange"),
+ strokeWidth: 2
+ });
+ }
+ }
+
+ remove_blip() {
+ if (typeof this.blip !== 'undefined')
+ this.blip.remove();
+ }
+};
\ No newline at end of file
diff --git a/erpnext/public/js/leaflet/leaflet.draw.js b/erpnext/public/js/leaflet/leaflet.draw.js
new file mode 100755
index 0000000..4352f70
--- /dev/null
+++ b/erpnext/public/js/leaflet/leaflet.draw.js
@@ -0,0 +1,143 @@
+/*
+ Leaflet.draw, a plugin that adds drawing and editing tools to Leaflet powered maps.
+ (c) 2012-2013, Jacob Toye, Smartrak
+
+ https://github.com/Leaflet/Leaflet.draw
+ http://leafletjs.com
+ https://github.com/jacobtoye
+*/
+! function(t, e) {
+ L.drawVersion = "0.2.3", L.drawLocal = { draw: { toolbar: { actions: { title: "Cancel drawing", text: "Cancel" }, undo: { title: "Delete last point drawn", text: "Delete last point" }, buttons: { polyline: "Draw a polyline", polygon: "Draw a polygon", rectangle: "Draw a rectangle", circle: "Draw a circle", marker: "Draw a marker" } }, handlers: { circle: { tooltip: { start: "Click and drag to draw circle." } }, marker: { tooltip: { start: "Click map to place marker." } }, polygon: { tooltip: { start: "Click to start drawing shape.", cont: "Click to continue drawing shape.", end: "Click first point to close this shape." } }, polyline: { error: "<strong>Error:</strong> shape edges cannot cross!", tooltip: { start: "Click to start drawing line.", cont: "Click to continue drawing line.", end: "Click last point to finish line." } }, rectangle: { tooltip: { start: "Click and drag to draw rectangle." } }, simpleshape: { tooltip: { end: "Release mouse to finish drawing." } } } }, edit: { toolbar: { actions: { save: { title: "Save changes.", text: "Save" }, cancel: { title: "Cancel editing, discards all changes.", text: "Cancel" } }, buttons: { edit: "Edit layers.", editDisabled: "No layers to edit.", remove: "Delete layers.", removeDisabled: "No layers to delete." } }, handlers: { edit: { tooltip: { text: "Drag handles, or marker to edit feature.", subtext: "Click cancel to undo changes." } }, remove: { tooltip: { text: "Click on a feature to remove" } } } } }, L.Draw = {}, L.Draw.Feature = L.Handler.extend({ includes: L.Mixin.Events, initialize: function(t, e) { this._map = t, this._container = t._container, this._overlayPane = t._panes.overlayPane, this._popupPane = t._panes.popupPane, e && e.shapeOptions && (e.shapeOptions = L.Util.extend({}, this.options.shapeOptions, e.shapeOptions)), L.setOptions(this, e) }, enable: function() { this._enabled || (this.fire("enabled", { handler: this.type }), this._map.fire("draw:drawstart", { layerType: this.type }), L.Handler.prototype.enable.call(this)) }, disable: function() { this._enabled && (L.Handler.prototype.disable.call(this), this._map.fire("draw:drawstop", { layerType: this.type }), this.fire("disabled", { handler: this.type })) }, addHooks: function() { var t = this._map;
+ t && (L.DomUtil.disableTextSelection(), t.getContainer().focus(), this._tooltip = new L.Tooltip(this._map), L.DomEvent.on(this._container, "keyup", this._cancelDrawing, this)) }, removeHooks: function() { this._map && (L.DomUtil.enableTextSelection(), this._tooltip.dispose(), this._tooltip = null, L.DomEvent.off(this._container, "keyup", this._cancelDrawing, this)) }, setOptions: function(t) { L.setOptions(this, t) }, _fireCreatedEvent: function(t) { this._map.fire("draw:created", { layer: t, layerType: this.type }) }, _cancelDrawing: function(t) { 27 === t.keyCode && this.disable() } }), L.Draw.Polyline = L.Draw.Feature.extend({ statics: { TYPE: "polyline" }, Poly: L.Polyline, options: { allowIntersection: !0, repeatMode: !1, drawError: { color: "#b00b00", timeout: 2500 }, icon: new L.DivIcon({ iconSize: new L.Point(8, 8), className: "leaflet-div-icon leaflet-editing-icon" }), guidelineDistance: 20, maxGuideLineLength: 4e3, shapeOptions: { stroke: !0, color: "#f06eaa", weight: 4, opacity: .5, fill: !1, clickable: !0 }, metric: !0, showLength: !0, zIndexOffset: 2e3 }, initialize: function(t, e) { this.options.drawError.message = L.drawLocal.draw.handlers.polyline.error, e && e.drawError && (e.drawError = L.Util.extend({}, this.options.drawError, e.drawError)), this.type = L.Draw.Polyline.TYPE, L.Draw.Feature.prototype.initialize.call(this, t, e) }, addHooks: function() { L.Draw.Feature.prototype.addHooks.call(this), this._map && (this._markers = [], this._markerGroup = new L.LayerGroup, this._map.addLayer(this._markerGroup), this._poly = new L.Polyline([], this.options.shapeOptions), this._tooltip.updateContent(this._getTooltipText()), this._mouseMarker || (this._mouseMarker = L.marker(this._map.getCenter(), { icon: L.divIcon({ className: "leaflet-mouse-marker", iconAnchor: [20, 20], iconSize: [40, 40] }), opacity: 0, zIndexOffset: this.options.zIndexOffset })), this._mouseMarker.on("mousedown", this._onMouseDown, this).addTo(this._map), this._map.on("mousemove", this._onMouseMove, this).on("mouseup", this._onMouseUp, this).on("zoomend", this._onZoomEnd, this)) }, removeHooks: function() { L.Draw.Feature.prototype.removeHooks.call(this), this._clearHideErrorTimeout(), this._cleanUpShape(), this._map.removeLayer(this._markerGroup), delete this._markerGroup, delete this._markers, this._map.removeLayer(this._poly), delete this._poly, this._mouseMarker.off("mousedown", this._onMouseDown, this).off("mouseup", this._onMouseUp, this), this._map.removeLayer(this._mouseMarker), delete this._mouseMarker, this._clearGuides(), this._map.off("mousemove", this._onMouseMove, this).off("zoomend", this._onZoomEnd, this) }, deleteLastVertex: function() { if (!(this._markers.length <= 1)) { var t = this._markers.pop(),
+ e = this._poly,
+ i = this._poly.spliceLatLngs(e.getLatLngs().length - 1, 1)[0];
+ this._markerGroup.removeLayer(t), e.getLatLngs().length < 2 && this._map.removeLayer(e), this._vertexChanged(i, !1) } }, addVertex: function(t) { var e = this._markers.length; return e > 0 && !this.options.allowIntersection && this._poly.newLatLngIntersects(t) ? void this._showErrorTooltip() : (this._errorShown && this._hideErrorTooltip(), this._markers.push(this._createMarker(t)), this._poly.addLatLng(t), 2 === this._poly.getLatLngs().length && this._map.addLayer(this._poly), void this._vertexChanged(t, !0)) }, _finishShape: function() { var t = this._poly.newLatLngIntersects(this._poly.getLatLngs()[0], !0); return !this.options.allowIntersection && t || !this._shapeIsValid() ? void this._showErrorTooltip() : (this._fireCreatedEvent(), this.disable(), void(this.options.repeatMode && this.enable())) }, _shapeIsValid: function() { return !0 }, _onZoomEnd: function() { this._updateGuide() }, _onMouseMove: function(t) { var e = t.layerPoint,
+ i = t.latlng;
+ this._currentLatLng = i, this._updateTooltip(i), this._updateGuide(e), this._mouseMarker.setLatLng(i), L.DomEvent.preventDefault(t.originalEvent) }, _vertexChanged: function(t, e) { this._updateFinishHandler(), this._updateRunningMeasure(t, e), this._clearGuides(), this._updateTooltip() }, _onMouseDown: function(t) { var e = t.originalEvent;
+ this._mouseDownOrigin = L.point(e.clientX, e.clientY) }, _onMouseUp: function(e) { if (this._mouseDownOrigin) { var i = L.point(e.originalEvent.clientX, e.originalEvent.clientY).distanceTo(this._mouseDownOrigin);
+ Math.abs(i) < 9 * (t.devicePixelRatio || 1) && this.addVertex(e.latlng) }
+ this._mouseDownOrigin = null }, _updateFinishHandler: function() { var t = this._markers.length;
+ t > 1 && this._markers[t - 1].on("click", this._finishShape, this), t > 2 && this._markers[t - 2].off("click", this._finishShape, this) }, _createMarker: function(t) { var e = new L.Marker(t, { icon: this.options.icon, zIndexOffset: 2 * this.options.zIndexOffset }); return this._markerGroup.addLayer(e), e }, _updateGuide: function(t) { var e = this._markers.length;
+ e > 0 && (t = t || this._map.latLngToLayerPoint(this._currentLatLng), this._clearGuides(), this._drawGuide(this._map.latLngToLayerPoint(this._markers[e - 1].getLatLng()), t)) }, _updateTooltip: function(t) { var e = this._getTooltipText();
+ t && this._tooltip.updatePosition(t), this._errorShown || this._tooltip.updateContent(e) }, _drawGuide: function(t, e) { var i, o, a, s = Math.floor(Math.sqrt(Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2))),
+ r = this.options.guidelineDistance,
+ n = this.options.maxGuideLineLength,
+ l = s > n ? s - n : r; for (this._guidesContainer || (this._guidesContainer = L.DomUtil.create("div", "leaflet-draw-guides", this._overlayPane)); s > l; l += this.options.guidelineDistance) i = l / s, o = { x: Math.floor(t.x * (1 - i) + i * e.x), y: Math.floor(t.y * (1 - i) + i * e.y) }, a = L.DomUtil.create("div", "leaflet-draw-guide-dash", this._guidesContainer), a.style.backgroundColor = this._errorShown ? this.options.drawError.color : this.options.shapeOptions.color, L.DomUtil.setPosition(a, o) }, _updateGuideColor: function(t) { if (this._guidesContainer)
+ for (var e = 0, i = this._guidesContainer.childNodes.length; i > e; e++) this._guidesContainer.childNodes[e].style.backgroundColor = t }, _clearGuides: function() { if (this._guidesContainer)
+ for (; this._guidesContainer.firstChild;) this._guidesContainer.removeChild(this._guidesContainer.firstChild) }, _getTooltipText: function() { var t, e, i = this.options.showLength; return 0 === this._markers.length ? t = { text: L.drawLocal.draw.handlers.polyline.tooltip.start } : (e = i ? this._getMeasurementString() : "", t = 1 === this._markers.length ? { text: L.drawLocal.draw.handlers.polyline.tooltip.cont, subtext: e } : { text: L.drawLocal.draw.handlers.polyline.tooltip.end, subtext: e }), t }, _updateRunningMeasure: function(t, e) { var i, o, a = this._markers.length;
+ 1 === this._markers.length ? this._measurementRunningTotal = 0 : (i = a - (e ? 2 : 1), o = t.distanceTo(this._markers[i].getLatLng()), this._measurementRunningTotal += o * (e ? 1 : -1)) }, _getMeasurementString: function() { var t, e = this._currentLatLng,
+ i = this._markers[this._markers.length - 1].getLatLng(); return t = this._measurementRunningTotal + e.distanceTo(i), L.GeometryUtil.readableDistance(t, this.options.metric) }, _showErrorTooltip: function() { this._errorShown = !0, this._tooltip.showAsError().updateContent({ text: this.options.drawError.message }), this._updateGuideColor(this.options.drawError.color), this._poly.setStyle({ color: this.options.drawError.color }), this._clearHideErrorTimeout(), this._hideErrorTimeout = setTimeout(L.Util.bind(this._hideErrorTooltip, this), this.options.drawError.timeout) }, _hideErrorTooltip: function() { this._errorShown = !1, this._clearHideErrorTimeout(), this._tooltip.removeError().updateContent(this._getTooltipText()), this._updateGuideColor(this.options.shapeOptions.color), this._poly.setStyle({ color: this.options.shapeOptions.color }) }, _clearHideErrorTimeout: function() { this._hideErrorTimeout && (clearTimeout(this._hideErrorTimeout), this._hideErrorTimeout = null) }, _cleanUpShape: function() { this._markers.length > 1 && this._markers[this._markers.length - 1].off("click", this._finishShape, this) }, _fireCreatedEvent: function() { var t = new this.Poly(this._poly.getLatLngs(), this.options.shapeOptions);
+ L.Draw.Feature.prototype._fireCreatedEvent.call(this, t) } }), L.Draw.Polygon = L.Draw.Polyline.extend({ statics: { TYPE: "polygon" }, Poly: L.Polygon, options: { showArea: !1, shapeOptions: { stroke: !0, color: "#f06eaa", weight: 4, opacity: .5, fill: !0, fillColor: null, fillOpacity: .2, clickable: !0 } }, initialize: function(t, e) { L.Draw.Polyline.prototype.initialize.call(this, t, e), this.type = L.Draw.Polygon.TYPE }, _updateFinishHandler: function() { var t = this._markers.length;
+ 1 === t && this._markers[0].on("click", this._finishShape, this), t > 2 && (this._markers[t - 1].on("dblclick", this._finishShape, this), t > 3 && this._markers[t - 2].off("dblclick", this._finishShape, this)) }, _getTooltipText: function() { var t, e; return 0 === this._markers.length ? t = L.drawLocal.draw.handlers.polygon.tooltip.start : this._markers.length < 3 ? t = L.drawLocal.draw.handlers.polygon.tooltip.cont : (t = L.drawLocal.draw.handlers.polygon.tooltip.end, e = this._getMeasurementString()), { text: t, subtext: e } }, _getMeasurementString: function() { var t = this._area; return t ? L.GeometryUtil.readableArea(t, this.options.metric) : null }, _shapeIsValid: function() { return this._markers.length >= 3 }, _vertexAdded: function() { if (!this.options.allowIntersection && this.options.showArea) { var t = this._poly.getLatLngs();
+ this._area = L.GeometryUtil.geodesicArea(t) } }, _cleanUpShape: function() { var t = this._markers.length;
+ t > 0 && (this._markers[0].off("click", this._finishShape, this), t > 2 && this._markers[t - 1].off("dblclick", this._finishShape, this)) } }), L.SimpleShape = {}, L.Draw.SimpleShape = L.Draw.Feature.extend({ options: { repeatMode: !1 }, initialize: function(t, e) { this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end, L.Draw.Feature.prototype.initialize.call(this, t, e) }, addHooks: function() { L.Draw.Feature.prototype.addHooks.call(this), this._map && (this._mapDraggable = this._map.dragging.enabled(), this._mapDraggable && this._map.dragging.disable(), this._container.style.cursor = "crosshair", this._tooltip.updateContent({ text: this._initialLabelText }), this._map.on("mousedown", this._onMouseDown, this).on("mousemove", this._onMouseMove, this)) }, removeHooks: function() { L.Draw.Feature.prototype.removeHooks.call(this), this._map && (this._mapDraggable && this._map.dragging.enable(), this._container.style.cursor = "", this._map.off("mousedown", this._onMouseDown, this).off("mousemove", this._onMouseMove, this), L.DomEvent.off(e, "mouseup", this._onMouseUp, this), this._shape && (this._map.removeLayer(this._shape), delete this._shape)), this._isDrawing = !1 }, _onMouseDown: function(t) { this._isDrawing = !0, this._startLatLng = t.latlng, L.DomEvent.on(e, "mouseup", this._onMouseUp, this).preventDefault(t.originalEvent) }, _onMouseMove: function(t) { var e = t.latlng;
+ this._tooltip.updatePosition(e), this._isDrawing && (this._tooltip.updateContent({ text: this._endLabelText }), this._drawShape(e)) }, _onMouseUp: function() { this._shape && this._fireCreatedEvent(), this.disable(), this.options.repeatMode && this.enable() } }), L.Draw.Rectangle = L.Draw.SimpleShape.extend({ statics: { TYPE: "rectangle" }, options: { shapeOptions: { stroke: !0, color: "#f06eaa", weight: 4, opacity: .5, fill: !0, fillColor: null, fillOpacity: .2, clickable: !0 } }, initialize: function(t, e) { this.type = L.Draw.Rectangle.TYPE, this._initialLabelText = L.drawLocal.draw.handlers.rectangle.tooltip.start, L.Draw.SimpleShape.prototype.initialize.call(this, t, e) }, _drawShape: function(t) { this._shape ? this._shape.setBounds(new L.LatLngBounds(this._startLatLng, t)) : (this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, t), this.options.shapeOptions), this._map.addLayer(this._shape)) }, _fireCreatedEvent: function() { var t = new L.Rectangle(this._shape.getBounds(), this.options.shapeOptions);
+ L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, t) } }), L.Draw.Circle = L.Draw.SimpleShape.extend({ statics: { TYPE: "circle" }, options: { shapeOptions: { stroke: !0, color: "#f06eaa", weight: 4, opacity: .5, fill: !0, fillColor: null, fillOpacity: .2, clickable: !0 }, showRadius: !0, metric: !0 }, initialize: function(t, e) { this.type = L.Draw.Circle.TYPE, this._initialLabelText = L.drawLocal.draw.handlers.circle.tooltip.start, L.Draw.SimpleShape.prototype.initialize.call(this, t, e) }, _drawShape: function(t) { this._shape ? this._shape.setRadius(this._startLatLng.distanceTo(t)) : (this._shape = new L.Circle(this._startLatLng, this._startLatLng.distanceTo(t), this.options.shapeOptions), this._map.addLayer(this._shape)) }, _fireCreatedEvent: function() { var t = new L.Circle(this._startLatLng, this._shape.getRadius(), this.options.shapeOptions);
+ L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, t) }, _onMouseMove: function(t) { var e, i = t.latlng,
+ o = this.options.showRadius,
+ a = this.options.metric;
+ this._tooltip.updatePosition(i), this._isDrawing && (this._drawShape(i), e = this._shape.getRadius().toFixed(1), this._tooltip.updateContent({ text: this._endLabelText, subtext: o ? "Radius: " + L.GeometryUtil.readableDistance(e, a) : "" })) } }), L.Draw.Marker = L.Draw.Feature.extend({ statics: { TYPE: "marker" }, options: { icon: new L.Icon.Default, repeatMode: !1, zIndexOffset: 2e3 }, initialize: function(t, e) { this.type = L.Draw.Marker.TYPE, L.Draw.Feature.prototype.initialize.call(this, t, e) }, addHooks: function() { L.Draw.Feature.prototype.addHooks.call(this), this._map && (this._tooltip.updateContent({ text: L.drawLocal.draw.handlers.marker.tooltip.start }), this._mouseMarker || (this._mouseMarker = L.marker(this._map.getCenter(), { icon: L.divIcon({ className: "leaflet-mouse-marker", iconAnchor: [20, 20], iconSize: [40, 40] }), opacity: 0, zIndexOffset: this.options.zIndexOffset })), this._mouseMarker.on("click", this._onClick, this).addTo(this._map), this._map.on("mousemove", this._onMouseMove, this)) }, removeHooks: function() { L.Draw.Feature.prototype.removeHooks.call(this), this._map && (this._marker && (this._marker.off("click", this._onClick, this), this._map.off("click", this._onClick, this).removeLayer(this._marker), delete this._marker), this._mouseMarker.off("click", this._onClick, this), this._map.removeLayer(this._mouseMarker), delete this._mouseMarker, this._map.off("mousemove", this._onMouseMove, this)) }, _onMouseMove: function(t) { var e = t.latlng;
+ this._tooltip.updatePosition(e), this._mouseMarker.setLatLng(e), this._marker ? (e = this._mouseMarker.getLatLng(), this._marker.setLatLng(e)) : (this._marker = new L.Marker(e, { icon: this.options.icon, zIndexOffset: this.options.zIndexOffset }), this._marker.on("click", this._onClick, this), this._map.on("click", this._onClick, this).addLayer(this._marker)) }, _onClick: function() { this._fireCreatedEvent(), this.disable(), this.options.repeatMode && this.enable() }, _fireCreatedEvent: function() { var t = new L.Marker(this._marker.getLatLng(), { icon: this.options.icon });
+ L.Draw.Feature.prototype._fireCreatedEvent.call(this, t) } }), L.Edit = L.Edit || {}, L.Edit.Poly = L.Handler.extend({ options: { icon: new L.DivIcon({ iconSize: new L.Point(8, 8), className: "leaflet-div-icon leaflet-editing-icon" }) }, initialize: function(t, e) { this._poly = t, L.setOptions(this, e) }, addHooks: function() { this._poly._map && (this._markerGroup || this._initMarkers(), this._poly._map.addLayer(this._markerGroup)) }, removeHooks: function() { this._poly._map && (this._poly._map.removeLayer(this._markerGroup), delete this._markerGroup, delete this._markers) }, updateMarkers: function() { this._markerGroup.clearLayers(), this._initMarkers() }, _initMarkers: function() { this._markerGroup || (this._markerGroup = new L.LayerGroup), this._markers = []; var t, e, i, o, a = this._poly._latlngs; for (t = 0, i = a.length; i > t; t++) o = this._createMarker(a[t], t), o.on("click", this._onMarkerClick, this), this._markers.push(o); var s, r; for (t = 0, e = i - 1; i > t; e = t++)(0 !== t || L.Polygon && this._poly instanceof L.Polygon) && (s = this._markers[e], r = this._markers[t], this._createMiddleMarker(s, r), this._updatePrevNext(s, r)) }, _createMarker: function(t, e) { var i = new L.Marker(t, { draggable: !0, icon: this.options.icon }); return i._origLatLng = t, i._index = e, i.on("drag", this._onMarkerDrag, this), i.on("dragend", this._fireEdit, this), this._markerGroup.addLayer(i), i }, _removeMarker: function(t) { var e = t._index;
+ this._markerGroup.removeLayer(t), this._markers.splice(e, 1), this._poly.spliceLatLngs(e, 1), this._updateIndexes(e, -1), t.off("drag", this._onMarkerDrag, this).off("dragend", this._fireEdit, this).off("click", this._onMarkerClick, this) }, _fireEdit: function() { this._poly.edited = !0, this._poly.fire("edit") }, _onMarkerDrag: function(t) { var e = t.target;
+ L.extend(e._origLatLng, e._latlng), e._middleLeft && e._middleLeft.setLatLng(this._getMiddleLatLng(e._prev, e)), e._middleRight && e._middleRight.setLatLng(this._getMiddleLatLng(e, e._next)), this._poly.redraw() }, _onMarkerClick: function(t) { var e = L.Polygon && this._poly instanceof L.Polygon ? 4 : 3,
+ i = t.target;
+ this._poly._latlngs.length < e || (this._removeMarker(i), this._updatePrevNext(i._prev, i._next), i._middleLeft && this._markerGroup.removeLayer(i._middleLeft), i._middleRight && this._markerGroup.removeLayer(i._middleRight), i._prev && i._next ? this._createMiddleMarker(i._prev, i._next) : i._prev ? i._next || (i._prev._middleRight = null) : i._next._middleLeft = null, this._fireEdit()) }, _updateIndexes: function(t, e) { this._markerGroup.eachLayer(function(i) { i._index > t && (i._index += e) }) }, _createMiddleMarker: function(t, e) { var i, o, a, s = this._getMiddleLatLng(t, e),
+ r = this._createMarker(s);
+ r.setOpacity(.6), t._middleRight = e._middleLeft = r, o = function() { var o = e._index;
+ r._index = o, r.off("click", i, this).on("click", this._onMarkerClick, this), s.lat = r.getLatLng().lat, s.lng = r.getLatLng().lng, this._poly.spliceLatLngs(o, 0, s), this._markers.splice(o, 0, r), r.setOpacity(1), this._updateIndexes(o, 1), e._index++, this._updatePrevNext(t, r), this._updatePrevNext(r, e), this._poly.fire("editstart") }, a = function() { r.off("dragstart", o, this), r.off("dragend", a, this), this._createMiddleMarker(t, r), this._createMiddleMarker(r, e) }, i = function() { o.call(this), a.call(this), this._fireEdit() }, r.on("click", i, this).on("dragstart", o, this).on("dragend", a, this), this._markerGroup.addLayer(r) }, _updatePrevNext: function(t, e) { t && (t._next = e), e && (e._prev = t) }, _getMiddleLatLng: function(t, e) { var i = this._poly._map,
+ o = i.project(t.getLatLng()),
+ a = i.project(e.getLatLng()); return i.unproject(o._add(a)._divideBy(2)) } }), L.Polyline.addInitHook(function() { this.editing || (L.Edit.Poly && (this.editing = new L.Edit.Poly(this), this.options.editable && this.editing.enable()), this.on("add", function() { this.editing && this.editing.enabled() && this.editing.addHooks() }), this.on("remove", function() { this.editing && this.editing.enabled() && this.editing.removeHooks() })) }), L.Edit = L.Edit || {}, L.Edit.SimpleShape = L.Handler.extend({ options: { moveIcon: new L.DivIcon({ iconSize: new L.Point(8, 8), className: "leaflet-div-icon leaflet-editing-icon leaflet-edit-move" }), resizeIcon: new L.DivIcon({ iconSize: new L.Point(8, 8), className: "leaflet-div-icon leaflet-editing-icon leaflet-edit-resize" }) }, initialize: function(t, e) { this._shape = t, L.Util.setOptions(this, e) }, addHooks: function() { this._shape._map && (this._map = this._shape._map, this._markerGroup || this._initMarkers(), this._map.addLayer(this._markerGroup)) }, removeHooks: function() { if (this._shape._map) { this._unbindMarker(this._moveMarker); for (var t = 0, e = this._resizeMarkers.length; e > t; t++) this._unbindMarker(this._resizeMarkers[t]);
+ this._resizeMarkers = null, this._map.removeLayer(this._markerGroup), delete this._markerGroup }
+ this._map = null }, updateMarkers: function() { this._markerGroup.clearLayers(), this._initMarkers() }, _initMarkers: function() { this._markerGroup || (this._markerGroup = new L.LayerGroup), this._createMoveMarker(), this._createResizeMarker() }, _createMoveMarker: function() {}, _createResizeMarker: function() {}, _createMarker: function(t, e) { var i = new L.Marker(t, { draggable: !0, icon: e, zIndexOffset: 10 }); return this._bindMarker(i), this._markerGroup.addLayer(i), i }, _bindMarker: function(t) { t.on("dragstart", this._onMarkerDragStart, this).on("drag", this._onMarkerDrag, this).on("dragend", this._onMarkerDragEnd, this) }, _unbindMarker: function(t) { t.off("dragstart", this._onMarkerDragStart, this).off("drag", this._onMarkerDrag, this).off("dragend", this._onMarkerDragEnd, this) }, _onMarkerDragStart: function(t) { var e = t.target;
+ e.setOpacity(0), this._shape.fire("editstart") }, _fireEdit: function() { this._shape.edited = !0, this._shape.fire("edit") }, _onMarkerDrag: function(t) { var e = t.target,
+ i = e.getLatLng();
+ e === this._moveMarker ? this._move(i) : this._resize(i), this._shape.redraw() }, _onMarkerDragEnd: function(t) { var e = t.target;
+ e.setOpacity(1), this._fireEdit() }, _move: function() {}, _resize: function() {} }), L.Edit = L.Edit || {}, L.Edit.Rectangle = L.Edit.SimpleShape.extend({ _createMoveMarker: function() { var t = this._shape.getBounds(),
+ e = t.getCenter();
+ this._moveMarker = this._createMarker(e, this.options.moveIcon) }, _createResizeMarker: function() { var t = this._getCorners();
+ this._resizeMarkers = []; for (var e = 0, i = t.length; i > e; e++) this._resizeMarkers.push(this._createMarker(t[e], this.options.resizeIcon)), this._resizeMarkers[e]._cornerIndex = e }, _onMarkerDragStart: function(t) { L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, t); var e = this._getCorners(),
+ i = t.target,
+ o = i._cornerIndex;
+ this._oppositeCorner = e[(o + 2) % 4], this._toggleCornerMarkers(0, o) }, _onMarkerDragEnd: function(t) { var e, i, o = t.target;
+ o === this._moveMarker && (e = this._shape.getBounds(), i = e.getCenter(), o.setLatLng(i)), this._toggleCornerMarkers(1), this._repositionCornerMarkers(), L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this, t) }, _move: function(t) { for (var e, i = this._shape.getLatLngs(), o = this._shape.getBounds(), a = o.getCenter(), s = [], r = 0, n = i.length; n > r; r++) e = [i[r].lat - a.lat, i[r].lng - a.lng], s.push([t.lat + e[0], t.lng + e[1]]);
+ this._shape.setLatLngs(s), this._repositionCornerMarkers() }, _resize: function(t) { var e;
+ this._shape.setBounds(L.latLngBounds(t, this._oppositeCorner)), e = this._shape.getBounds(), this._moveMarker.setLatLng(e.getCenter()) }, _getCorners: function() { var t = this._shape.getBounds(),
+ e = t.getNorthWest(),
+ i = t.getNorthEast(),
+ o = t.getSouthEast(),
+ a = t.getSouthWest(); return [e, i, o, a] }, _toggleCornerMarkers: function(t) { for (var e = 0, i = this._resizeMarkers.length; i > e; e++) this._resizeMarkers[e].setOpacity(t) }, _repositionCornerMarkers: function() { for (var t = this._getCorners(), e = 0, i = this._resizeMarkers.length; i > e; e++) this._resizeMarkers[e].setLatLng(t[e]) } }), L.Rectangle.addInitHook(function() { L.Edit.Rectangle && (this.editing = new L.Edit.Rectangle(this), this.options.editable && this.editing.enable()) }), L.Edit = L.Edit || {}, L.Edit.Circle = L.Edit.SimpleShape.extend({ _createMoveMarker: function() { var t = this._shape.getLatLng();
+ this._moveMarker = this._createMarker(t, this.options.moveIcon) }, _createResizeMarker: function() { var t = this._shape.getLatLng(),
+ e = this._getResizeMarkerPoint(t);
+ this._resizeMarkers = [], this._resizeMarkers.push(this._createMarker(e, this.options.resizeIcon)) }, _getResizeMarkerPoint: function(t) { var e = this._shape._radius * Math.cos(Math.PI / 4),
+ i = this._map.project(t); return this._map.unproject([i.x + e, i.y - e]) }, _move: function(t) { var e = this._getResizeMarkerPoint(t);
+ this._resizeMarkers[0].setLatLng(e), this._shape.setLatLng(t) }, _resize: function(t) { var e = this._moveMarker.getLatLng(),
+ i = e.distanceTo(t);
+ this._shape.setRadius(i) } }), L.Circle.addInitHook(function() { L.Edit.Circle && (this.editing = new L.Edit.Circle(this), this.options.editable && this.editing.enable()), this.on("add", function() { this.editing && this.editing.enabled() && this.editing.addHooks() }), this.on("remove", function() { this.editing && this.editing.enabled() && this.editing.removeHooks() }) }), L.LatLngUtil = { cloneLatLngs: function(t) { for (var e = [], i = 0, o = t.length; o > i; i++) e.push(this.cloneLatLng(t[i])); return e }, cloneLatLng: function(t) { return L.latLng(t.lat, t.lng) } }, L.GeometryUtil = L.extend(L.GeometryUtil || {}, { geodesicArea: function(t) { var e, i, o = t.length,
+ a = 0,
+ s = L.LatLng.DEG_TO_RAD; if (o > 2) { for (var r = 0; o > r; r++) e = t[r], i = t[(r + 1) % o], a += (i.lng - e.lng) * s * (2 + Math.sin(e.lat * s) + Math.sin(i.lat * s));
+ a = 6378137 * a * 6378137 / 2 } return Math.abs(a) }, readableArea: function(t, e) { var i; return e ? i = t >= 1e4 ? (1e-4 * t).toFixed(2) + " ha" : t.toFixed(2) + " m²" : (t *= .836127, i = t >= 3097600 ? (t / 3097600).toFixed(2) + " mi²" : t >= 4840 ? (t / 4840).toFixed(2) + " acres" : Math.ceil(t) + " yd²"), i }, readableDistance: function(t, e) { var i; return e ? i = t > 1e3 ? (t / 1e3).toFixed(2) + " km" : Math.ceil(t) + " m" : (t *= 1.09361, i = t > 1760 ? (t / 1760).toFixed(2) + " miles" : Math.ceil(t) + " yd"), i } }), L.Util.extend(L.LineUtil, { segmentsIntersect: function(t, e, i, o) { return this._checkCounterclockwise(t, i, o) !== this._checkCounterclockwise(e, i, o) && this._checkCounterclockwise(t, e, i) !== this._checkCounterclockwise(t, e, o) }, _checkCounterclockwise: function(t, e, i) { return (i.y - t.y) * (e.x - t.x) > (e.y - t.y) * (i.x - t.x) } }), L.Polyline.include({ intersects: function() { var t, e, i, o = this._originalPoints,
+ a = o ? o.length : 0; if (this._tooFewPointsForIntersection()) return !1; for (t = a - 1; t >= 3; t--)
+ if (e = o[t - 1], i = o[t], this._lineSegmentsIntersectsRange(e, i, t - 2)) return !0;
+ return !1 }, newLatLngIntersects: function(t, e) { return this._map ? this.newPointIntersects(this._map.latLngToLayerPoint(t), e) : !1 }, newPointIntersects: function(t, e) { var i = this._originalPoints,
+ o = i ? i.length : 0,
+ a = i ? i[o - 1] : null,
+ s = o - 2; return this._tooFewPointsForIntersection(1) ? !1 : this._lineSegmentsIntersectsRange(a, t, s, e ? 1 : 0) }, _tooFewPointsForIntersection: function(t) { var e = this._originalPoints,
+ i = e ? e.length : 0; return i += t || 0, !this._originalPoints || 3 >= i }, _lineSegmentsIntersectsRange: function(t, e, i, o) { var a, s, r = this._originalPoints;
+ o = o || 0; for (var n = i; n > o; n--)
+ if (a = r[n - 1], s = r[n], L.LineUtil.segmentsIntersect(t, e, a, s)) return !0;
+ return !1 } }), L.Polygon.include({ intersects: function() { var t, e, i, o, a, s = this._originalPoints; return this._tooFewPointsForIntersection() ? !1 : (t = L.Polyline.prototype.intersects.call(this)) ? !0 : (e = s.length, i = s[0], o = s[e - 1], a = e - 2, this._lineSegmentsIntersectsRange(o, i, a, 1)) } }), L.Control.Draw = L.Control.extend({ options: { position: "topleft", draw: {}, edit: !1 }, initialize: function(t) { if (L.version < "0.7") throw new Error("Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/");
+ L.Control.prototype.initialize.call(this, t); var e, i;
+ this._toolbars = {}, L.DrawToolbar && this.options.draw && (i = new L.DrawToolbar(this.options.draw), e = L.stamp(i), this._toolbars[e] = i, this._toolbars[e].on("enable", this._toolbarEnabled, this)), L.EditToolbar && this.options.edit && (i = new L.EditToolbar(this.options.edit), e = L.stamp(i), this._toolbars[e] = i, this._toolbars[e].on("enable", this._toolbarEnabled, this)) }, onAdd: function(t) { var e, i = L.DomUtil.create("div", "leaflet-draw"),
+ o = !1,
+ a = "leaflet-draw-toolbar-top"; for (var s in this._toolbars) this._toolbars.hasOwnProperty(s) && (e = this._toolbars[s].addToolbar(t), e && (o || (L.DomUtil.hasClass(e, a) || L.DomUtil.addClass(e.childNodes[0], a), o = !0), i.appendChild(e))); return i }, onRemove: function() { for (var t in this._toolbars) this._toolbars.hasOwnProperty(t) && this._toolbars[t].removeToolbar() }, setDrawingOptions: function(t) { for (var e in this._toolbars) this._toolbars[e] instanceof L.DrawToolbar && this._toolbars[e].setOptions(t) }, _toolbarEnabled: function(t) { var e = "" + L.stamp(t.target); for (var i in this._toolbars) this._toolbars.hasOwnProperty(i) && i !== e && this._toolbars[i].disable() } }), L.Map.mergeOptions({ drawControlTooltips: !0, drawControl: !1 }), L.Map.addInitHook(function() { this.options.drawControl && (this.drawControl = new L.Control.Draw, this.addControl(this.drawControl)) }), L.Toolbar = L.Class.extend({
+ includes: [L.Mixin.Events],
+ initialize: function(t) { L.setOptions(this, t), this._modes = {}, this._actionButtons = [], this._activeMode = null },
+ enabled: function() { return null !== this._activeMode },
+ disable: function() { this.enabled() && this._activeMode.handler.disable() },
+ addToolbar: function(t) { var e, i = L.DomUtil.create("div", "leaflet-draw-section"),
+ o = 0,
+ a = this._toolbarClass || "",
+ s = this.getModeHandlers(t); for (this._toolbarContainer = L.DomUtil.create("div", "leaflet-draw-toolbar leaflet-bar"), this._map = t, e = 0; e < s.length; e++) s[e].enabled && this._initModeHandler(s[e].handler, this._toolbarContainer, o++, a, s[e].title); return o ? (this._lastButtonIndex = --o, this._actionsContainer = L.DomUtil.create("ul", "leaflet-draw-actions"), i.appendChild(this._toolbarContainer), i.appendChild(this._actionsContainer), i) : void 0 },
+ removeToolbar: function() { for (var t in this._modes) this._modes.hasOwnProperty(t) && (this._disposeButton(this._modes[t].button, this._modes[t].handler.enable, this._modes[t].handler), this._modes[t].handler.disable(), this._modes[t].handler.off("enabled", this._handlerActivated, this).off("disabled", this._handlerDeactivated, this));
+ this._modes = {}; for (var e = 0, i = this._actionButtons.length; i > e; e++) this._disposeButton(this._actionButtons[e].button, this._actionButtons[e].callback, this);
+ this._actionButtons = [], this._actionsContainer = null },
+ _initModeHandler: function(t, e, i, o, a) { var s = t.type;
+ this._modes[s] = {}, this._modes[s].handler = t, this._modes[s].button = this._createButton({ title: a, className: o + "-" + s, container: e, callback: this._modes[s].handler.enable, context: this._modes[s].handler }), this._modes[s].buttonIndex = i, this._modes[s].handler.on("enabled", this._handlerActivated, this).on("disabled", this._handlerDeactivated, this) },
+ _createButton: function(t) { var e = L.DomUtil.create("a", t.className || "", t.container); return e.href = "#", t.text && (e.innerHTML = t.text), t.title && (e.title = t.title), L.DomEvent.on(e, "click", L.DomEvent.stopPropagation).on(e, "mousedown", L.DomEvent.stopPropagation).on(e, "dblclick", L.DomEvent.stopPropagation).on(e, "click", L.DomEvent.preventDefault).on(e, "click", t.callback, t.context), e },
+ _disposeButton: function(t, e) { L.DomEvent.off(t, "click", L.DomEvent.stopPropagation).off(t, "mousedown", L.DomEvent.stopPropagation).off(t, "dblclick", L.DomEvent.stopPropagation).off(t, "click", L.DomEvent.preventDefault).off(t, "click", e) },
+ _handlerActivated: function(t) { this.disable(), this._activeMode = this._modes[t.handler], L.DomUtil.addClass(this._activeMode.button, "leaflet-draw-toolbar-button-enabled"), this._showActionsToolbar(), this.fire("enable") },
+ _handlerDeactivated: function() { this._hideActionsToolbar(), L.DomUtil.removeClass(this._activeMode.button, "leaflet-draw-toolbar-button-enabled"), this._activeMode = null, this.fire("disable") },
+ _createActions: function(t) { var e, i, o, a, s = this._actionsContainer,
+ r = this.getActions(t),
+ n = r.length; for (i = 0, o = this._actionButtons.length; o > i; i++) this._disposeButton(this._actionButtons[i].button, this._actionButtons[i].callback); for (this._actionButtons = []; s.firstChild;) s.removeChild(s.firstChild); for (var l = 0; n > l; l++) "enabled" in r[l] && !r[l].enabled || (e = L.DomUtil.create("li", "", s), a = this._createButton({ title: r[l].title, text: r[l].text, container: e, callback: r[l].callback, context: r[l].context }), this._actionButtons.push({ button: a, callback: r[l].callback })) },
+ _showActionsToolbar: function() {
+ var t = this._activeMode.buttonIndex,
+ e = this._lastButtonIndex,
+ i = this._activeMode.button.offsetTop - 1;
+ this._createActions(this._activeMode.handler), this._actionsContainer.style.top = i + "px", 0 === t && (L.DomUtil.addClass(this._toolbarContainer, "leaflet-draw-toolbar-notop"), L.DomUtil.addClass(this._actionsContainer, "leaflet-draw-actions-top")), t === e && (L.DomUtil.addClass(this._toolbarContainer, "leaflet-draw-toolbar-nobottom"), L.DomUtil.addClass(this._actionsContainer, "leaflet-draw-actions-bottom")), this._actionsContainer.style.display = "block"
+ },
+ _hideActionsToolbar: function() { this._actionsContainer.style.display = "none", L.DomUtil.removeClass(this._toolbarContainer, "leaflet-draw-toolbar-notop"), L.DomUtil.removeClass(this._toolbarContainer, "leaflet-draw-toolbar-nobottom"), L.DomUtil.removeClass(this._actionsContainer, "leaflet-draw-actions-top"), L.DomUtil.removeClass(this._actionsContainer, "leaflet-draw-actions-bottom") }
+ }), L.Tooltip = L.Class.extend({ initialize: function(t) { this._map = t, this._popupPane = t._panes.popupPane, this._container = t.options.drawControlTooltips ? L.DomUtil.create("div", "leaflet-draw-tooltip", this._popupPane) : null, this._singleLineLabel = !1 }, dispose: function() { this._container && (this._popupPane.removeChild(this._container), this._container = null) }, updateContent: function(t) { return this._container ? (t.subtext = t.subtext || "", 0 !== t.subtext.length || this._singleLineLabel ? t.subtext.length > 0 && this._singleLineLabel && (L.DomUtil.removeClass(this._container, "leaflet-draw-tooltip-single"), this._singleLineLabel = !1) : (L.DomUtil.addClass(this._container, "leaflet-draw-tooltip-single"), this._singleLineLabel = !0), this._container.innerHTML = (t.subtext.length > 0 ? '<span class="leaflet-draw-tooltip-subtext">' + t.subtext + "</span><br />" : "") + "<span>" + t.text + "</span>", this) : this }, updatePosition: function(t) { var e = this._map.latLngToLayerPoint(t),
+ i = this._container; return this._container && (i.style.visibility = "inherit", L.DomUtil.setPosition(i, e)), this }, showAsError: function() { return this._container && L.DomUtil.addClass(this._container, "leaflet-error-draw-tooltip"), this }, removeError: function() { return this._container && L.DomUtil.removeClass(this._container, "leaflet-error-draw-tooltip"), this } }), L.DrawToolbar = L.Toolbar.extend({ options: { polyline: {}, polygon: {}, rectangle: {}, circle: {}, marker: {} }, initialize: function(t) { for (var e in this.options) this.options.hasOwnProperty(e) && t[e] && (t[e] = L.extend({}, this.options[e], t[e]));
+ this._toolbarClass = "leaflet-draw-draw", L.Toolbar.prototype.initialize.call(this, t) }, getModeHandlers: function(t) { return [{ enabled: this.options.polyline, handler: new L.Draw.Polyline(t, this.options.polyline), title: L.drawLocal.draw.toolbar.buttons.polyline }, { enabled: this.options.polygon, handler: new L.Draw.Polygon(t, this.options.polygon), title: L.drawLocal.draw.toolbar.buttons.polygon }, { enabled: this.options.rectangle, handler: new L.Draw.Rectangle(t, this.options.rectangle), title: L.drawLocal.draw.toolbar.buttons.rectangle }, { enabled: this.options.circle, handler: new L.Draw.Circle(t, this.options.circle), title: L.drawLocal.draw.toolbar.buttons.circle }, { enabled: this.options.marker, handler: new L.Draw.Marker(t, this.options.marker), title: L.drawLocal.draw.toolbar.buttons.marker }] }, getActions: function(t) { return [{ enabled: t.deleteLastVertex, title: L.drawLocal.draw.toolbar.undo.title, text: L.drawLocal.draw.toolbar.undo.text, callback: t.deleteLastVertex, context: t }, { title: L.drawLocal.draw.toolbar.actions.title, text: L.drawLocal.draw.toolbar.actions.text, callback: this.disable, context: this }] }, setOptions: function(t) { L.setOptions(this, t); for (var e in this._modes) this._modes.hasOwnProperty(e) && t.hasOwnProperty(e) && this._modes[e].handler.setOptions(t[e]) } }), L.EditToolbar = L.Toolbar.extend({ options: { edit: { selectedPathOptions: { color: "#fe57a1", opacity: .6, dashArray: "10, 10", fill: !0, fillColor: "#fe57a1", fillOpacity: .1 } }, remove: {}, featureGroup: null }, initialize: function(t) { t.edit && ("undefined" == typeof t.edit.selectedPathOptions && (t.edit.selectedPathOptions = this.options.edit.selectedPathOptions), t.edit = L.extend({}, this.options.edit, t.edit)), t.remove && (t.remove = L.extend({}, this.options.remove, t.remove)), this._toolbarClass = "leaflet-draw-edit", L.Toolbar.prototype.initialize.call(this, t), this._selectedFeatureCount = 0 }, getModeHandlers: function(t) { var e = this.options.featureGroup; return [{ enabled: this.options.edit, handler: new L.EditToolbar.Edit(t, { featureGroup: e, selectedPathOptions: this.options.edit.selectedPathOptions }), title: L.drawLocal.edit.toolbar.buttons.edit }, { enabled: this.options.remove, handler: new L.EditToolbar.Delete(t, { featureGroup: e }), title: L.drawLocal.edit.toolbar.buttons.remove }] }, getActions: function() { return [{ title: L.drawLocal.edit.toolbar.actions.save.title, text: L.drawLocal.edit.toolbar.actions.save.text, callback: this._save, context: this }, { title: L.drawLocal.edit.toolbar.actions.cancel.title, text: L.drawLocal.edit.toolbar.actions.cancel.text, callback: this.disable, context: this }] }, addToolbar: function(t) { var e = L.Toolbar.prototype.addToolbar.call(this, t); return this._checkDisabled(), this.options.featureGroup.on("layeradd layerremove", this._checkDisabled, this), e }, removeToolbar: function() { this.options.featureGroup.off("layeradd layerremove", this._checkDisabled, this), L.Toolbar.prototype.removeToolbar.call(this) }, disable: function() { this.enabled() && (this._activeMode.handler.revertLayers(), L.Toolbar.prototype.disable.call(this)) }, _save: function() { this._activeMode.handler.save(), this._activeMode.handler.disable() }, _checkDisabled: function() { var t, e = this.options.featureGroup,
+ i = 0 !== e.getLayers().length;
+ this.options.edit && (t = this._modes[L.EditToolbar.Edit.TYPE].button, i ? L.DomUtil.removeClass(t, "leaflet-disabled") : L.DomUtil.addClass(t, "leaflet-disabled"), t.setAttribute("title", i ? L.drawLocal.edit.toolbar.buttons.edit : L.drawLocal.edit.toolbar.buttons.editDisabled)), this.options.remove && (t = this._modes[L.EditToolbar.Delete.TYPE].button, i ? L.DomUtil.removeClass(t, "leaflet-disabled") : L.DomUtil.addClass(t, "leaflet-disabled"), t.setAttribute("title", i ? L.drawLocal.edit.toolbar.buttons.remove : L.drawLocal.edit.toolbar.buttons.removeDisabled)) } }), L.EditToolbar.Edit = L.Handler.extend({ statics: { TYPE: "edit" }, includes: L.Mixin.Events, initialize: function(t, e) { if (L.Handler.prototype.initialize.call(this, t), this._selectedPathOptions = e.selectedPathOptions, this._featureGroup = e.featureGroup, !(this._featureGroup instanceof L.FeatureGroup)) throw new Error("options.featureGroup must be a L.FeatureGroup");
+ this._uneditedLayerProps = {}, this.type = L.EditToolbar.Edit.TYPE }, enable: function() {!this._enabled && this._hasAvailableLayers() && (this.fire("enabled", { handler: this.type }), this._map.fire("draw:editstart", { handler: this.type }), L.Handler.prototype.enable.call(this), this._featureGroup.on("layeradd", this._enableLayerEdit, this).on("layerremove", this._disableLayerEdit, this)) }, disable: function() { this._enabled && (this._featureGroup.off("layeradd", this._enableLayerEdit, this).off("layerremove", this._disableLayerEdit, this), L.Handler.prototype.disable.call(this), this._map.fire("draw:editstop", { handler: this.type }), this.fire("disabled", { handler: this.type })) }, addHooks: function() { var t = this._map;
+ t && (t.getContainer().focus(), this._featureGroup.eachLayer(this._enableLayerEdit, this), this._tooltip = new L.Tooltip(this._map), this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.edit.tooltip.text, subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext }), this._map.on("mousemove", this._onMouseMove, this)) }, removeHooks: function() { this._map && (this._featureGroup.eachLayer(this._disableLayerEdit, this), this._uneditedLayerProps = {}, this._tooltip.dispose(), this._tooltip = null, this._map.off("mousemove", this._onMouseMove, this)) }, revertLayers: function() { this._featureGroup.eachLayer(function(t) { this._revertLayer(t) }, this) }, save: function() { var t = new L.LayerGroup;
+ this._featureGroup.eachLayer(function(e) { e.edited && (t.addLayer(e), e.edited = !1) }), this._map.fire("draw:edited", { layers: t }) }, _backupLayer: function(t) { var e = L.Util.stamp(t);
+ this._uneditedLayerProps[e] || (t instanceof L.Polyline || t instanceof L.Polygon || t instanceof L.Rectangle ? this._uneditedLayerProps[e] = { latlngs: L.LatLngUtil.cloneLatLngs(t.getLatLngs()) } : t instanceof L.Circle ? this._uneditedLayerProps[e] = { latlng: L.LatLngUtil.cloneLatLng(t.getLatLng()), radius: t.getRadius() } : t instanceof L.Marker && (this._uneditedLayerProps[e] = { latlng: L.LatLngUtil.cloneLatLng(t.getLatLng()) })) }, _revertLayer: function(t) { var e = L.Util.stamp(t);
+ t.edited = !1, this._uneditedLayerProps.hasOwnProperty(e) && (t instanceof L.Polyline || t instanceof L.Polygon || t instanceof L.Rectangle ? t.setLatLngs(this._uneditedLayerProps[e].latlngs) : t instanceof L.Circle ? (t.setLatLng(this._uneditedLayerProps[e].latlng), t.setRadius(this._uneditedLayerProps[e].radius)) : t instanceof L.Marker && t.setLatLng(this._uneditedLayerProps[e].latlng)) }, _toggleMarkerHighlight: function(t) { if (t._icon) { var e = t._icon;
+ e.style.display = "none", L.DomUtil.hasClass(e, "leaflet-edit-marker-selected") ? (L.DomUtil.removeClass(e, "leaflet-edit-marker-selected"), this._offsetMarker(e, -4)) : (L.DomUtil.addClass(e, "leaflet-edit-marker-selected"), this._offsetMarker(e, 4)), e.style.display = "" } }, _offsetMarker: function(t, e) { var i = parseInt(t.style.marginTop, 10) - e,
+ o = parseInt(t.style.marginLeft, 10) - e;
+ t.style.marginTop = i + "px", t.style.marginLeft = o + "px" }, _enableLayerEdit: function(t) { var e, i = t.layer || t.target || t,
+ o = i instanceof L.Marker;
+ (!o || i._icon) && (this._backupLayer(i), this._selectedPathOptions && (e = L.Util.extend({}, this._selectedPathOptions), o ? this._toggleMarkerHighlight(i) : (i.options.previousOptions = L.Util.extend({ dashArray: null }, i.options), i instanceof L.Circle || i instanceof L.Polygon || i instanceof L.Rectangle || (e.fill = !1), i.setStyle(e))), o ? (i.dragging.enable(), i.on("dragend", this._onMarkerDragEnd)) : i.editing.enable()) }, _disableLayerEdit: function(t) { var e = t.layer || t.target || t;
+ e.edited = !1, this._selectedPathOptions && (e instanceof L.Marker ? this._toggleMarkerHighlight(e) : (e.setStyle(e.options.previousOptions), delete e.options.previousOptions)), e instanceof L.Marker ? (e.dragging.disable(), e.off("dragend", this._onMarkerDragEnd, this)) : e.editing.disable() }, _onMarkerDragEnd: function(t) { var e = t.target;
+ e.edited = !0 }, _onMouseMove: function(t) { this._tooltip.updatePosition(t.latlng) }, _hasAvailableLayers: function() { return 0 !== this._featureGroup.getLayers().length } }), L.EditToolbar.Delete = L.Handler.extend({ statics: { TYPE: "remove" }, includes: L.Mixin.Events, initialize: function(t, e) { if (L.Handler.prototype.initialize.call(this, t), L.Util.setOptions(this, e), this._deletableLayers = this.options.featureGroup, !(this._deletableLayers instanceof L.FeatureGroup)) throw new Error("options.featureGroup must be a L.FeatureGroup");
+ this.type = L.EditToolbar.Delete.TYPE }, enable: function() {!this._enabled && this._hasAvailableLayers() && (this.fire("enabled", { handler: this.type }), this._map.fire("draw:deletestart", { handler: this.type }), L.Handler.prototype.enable.call(this), this._deletableLayers.on("layeradd", this._enableLayerDelete, this).on("layerremove", this._disableLayerDelete, this)) }, disable: function() { this._enabled && (this._deletableLayers.off("layeradd", this._enableLayerDelete, this).off("layerremove", this._disableLayerDelete, this), L.Handler.prototype.disable.call(this), this._map.fire("draw:deletestop", { handler: this.type }), this.fire("disabled", { handler: this.type })) }, addHooks: function() { var t = this._map;
+ t && (t.getContainer().focus(), this._deletableLayers.eachLayer(this._enableLayerDelete, this), this._deletedLayers = new L.layerGroup, this._tooltip = new L.Tooltip(this._map), this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.remove.tooltip.text }), this._map.on("mousemove", this._onMouseMove, this)) }, removeHooks: function() { this._map && (this._deletableLayers.eachLayer(this._disableLayerDelete, this), this._deletedLayers = null, this._tooltip.dispose(), this._tooltip = null, this._map.off("mousemove", this._onMouseMove, this)) }, revertLayers: function() { this._deletedLayers.eachLayer(function(t) { this._deletableLayers.addLayer(t) }, this) }, save: function() { this._map.fire("draw:deleted", { layers: this._deletedLayers }) }, _enableLayerDelete: function(t) { var e = t.layer || t.target || t;
+ e.on("click", this._removeLayer, this) }, _disableLayerDelete: function(t) { var e = t.layer || t.target || t;
+ e.off("click", this._removeLayer, this), this._deletedLayers.removeLayer(e) }, _removeLayer: function(t) { var e = t.layer || t.target || t;
+ this._deletableLayers.removeLayer(e), this._deletedLayers.addLayer(e) }, _onMouseMove: function(t) { this._tooltip.updatePosition(t.latlng) }, _hasAvailableLayers: function() { return 0 !== this._deletableLayers.getLayers().length } })
+}(window, document);
\ No newline at end of file
diff --git a/erpnext/public/js/leaflet/leaflet.js b/erpnext/public/js/leaflet/leaflet.js
new file mode 100755
index 0000000..41d9bb9
--- /dev/null
+++ b/erpnext/public/js/leaflet/leaflet.js
@@ -0,0 +1,771 @@
+/*
+ Leaflet 1.0.0-beta.2 (dd0faa1), a JS library for interactive maps. http://leafletjs.com
+ (c) 2010-2015 Vladimir Agafonkin, (c) 2010-2011 CloudMade
+*/
+! function(t, e, i) {
+ function n() { var e = t.L;
+ o.noConflict = function() { return t.L = e, this }, t.L = o }
+ var o = { version: "1.0.0-beta.2" };
+ "object" == typeof module && "object" == typeof module.exports ? module.exports = o : "function" == typeof define && define.amd && define(o), "undefined" != typeof t && n(), o.Util = { extend: function(t) { var e, i, n, o; for (i = 1, n = arguments.length; n > i; i++) { o = arguments[i]; for (e in o) t[e] = o[e] } return t }, create: Object.create || function() {
+ function t() {} return function(e) { return t.prototype = e, new t } }(), bind: function(t, e) { var i = Array.prototype.slice; if (t.bind) return t.bind.apply(t, i.call(arguments, 1)); var n = i.call(arguments, 2); return function() { return t.apply(e, n.length ? n.concat(i.call(arguments)) : arguments) } }, stamp: function(t) { return t._leaflet_id = t._leaflet_id || ++o.Util.lastId, t._leaflet_id }, lastId: 0, throttle: function(t, e, i) { var n, o, s, r; return r = function() { n = !1, o && (s.apply(i, o), o = !1) }, s = function() { n ? o = arguments : (t.apply(i, arguments), setTimeout(r, e), n = !0) } }, wrapNum: function(t, e, i) { var n = e[1],
+ o = e[0],
+ s = n - o; return t === n && i ? t : ((t - o) % s + s) % s + o }, falseFn: function() { return !1 }, formatNum: function(t, e) { var i = Math.pow(10, e || 5); return Math.round(t * i) / i }, trim: function(t) { return t.trim ? t.trim() : t.replace(/^\s+|\s+$/g, "") }, splitWords: function(t) { return o.Util.trim(t).split(/\s+/) }, setOptions: function(t, e) { t.hasOwnProperty("options") || (t.options = t.options ? o.Util.create(t.options) : {}); for (var i in e) t.options[i] = e[i]; return t.options }, getParamString: function(t, e, i) { var n = []; for (var o in t) n.push(encodeURIComponent(i ? o.toUpperCase() : o) + "=" + encodeURIComponent(t[o])); return (e && -1 !== e.indexOf("?") ? "&" : "?") + n.join("&") }, template: function(t, e) { return t.replace(o.Util.templateRe, function(t, n) { var o = e[n]; if (o === i) throw new Error("No value provided for variable " + t); return "function" == typeof o && (o = o(e)), o }) }, templateRe: /\{ *([\w_]+) *\}/g, isArray: Array.isArray || function(t) { return "[object Array]" === Object.prototype.toString.call(t) }, indexOf: function(t, e) { for (var i = 0; i < t.length; i++)
+ if (t[i] === e) return i;
+ return -1 }, emptyImageUrl: "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" },
+ function() {
+ function e(e) { return t["webkit" + e] || t["moz" + e] || t["ms" + e] }
+
+ function i(e) { var i = +new Date,
+ o = Math.max(0, 16 - (i - n)); return n = i + o, t.setTimeout(e, o) } var n = 0,
+ s = t.requestAnimationFrame || e("RequestAnimationFrame") || i,
+ r = t.cancelAnimationFrame || e("CancelAnimationFrame") || e("CancelRequestAnimationFrame") || function(e) { t.clearTimeout(e) };
+ o.Util.requestAnimFrame = function(e, n, r) { return r && s === i ? void e.call(n) : s.call(t, o.bind(e, n)) }, o.Util.cancelAnimFrame = function(e) { e && r.call(t, e) } }(), o.extend = o.Util.extend, o.bind = o.Util.bind, o.stamp = o.Util.stamp, o.setOptions = o.Util.setOptions, o.Class = function() {}, o.Class.extend = function(t) { var e = function() { this.initialize && this.initialize.apply(this, arguments), this.callInitHooks() },
+ i = e.__super__ = this.prototype,
+ n = o.Util.create(i);
+ n.constructor = e, e.prototype = n; for (var s in this) this.hasOwnProperty(s) && "prototype" !== s && (e[s] = this[s]); return t.statics && (o.extend(e, t.statics), delete t.statics), t.includes && (o.Util.extend.apply(null, [n].concat(t.includes)), delete t.includes), n.options && (t.options = o.Util.extend(o.Util.create(n.options), t.options)), o.extend(n, t), n._initHooks = [], n.callInitHooks = function() { if (!this._initHooksCalled) { i.callInitHooks && i.callInitHooks.call(this), this._initHooksCalled = !0; for (var t = 0, e = n._initHooks.length; e > t; t++) n._initHooks[t].call(this) } }, e }, o.Class.include = function(t) { o.extend(this.prototype, t) }, o.Class.mergeOptions = function(t) { o.extend(this.prototype.options, t) }, o.Class.addInitHook = function(t) { var e = Array.prototype.slice.call(arguments, 1),
+ i = "function" == typeof t ? t : function() { this[t].apply(this, e) };
+ this.prototype._initHooks = this.prototype._initHooks || [], this.prototype._initHooks.push(i) }, o.Evented = o.Class.extend({ on: function(t, e, i) { if ("object" == typeof t)
+ for (var n in t) this._on(n, t[n], e);
+ else { t = o.Util.splitWords(t); for (var s = 0, r = t.length; r > s; s++) this._on(t[s], e, i) } return this }, off: function(t, e, i) { if (t)
+ if ("object" == typeof t)
+ for (var n in t) this._off(n, t[n], e);
+ else { t = o.Util.splitWords(t); for (var s = 0, r = t.length; r > s; s++) this._off(t[s], e, i) }
+ else delete this._events; return this }, _on: function(t, e, i) { var n = this._events = this._events || {},
+ s = i && i !== this && o.stamp(i); if (s) { var r = t + "_idx",
+ a = t + "_len",
+ h = n[r] = n[r] || {},
+ l = o.stamp(e) + "_" + s;
+ h[l] || (h[l] = { fn: e, ctx: i }, n[a] = (n[a] || 0) + 1) } else n[t] = n[t] || [], n[t].push({ fn: e }) }, _off: function(t, e, i) { var n = this._events,
+ s = t + "_idx",
+ r = t + "_len"; if (n) { if (!e) return delete n[t], delete n[s], void delete n[r]; var a, h, l, u, c, d = i && i !== this && o.stamp(i); if (d) c = o.stamp(e) + "_" + d, a = n[s], a && a[c] && (u = a[c], delete a[c], n[r]--);
+ else if (a = n[t])
+ for (h = 0, l = a.length; l > h; h++)
+ if (a[h].fn === e) { u = a[h], a.splice(h, 1); break }
+ u && (u.fn = o.Util.falseFn) } }, fire: function(t, e, i) { if (!this.listens(t, i)) return this; var n = o.Util.extend({}, e, { type: t, target: this }),
+ s = this._events; if (s) { var r, a, h, l, u = s[t + "_idx"]; if (s[t])
+ for (h = s[t].slice(), r = 0, a = h.length; a > r; r++) h[r].fn.call(this, n); for (l in u) u[l].fn.call(u[l].ctx, n) } return i && this._propagateEvent(n), this }, listens: function(t, e) { var i = this._events; if (i && (i[t] || i[t + "_len"])) return !0; if (e)
+ for (var n in this._eventParents)
+ if (this._eventParents[n].listens(t, e)) return !0;
+ return !1 }, once: function(t, e, i) { if ("object" == typeof t) { for (var n in t) this.once(n, t[n], e); return this } var s = o.bind(function() { this.off(t, e, i).off(t, s, i) }, this); return this.on(t, e, i).on(t, s, i) }, addEventParent: function(t) { return this._eventParents = this._eventParents || {}, this._eventParents[o.stamp(t)] = t, this }, removeEventParent: function(t) { return this._eventParents && delete this._eventParents[o.stamp(t)], this }, _propagateEvent: function(t) { for (var e in this._eventParents) this._eventParents[e].fire(t.type, o.extend({ layer: t.target }, t), !0) } });
+ var s = o.Evented.prototype;
+ s.addEventListener = s.on, s.removeEventListener = s.clearAllEventListeners = s.off, s.addOneTimeEventListener = s.once, s.fireEvent = s.fire, s.hasEventListeners = s.listens, o.Mixin = { Events: s },
+ function() { var i = navigator.userAgent.toLowerCase(),
+ n = e.documentElement,
+ s = "ActiveXObject" in t,
+ r = -1 !== i.indexOf("webkit"),
+ a = -1 !== i.indexOf("phantom"),
+ h = -1 !== i.search("android [23]"),
+ l = -1 !== i.indexOf("chrome"),
+ u = -1 !== i.indexOf("gecko") && !r && !t.opera && !s,
+ c = "undefined" != typeof orientation || -1 !== i.indexOf("mobile"),
+ d = !t.PointerEvent && t.MSPointerEvent,
+ _ = t.PointerEvent && navigator.pointerEnabled || d,
+ m = s && "transition" in n.style,
+ p = "WebKitCSSMatrix" in t && "m11" in new t.WebKitCSSMatrix && !h,
+ f = "MozPerspective" in n.style,
+ g = "OTransition" in n.style,
+ v = !t.L_NO_TOUCH && !a && (_ || "ontouchstart" in t || t.DocumentTouch && e instanceof t.DocumentTouch);
+ o.Browser = { ie: s, ielt9: s && !e.addEventListener, webkit: r, gecko: u, android: -1 !== i.indexOf("android"), android23: h, chrome: l, safari: !l && -1 !== i.indexOf("safari"), ie3d: m, webkit3d: p, gecko3d: f, opera12: g, any3d: !t.L_DISABLE_3D && (m || p || f) && !g && !a, mobile: c, mobileWebkit: c && r, mobileWebkit3d: c && p, mobileOpera: c && t.opera, mobileGecko: c && u, touch: !!v, msPointer: !!d, pointer: !!_, retina: (t.devicePixelRatio || t.screen.deviceXDPI / t.screen.logicalXDPI) > 1 } }(), o.Point = function(t, e, i) { this.x = i ? Math.round(t) : t, this.y = i ? Math.round(e) : e }, o.Point.prototype = { clone: function() { return new o.Point(this.x, this.y) }, add: function(t) { return this.clone()._add(o.point(t)) }, _add: function(t) { return this.x += t.x, this.y += t.y, this }, subtract: function(t) { return this.clone()._subtract(o.point(t)) }, _subtract: function(t) { return this.x -= t.x, this.y -= t.y, this }, divideBy: function(t) { return this.clone()._divideBy(t) }, _divideBy: function(t) { return this.x /= t, this.y /= t, this }, multiplyBy: function(t) { return this.clone()._multiplyBy(t) }, _multiplyBy: function(t) { return this.x *= t, this.y *= t, this }, scaleBy: function(t) { return new o.Point(this.x * t.x, this.y * t.y) }, unscaleBy: function(t) { return new o.Point(this.x / t.x, this.y / t.y) }, round: function() { return this.clone()._round() }, _round: function() { return this.x = Math.round(this.x), this.y = Math.round(this.y), this }, floor: function() { return this.clone()._floor() }, _floor: function() { return this.x = Math.floor(this.x), this.y = Math.floor(this.y), this }, ceil: function() { return this.clone()._ceil() }, _ceil: function() { return this.x = Math.ceil(this.x), this.y = Math.ceil(this.y), this }, distanceTo: function(t) { t = o.point(t); var e = t.x - this.x,
+ i = t.y - this.y; return Math.sqrt(e * e + i * i) }, equals: function(t) { return t = o.point(t), t.x === this.x && t.y === this.y }, contains: function(t) { return t = o.point(t), Math.abs(t.x) <= Math.abs(this.x) && Math.abs(t.y) <= Math.abs(this.y) }, toString: function() { return "Point(" + o.Util.formatNum(this.x) + ", " + o.Util.formatNum(this.y) + ")" } }, o.point = function(t, e, n) { return t instanceof o.Point ? t : o.Util.isArray(t) ? new o.Point(t[0], t[1]) : t === i || null === t ? t : new o.Point(t, e, n) }, o.Bounds = function(t, e) { if (t)
+ for (var i = e ? [t, e] : t, n = 0, o = i.length; o > n; n++) this.extend(i[n]) }, o.Bounds.prototype = { extend: function(t) { return t = o.point(t), this.min || this.max ? (this.min.x = Math.min(t.x, this.min.x), this.max.x = Math.max(t.x, this.max.x), this.min.y = Math.min(t.y, this.min.y), this.max.y = Math.max(t.y, this.max.y)) : (this.min = t.clone(), this.max = t.clone()), this }, getCenter: function(t) { return new o.Point((this.min.x + this.max.x) / 2, (this.min.y + this.max.y) / 2, t) }, getBottomLeft: function() { return new o.Point(this.min.x, this.max.y) }, getTopRight: function() { return new o.Point(this.max.x, this.min.y) }, getSize: function() { return this.max.subtract(this.min) }, contains: function(t) { var e, i; return t = "number" == typeof t[0] || t instanceof o.Point ? o.point(t) : o.bounds(t), t instanceof o.Bounds ? (e = t.min, i = t.max) : e = i = t, e.x >= this.min.x && i.x <= this.max.x && e.y >= this.min.y && i.y <= this.max.y }, intersects: function(t) { t = o.bounds(t); var e = this.min,
+ i = this.max,
+ n = t.min,
+ s = t.max,
+ r = s.x >= e.x && n.x <= i.x,
+ a = s.y >= e.y && n.y <= i.y; return r && a }, overlaps: function(t) { t = o.bounds(t); var e = this.min,
+ i = this.max,
+ n = t.min,
+ s = t.max,
+ r = s.x > e.x && n.x < i.x,
+ a = s.y > e.y && n.y < i.y; return r && a }, isValid: function() { return !(!this.min || !this.max) } }, o.bounds = function(t, e) { return !t || t instanceof o.Bounds ? t : new o.Bounds(t, e) }, o.Transformation = function(t, e, i, n) { this._a = t, this._b = e, this._c = i, this._d = n }, o.Transformation.prototype = { transform: function(t, e) { return this._transform(t.clone(), e) }, _transform: function(t, e) { return e = e || 1, t.x = e * (this._a * t.x + this._b), t.y = e * (this._c * t.y + this._d), t }, untransform: function(t, e) { return e = e || 1, new o.Point((t.x / e - this._b) / this._a, (t.y / e - this._d) / this._c) } }, o.DomUtil = { get: function(t) { return "string" == typeof t ? e.getElementById(t) : t }, getStyle: function(t, i) { var n = t.style[i] || t.currentStyle && t.currentStyle[i]; if ((!n || "auto" === n) && e.defaultView) { var o = e.defaultView.getComputedStyle(t, null);
+ n = o ? o[i] : null } return "auto" === n ? null : n }, create: function(t, i, n) { var o = e.createElement(t); return o.className = i, n && n.appendChild(o), o }, remove: function(t) { var e = t.parentNode;
+ e && e.removeChild(t) }, empty: function(t) { for (; t.firstChild;) t.removeChild(t.firstChild) }, toFront: function(t) { t.parentNode.appendChild(t) }, toBack: function(t) { var e = t.parentNode;
+ e.insertBefore(t, e.firstChild) }, hasClass: function(t, e) { if (t.classList !== i) return t.classList.contains(e); var n = o.DomUtil.getClass(t); return n.length > 0 && new RegExp("(^|\\s)" + e + "(\\s|$)").test(n) }, addClass: function(t, e) { if (t.classList !== i)
+ for (var n = o.Util.splitWords(e), s = 0, r = n.length; r > s; s++) t.classList.add(n[s]);
+ else if (!o.DomUtil.hasClass(t, e)) { var a = o.DomUtil.getClass(t);
+ o.DomUtil.setClass(t, (a ? a + " " : "") + e) } }, removeClass: function(t, e) { t.classList !== i ? t.classList.remove(e) : o.DomUtil.setClass(t, o.Util.trim((" " + o.DomUtil.getClass(t) + " ").replace(" " + e + " ", " "))) }, setClass: function(t, e) { t.className.baseVal === i ? t.className = e : t.className.baseVal = e }, getClass: function(t) { return t.className.baseVal === i ? t.className : t.className.baseVal }, setOpacity: function(t, e) { "opacity" in t.style ? t.style.opacity = e : "filter" in t.style && o.DomUtil._setOpacityIE(t, e) }, _setOpacityIE: function(t, e) { var i = !1,
+ n = "DXImageTransform.Microsoft.Alpha"; try { i = t.filters.item(n) } catch (o) { if (1 === e) return }
+ e = Math.round(100 * e), i ? (i.Enabled = 100 !== e, i.Opacity = e) : t.style.filter += " progid:" + n + "(opacity=" + e + ")" }, testProp: function(t) { for (var i = e.documentElement.style, n = 0; n < t.length; n++)
+ if (t[n] in i) return t[n];
+ return !1 }, setTransform: function(t, e, i) { var n = e || new o.Point(0, 0);
+ t.style[o.DomUtil.TRANSFORM] = (o.Browser.ie3d ? "translate(" + n.x + "px," + n.y + "px)" : "translate3d(" + n.x + "px," + n.y + "px,0)") + (i ? " scale(" + i + ")" : "") }, setPosition: function(t, e) { t._leaflet_pos = e, o.Browser.any3d ? o.DomUtil.setTransform(t, e) : (t.style.left = e.x + "px", t.style.top = e.y + "px") }, getPosition: function(t) { return t._leaflet_pos } },
+ function() { o.DomUtil.TRANSFORM = o.DomUtil.testProp(["transform", "WebkitTransform", "OTransform", "MozTransform", "msTransform"]); var i = o.DomUtil.TRANSITION = o.DomUtil.testProp(["webkitTransition", "transition", "OTransition", "MozTransition", "msTransition"]); if (o.DomUtil.TRANSITION_END = "webkitTransition" === i || "OTransition" === i ? i + "End" : "transitionend", "onselectstart" in e) o.DomUtil.disableTextSelection = function() { o.DomEvent.on(t, "selectstart", o.DomEvent.preventDefault) }, o.DomUtil.enableTextSelection = function() { o.DomEvent.off(t, "selectstart", o.DomEvent.preventDefault) };
+ else { var n = o.DomUtil.testProp(["userSelect", "WebkitUserSelect", "OUserSelect", "MozUserSelect", "msUserSelect"]);
+ o.DomUtil.disableTextSelection = function() { if (n) { var t = e.documentElement.style;
+ this._userSelect = t[n], t[n] = "none" } }, o.DomUtil.enableTextSelection = function() { n && (e.documentElement.style[n] = this._userSelect, delete this._userSelect) } }
+ o.DomUtil.disableImageDrag = function() { o.DomEvent.on(t, "dragstart", o.DomEvent.preventDefault) }, o.DomUtil.enableImageDrag = function() { o.DomEvent.off(t, "dragstart", o.DomEvent.preventDefault) }, o.DomUtil.preventOutline = function(e) { for (; - 1 === e.tabIndex;) e = e.parentNode;
+ e && e.style && (o.DomUtil.restoreOutline(), this._outlineElement = e, this._outlineStyle = e.style.outline, e.style.outline = "none", o.DomEvent.on(t, "keydown", o.DomUtil.restoreOutline, this)) }, o.DomUtil.restoreOutline = function() { this._outlineElement && (this._outlineElement.style.outline = this._outlineStyle, delete this._outlineElement, delete this._outlineStyle, o.DomEvent.off(t, "keydown", o.DomUtil.restoreOutline, this)) } }(), o.LatLng = function(t, e, n) { if (isNaN(t) || isNaN(e)) throw new Error("Invalid LatLng object: (" + t + ", " + e + ")");
+ this.lat = +t, this.lng = +e, n !== i && (this.alt = +n) }, o.LatLng.prototype = { equals: function(t, e) { if (!t) return !1;
+ t = o.latLng(t); var n = Math.max(Math.abs(this.lat - t.lat), Math.abs(this.lng - t.lng)); return (e === i ? 1e-9 : e) >= n }, toString: function(t) { return "LatLng(" + o.Util.formatNum(this.lat, t) + ", " + o.Util.formatNum(this.lng, t) + ")" }, distanceTo: function(t) { return o.CRS.Earth.distance(this, o.latLng(t)) }, wrap: function() { return o.CRS.Earth.wrapLatLng(this) }, toBounds: function(t) { var e = 180 * t / 40075017,
+ i = e / Math.cos(Math.PI / 180 * this.lat); return o.latLngBounds([this.lat - e, this.lng - i], [this.lat + e, this.lng + i]) }, clone: function() { return new o.LatLng(this.lat, this.lng, this.alt) } }, o.latLng = function(t, e, n) { return t instanceof o.LatLng ? t : o.Util.isArray(t) && "object" != typeof t[0] ? 3 === t.length ? new o.LatLng(t[0], t[1], t[2]) : 2 === t.length ? new o.LatLng(t[0], t[1]) : null : t === i || null === t ? t : "object" == typeof t && "lat" in t ? new o.LatLng(t.lat, "lng" in t ? t.lng : t.lon, t.alt) : e === i ? null : new o.LatLng(t, e, n) }, o.LatLngBounds = function(t, e) { if (t)
+ for (var i = e ? [t, e] : t, n = 0, o = i.length; o > n; n++) this.extend(i[n]) }, o.LatLngBounds.prototype = { extend: function(t) { var e, i, n = this._southWest,
+ s = this._northEast; if (t instanceof o.LatLng) e = t, i = t;
+ else { if (!(t instanceof o.LatLngBounds)) return t ? this.extend(o.latLng(t) || o.latLngBounds(t)) : this; if (e = t._southWest, i = t._northEast, !e || !i) return this } return n || s ? (n.lat = Math.min(e.lat, n.lat), n.lng = Math.min(e.lng, n.lng), s.lat = Math.max(i.lat, s.lat), s.lng = Math.max(i.lng, s.lng)) : (this._southWest = new o.LatLng(e.lat, e.lng), this._northEast = new o.LatLng(i.lat, i.lng)), this }, pad: function(t) { var e = this._southWest,
+ i = this._northEast,
+ n = Math.abs(e.lat - i.lat) * t,
+ s = Math.abs(e.lng - i.lng) * t; return new o.LatLngBounds(new o.LatLng(e.lat - n, e.lng - s), new o.LatLng(i.lat + n, i.lng + s)) }, getCenter: function() { return new o.LatLng((this._southWest.lat + this._northEast.lat) / 2, (this._southWest.lng + this._northEast.lng) / 2) }, getSouthWest: function() { return this._southWest }, getNorthEast: function() { return this._northEast }, getNorthWest: function() { return new o.LatLng(this.getNorth(), this.getWest()) }, getSouthEast: function() { return new o.LatLng(this.getSouth(), this.getEast()) }, getWest: function() { return this._southWest.lng }, getSouth: function() { return this._southWest.lat }, getEast: function() { return this._northEast.lng }, getNorth: function() { return this._northEast.lat }, contains: function(t) { t = "number" == typeof t[0] || t instanceof o.LatLng ? o.latLng(t) : o.latLngBounds(t); var e, i, n = this._southWest,
+ s = this._northEast; return t instanceof o.LatLngBounds ? (e = t.getSouthWest(), i = t.getNorthEast()) : e = i = t, e.lat >= n.lat && i.lat <= s.lat && e.lng >= n.lng && i.lng <= s.lng }, intersects: function(t) { t = o.latLngBounds(t); var e = this._southWest,
+ i = this._northEast,
+ n = t.getSouthWest(),
+ s = t.getNorthEast(),
+ r = s.lat >= e.lat && n.lat <= i.lat,
+ a = s.lng >= e.lng && n.lng <= i.lng; return r && a }, overlaps: function(t) { t = o.latLngBounds(t); var e = this._southWest,
+ i = this._northEast,
+ n = t.getSouthWest(),
+ s = t.getNorthEast(),
+ r = s.lat > e.lat && n.lat < i.lat,
+ a = s.lng > e.lng && n.lng < i.lng; return r && a }, toBBoxString: function() { return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(",") }, equals: function(t) { return t ? (t = o.latLngBounds(t), this._southWest.equals(t.getSouthWest()) && this._northEast.equals(t.getNorthEast())) : !1 }, isValid: function() { return !(!this._southWest || !this._northEast) } }, o.latLngBounds = function(t, e) { return !t || t instanceof o.LatLngBounds ? t : new o.LatLngBounds(t, e) }, o.Projection = {}, o.Projection.LonLat = { project: function(t) { return new o.Point(t.lng, t.lat) }, unproject: function(t) { return new o.LatLng(t.y, t.x) }, bounds: o.bounds([-180, -90], [180, 90]) }, o.Projection.SphericalMercator = { R: 6378137, MAX_LATITUDE: 85.0511287798, project: function(t) { var e = Math.PI / 180,
+ i = this.MAX_LATITUDE,
+ n = Math.max(Math.min(i, t.lat), -i),
+ s = Math.sin(n * e); return new o.Point(this.R * t.lng * e, this.R * Math.log((1 + s) / (1 - s)) / 2) }, unproject: function(t) { var e = 180 / Math.PI; return new o.LatLng((2 * Math.atan(Math.exp(t.y / this.R)) - Math.PI / 2) * e, t.x * e / this.R) }, bounds: function() { var t = 6378137 * Math.PI; return o.bounds([-t, -t], [t, t]) }() }, o.CRS = { latLngToPoint: function(t, e) { var i = this.projection.project(t),
+ n = this.scale(e); return this.transformation._transform(i, n) }, pointToLatLng: function(t, e) { var i = this.scale(e),
+ n = this.transformation.untransform(t, i); return this.projection.unproject(n) }, project: function(t) { return this.projection.project(t) }, unproject: function(t) { return this.projection.unproject(t) }, scale: function(t) { return 256 * Math.pow(2, t) }, zoom: function(t) { return Math.log(t / 256) / Math.LN2 }, getProjectedBounds: function(t) { if (this.infinite) return null; var e = this.projection.bounds,
+ i = this.scale(t),
+ n = this.transformation.transform(e.min, i),
+ s = this.transformation.transform(e.max, i); return o.bounds(n, s) }, wrapLatLng: function(t) { var e = this.wrapLng ? o.Util.wrapNum(t.lng, this.wrapLng, !0) : t.lng,
+ i = this.wrapLat ? o.Util.wrapNum(t.lat, this.wrapLat, !0) : t.lat,
+ n = t.alt; return o.latLng(i, e, n) } }, o.CRS.Simple = o.extend({}, o.CRS, { projection: o.Projection.LonLat, transformation: new o.Transformation(1, 0, -1, 0), scale: function(t) { return Math.pow(2, t) }, zoom: function(t) { return Math.log(t) / Math.LN2 }, distance: function(t, e) { var i = e.lng - t.lng,
+ n = e.lat - t.lat; return Math.sqrt(i * i + n * n) }, infinite: !0 }), o.CRS.Earth = o.extend({}, o.CRS, { wrapLng: [-180, 180], R: 6378137, distance: function(t, e) { var i = Math.PI / 180,
+ n = t.lat * i,
+ o = e.lat * i,
+ s = Math.sin(n) * Math.sin(o) + Math.cos(n) * Math.cos(o) * Math.cos((e.lng - t.lng) * i); return this.R * Math.acos(Math.min(s, 1)) } }), o.CRS.EPSG3857 = o.extend({}, o.CRS.Earth, { code: "EPSG:3857", projection: o.Projection.SphericalMercator, transformation: function() { var t = .5 / (Math.PI * o.Projection.SphericalMercator.R); return new o.Transformation(t, .5, -t, .5) }() }), o.CRS.EPSG900913 = o.extend({}, o.CRS.EPSG3857, { code: "EPSG:900913" }), o.CRS.EPSG4326 = o.extend({}, o.CRS.Earth, { code: "EPSG:4326", projection: o.Projection.LonLat, transformation: new o.Transformation(1 / 180, 1, -1 / 180, .5) }), o.Map = o.Evented.extend({
+ options: { crs: o.CRS.EPSG3857, fadeAnimation: !0, trackResize: !0, markerZoomAnimation: !0, maxBoundsViscosity: 0, transform3DLimit: 8388608 },
+ initialize: function(t, e) { e = o.setOptions(this, e), this._initContainer(t), this._initLayout(), this._onResize = o.bind(this._onResize, this), this._initEvents(), e.maxBounds && this.setMaxBounds(e.maxBounds), e.zoom !== i && (this._zoom = this._limitZoom(e.zoom)), e.center && e.zoom !== i && this.setView(o.latLng(e.center), e.zoom, { reset: !0 }), this._handlers = [], this._layers = {}, this._zoomBoundLayers = {}, this._sizeChanged = !0, this.callInitHooks(), this._addLayers(this.options.layers) },
+ setView: function(t, e) { return e = e === i ? this.getZoom() : e, this._resetView(o.latLng(t), e), this },
+ setZoom: function(t, e) { return this._loaded ? this.setView(this.getCenter(), t, { zoom: e }) : (this._zoom = t, this) },
+ zoomIn: function(t, e) { return this.setZoom(this._zoom + (t || 1), e) },
+ zoomOut: function(t, e) { return this.setZoom(this._zoom - (t || 1), e) },
+ setZoomAround: function(t, e, i) { var n = this.getZoomScale(e),
+ s = this.getSize().divideBy(2),
+ r = t instanceof o.Point ? t : this.latLngToContainerPoint(t),
+ a = r.subtract(s).multiplyBy(1 - 1 / n),
+ h = this.containerPointToLatLng(s.add(a)); return this.setView(h, e, { zoom: i }) },
+ _getBoundsCenterZoom: function(t, e) { e = e || {}, t = t.getBounds ? t.getBounds() : o.latLngBounds(t); var i = o.point(e.paddingTopLeft || e.padding || [0, 0]),
+ n = o.point(e.paddingBottomRight || e.padding || [0, 0]),
+ s = this.getBoundsZoom(t, !1, i.add(n));
+ s = e.maxZoom ? Math.min(e.maxZoom, s) : s; var r = n.subtract(i).divideBy(2),
+ a = this.project(t.getSouthWest(), s),
+ h = this.project(t.getNorthEast(), s),
+ l = this.unproject(a.add(h).divideBy(2).add(r), s); return { center: l, zoom: s } },
+ fitBounds: function(t, e) { var i = this._getBoundsCenterZoom(t, e); return this.setView(i.center, i.zoom, e) },
+ fitWorld: function(t) { return this.fitBounds([
+ [-90, -180],
+ [90, 180]
+ ], t) },
+ panTo: function(t, e) { return this.setView(t, this._zoom, { pan: e }) },
+ panBy: function(t) { return this.fire("movestart"), this._rawPanBy(o.point(t)), this.fire("move"), this.fire("moveend") },
+ setMaxBounds: function(t) { return (t = o.latLngBounds(t)) ? (this.options.maxBounds && this.off("moveend", this._panInsideMaxBounds), this.options.maxBounds = t, this._loaded && this._panInsideMaxBounds(), this.on("moveend", this._panInsideMaxBounds)) : this.off("moveend", this._panInsideMaxBounds) },
+ setMinZoom: function(t) { return this.options.minZoom = t, this._loaded && this.getZoom() < this.options.minZoom ? this.setZoom(t) : this },
+ setMaxZoom: function(t) { return this.options.maxZoom = t, this._loaded && this.getZoom() > this.options.maxZoom ? this.setZoom(t) : this },
+ panInsideBounds: function(t, e) { this._enforcingBounds = !0; var i = this.getCenter(),
+ n = this._limitCenter(i, this._zoom, o.latLngBounds(t)); return i.equals(n) ? this : (this.panTo(n, e), this._enforcingBounds = !1, this) },
+ invalidateSize: function(t) { if (!this._loaded) return this;
+ t = o.extend({ animate: !1, pan: !0 }, t === !0 ? { animate: !0 } : t); var e = this.getSize();
+ this._sizeChanged = !0, this._lastCenter = null; var i = this.getSize(),
+ n = e.divideBy(2).round(),
+ s = i.divideBy(2).round(),
+ r = n.subtract(s); return r.x || r.y ? (t.animate && t.pan ? this.panBy(r) : (t.pan && this._rawPanBy(r), this.fire("move"), t.debounceMoveend ? (clearTimeout(this._sizeTimer), this._sizeTimer = setTimeout(o.bind(this.fire, this, "moveend"), 200)) : this.fire("moveend")), this.fire("resize", { oldSize: e, newSize: i })) : this },
+ stop: function() { return o.Util.cancelAnimFrame(this._flyToFrame), this._panAnim && this._panAnim.stop(), this },
+ addHandler: function(t, e) { if (!e) return this; var i = this[t] = new e(this); return this._handlers.push(i), this.options[t] && i.enable(), this },
+ remove: function() { this._initEvents(!0); try { delete this._container._leaflet } catch (t) { this._container._leaflet = i }
+ o.DomUtil.remove(this._mapPane), this._clearControlPos && this._clearControlPos(), this._clearHandlers(), this._loaded && this.fire("unload"); for (var e in this._layers) this._layers[e].remove(); return this },
+ createPane: function(t, e) { var i = "leaflet-pane" + (t ? " leaflet-" + t.replace("Pane", "") + "-pane" : ""),
+ n = o.DomUtil.create("div", i, e || this._mapPane); return t && (this._panes[t] = n), n },
+ getCenter: function() { return this._checkIfLoaded(), this._lastCenter && !this._moved() ? this._lastCenter : this.layerPointToLatLng(this._getCenterLayerPoint()) },
+ getZoom: function() { return this._zoom },
+ getBounds: function() { var t = this.getPixelBounds(),
+ e = this.unproject(t.getBottomLeft()),
+ i = this.unproject(t.getTopRight()); return new o.LatLngBounds(e, i) },
+ getMinZoom: function() { return this.options.minZoom === i ? this._layersMinZoom || 0 : this.options.minZoom },
+ getMaxZoom: function() { return this.options.maxZoom === i ? this._layersMaxZoom === i ? 1 / 0 : this._layersMaxZoom : this.options.maxZoom },
+ getBoundsZoom: function(t, e, i) { t = o.latLngBounds(t); var n, s = this.getMinZoom() - (e ? 1 : 0),
+ r = this.getMaxZoom(),
+ a = this.getSize(),
+ h = t.getNorthWest(),
+ l = t.getSouthEast(),
+ u = !0;
+ i = o.point(i || [0, 0]);
+ do s++, n = this.project(l, s).subtract(this.project(h, s)).add(i).floor(), u = e ? n.x < a.x || n.y < a.y : a.contains(n); while (u && r >= s); return u && e ? null : e ? s : s - 1 },
+ getSize: function() { return (!this._size || this._sizeChanged) && (this._size = new o.Point(this._container.clientWidth, this._container.clientHeight), this._sizeChanged = !1), this._size.clone() },
+ getPixelBounds: function(t, e) { var i = this._getTopLeftPoint(t, e); return new o.Bounds(i, i.add(this.getSize())) },
+ getPixelOrigin: function() { return this._checkIfLoaded(), this._pixelOrigin },
+ getPixelWorldBounds: function(t) { return this.options.crs.getProjectedBounds(t === i ? this.getZoom() : t) },
+ getPane: function(t) { return "string" == typeof t ? this._panes[t] : t },
+ getPanes: function() { return this._panes },
+ getContainer: function() { return this._container },
+ getZoomScale: function(t, e) { var n = this.options.crs; return e = e === i ? this._zoom : e, n.scale(t) / n.scale(e) },
+ getScaleZoom: function(t, e) { var n = this.options.crs; return e = e === i ? this._zoom : e, n.zoom(t * n.scale(e)) },
+ project: function(t, e) { return e = e === i ? this._zoom : e, this.options.crs.latLngToPoint(o.latLng(t), e) },
+ unproject: function(t, e) { return e = e === i ? this._zoom : e, this.options.crs.pointToLatLng(o.point(t), e) },
+ layerPointToLatLng: function(t) { var e = o.point(t).add(this.getPixelOrigin()); return this.unproject(e) },
+ latLngToLayerPoint: function(t) { var e = this.project(o.latLng(t))._round(); return e._subtract(this.getPixelOrigin()) },
+ wrapLatLng: function(t) { return this.options.crs.wrapLatLng(o.latLng(t)) },
+ distance: function(t, e) { return this.options.crs.distance(o.latLng(t), o.latLng(e)) },
+ containerPointToLayerPoint: function(t) { return o.point(t).subtract(this._getMapPanePos()) },
+ layerPointToContainerPoint: function(t) { return o.point(t).add(this._getMapPanePos()) },
+ containerPointToLatLng: function(t) { var e = this.containerPointToLayerPoint(o.point(t)); return this.layerPointToLatLng(e) },
+ latLngToContainerPoint: function(t) { return this.layerPointToContainerPoint(this.latLngToLayerPoint(o.latLng(t))) },
+ mouseEventToContainerPoint: function(t) { return o.DomEvent.getMousePosition(t, this._container) },
+ mouseEventToLayerPoint: function(t) { return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t)) },
+ mouseEventToLatLng: function(t) { return this.layerPointToLatLng(this.mouseEventToLayerPoint(t)) },
+ _initContainer: function(t) { var e = this._container = o.DomUtil.get(t); if (!e) throw new Error("Map container not found."); if (e._leaflet) throw new Error("Map container is already initialized.");
+ o.DomEvent.addListener(e, "scroll", this._onScroll, this), e._leaflet = !0 },
+ _initLayout: function() { var t = this._container;
+ this._fadeAnimated = this.options.fadeAnimation && o.Browser.any3d, o.DomUtil.addClass(t, "leaflet-container" + (o.Browser.touch ? " leaflet-touch" : "") + (o.Browser.retina ? " leaflet-retina" : "") + (o.Browser.ielt9 ? " leaflet-oldie" : "") + (o.Browser.safari ? " leaflet-safari" : "") + (this._fadeAnimated ? " leaflet-fade-anim" : "")); var e = o.DomUtil.getStyle(t, "position"); "absolute" !== e && "relative" !== e && "fixed" !== e && (t.style.position = "relative"), this._initPanes(), this._initControlPos && this._initControlPos() },
+ _initPanes: function() { var t = this._panes = {};
+ this._paneRenderers = {}, this._mapPane = this.createPane("mapPane", this._container), o.DomUtil.setPosition(this._mapPane, new o.Point(0, 0)), this.createPane("tilePane"), this.createPane("shadowPane"), this.createPane("overlayPane"), this.createPane("markerPane"), this.createPane("popupPane"), this.options.markerZoomAnimation || (o.DomUtil.addClass(t.markerPane, "leaflet-zoom-hide"), o.DomUtil.addClass(t.shadowPane, "leaflet-zoom-hide")) },
+ _resetView: function(t, e) { o.DomUtil.setPosition(this._mapPane, new o.Point(0, 0)); var i = !this._loaded;
+ this._loaded = !0, e = this._limitZoom(e); var n = this._zoom !== e;
+ this._moveStart(n)._move(t, e)._moveEnd(n), this.fire("viewreset"), i && this.fire("load") },
+ _moveStart: function(t) { return t && this.fire("zoomstart"), this.fire("movestart") },
+ _move: function(t, e, n) { e === i && (e = this._zoom); var o = this._zoom !== e; return this._zoom = e, this._lastCenter = t, this._pixelOrigin = this._getNewPixelOrigin(t), o && this.fire("zoom", n), this.fire("move", n) },
+ _moveEnd: function(t) { return t && this.fire("zoomend"), this.fire("moveend") },
+ _rawPanBy: function(t) { o.DomUtil.setPosition(this._mapPane, this._getMapPanePos().subtract(t)) },
+ _getZoomSpan: function() { return this.getMaxZoom() - this.getMinZoom() },
+ _panInsideMaxBounds: function() { this._enforcingBounds || this.panInsideBounds(this.options.maxBounds) },
+ _checkIfLoaded: function() { if (!this._loaded) throw new Error("Set map center and zoom first.") },
+ _initEvents: function(e) { if (o.DomEvent) { this._targets = {}, this._targets[o.stamp(this._container)] = this; var i = e ? "off" : "on";
+ o.DomEvent[i](this._container, "click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress", this._handleDOMEvent, this), this.options.trackResize && o.DomEvent[i](t, "resize", this._onResize, this), o.Browser.any3d && this.options.transform3DLimit && this[i]("moveend", this._onMoveEnd) } },
+ _onResize: function() { o.Util.cancelAnimFrame(this._resizeRequest), this._resizeRequest = o.Util.requestAnimFrame(function() { this.invalidateSize({ debounceMoveend: !0 }) }, this) },
+ _onScroll: function() { this._container.scrollTop = 0, this._container.scrollLeft = 0 },
+ _onMoveEnd: function() { var t = this._getMapPanePos();
+ Math.max(Math.abs(t.x), Math.abs(t.y)) >= this.options.transform3DLimit && this._resetView(this.getCenter(), this.getZoom()) },
+ _findEventTargets: function(t, e) { for (var i, n = [], s = "mouseout" === e || "mouseover" === e, r = t.target || t.srcElement; r;) { if (i = this._targets[o.stamp(r)], i && i.listens(e, !0)) { if (s && !o.DomEvent._isExternalTarget(r, t)) break; if (n.push(i), s) break } if (r === this._container) break;
+ r = r.parentNode } return n.length || s || !o.DomEvent._isExternalTarget(r, t) || (n = [this]), n },
+ _handleDOMEvent: function(t) { if (this._loaded && !o.DomEvent._skipped(t)) { var e = "keypress" === t.type && 13 === t.keyCode ? "click" : t.type; if ("click" === t.type) { var i = o.Util.extend({}, t);
+ i.type = "preclick", this._handleDOMEvent(i) } "mousedown" === e && o.DomUtil.preventOutline(t.target || t.srcElement), this._fireDOMEvent(t, e) } },
+ _fireDOMEvent: function(t, e, i) { if (!t._stopped && (i = (i || []).concat(this._findEventTargets(t, e)), i.length)) { var n = i[0]; if ("contextmenu" === e && n.listens(e, !0) && o.DomEvent.preventDefault(t), "click" !== t.type && "preclick" !== t.type || t._simulated || !this._draggableMoved(n)) { var s = { originalEvent: t }; if ("keypress" !== t.type) { var r = n instanceof o.Marker;
+ s.containerPoint = r ? this.latLngToContainerPoint(n.getLatLng()) : this.mouseEventToContainerPoint(t), s.layerPoint = this.containerPointToLayerPoint(s.containerPoint), s.latlng = r ? n.getLatLng() : this.layerPointToLatLng(s.layerPoint) } for (var a = 0; a < i.length; a++)
+ if (i[a].fire(e, s, !0), s.originalEvent._stopped || i[a].options.nonBubblingEvents && -1 !== o.Util.indexOf(i[a].options.nonBubblingEvents, e)) return } } },
+ _draggableMoved: function(t) { return t = t.options.draggable ? t : this, t.dragging && t.dragging.moved() || this.boxZoom && this.boxZoom.moved() },
+ _clearHandlers: function() { for (var t = 0, e = this._handlers.length; e > t; t++) this._handlers[t].disable() },
+ whenReady: function(t, e) { return this._loaded ? t.call(e || this, { target: this }) : this.on("load", t, e), this },
+ _getMapPanePos: function() { return o.DomUtil.getPosition(this._mapPane) || new o.Point(0, 0) },
+ _moved: function() { var t = this._getMapPanePos(); return t && !t.equals([0, 0]) },
+ _getTopLeftPoint: function(t, e) { var n = t && e !== i ? this._getNewPixelOrigin(t, e) : this.getPixelOrigin(); return n.subtract(this._getMapPanePos()) },
+ _getNewPixelOrigin: function(t, e) { var i = this.getSize()._divideBy(2); return this.project(t, e)._subtract(i)._add(this._getMapPanePos())._round() },
+ _latLngToNewLayerPoint: function(t, e, i) {
+ var n = this._getNewPixelOrigin(i, e);
+ return this.project(t, e)._subtract(n)
+ },
+ _getCenterLayerPoint: function() { return this.containerPointToLayerPoint(this.getSize()._divideBy(2)) },
+ _getCenterOffset: function(t) { return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint()) },
+ _limitCenter: function(t, e, i) { if (!i) return t; var n = this.project(t, e),
+ s = this.getSize().divideBy(2),
+ r = new o.Bounds(n.subtract(s), n.add(s)),
+ a = this._getBoundsOffset(r, i, e); return this.unproject(n.add(a), e) },
+ _limitOffset: function(t, e) { if (!e) return t; var i = this.getPixelBounds(),
+ n = new o.Bounds(i.min.add(t), i.max.add(t)); return t.add(this._getBoundsOffset(n, e)) },
+ _getBoundsOffset: function(t, e, i) { var n = this.project(e.getNorthWest(), i).subtract(t.min),
+ s = this.project(e.getSouthEast(), i).subtract(t.max),
+ r = this._rebound(n.x, -s.x),
+ a = this._rebound(n.y, -s.y); return new o.Point(r, a) },
+ _rebound: function(t, e) { return t + e > 0 ? Math.round(t - e) / 2 : Math.max(0, Math.ceil(t)) - Math.max(0, Math.floor(e)) },
+ _limitZoom: function(t) { var e = this.getMinZoom(),
+ i = this.getMaxZoom(); return o.Browser.any3d || (t = Math.round(t)), Math.max(e, Math.min(i, t)) }
+ }), o.map = function(t, e) { return new o.Map(t, e) }, o.Layer = o.Evented.extend({ options: { pane: "overlayPane", nonBubblingEvents: [] }, addTo: function(t) { return t.addLayer(this), this }, remove: function() { return this.removeFrom(this._map || this._mapToAdd) }, removeFrom: function(t) { return t && t.removeLayer(this), this }, getPane: function(t) { return this._map.getPane(t ? this.options[t] || t : this.options.pane) }, addInteractiveTarget: function(t) { return this._map._targets[o.stamp(t)] = this, this }, removeInteractiveTarget: function(t) { return delete this._map._targets[o.stamp(t)], this }, _layerAdd: function(t) { var e = t.target;
+ e.hasLayer(this) && (this._map = e, this._zoomAnimated = e._zoomAnimated, this.getEvents && e.on(this.getEvents(), this), this.onAdd(e), this.getAttribution && this._map.attributionControl && this._map.attributionControl.addAttribution(this.getAttribution()), this.fire("add"), e.fire("layeradd", { layer: this })) } }), o.Map.include({ addLayer: function(t) { var e = o.stamp(t); return this._layers[e] ? t : (this._layers[e] = t, t._mapToAdd = this, t.beforeAdd && t.beforeAdd(this), this.whenReady(t._layerAdd, t), this) }, removeLayer: function(t) { var e = o.stamp(t); return this._layers[e] ? (this._loaded && t.onRemove(this), t.getAttribution && this.attributionControl && this.attributionControl.removeAttribution(t.getAttribution()), t.getEvents && this.off(t.getEvents(), t), delete this._layers[e], this._loaded && (this.fire("layerremove", { layer: t }), t.fire("remove")), t._map = t._mapToAdd = null, this) : this }, hasLayer: function(t) { return !!t && o.stamp(t) in this._layers }, eachLayer: function(t, e) { for (var i in this._layers) t.call(e, this._layers[i]); return this }, _addLayers: function(t) { t = t ? o.Util.isArray(t) ? t : [t] : []; for (var e = 0, i = t.length; i > e; e++) this.addLayer(t[e]) }, _addZoomLimit: function(t) {
+ (isNaN(t.options.maxZoom) || !isNaN(t.options.minZoom)) && (this._zoomBoundLayers[o.stamp(t)] = t, this._updateZoomLevels()) }, _removeZoomLimit: function(t) { var e = o.stamp(t);
+ this._zoomBoundLayers[e] && (delete this._zoomBoundLayers[e], this._updateZoomLevels()) }, _updateZoomLevels: function() { var t = 1 / 0,
+ e = -(1 / 0),
+ n = this._getZoomSpan(); for (var o in this._zoomBoundLayers) { var s = this._zoomBoundLayers[o].options;
+ t = s.minZoom === i ? t : Math.min(t, s.minZoom), e = s.maxZoom === i ? e : Math.max(e, s.maxZoom) }
+ this._layersMaxZoom = e === -(1 / 0) ? i : e, this._layersMinZoom = t === 1 / 0 ? i : t, n !== this._getZoomSpan() && this.fire("zoomlevelschange") } }), o.Projection.Mercator = { R: 6378137, R_MINOR: 6356752.314245179, bounds: o.bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]), project: function(t) { var e = Math.PI / 180,
+ i = this.R,
+ n = t.lat * e,
+ s = this.R_MINOR / i,
+ r = Math.sqrt(1 - s * s),
+ a = r * Math.sin(n),
+ h = Math.tan(Math.PI / 4 - n / 2) / Math.pow((1 - a) / (1 + a), r / 2); return n = -i * Math.log(Math.max(h, 1e-10)), new o.Point(t.lng * e * i, n) }, unproject: function(t) { for (var e, i = 180 / Math.PI, n = this.R, s = this.R_MINOR / n, r = Math.sqrt(1 - s * s), a = Math.exp(-t.y / n), h = Math.PI / 2 - 2 * Math.atan(a), l = 0, u = .1; 15 > l && Math.abs(u) > 1e-7; l++) e = r * Math.sin(h), e = Math.pow((1 - e) / (1 + e), r / 2), u = Math.PI / 2 - 2 * Math.atan(a * e) - h, h += u; return new o.LatLng(h * i, t.x * i / n) } }, o.CRS.EPSG3395 = o.extend({}, o.CRS.Earth, { code: "EPSG:3395", projection: o.Projection.Mercator, transformation: function() { var t = .5 / (Math.PI * o.Projection.Mercator.R); return new o.Transformation(t, .5, -t, .5) }() }), o.GridLayer = o.Layer.extend({ options: { pane: "tilePane", tileSize: 256, opacity: 1, zIndex: 1, updateWhenIdle: o.Browser.mobile, updateInterval: 200, attribution: null, bounds: null, minZoom: 0 }, initialize: function(t) { t = o.setOptions(this, t) }, onAdd: function() { this._initContainer(), this._levels = {}, this._tiles = {}, this._resetView(), this._update() }, beforeAdd: function(t) { t._addZoomLimit(this) }, onRemove: function(t) { o.DomUtil.remove(this._container), t._removeZoomLimit(this), this._container = null, this._tileZoom = null }, bringToFront: function() { return this._map && (o.DomUtil.toFront(this._container), this._setAutoZIndex(Math.max)), this }, bringToBack: function() { return this._map && (o.DomUtil.toBack(this._container), this._setAutoZIndex(Math.min)), this }, getAttribution: function() { return this.options.attribution }, getContainer: function() { return this._container }, setOpacity: function(t) { return this.options.opacity = t, this._updateOpacity(), this }, setZIndex: function(t) { return this.options.zIndex = t, this._updateZIndex(), this }, isLoading: function() { return this._loading }, redraw: function() { return this._map && (this._removeAllTiles(), this._update()), this }, getEvents: function() { var t = { viewreset: this._resetAll, zoom: this._resetView, moveend: this._onMoveEnd }; return this.options.updateWhenIdle || (this._onMove || (this._onMove = o.Util.throttle(this._onMoveEnd, this.options.updateInterval, this)), t.move = this._onMove), this._zoomAnimated && (t.zoomanim = this._animateZoom), t }, createTile: function() { return e.createElement("div") }, getTileSize: function() { var t = this.options.tileSize; return t instanceof o.Point ? t : new o.Point(t, t) }, _updateZIndex: function() { this._container && this.options.zIndex !== i && null !== this.options.zIndex && (this._container.style.zIndex = this.options.zIndex) }, _setAutoZIndex: function(t) { for (var e, i = this.getPane().children, n = -t(-(1 / 0), 1 / 0), o = 0, s = i.length; s > o; o++) e = i[o].style.zIndex, i[o] !== this._container && e && (n = t(n, +e));
+ isFinite(n) && (this.options.zIndex = n + t(-1, 1), this._updateZIndex()) }, _updateOpacity: function() { if (this._map && !o.Browser.ielt9 && this._map._fadeAnimated) { o.DomUtil.setOpacity(this._container, this.options.opacity); var t = +new Date,
+ e = !1,
+ i = !1; for (var n in this._tiles) { var s = this._tiles[n]; if (s.current && s.loaded) { var r = Math.min(1, (t - s.loaded) / 200);
+ o.DomUtil.setOpacity(s.el, r), 1 > r ? e = !0 : (s.active && (i = !0), s.active = !0) } }
+ i && !this._noPrune && this._pruneTiles(), e && (o.Util.cancelAnimFrame(this._fadeFrame), this._fadeFrame = o.Util.requestAnimFrame(this._updateOpacity, this)) } }, _initContainer: function() { this._container || (this._container = o.DomUtil.create("div", "leaflet-layer"), this._updateZIndex(), this.options.opacity < 1 && this._updateOpacity(), this.getPane().appendChild(this._container)) }, _updateLevels: function() { var t = this._tileZoom,
+ e = this.options.maxZoom; for (var i in this._levels) this._levels[i].el.children.length || i === t ? this._levels[i].el.style.zIndex = e - Math.abs(t - i) : (o.DomUtil.remove(this._levels[i].el), delete this._levels[i]); var n = this._levels[t],
+ s = this._map; return n || (n = this._levels[t] = {}, n.el = o.DomUtil.create("div", "leaflet-tile-container leaflet-zoom-animated", this._container), n.el.style.zIndex = e, n.origin = s.project(s.unproject(s.getPixelOrigin()), t).round(), n.zoom = t, this._setZoomTransform(n, s.getCenter(), s.getZoom()), o.Util.falseFn(n.el.offsetWidth)), this._level = n, n }, _pruneTiles: function() { var t, e, i = this._map.getZoom(); if (i > this.options.maxZoom || i < this.options.minZoom) return this._removeAllTiles(); for (t in this._tiles) e = this._tiles[t], e.retain = e.current; for (t in this._tiles)
+ if (e = this._tiles[t], e.current && !e.active) { var n = e.coords;
+ this._retainParent(n.x, n.y, n.z, n.z - 5) || this._retainChildren(n.x, n.y, n.z, n.z + 2) }
+ for (t in this._tiles) this._tiles[t].retain || this._removeTile(t) }, _removeAllTiles: function() { for (var t in this._tiles) this._removeTile(t) }, _resetAll: function() { for (var t in this._levels) o.DomUtil.remove(this._levels[t].el), delete this._levels[t];
+ this._removeAllTiles(), this._tileZoom = null, this._resetView() }, _retainParent: function(t, e, i, n) { var o = Math.floor(t / 2),
+ s = Math.floor(e / 2),
+ r = i - 1,
+ a = o + ":" + s + ":" + r,
+ h = this._tiles[a]; return h && h.active ? (h.retain = !0, !0) : (h && h.loaded && (h.retain = !0), r > n ? this._retainParent(o, s, r, n) : !1) }, _retainChildren: function(t, e, i, n) { for (var o = 2 * t; 2 * t + 2 > o; o++)
+ for (var s = 2 * e; 2 * e + 2 > s; s++) { var r = o + ":" + s + ":" + (i + 1),
+ a = this._tiles[r];
+ a && a.active ? a.retain = !0 : (a && a.loaded && (a.retain = !0), n > i + 1 && this._retainChildren(o, s, i + 1, n)) } }, _resetView: function(t) { var e = t && (t.pinch || t.flyTo);
+ this._setView(this._map.getCenter(), this._map.getZoom(), e, e) }, _animateZoom: function(t) { this._setView(t.center, t.zoom, !0, t.noUpdate) }, _setView: function(t, e, n, o) { var s = Math.round(e);
+ (this.options.maxZoom !== i && s > this.options.maxZoom || this.options.minZoom !== i && s < this.options.minZoom) && (s = i); var r = s !== this._tileZoom;
+ (!o || r) && (this._tileZoom = s, this._abortLoading && this._abortLoading(), this._updateLevels(), this._resetGrid(), s !== i && this._update(t), n || this._pruneTiles(), this._noPrune = !!n), this._setZoomTransforms(t, e) }, _setZoomTransforms: function(t, e) { for (var i in this._levels) this._setZoomTransform(this._levels[i], t, e) }, _setZoomTransform: function(t, e, i) { var n = this._map.getZoomScale(i, t.zoom),
+ s = t.origin.multiplyBy(n).subtract(this._map._getNewPixelOrigin(e, i)).round();
+ o.Browser.any3d ? o.DomUtil.setTransform(t.el, s, n) : o.DomUtil.setPosition(t.el, s) }, _resetGrid: function() { var t = this._map,
+ e = t.options.crs,
+ i = this._tileSize = this.getTileSize(),
+ n = this._tileZoom,
+ o = this._map.getPixelWorldBounds(this._tileZoom);
+ o && (this._globalTileRange = this._pxBoundsToTileRange(o)), this._wrapX = e.wrapLng && !this.options.noWrap && [Math.floor(t.project([0, e.wrapLng[0]], n).x / i.x), Math.ceil(t.project([0, e.wrapLng[1]], n).x / i.y)], this._wrapY = e.wrapLat && !this.options.noWrap && [Math.floor(t.project([e.wrapLat[0], 0], n).y / i.x), Math.ceil(t.project([e.wrapLat[1], 0], n).y / i.y)] }, _onMoveEnd: function() { this._map && !this._map._animatingZoom && this._resetView() }, _getTiledPixelBounds: function(t, e, i) { var n = this._map,
+ s = n.getZoomScale(e, i),
+ r = n.project(t, i).floor(),
+ a = n.getSize().divideBy(2 * s); return new o.Bounds(r.subtract(a), r.add(a)) }, _update: function(t) { var n = this._map; if (n) { var s = n.getZoom(); if (t === i && (t = n.getCenter()), this._tileZoom !== i) { var r = this._getTiledPixelBounds(t, s, this._tileZoom),
+ a = this._pxBoundsToTileRange(r),
+ h = a.getCenter(),
+ l = []; for (var u in this._tiles) this._tiles[u].current = !1; if (Math.abs(s - this._tileZoom) > 1) return void this._setView(t, s); for (var c = a.min.y; c <= a.max.y; c++)
+ for (var d = a.min.x; d <= a.max.x; d++) { var _ = new o.Point(d, c); if (_.z = this._tileZoom, this._isValidTile(_)) { var m = this._tiles[this._tileCoordsToKey(_)];
+ m ? m.current = !0 : l.push(_) } }
+ if (l.sort(function(t, e) { return t.distanceTo(h) - e.distanceTo(h) }), 0 !== l.length) { this._loading || (this._loading = !0, this.fire("loading")); var p = e.createDocumentFragment(); for (d = 0; d < l.length; d++) this._addTile(l[d], p);
+ this._level.el.appendChild(p) } } } }, _isValidTile: function(t) { var e = this._map.options.crs; if (!e.infinite) { var i = this._globalTileRange; if (!e.wrapLng && (t.x < i.min.x || t.x > i.max.x) || !e.wrapLat && (t.y < i.min.y || t.y > i.max.y)) return !1 } if (!this.options.bounds) return !0; var n = this._tileCoordsToBounds(t); return o.latLngBounds(this.options.bounds).overlaps(n) }, _keyToBounds: function(t) { return this._tileCoordsToBounds(this._keyToTileCoords(t)) }, _tileCoordsToBounds: function(t) { var e = this._map,
+ i = this.getTileSize(),
+ n = t.scaleBy(i),
+ s = n.add(i),
+ r = e.wrapLatLng(e.unproject(n, t.z)),
+ a = e.wrapLatLng(e.unproject(s, t.z)); return new o.LatLngBounds(r, a) }, _tileCoordsToKey: function(t) { return t.x + ":" + t.y + ":" + t.z }, _keyToTileCoords: function(t) { var e = t.split(":"),
+ i = new o.Point(+e[0], +e[1]); return i.z = +e[2], i }, _removeTile: function(t) { var e = this._tiles[t];
+ e && (o.DomUtil.remove(e.el), delete this._tiles[t], this.fire("tileunload", { tile: e.el, coords: this._keyToTileCoords(t) })) }, _initTile: function(t) { o.DomUtil.addClass(t, "leaflet-tile"); var e = this.getTileSize();
+ t.style.width = e.x + "px", t.style.height = e.y + "px", t.onselectstart = o.Util.falseFn, t.onmousemove = o.Util.falseFn, o.Browser.ielt9 && this.options.opacity < 1 && o.DomUtil.setOpacity(t, this.options.opacity), o.Browser.android && !o.Browser.android23 && (t.style.WebkitBackfaceVisibility = "hidden") }, _addTile: function(t, e) { var i = this._getTilePos(t),
+ n = this._tileCoordsToKey(t),
+ s = this.createTile(this._wrapCoords(t), o.bind(this._tileReady, this, t));
+ this._initTile(s), this.createTile.length < 2 && o.Util.requestAnimFrame(o.bind(this._tileReady, this, t, null, s)), o.DomUtil.setPosition(s, i), this._tiles[n] = { el: s, coords: t, current: !0 }, e.appendChild(s), this.fire("tileloadstart", { tile: s, coords: t }) }, _tileReady: function(t, e, i) { if (this._map) { e && this.fire("tileerror", { error: e, tile: i, coords: t }); var n = this._tileCoordsToKey(t);
+ i = this._tiles[n], i && (i.loaded = +new Date, this._map._fadeAnimated ? (o.DomUtil.setOpacity(i.el, 0), o.Util.cancelAnimFrame(this._fadeFrame), this._fadeFrame = o.Util.requestAnimFrame(this._updateOpacity, this)) : (i.active = !0, this._pruneTiles()), o.DomUtil.addClass(i.el, "leaflet-tile-loaded"), this.fire("tileload", { tile: i.el, coords: t }), this._noTilesToLoad() && (this._loading = !1, this.fire("load"))) } }, _getTilePos: function(t) { return t.scaleBy(this.getTileSize()).subtract(this._level.origin) }, _wrapCoords: function(t) { var e = new o.Point(this._wrapX ? o.Util.wrapNum(t.x, this._wrapX) : t.x, this._wrapY ? o.Util.wrapNum(t.y, this._wrapY) : t.y); return e.z = t.z, e }, _pxBoundsToTileRange: function(t) { var e = this.getTileSize(); return new o.Bounds(t.min.unscaleBy(e).floor(), t.max.unscaleBy(e).ceil().subtract([1, 1])) }, _noTilesToLoad: function() { for (var t in this._tiles)
+ if (!this._tiles[t].loaded) return !1;
+ return !0 } }), o.gridLayer = function(t) { return new o.GridLayer(t) }, o.TileLayer = o.GridLayer.extend({ options: { maxZoom: 18, subdomains: "abc", errorTileUrl: "", zoomOffset: 0, maxNativeZoom: null, tms: !1, zoomReverse: !1, detectRetina: !1, crossOrigin: !1 }, initialize: function(t, e) { this._url = t, e = o.setOptions(this, e), e.detectRetina && o.Browser.retina && e.maxZoom > 0 && (e.tileSize = Math.floor(e.tileSize / 2), e.zoomOffset++, e.minZoom = Math.max(0, e.minZoom), e.maxZoom--), "string" == typeof e.subdomains && (e.subdomains = e.subdomains.split("")), o.Browser.android || this.on("tileunload", this._onTileRemove) }, setUrl: function(t, e) { return this._url = t, e || this.redraw(), this }, createTile: function(t, i) { var n = e.createElement("img"); return o.DomEvent.on(n, "load", o.bind(this._tileOnLoad, this, i, n)), o.DomEvent.on(n, "error", o.bind(this._tileOnError, this, i, n)), this.options.crossOrigin && (n.crossOrigin = ""), n.alt = "", n.src = this.getTileUrl(t), n }, getTileUrl: function(t) { return o.Util.template(this._url, o.extend({ r: this.options.detectRetina && o.Browser.retina && this.options.maxZoom > 0 ? "@2x" : "", s: this._getSubdomain(t), x: t.x, y: this.options.tms ? this._globalTileRange.max.y - t.y : t.y, z: this._getZoomForUrl() }, this.options)) }, _tileOnLoad: function(t, e) { o.Browser.ielt9 ? setTimeout(o.bind(t, this, null, e), 0) : t(null, e) }, _tileOnError: function(t, e, i) { var n = this.options.errorTileUrl;
+ n && (e.src = n), t(i, e) }, getTileSize: function() { var t = this._map,
+ e = o.GridLayer.prototype.getTileSize.call(this),
+ i = this._tileZoom + this.options.zoomOffset,
+ n = this.options.maxNativeZoom; return null !== n && i > n ? e.divideBy(t.getZoomScale(n, i)).round() : e }, _onTileRemove: function(t) { t.tile.onload = null }, _getZoomForUrl: function() { var t = this.options,
+ e = this._tileZoom; return t.zoomReverse && (e = t.maxZoom - e), e += t.zoomOffset, null !== t.maxNativeZoom ? Math.min(e, t.maxNativeZoom) : e }, _getSubdomain: function(t) { var e = Math.abs(t.x + t.y) % this.options.subdomains.length; return this.options.subdomains[e] }, _abortLoading: function() { var t, e; for (t in this._tiles) this._tiles[t].coords.z !== this._tileZoom && (e = this._tiles[t].el, e.onload = o.Util.falseFn, e.onerror = o.Util.falseFn, e.complete || (e.src = o.Util.emptyImageUrl, o.DomUtil.remove(e))) } }), o.tileLayer = function(t, e) { return new o.TileLayer(t, e) }, o.TileLayer.WMS = o.TileLayer.extend({ defaultWmsParams: { service: "WMS", request: "GetMap", version: "1.1.1", layers: "", styles: "", format: "image/jpeg", transparent: !1 }, options: { crs: null, uppercase: !1 }, initialize: function(t, e) { this._url = t; var i = o.extend({}, this.defaultWmsParams); for (var n in e) n in this.options || (i[n] = e[n]);
+ e = o.setOptions(this, e), i.width = i.height = e.tileSize * (e.detectRetina && o.Browser.retina ? 2 : 1), this.wmsParams = i }, onAdd: function(t) { this._crs = this.options.crs || t.options.crs, this._wmsVersion = parseFloat(this.wmsParams.version); var e = this._wmsVersion >= 1.3 ? "crs" : "srs";
+ this.wmsParams[e] = this._crs.code, o.TileLayer.prototype.onAdd.call(this, t) }, getTileUrl: function(t) { var e = this._tileCoordsToBounds(t),
+ i = this._crs.project(e.getNorthWest()),
+ n = this._crs.project(e.getSouthEast()),
+ s = (this._wmsVersion >= 1.3 && this._crs === o.CRS.EPSG4326 ? [n.y, i.x, i.y, n.x] : [i.x, n.y, n.x, i.y]).join(","),
+ r = o.TileLayer.prototype.getTileUrl.call(this, t); return r + o.Util.getParamString(this.wmsParams, r, this.options.uppercase) + (this.options.uppercase ? "&BBOX=" : "&bbox=") + s }, setParams: function(t, e) { return o.extend(this.wmsParams, t), e || this.redraw(), this } }), o.tileLayer.wms = function(t, e) { return new o.TileLayer.WMS(t, e) }, o.ImageOverlay = o.Layer.extend({ options: { opacity: 1, alt: "", interactive: !1 }, initialize: function(t, e, i) { this._url = t, this._bounds = o.latLngBounds(e), o.setOptions(this, i) }, onAdd: function() { this._image || (this._initImage(), this.options.opacity < 1 && this._updateOpacity()), this.options.interactive && (o.DomUtil.addClass(this._image, "leaflet-interactive"), this.addInteractiveTarget(this._image)), this.getPane().appendChild(this._image), this._reset() }, onRemove: function() { o.DomUtil.remove(this._image), this.options.interactive && this.removeInteractiveTarget(this._image) }, setOpacity: function(t) { return this.options.opacity = t, this._image && this._updateOpacity(), this }, setStyle: function(t) { return t.opacity && this.setOpacity(t.opacity), this }, bringToFront: function() { return this._map && o.DomUtil.toFront(this._image), this }, bringToBack: function() { return this._map && o.DomUtil.toBack(this._image), this }, setUrl: function(t) { return this._url = t, this._image && (this._image.src = t), this }, setBounds: function(t) { return this._bounds = t, this._map && this._reset(), this }, getAttribution: function() { return this.options.attribution }, getEvents: function() { var t = { zoom: this._reset, viewreset: this._reset }; return this._zoomAnimated && (t.zoomanim = this._animateZoom), t }, getBounds: function() { return this._bounds }, getElement: function() { return this._image }, _initImage: function() { var t = this._image = o.DomUtil.create("img", "leaflet-image-layer " + (this._zoomAnimated ? "leaflet-zoom-animated" : ""));
+ t.onselectstart = o.Util.falseFn, t.onmousemove = o.Util.falseFn, t.onload = o.bind(this.fire, this, "load"), this.options.crossOrigin && (t.crossOrigin = ""), t.src = this._url, t.alt = this.options.alt }, _animateZoom: function(t) { var e = this._map.getZoomScale(t.zoom),
+ i = this._map._latLngToNewLayerPoint(this._bounds.getNorthWest(), t.zoom, t.center);
+ o.DomUtil.setTransform(this._image, i, e) }, _reset: function() { var t = this._image,
+ e = new o.Bounds(this._map.latLngToLayerPoint(this._bounds.getNorthWest()), this._map.latLngToLayerPoint(this._bounds.getSouthEast())),
+ i = e.getSize();
+ o.DomUtil.setPosition(t, e.min), t.style.width = i.x + "px", t.style.height = i.y + "px" }, _updateOpacity: function() { o.DomUtil.setOpacity(this._image, this.options.opacity) } }), o.imageOverlay = function(t, e, i) { return new o.ImageOverlay(t, e, i) }, o.Icon = o.Class.extend({ initialize: function(t) { o.setOptions(this, t) }, createIcon: function(t) { return this._createIcon("icon", t) }, createShadow: function(t) { return this._createIcon("shadow", t) }, _createIcon: function(t, e) { var i = this._getIconUrl(t); if (!i) { if ("icon" === t) throw new Error("iconUrl not set in Icon options (see the docs)."); return null } var n = this._createImg(i, e && "IMG" === e.tagName ? e : null); return this._setIconStyles(n, t), n }, _setIconStyles: function(t, e) { var i = this.options,
+ n = o.point(i[e + "Size"]),
+ s = o.point("shadow" === e && i.shadowAnchor || i.iconAnchor || n && n.divideBy(2, !0));
+ t.className = "leaflet-marker-" + e + " " + (i.className || ""), s && (t.style.marginLeft = -s.x + "px", t.style.marginTop = -s.y + "px"), n && (t.style.width = n.x + "px", t.style.height = n.y + "px") }, _createImg: function(t, i) { return i = i || e.createElement("img"), i.src = t, i }, _getIconUrl: function(t) { return o.Browser.retina && this.options[t + "RetinaUrl"] || this.options[t + "Url"] } }), o.icon = function(t) { return new o.Icon(t) }, o.Icon.Default = o.Icon.extend({ options: { iconSize: [25, 41], iconAnchor: [12, 41], popupAnchor: [1, -34], shadowSize: [41, 41] }, _getIconUrl: function(t) { var e = t + "Url"; if (this.options[e]) return this.options[e]; var i = o.Icon.Default.imagePath; if (!i) throw new Error("Couldn't autodetect L.Icon.Default.imagePath, set it manually."); return i + "/marker-" + t + (o.Browser.retina && "icon" === t ? "-2x" : "") + ".png" } }), o.Icon.Default.imagePath = function() { var t, i, n, o, s = e.getElementsByTagName("script"),
+ r = /[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/; for (t = 0, i = s.length; i > t; t++)
+ if (n = s[t].src || "", n.match(r)) return o = n.split(r)[0], (o ? o + "/" : "") + "images" }(), o.Marker = o.Layer.extend({ options: { pane: "markerPane", nonBubblingEvents: ["click", "dblclick", "mouseover", "mouseout", "contextmenu"], icon: new o.Icon.Default, interactive: !0, keyboard: !0, zIndexOffset: 0, opacity: 1, riseOffset: 250 }, initialize: function(t, e) { o.setOptions(this, e), this._latlng = o.latLng(t) }, onAdd: function(t) { this._zoomAnimated = this._zoomAnimated && t.options.markerZoomAnimation, this._initIcon(), this.update() }, onRemove: function() { this.dragging && this.dragging.enabled() && (this.options.draggable = !0, this.dragging.removeHooks()), this._removeIcon(), this._removeShadow() }, getEvents: function() { var t = { zoom: this.update, viewreset: this.update }; return this._zoomAnimated && (t.zoomanim = this._animateZoom), t }, getLatLng: function() { return this._latlng }, setLatLng: function(t) { var e = this._latlng; return this._latlng = o.latLng(t), this.update(), this.fire("move", { oldLatLng: e, latlng: this._latlng }) }, setZIndexOffset: function(t) { return this.options.zIndexOffset = t, this.update() }, setIcon: function(t) { return this.options.icon = t, this._map && (this._initIcon(), this.update()), this._popup && this.bindPopup(this._popup, this._popup.options), this }, getElement: function() { return this._icon }, update: function() { if (this._icon) { var t = this._map.latLngToLayerPoint(this._latlng).round();
+ this._setPos(t) } return this }, _initIcon: function() { var t = this.options,
+ e = "leaflet-zoom-" + (this._zoomAnimated ? "animated" : "hide"),
+ i = t.icon.createIcon(this._icon),
+ n = !1;
+ i !== this._icon && (this._icon && this._removeIcon(), n = !0, t.title && (i.title = t.title), t.alt && (i.alt = t.alt)), o.DomUtil.addClass(i, e), t.keyboard && (i.tabIndex = "0"), this._icon = i, t.riseOnHover && this.on({ mouseover: this._bringToFront, mouseout: this._resetZIndex }); var s = t.icon.createShadow(this._shadow),
+ r = !1;
+ s !== this._shadow && (this._removeShadow(), r = !0), s && o.DomUtil.addClass(s, e), this._shadow = s, t.opacity < 1 && this._updateOpacity(), n && (this.getPane().appendChild(this._icon), this._initInteraction()), s && r && this.getPane("shadowPane").appendChild(this._shadow) }, _removeIcon: function() { this.options.riseOnHover && this.off({ mouseover: this._bringToFront, mouseout: this._resetZIndex }), o.DomUtil.remove(this._icon), this.removeInteractiveTarget(this._icon), this._icon = null }, _removeShadow: function() { this._shadow && o.DomUtil.remove(this._shadow), this._shadow = null }, _setPos: function(t) { o.DomUtil.setPosition(this._icon, t), this._shadow && o.DomUtil.setPosition(this._shadow, t), this._zIndex = t.y + this.options.zIndexOffset, this._resetZIndex() }, _updateZIndex: function(t) { this._icon.style.zIndex = this._zIndex + t }, _animateZoom: function(t) { var e = this._map._latLngToNewLayerPoint(this._latlng, t.zoom, t.center).round();
+ this._setPos(e) }, _initInteraction: function() { if (this.options.interactive && (o.DomUtil.addClass(this._icon, "leaflet-interactive"), this.addInteractiveTarget(this._icon), o.Handler.MarkerDrag)) { var t = this.options.draggable;
+ this.dragging && (t = this.dragging.enabled(), this.dragging.disable()), this.dragging = new o.Handler.MarkerDrag(this), t && this.dragging.enable() } }, setOpacity: function(t) { return this.options.opacity = t, this._map && this._updateOpacity(), this }, _updateOpacity: function() { var t = this.options.opacity;
+ o.DomUtil.setOpacity(this._icon, t), this._shadow && o.DomUtil.setOpacity(this._shadow, t) }, _bringToFront: function() { this._updateZIndex(this.options.riseOffset) }, _resetZIndex: function() { this._updateZIndex(0) } }), o.marker = function(t, e) { return new o.Marker(t, e) }, o.DivIcon = o.Icon.extend({ options: { iconSize: [12, 12], className: "leaflet-div-icon", html: !1 }, createIcon: function(t) { var i = t && "DIV" === t.tagName ? t : e.createElement("div"),
+ n = this.options; return i.innerHTML = n.html !== !1 ? n.html : "", n.bgPos && (i.style.backgroundPosition = -n.bgPos.x + "px " + -n.bgPos.y + "px"), this._setIconStyles(i, "icon"), i }, createShadow: function() { return null } }), o.divIcon = function(t) { return new o.DivIcon(t) }, o.Map.mergeOptions({ closePopupOnClick: !0 }), o.Popup = o.Layer.extend({ options: { pane: "popupPane", minWidth: 50, maxWidth: 300, offset: [0, 7], autoPan: !0, autoPanPadding: [5, 5], closeButton: !0, autoClose: !0, zoomAnimation: !0 }, initialize: function(t, e) { o.setOptions(this, t), this._source = e }, onAdd: function(t) { this._zoomAnimated = this._zoomAnimated && this.options.zoomAnimation, this._container || this._initLayout(), t._fadeAnimated && o.DomUtil.setOpacity(this._container, 0), clearTimeout(this._removeTimeout), this.getPane().appendChild(this._container), this.update(), t._fadeAnimated && o.DomUtil.setOpacity(this._container, 1), t.fire("popupopen", { popup: this }), this._source && this._source.fire("popupopen", { popup: this }, !0) }, openOn: function(t) { return t.openPopup(this), this }, onRemove: function(t) { t._fadeAnimated ? (o.DomUtil.setOpacity(this._container, 0), this._removeTimeout = setTimeout(o.bind(o.DomUtil.remove, o.DomUtil, this._container), 200)) : o.DomUtil.remove(this._container), t.fire("popupclose", { popup: this }), this._source && this._source.fire("popupclose", { popup: this }, !0) }, getLatLng: function() { return this._latlng }, setLatLng: function(t) { return this._latlng = o.latLng(t), this._map && (this._updatePosition(), this._adjustPan()), this }, getContent: function() { return this._content }, setContent: function(t) { return this._content = t, this.update(), this }, getElement: function() { return this._container }, update: function() { this._map && (this._container.style.visibility = "hidden", this._updateContent(), this._updateLayout(), this._updatePosition(), this._container.style.visibility = "", this._adjustPan()) }, getEvents: function() { var t = { zoom: this._updatePosition, viewreset: this._updatePosition }; return this._zoomAnimated && (t.zoomanim = this._animateZoom), ("closeOnClick" in this.options ? this.options.closeOnClick : this._map.options.closePopupOnClick) && (t.preclick = this._close), this.options.keepInView && (t.moveend = this._adjustPan), t }, isOpen: function() { return !!this._map && this._map.hasLayer(this) }, bringToFront: function() { return this._map && o.DomUtil.toFront(this._container), this }, bringToBack: function() { return this._map && o.DomUtil.toBack(this._container), this }, _close: function() { this._map && this._map.closePopup(this) }, _initLayout: function() { var t = "leaflet-popup",
+ e = this._container = o.DomUtil.create("div", t + " " + (this.options.className || "") + " leaflet-zoom-" + (this._zoomAnimated ? "animated" : "hide")); if (this.options.closeButton) { var i = this._closeButton = o.DomUtil.create("a", t + "-close-button", e);
+ i.href = "#close", i.innerHTML = "×", o.DomEvent.on(i, "click", this._onCloseButtonClick, this) } var n = this._wrapper = o.DomUtil.create("div", t + "-content-wrapper", e);
+ this._contentNode = o.DomUtil.create("div", t + "-content", n), o.DomEvent.disableClickPropagation(n).disableScrollPropagation(this._contentNode).on(n, "contextmenu", o.DomEvent.stopPropagation), this._tipContainer = o.DomUtil.create("div", t + "-tip-container", e), this._tip = o.DomUtil.create("div", t + "-tip", this._tipContainer) }, _updateContent: function() { if (this._content) { var t = this._contentNode,
+ e = "function" == typeof this._content ? this._content(this._source || this) : this._content; if ("string" == typeof e) t.innerHTML = e;
+ else { for (; t.hasChildNodes();) t.removeChild(t.firstChild);
+ t.appendChild(e) }
+ this.fire("contentupdate") } }, _updateLayout: function() { var t = this._contentNode,
+ e = t.style;
+ e.width = "", e.whiteSpace = "nowrap"; var i = t.offsetWidth;
+ i = Math.min(i, this.options.maxWidth), i = Math.max(i, this.options.minWidth), e.width = i + 1 + "px", e.whiteSpace = "", e.height = ""; var n = t.offsetHeight,
+ s = this.options.maxHeight,
+ r = "leaflet-popup-scrolled";
+ s && n > s ? (e.height = s + "px", o.DomUtil.addClass(t, r)) : o.DomUtil.removeClass(t, r), this._containerWidth = this._container.offsetWidth }, _updatePosition: function() { if (this._map) { var t = this._map.latLngToLayerPoint(this._latlng),
+ e = o.point(this.options.offset);
+ this._zoomAnimated ? o.DomUtil.setPosition(this._container, t) : e = e.add(t); var i = this._containerBottom = -e.y,
+ n = this._containerLeft = -Math.round(this._containerWidth / 2) + e.x;
+ this._container.style.bottom = i + "px", this._container.style.left = n + "px" } }, _animateZoom: function(t) { var e = this._map._latLngToNewLayerPoint(this._latlng, t.zoom, t.center);
+ o.DomUtil.setPosition(this._container, e) }, _adjustPan: function() { if (!(!this.options.autoPan || this._map._panAnim && this._map._panAnim._inProgress)) { var t = this._map,
+ e = this._container.offsetHeight,
+ i = this._containerWidth,
+ n = new o.Point(this._containerLeft, -e - this._containerBottom);
+ this._zoomAnimated && n._add(o.DomUtil.getPosition(this._container)); var s = t.layerPointToContainerPoint(n),
+ r = o.point(this.options.autoPanPadding),
+ a = o.point(this.options.autoPanPaddingTopLeft || r),
+ h = o.point(this.options.autoPanPaddingBottomRight || r),
+ l = t.getSize(),
+ u = 0,
+ c = 0;
+ s.x + i + h.x > l.x && (u = s.x + i - l.x + h.x), s.x - u - a.x < 0 && (u = s.x - a.x), s.y + e + h.y > l.y && (c = s.y + e - l.y + h.y), s.y - c - a.y < 0 && (c = s.y - a.y), (u || c) && t.fire("autopanstart").panBy([u, c]) } }, _onCloseButtonClick: function(t) { this._close(), o.DomEvent.stop(t) } }), o.popup = function(t, e) { return new o.Popup(t, e) }, o.Map.include({ openPopup: function(t, e, i) { return t instanceof o.Popup || (t = new o.Popup(i).setContent(t)), e && t.setLatLng(e), this.hasLayer(t) ? this : (this._popup && this._popup.options.autoClose && this.closePopup(), this._popup = t, this.addLayer(t)) }, closePopup: function(t) { return t && t !== this._popup || (t = this._popup, this._popup = null), t && this.removeLayer(t), this } }), o.Layer.include({ bindPopup: function(t, e) { return t instanceof o.Popup ? (o.setOptions(t, e), this._popup = t, t._source = this) : ((!this._popup || e) && (this._popup = new o.Popup(e, this)), this._popup.setContent(t)), this._popupHandlersAdded || (this.on({ click: this._openPopup, remove: this.closePopup, move: this._movePopup }), this._popupHandlersAdded = !0), this._originalPopupOffset = this._popup.options.offset, this }, unbindPopup: function() { return this._popup && (this.off({ click: this._openPopup, remove: this.closePopup, move: this._movePopup }), this._popupHandlersAdded = !1, this._popup = null), this }, openPopup: function(t, e) { if (t instanceof o.Layer || (e = t, t = this), t instanceof o.FeatureGroup)
+ for (var i in this._layers) { t = this._layers[i]; break }
+ return e || (e = t.getCenter ? t.getCenter() : t.getLatLng()), this._popup && this._map && (this._popup.options.offset = this._popupAnchor(t), this._popup._source = t, this._popup.update(), this._map.openPopup(this._popup, e)), this }, closePopup: function() { return this._popup && this._popup._close(), this }, togglePopup: function(t) { return this._popup && (this._popup._map ? this.closePopup() : this.openPopup(t)), this }, isPopupOpen: function() { return this._popup.isOpen() }, setPopupContent: function(t) { return this._popup && this._popup.setContent(t), this }, getPopup: function() { return this._popup }, _openPopup: function(t) { var e = t.layer || t.target; if (this._popup && this._map) return e instanceof o.Path ? void this.openPopup(t.layer || t.target, t.latlng) : void(this._map.hasLayer(this._popup) && this._popup._source === e ? this.closePopup() : this.openPopup(e, t.latlng)) }, _popupAnchor: function(t) { var e = t._getPopupAnchor ? t._getPopupAnchor() : [0, 0],
+ i = this._originalPopupOffset || o.Popup.prototype.options.offset; return o.point(e).add(i) }, _movePopup: function(t) { this._popup.setLatLng(t.latlng) } }), o.Marker.include({ _getPopupAnchor: function() { return this.options.icon.options.popupAnchor || [0, 0] } }), o.LayerGroup = o.Layer.extend({
+ initialize: function(t) { this._layers = {}; var e, i; if (t)
+ for (e = 0, i = t.length; i > e; e++) this.addLayer(t[e]) },
+ addLayer: function(t) { var e = this.getLayerId(t); return this._layers[e] = t, this._map && this._map.addLayer(t), this },
+ removeLayer: function(t) {
+ var e = t in this._layers ? t : this.getLayerId(t);
+ return this._map && this._layers[e] && this._map.removeLayer(this._layers[e]),
+ delete this._layers[e], this
+ },
+ hasLayer: function(t) { return !!t && (t in this._layers || this.getLayerId(t) in this._layers) },
+ clearLayers: function() { for (var t in this._layers) this.removeLayer(this._layers[t]); return this },
+ invoke: function(t) { var e, i, n = Array.prototype.slice.call(arguments, 1); for (e in this._layers) i = this._layers[e], i[t] && i[t].apply(i, n); return this },
+ onAdd: function(t) { for (var e in this._layers) t.addLayer(this._layers[e]) },
+ onRemove: function(t) { for (var e in this._layers) t.removeLayer(this._layers[e]) },
+ eachLayer: function(t, e) { for (var i in this._layers) t.call(e, this._layers[i]); return this },
+ getLayer: function(t) { return this._layers[t] },
+ getLayers: function() { var t = []; for (var e in this._layers) t.push(this._layers[e]); return t },
+ setZIndex: function(t) { return this.invoke("setZIndex", t) },
+ getLayerId: function(t) { return o.stamp(t) }
+ }), o.layerGroup = function(t) { return new o.LayerGroup(t) }, o.FeatureGroup = o.LayerGroup.extend({ addLayer: function(t) { return this.hasLayer(t) ? this : (t.addEventParent(this), o.LayerGroup.prototype.addLayer.call(this, t), this.fire("layeradd", { layer: t })) }, removeLayer: function(t) { return this.hasLayer(t) ? (t in this._layers && (t = this._layers[t]), t.removeEventParent(this), o.LayerGroup.prototype.removeLayer.call(this, t), this.fire("layerremove", { layer: t })) : this }, setStyle: function(t) { return this.invoke("setStyle", t) }, bringToFront: function() { return this.invoke("bringToFront") }, bringToBack: function() { return this.invoke("bringToBack") }, getBounds: function() { var t = new o.LatLngBounds; for (var e in this._layers) { var i = this._layers[e];
+ t.extend(i.getBounds ? i.getBounds() : i.getLatLng()) } return t } }), o.featureGroup = function(t) { return new o.FeatureGroup(t) }, o.Renderer = o.Layer.extend({ options: { padding: .1 }, initialize: function(t) { o.setOptions(this, t), o.stamp(this) }, onAdd: function() { this._container || (this._initContainer(), this._zoomAnimated && o.DomUtil.addClass(this._container, "leaflet-zoom-animated")), this.getPane().appendChild(this._container), this._update() }, onRemove: function() { o.DomUtil.remove(this._container) }, getEvents: function() { var t = { viewreset: this._reset, zoomstart: this._onZoomStart, zoom: this._onZoom, moveend: this._update }; return this._zoomAnimated && (t.zoomanim = this._onAnimZoom), t }, _onAnimZoom: function(t) { this._updateTransform(t.center, t.zoom) }, _onZoom: function() { this._updateTransform(this._map.getCenter(), this._map.getZoom()) }, _onZoomStart: function() { this._update() }, _updateTransform: function(t, e) { var i = this._map.getZoomScale(e, this._zoom),
+ n = o.DomUtil.getPosition(this._container),
+ s = this._map.getSize().multiplyBy(.5 + this.options.padding),
+ r = this._map.project(this._center, e),
+ a = this._map.project(t, e),
+ h = a.subtract(r),
+ l = s.multiplyBy(-i).add(n).add(s).subtract(h);
+ o.DomUtil.setTransform(this._container, l, i) }, _reset: function() { this._update(), this._updateTransform(this._center, this._zoom) }, _update: function() { var t = this.options.padding,
+ e = this._map.getSize(),
+ i = this._map.containerPointToLayerPoint(e.multiplyBy(-t)).round();
+ this._bounds = new o.Bounds(i, i.add(e.multiplyBy(1 + 2 * t)).round()), this._center = this._map.getCenter(), this._zoom = this._map.getZoom() } }), o.Map.include({ getRenderer: function(t) { var e = t.options.renderer || this._getPaneRenderer(t.options.pane) || this.options.renderer || this._renderer; return e || (e = this._renderer = this.options.preferCanvas && o.canvas() || o.svg()), this.hasLayer(e) || this.addLayer(e), e }, _getPaneRenderer: function(t) { if ("overlayPane" === t || t === i) return !1; var e = this._paneRenderers[t]; return e === i && (e = o.SVG && o.svg({ pane: t }) || o.Canvas && o.canvas({ pane: t }), this._paneRenderers[t] = e), e } }), o.Path = o.Layer.extend({ options: { stroke: !0, color: "#3388ff", weight: 3, opacity: 1, lineCap: "round", lineJoin: "round", fillOpacity: .2, fillRule: "evenodd", interactive: !0 }, beforeAdd: function(t) { this._renderer = t.getRenderer(this) }, onAdd: function() { this._renderer._initPath(this), this._reset(), this._renderer._addPath(this) }, onRemove: function() { this._renderer._removePath(this) }, getEvents: function() { return { zoomend: this._project, moveend: this._update, viewreset: this._reset } }, redraw: function() { return this._map && this._renderer._updatePath(this), this }, setStyle: function(t) { return o.setOptions(this, t), this._renderer && this._renderer._updateStyle(this), this }, bringToFront: function() { return this._renderer && this._renderer._bringToFront(this), this }, bringToBack: function() { return this._renderer && this._renderer._bringToBack(this), this }, getElement: function() { return this._path }, _reset: function() { this._project(), this._update() }, _clickTolerance: function() { return (this.options.stroke ? this.options.weight / 2 : 0) + (o.Browser.touch ? 10 : 0) } }), o.LineUtil = { simplify: function(t, e) { if (!e || !t.length) return t.slice(); var i = e * e; return t = this._reducePoints(t, i), t = this._simplifyDP(t, i) }, pointToSegmentDistance: function(t, e, i) { return Math.sqrt(this._sqClosestPointOnSegment(t, e, i, !0)) }, closestPointOnSegment: function(t, e, i) { return this._sqClosestPointOnSegment(t, e, i) }, _simplifyDP: function(t, e) { var n = t.length,
+ o = typeof Uint8Array != i + "" ? Uint8Array : Array,
+ s = new o(n);
+ s[0] = s[n - 1] = 1, this._simplifyDPStep(t, s, e, 0, n - 1); var r, a = []; for (r = 0; n > r; r++) s[r] && a.push(t[r]); return a }, _simplifyDPStep: function(t, e, i, n, o) { var s, r, a, h = 0; for (r = n + 1; o - 1 >= r; r++) a = this._sqClosestPointOnSegment(t[r], t[n], t[o], !0), a > h && (s = r, h = a);
+ h > i && (e[s] = 1, this._simplifyDPStep(t, e, i, n, s), this._simplifyDPStep(t, e, i, s, o)) }, _reducePoints: function(t, e) { for (var i = [t[0]], n = 1, o = 0, s = t.length; s > n; n++) this._sqDist(t[n], t[o]) > e && (i.push(t[n]), o = n); return s - 1 > o && i.push(t[s - 1]), i }, clipSegment: function(t, e, i, n, o) { var s, r, a, h = n ? this._lastCode : this._getBitCode(t, i),
+ l = this._getBitCode(e, i); for (this._lastCode = l;;) { if (!(h | l)) return [t, e]; if (h & l) return !1;
+ s = h || l, r = this._getEdgeIntersection(t, e, s, i, o), a = this._getBitCode(r, i), s === h ? (t = r, h = a) : (e = r, l = a) } }, _getEdgeIntersection: function(t, e, i, n, s) { var r, a, h = e.x - t.x,
+ l = e.y - t.y,
+ u = n.min,
+ c = n.max; return 8 & i ? (r = t.x + h * (c.y - t.y) / l, a = c.y) : 4 & i ? (r = t.x + h * (u.y - t.y) / l, a = u.y) : 2 & i ? (r = c.x, a = t.y + l * (c.x - t.x) / h) : 1 & i && (r = u.x, a = t.y + l * (u.x - t.x) / h), new o.Point(r, a, s) }, _getBitCode: function(t, e) { var i = 0; return t.x < e.min.x ? i |= 1 : t.x > e.max.x && (i |= 2), t.y < e.min.y ? i |= 4 : t.y > e.max.y && (i |= 8), i }, _sqDist: function(t, e) { var i = e.x - t.x,
+ n = e.y - t.y; return i * i + n * n }, _sqClosestPointOnSegment: function(t, e, i, n) { var s, r = e.x,
+ a = e.y,
+ h = i.x - r,
+ l = i.y - a,
+ u = h * h + l * l; return u > 0 && (s = ((t.x - r) * h + (t.y - a) * l) / u, s > 1 ? (r = i.x, a = i.y) : s > 0 && (r += h * s, a += l * s)), h = t.x - r, l = t.y - a, n ? h * h + l * l : new o.Point(r, a) } }, o.Polyline = o.Path.extend({ options: { smoothFactor: 1 }, initialize: function(t, e) { o.setOptions(this, e), this._setLatLngs(t) }, getLatLngs: function() { return this._latlngs }, setLatLngs: function(t) { return this._setLatLngs(t), this.redraw() }, isEmpty: function() { return !this._latlngs.length }, closestLayerPoint: function(t) { for (var e, i, n = 1 / 0, s = null, r = o.LineUtil._sqClosestPointOnSegment, a = 0, h = this._parts.length; h > a; a++)
+ for (var l = this._parts[a], u = 1, c = l.length; c > u; u++) { e = l[u - 1], i = l[u]; var d = r(t, e, i, !0);
+ n > d && (n = d, s = r(t, e, i)) }
+ return s && (s.distance = Math.sqrt(n)), s }, getCenter: function() { var t, e, i, n, o, s, r, a = this._rings[0],
+ h = a.length; if (!h) return null; for (t = 0, e = 0; h - 1 > t; t++) e += a[t].distanceTo(a[t + 1]) / 2; if (0 === e) return this._map.layerPointToLatLng(a[0]); for (t = 0, n = 0; h - 1 > t; t++)
+ if (o = a[t], s = a[t + 1], i = o.distanceTo(s), n += i, n > e) return r = (n - e) / i, this._map.layerPointToLatLng([s.x - r * (s.x - o.x), s.y - r * (s.y - o.y)]) }, getBounds: function() { return this._bounds }, addLatLng: function(t, e) { return e = e || this._defaultShape(), t = o.latLng(t), e.push(t), this._bounds.extend(t), this.redraw() }, _setLatLngs: function(t) { this._bounds = new o.LatLngBounds, this._latlngs = this._convertLatLngs(t) }, _defaultShape: function() { return o.Polyline._flat(this._latlngs) ? this._latlngs : this._latlngs[0] }, _convertLatLngs: function(t) { for (var e = [], i = o.Polyline._flat(t), n = 0, s = t.length; s > n; n++) i ? (e[n] = o.latLng(t[n]), this._bounds.extend(e[n])) : e[n] = this._convertLatLngs(t[n]); return e }, _project: function() { this._rings = [], this._projectLatlngs(this._latlngs, this._rings); var t = this._clickTolerance(),
+ e = new o.Point(t, -t);
+ this._bounds.isValid() && (this._pxBounds = new o.Bounds(this._map.latLngToLayerPoint(this._bounds.getSouthWest())._subtract(e), this._map.latLngToLayerPoint(this._bounds.getNorthEast())._add(e))) }, _projectLatlngs: function(t, e) { var i, n, s = t[0] instanceof o.LatLng,
+ r = t.length; if (s) { for (n = [], i = 0; r > i; i++) n[i] = this._map.latLngToLayerPoint(t[i]);
+ e.push(n) } else
+ for (i = 0; r > i; i++) this._projectLatlngs(t[i], e) }, _clipPoints: function() { var t = this._renderer._bounds; if (this._parts = [], this._pxBounds && this._pxBounds.intersects(t)) { if (this.options.noClip) return void(this._parts = this._rings); var e, i, n, s, r, a, h, l = this._parts; for (e = 0, n = 0, s = this._rings.length; s > e; e++)
+ for (h = this._rings[e], i = 0, r = h.length; r - 1 > i; i++) a = o.LineUtil.clipSegment(h[i], h[i + 1], t, i, !0), a && (l[n] = l[n] || [], l[n].push(a[0]), (a[1] !== h[i + 1] || i === r - 2) && (l[n].push(a[1]), n++)) } }, _simplifyPoints: function() { for (var t = this._parts, e = this.options.smoothFactor, i = 0, n = t.length; n > i; i++) t[i] = o.LineUtil.simplify(t[i], e) }, _update: function() { this._map && (this._clipPoints(), this._simplifyPoints(), this._updatePath()) }, _updatePath: function() { this._renderer._updatePoly(this) } }), o.polyline = function(t, e) { return new o.Polyline(t, e) }, o.Polyline._flat = function(t) { return !o.Util.isArray(t[0]) || "object" != typeof t[0][0] && "undefined" != typeof t[0][0] }, o.PolyUtil = {}, o.PolyUtil.clipPolygon = function(t, e, i) { var n, s, r, a, h, l, u, c, d, _ = [1, 4, 2, 8],
+ m = o.LineUtil; for (s = 0, u = t.length; u > s; s++) t[s]._code = m._getBitCode(t[s], e); for (a = 0; 4 > a; a++) { for (c = _[a], n = [], s = 0, u = t.length, r = u - 1; u > s; r = s++) h = t[s], l = t[r], h._code & c ? l._code & c || (d = m._getEdgeIntersection(l, h, c, e, i), d._code = m._getBitCode(d, e), n.push(d)) : (l._code & c && (d = m._getEdgeIntersection(l, h, c, e, i), d._code = m._getBitCode(d, e), n.push(d)), n.push(h));
+ t = n } return t }, o.Polygon = o.Polyline.extend({ options: { fill: !0 }, isEmpty: function() { return !this._latlngs.length || !this._latlngs[0].length }, getCenter: function() { var t, e, i, n, o, s, r, a, h, l = this._rings[0],
+ u = l.length; if (!u) return null; for (s = r = a = 0, t = 0, e = u - 1; u > t; e = t++) i = l[t], n = l[e], o = i.y * n.x - n.y * i.x, r += (i.x + n.x) * o, a += (i.y + n.y) * o, s += 3 * o; return h = 0 === s ? l[0] : [r / s, a / s], this._map.layerPointToLatLng(h) }, _convertLatLngs: function(t) { var e = o.Polyline.prototype._convertLatLngs.call(this, t),
+ i = e.length; return i >= 2 && e[0] instanceof o.LatLng && e[0].equals(e[i - 1]) && e.pop(), e }, _setLatLngs: function(t) { o.Polyline.prototype._setLatLngs.call(this, t), o.Polyline._flat(this._latlngs) && (this._latlngs = [this._latlngs]) }, _defaultShape: function() { return o.Polyline._flat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0] }, _clipPoints: function() { var t = this._renderer._bounds,
+ e = this.options.weight,
+ i = new o.Point(e, e); if (t = new o.Bounds(t.min.subtract(i), t.max.add(i)), this._parts = [], this._pxBounds && this._pxBounds.intersects(t)) { if (this.options.noClip) return void(this._parts = this._rings); for (var n, s = 0, r = this._rings.length; r > s; s++) n = o.PolyUtil.clipPolygon(this._rings[s], t, !0), n.length && this._parts.push(n) } }, _updatePath: function() { this._renderer._updatePoly(this, !0) } }), o.polygon = function(t, e) { return new o.Polygon(t, e) }, o.Rectangle = o.Polygon.extend({ initialize: function(t, e) { o.Polygon.prototype.initialize.call(this, this._boundsToLatLngs(t), e) }, setBounds: function(t) { return this.setLatLngs(this._boundsToLatLngs(t)) }, _boundsToLatLngs: function(t) { return t = o.latLngBounds(t), [t.getSouthWest(), t.getNorthWest(), t.getNorthEast(), t.getSouthEast()] } }), o.rectangle = function(t, e) { return new o.Rectangle(t, e) }, o.CircleMarker = o.Path.extend({ options: { fill: !0, radius: 10 }, initialize: function(t, e) { o.setOptions(this, e), this._latlng = o.latLng(t), this._radius = this.options.radius }, setLatLng: function(t) { return this._latlng = o.latLng(t), this.redraw(), this.fire("move", { latlng: this._latlng }) }, getLatLng: function() { return this._latlng }, setRadius: function(t) { return this.options.radius = this._radius = t, this.redraw() }, getRadius: function() { return this._radius }, setStyle: function(t) { var e = t && t.radius || this._radius; return o.Path.prototype.setStyle.call(this, t), this.setRadius(e), this }, _project: function() { this._point = this._map.latLngToLayerPoint(this._latlng), this._updateBounds() }, _updateBounds: function() { var t = this._radius,
+ e = this._radiusY || t,
+ i = this._clickTolerance(),
+ n = [t + i, e + i];
+ this._pxBounds = new o.Bounds(this._point.subtract(n), this._point.add(n)) }, _update: function() { this._map && this._updatePath() }, _updatePath: function() { this._renderer._updateCircle(this) }, _empty: function() { return this._radius && !this._renderer._bounds.intersects(this._pxBounds) } }), o.circleMarker = function(t, e) { return new o.CircleMarker(t, e) }, o.Circle = o.CircleMarker.extend({ initialize: function(t, e) { o.setOptions(this, e), this._latlng = o.latLng(t), this._mRadius = this.options.radius }, setRadius: function(t) { return this._mRadius = t, this.redraw() }, getRadius: function() { return this._mRadius }, getBounds: function() { var t = [this._radius, this._radiusY || this._radius]; return new o.LatLngBounds(this._map.layerPointToLatLng(this._point.subtract(t)), this._map.layerPointToLatLng(this._point.add(t))) }, setStyle: o.Path.prototype.setStyle, _project: function() { var t = this._latlng.lng,
+ e = this._latlng.lat,
+ i = this._map,
+ n = i.options.crs; if (n.distance === o.CRS.Earth.distance) { var s = Math.PI / 180,
+ r = this._mRadius / o.CRS.Earth.R / s,
+ a = i.project([e + r, t]),
+ h = i.project([e - r, t]),
+ l = a.add(h).divideBy(2),
+ u = i.unproject(l).lat,
+ c = Math.acos((Math.cos(r * s) - Math.sin(e * s) * Math.sin(u * s)) / (Math.cos(e * s) * Math.cos(u * s))) / s;
+ this._point = l.subtract(i.getPixelOrigin()), this._radius = isNaN(c) ? 0 : Math.max(Math.round(l.x - i.project([u, t - c]).x), 1), this._radiusY = Math.max(Math.round(l.y - a.y), 1) } else { var d = n.unproject(n.project(this._latlng).subtract([this._mRadius, 0]));
+ this._point = i.latLngToLayerPoint(this._latlng), this._radius = this._point.x - i.latLngToLayerPoint(d).x }
+ this._updateBounds() } }), o.circle = function(t, e, i) { return "number" == typeof e && (e = o.extend({}, i, { radius: e })), new o.Circle(t, e) }, o.SVG = o.Renderer.extend({ _initContainer: function() { this._container = o.SVG.create("svg"), this._container.setAttribute("pointer-events", "none"), this._rootGroup = o.SVG.create("g"), this._container.appendChild(this._rootGroup) }, _update: function() { if (!this._map._animatingZoom || !this._bounds) { o.Renderer.prototype._update.call(this); var t = this._bounds,
+ e = t.getSize(),
+ i = this._container;
+ this._svgSize && this._svgSize.equals(e) || (this._svgSize = e, i.setAttribute("width", e.x), i.setAttribute("height", e.y)), o.DomUtil.setPosition(i, t.min), i.setAttribute("viewBox", [t.min.x, t.min.y, e.x, e.y].join(" ")) } }, _initPath: function(t) { var e = t._path = o.SVG.create("path");
+ t.options.className && o.DomUtil.addClass(e, t.options.className), t.options.interactive && o.DomUtil.addClass(e, "leaflet-interactive"), this._updateStyle(t) }, _addPath: function(t) { this._rootGroup.appendChild(t._path), t.addInteractiveTarget(t._path) }, _removePath: function(t) { o.DomUtil.remove(t._path), t.removeInteractiveTarget(t._path) }, _updatePath: function(t) { t._project(), t._update() }, _updateStyle: function(t) { var e = t._path,
+ i = t.options;
+ e && (i.stroke ? (e.setAttribute("stroke", i.color), e.setAttribute("stroke-opacity", i.opacity), e.setAttribute("stroke-width", i.weight), e.setAttribute("stroke-linecap", i.lineCap), e.setAttribute("stroke-linejoin", i.lineJoin), i.dashArray ? e.setAttribute("stroke-dasharray", i.dashArray) : e.removeAttribute("stroke-dasharray"), i.dashOffset ? e.setAttribute("stroke-dashoffset", i.dashOffset) : e.removeAttribute("stroke-dashoffset")) : e.setAttribute("stroke", "none"), i.fill ? (e.setAttribute("fill", i.fillColor || i.color), e.setAttribute("fill-opacity", i.fillOpacity), e.setAttribute("fill-rule", i.fillRule || "evenodd")) : e.setAttribute("fill", "none"), e.setAttribute("pointer-events", i.pointerEvents || (i.interactive ? "visiblePainted" : "none"))) }, _updatePoly: function(t, e) { this._setPath(t, o.SVG.pointsToPath(t._parts, e)) }, _updateCircle: function(t) { var e = t._point,
+ i = t._radius,
+ n = t._radiusY || i,
+ o = "a" + i + "," + n + " 0 1,0 ",
+ s = t._empty() ? "M0 0" : "M" + (e.x - i) + "," + e.y + o + 2 * i + ",0 " + o + 2 * -i + ",0 ";
+ this._setPath(t, s) }, _setPath: function(t, e) { t._path.setAttribute("d", e) }, _bringToFront: function(t) { o.DomUtil.toFront(t._path) }, _bringToBack: function(t) { o.DomUtil.toBack(t._path) } }), o.extend(o.SVG, { create: function(t) { return e.createElementNS("http://www.w3.org/2000/svg", t) }, pointsToPath: function(t, e) { var i, n, s, r, a, h, l = ""; for (i = 0, s = t.length; s > i; i++) { for (a = t[i], n = 0, r = a.length; r > n; n++) h = a[n], l += (n ? "L" : "M") + h.x + " " + h.y;
+ l += e ? o.Browser.svg ? "z" : "x" : "" } return l || "M0 0" } }), o.Browser.svg = !(!e.createElementNS || !o.SVG.create("svg").createSVGRect), o.svg = function(t) { return o.Browser.svg || o.Browser.vml ? new o.SVG(t) : null }, o.Browser.vml = !o.Browser.svg && function() { try { var t = e.createElement("div");
+ t.innerHTML = '<v:shape adj="1"/>'; var i = t.firstChild; return i.style.behavior = "url(#default#VML)", i && "object" == typeof i.adj } catch (n) { return !1 } }(), o.SVG.include(o.Browser.vml ? { _initContainer: function() { this._container = o.DomUtil.create("div", "leaflet-vml-container") }, _update: function() { this._map._animatingZoom || o.Renderer.prototype._update.call(this) }, _initPath: function(t) { var e = t._container = o.SVG.create("shape");
+ o.DomUtil.addClass(e, "leaflet-vml-shape " + (this.options.className || "")), e.coordsize = "1 1", t._path = o.SVG.create("path"), e.appendChild(t._path), this._updateStyle(t) }, _addPath: function(t) { var e = t._container;
+ this._container.appendChild(e), t.options.interactive && t.addInteractiveTarget(e) }, _removePath: function(t) { var e = t._container;
+ o.DomUtil.remove(e), t.removeInteractiveTarget(e) }, _updateStyle: function(t) { var e = t._stroke,
+ i = t._fill,
+ n = t.options,
+ s = t._container;
+ s.stroked = !!n.stroke, s.filled = !!n.fill, n.stroke ? (e || (e = t._stroke = o.SVG.create("stroke")), s.appendChild(e), e.weight = n.weight + "px", e.color = n.color, e.opacity = n.opacity, n.dashArray ? e.dashStyle = o.Util.isArray(n.dashArray) ? n.dashArray.join(" ") : n.dashArray.replace(/( *, *)/g, " ") : e.dashStyle = "", e.endcap = n.lineCap.replace("butt", "flat"), e.joinstyle = n.lineJoin) : e && (s.removeChild(e), t._stroke = null), n.fill ? (i || (i = t._fill = o.SVG.create("fill")), s.appendChild(i), i.color = n.fillColor || n.color, i.opacity = n.fillOpacity) : i && (s.removeChild(i), t._fill = null) }, _updateCircle: function(t) { var e = t._point.round(),
+ i = Math.round(t._radius),
+ n = Math.round(t._radiusY || i);
+ this._setPath(t, t._empty() ? "M0 0" : "AL " + e.x + "," + e.y + " " + i + "," + n + " 0,23592600") }, _setPath: function(t, e) { t._path.v = e }, _bringToFront: function(t) { o.DomUtil.toFront(t._container) }, _bringToBack: function(t) { o.DomUtil.toBack(t._container) } } : {}), o.Browser.vml && (o.SVG.create = function() { try { return e.namespaces.add("lvml", "urn:schemas-microsoft-com:vml"),
+ function(t) { return e.createElement("<lvml:" + t + ' class="lvml">') } } catch (t) { return function(t) { return e.createElement("<" + t + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">') } } }()), o.Canvas = o.Renderer.extend({ onAdd: function() { o.Renderer.prototype.onAdd.call(this), this._layers = this._layers || {}, this._draw() }, _initContainer: function() { var t = this._container = e.createElement("canvas");
+ o.DomEvent.on(t, "mousemove", o.Util.throttle(this._onMouseMove, 32, this), this).on(t, "click dblclick mousedown mouseup contextmenu", this._onClick, this).on(t, "mouseout", this._handleMouseOut, this), this._ctx = t.getContext("2d") }, _update: function() { if (!this._map._animatingZoom || !this._bounds) { this._drawnLayers = {}, o.Renderer.prototype._update.call(this); var t = this._bounds,
+ e = this._container,
+ i = t.getSize(),
+ n = o.Browser.retina ? 2 : 1;
+ o.DomUtil.setPosition(e, t.min), e.width = n * i.x, e.height = n * i.y, e.style.width = i.x + "px", e.style.height = i.y + "px", o.Browser.retina && this._ctx.scale(2, 2), this._ctx.translate(-t.min.x, -t.min.y) } }, _initPath: function(t) { this._layers[o.stamp(t)] = t }, _addPath: o.Util.falseFn, _removePath: function(t) { t._removed = !0, this._requestRedraw(t) }, _updatePath: function(t) { this._redrawBounds = t._pxBounds, this._draw(!0), t._project(), t._update(), this._draw(), this._redrawBounds = null }, _updateStyle: function(t) { this._requestRedraw(t) }, _requestRedraw: function(t) { if (this._map) { var e = (t.options.weight || 0) + 1;
+ this._redrawBounds = this._redrawBounds || new o.Bounds, this._redrawBounds.extend(t._pxBounds.min.subtract([e, e])), this._redrawBounds.extend(t._pxBounds.max.add([e, e])), this._redrawRequest = this._redrawRequest || o.Util.requestAnimFrame(this._redraw, this) } }, _redraw: function() { this._redrawRequest = null, this._draw(!0), this._draw(), this._redrawBounds = null }, _draw: function(t) { this._clear = t; var e, i = this._redrawBounds;
+ this._ctx.save(), i && (this._ctx.beginPath(), this._ctx.rect(i.min.x, i.min.y, i.max.x - i.min.x, i.max.y - i.min.y), this._ctx.clip()); for (var n in this._layers) e = this._layers[n], (!i || e._pxBounds.intersects(i)) && e._updatePath(), t && e._removed && (delete e._removed, delete this._layers[n]);
+ this._ctx.restore() }, _updatePoly: function(t, e) { var i, n, o, s, r = t._parts,
+ a = r.length,
+ h = this._ctx; if (a) { for (this._drawnLayers[t._leaflet_id] = t, h.beginPath(), i = 0; a > i; i++) { for (n = 0, o = r[i].length; o > n; n++) s = r[i][n], h[n ? "lineTo" : "moveTo"](s.x, s.y);
+ e && h.closePath() }
+ this._fillStroke(h, t) } }, _updateCircle: function(t) { if (!t._empty()) { var e = t._point,
+ i = this._ctx,
+ n = t._radius,
+ o = (t._radiusY || n) / n;
+ 1 !== o && (i.save(), i.scale(1, o)), i.beginPath(), i.arc(e.x, e.y / o, n, 0, 2 * Math.PI, !1), 1 !== o && i.restore(), this._fillStroke(i, t) } }, _fillStroke: function(t, e) { var i = this._clear,
+ n = e.options;
+ t.globalCompositeOperation = i ? "destination-out" : "source-over", n.fill && (t.globalAlpha = i ? 1 : n.fillOpacity, t.fillStyle = n.fillColor || n.color, t.fill(n.fillRule || "evenodd")), n.stroke && 0 !== n.weight && (t.globalAlpha = i ? 1 : n.opacity, e._prevWeight = t.lineWidth = i ? e._prevWeight + 1 : n.weight, t.strokeStyle = n.color, t.lineCap = n.lineCap, t.lineJoin = n.lineJoin, t.stroke()) }, _onClick: function(t) { var e = this._map.mouseEventToLayerPoint(t),
+ i = []; for (var n in this._layers) this._layers[n]._containsPoint(e) && (o.DomEvent._fakeStop(t), i.push(this._layers[n]));
+ i.length && this._fireEvent(i, t) }, _onMouseMove: function(t) { if (this._map && !this._map.dragging._draggable._moving && !this._map._animatingZoom) { var e = this._map.mouseEventToLayerPoint(t);
+ this._handleMouseOut(t, e), this._handleMouseHover(t, e) } }, _handleMouseOut: function(t, e) { var i = this._hoveredLayer;!i || "mouseout" !== t.type && i._containsPoint(e) || (o.DomUtil.removeClass(this._container, "leaflet-interactive"), this._fireEvent([i], t, "mouseout"), this._hoveredLayer = null) }, _handleMouseHover: function(t, e) { var i, n; if (!this._hoveredLayer)
+ for (i in this._drawnLayers)
+ if (n = this._drawnLayers[i], n.options.interactive && n._containsPoint(e)) { o.DomUtil.addClass(this._container, "leaflet-interactive"), this._fireEvent([n], t, "mouseover"), this._hoveredLayer = n; break }
+ this._hoveredLayer && this._fireEvent([this._hoveredLayer], t) }, _fireEvent: function(t, e, i) { this._map._fireDOMEvent(e, i || e.type, t) }, _bringToFront: o.Util.falseFn, _bringToBack: o.Util.falseFn }), o.Browser.canvas = function() { return !!e.createElement("canvas").getContext }(), o.canvas = function(t) { return o.Browser.canvas ? new o.Canvas(t) : null }, o.Polyline.prototype._containsPoint = function(t, e) { var i, n, s, r, a, h, l = this._clickTolerance(); if (!this._pxBounds.contains(t)) return !1; for (i = 0, r = this._parts.length; r > i; i++)
+ for (h = this._parts[i], n = 0, a = h.length, s = a - 1; a > n; s = n++)
+ if ((e || 0 !== n) && o.LineUtil.pointToSegmentDistance(t, h[s], h[n]) <= l) return !0;
+ return !1 }, o.Polygon.prototype._containsPoint = function(t) { var e, i, n, s, r, a, h, l, u = !1; if (!this._pxBounds.contains(t)) return !1; for (s = 0, h = this._parts.length; h > s; s++)
+ for (e = this._parts[s], r = 0, l = e.length, a = l - 1; l > r; a = r++) i = e[r], n = e[a], i.y > t.y != n.y > t.y && t.x < (n.x - i.x) * (t.y - i.y) / (n.y - i.y) + i.x && (u = !u); return u || o.Polyline.prototype._containsPoint.call(this, t, !0) }, o.CircleMarker.prototype._containsPoint = function(t) { return t.distanceTo(this._point) <= this._radius + this._clickTolerance() }, o.GeoJSON = o.FeatureGroup.extend({ initialize: function(t, e) { o.setOptions(this, e), this._layers = {}, t && this.addData(t) }, addData: function(t) { var e, i, n, s = o.Util.isArray(t) ? t : t.features; if (s) { for (e = 0, i = s.length; i > e; e++) n = s[e], (n.geometries || n.geometry || n.features || n.coordinates) && this.addData(n); return this } var r = this.options; if (r.filter && !r.filter(t)) return this; var a = o.GeoJSON.geometryToLayer(t, r); return a ? (a.feature = o.GeoJSON.asFeature(t), a.defaultOptions = a.options, this.resetStyle(a), r.onEachFeature && r.onEachFeature(t, a), this.addLayer(a)) : this }, resetStyle: function(t) { return t.options = t.defaultOptions, this._setLayerStyle(t, this.options.style), this }, setStyle: function(t) { return this.eachLayer(function(e) { this._setLayerStyle(e, t) }, this) }, _setLayerStyle: function(t, e) { "function" == typeof e && (e = e(t.feature)), t.setStyle && t.setStyle(e) } }), o.extend(o.GeoJSON, { geometryToLayer: function(t, e) { var i, n, s, r, a = "Feature" === t.type ? t.geometry : t,
+ h = a ? a.coordinates : null,
+ l = [],
+ u = e && e.pointToLayer,
+ c = e && e.coordsToLatLng || this.coordsToLatLng; if (!h && !a) return null; switch (a.type) {
+ case "Point":
+ return i = c(h), u ? u(t, i) : new o.Marker(i);
+ case "MultiPoint":
+ for (s = 0, r = h.length; r > s; s++) i = c(h[s]), l.push(u ? u(t, i) : new o.Marker(i)); return new o.FeatureGroup(l);
+ case "LineString":
+ case "MultiLineString":
+ return n = this.coordsToLatLngs(h, "LineString" === a.type ? 0 : 1, c), new o.Polyline(n, e);
+ case "Polygon":
+ case "MultiPolygon":
+ return n = this.coordsToLatLngs(h, "Polygon" === a.type ? 1 : 2, c), new o.Polygon(n, e);
+ case "GeometryCollection":
+ for (s = 0, r = a.geometries.length; r > s; s++) { var d = this.geometryToLayer({ geometry: a.geometries[s], type: "Feature", properties: t.properties }, e);
+ d && l.push(d) } return new o.FeatureGroup(l);
+ default:
+ throw new Error("Invalid GeoJSON object.") } }, coordsToLatLng: function(t) { return new o.LatLng(t[1], t[0], t[2]) }, coordsToLatLngs: function(t, e, i) { for (var n, o = [], s = 0, r = t.length; r > s; s++) n = e ? this.coordsToLatLngs(t[s], e - 1, i) : (i || this.coordsToLatLng)(t[s]), o.push(n); return o }, latLngToCoords: function(t) { return t.alt !== i ? [t.lng, t.lat, t.alt] : [t.lng, t.lat] }, latLngsToCoords: function(t, e, i) { for (var n = [], s = 0, r = t.length; r > s; s++) n.push(e ? o.GeoJSON.latLngsToCoords(t[s], e - 1, i) : o.GeoJSON.latLngToCoords(t[s])); return !e && i && n.push(n[0]), n }, getFeature: function(t, e) { return t.feature ? o.extend({}, t.feature, { geometry: e }) : o.GeoJSON.asFeature(e) }, asFeature: function(t) { return "Feature" === t.type ? t : { type: "Feature", properties: {}, geometry: t } } });
+ var r = { toGeoJSON: function() { return o.GeoJSON.getFeature(this, { type: "Point", coordinates: o.GeoJSON.latLngToCoords(this.getLatLng()) }) } };
+ o.Marker.include(r), o.Circle.include(r), o.CircleMarker.include(r), o.Polyline.prototype.toGeoJSON = function() { var t = !o.Polyline._flat(this._latlngs),
+ e = o.GeoJSON.latLngsToCoords(this._latlngs, t ? 1 : 0); return o.GeoJSON.getFeature(this, { type: (t ? "Multi" : "") + "LineString", coordinates: e }) }, o.Polygon.prototype.toGeoJSON = function() { var t = !o.Polyline._flat(this._latlngs),
+ e = t && !o.Polyline._flat(this._latlngs[0]),
+ i = o.GeoJSON.latLngsToCoords(this._latlngs, e ? 2 : t ? 1 : 0, !0); return t || (i = [i]), o.GeoJSON.getFeature(this, { type: (e ? "Multi" : "") + "Polygon", coordinates: i }) }, o.LayerGroup.include({ toMultiPoint: function() { var t = []; return this.eachLayer(function(e) { t.push(e.toGeoJSON().geometry.coordinates) }), o.GeoJSON.getFeature(this, { type: "MultiPoint", coordinates: t }) }, toGeoJSON: function() { var t = this.feature && this.feature.geometry && this.feature.geometry.type; if ("MultiPoint" === t) return this.toMultiPoint(); var e = "GeometryCollection" === t,
+ i = []; return this.eachLayer(function(t) { if (t.toGeoJSON) { var n = t.toGeoJSON();
+ i.push(e ? n.geometry : o.GeoJSON.asFeature(n)) } }), e ? o.GeoJSON.getFeature(this, { geometries: i, type: "GeometryCollection" }) : { type: "FeatureCollection", features: i } } }), o.geoJson = function(t, e) { return new o.GeoJSON(t, e) };
+ var a = "_leaflet_events";
+ o.DomEvent = { on: function(t, e, i, n) { if ("object" == typeof e)
+ for (var s in e) this._on(t, s, e[s], i);
+ else { e = o.Util.splitWords(e); for (var r = 0, a = e.length; a > r; r++) this._on(t, e[r], i, n) } return this }, off: function(t, e, i, n) { if ("object" == typeof e)
+ for (var s in e) this._off(t, s, e[s], i);
+ else { e = o.Util.splitWords(e); for (var r = 0, a = e.length; a > r; r++) this._off(t, e[r], i, n) } return this }, _on: function(e, i, n, s) { var r = i + o.stamp(n) + (s ? "_" + o.stamp(s) : ""); if (e[a] && e[a][r]) return this; var h = function(i) { return n.call(s || e, i || t.event) },
+ l = h; return o.Browser.pointer && 0 === i.indexOf("touch") ? this.addPointerListener(e, i, h, r) : o.Browser.touch && "dblclick" === i && this.addDoubleTapListener ? this.addDoubleTapListener(e, h, r) : "addEventListener" in e ? "mousewheel" === i ? (e.addEventListener("DOMMouseScroll", h, !1), e.addEventListener(i, h, !1)) : "mouseenter" === i || "mouseleave" === i ? (h = function(i) { i = i || t.event, o.DomEvent._isExternalTarget(e, i) && l(i) }, e.addEventListener("mouseenter" === i ? "mouseover" : "mouseout", h, !1)) : ("click" === i && o.Browser.android && (h = function(t) { return o.DomEvent._filterClick(t, l) }), e.addEventListener(i, h, !1)) : "attachEvent" in e && e.attachEvent("on" + i, h), e[a] = e[a] || {}, e[a][r] = h, this }, _off: function(t, e, i, n) { var s = e + o.stamp(i) + (n ? "_" + o.stamp(n) : ""),
+ r = t[a] && t[a][s]; return r ? (o.Browser.pointer && 0 === e.indexOf("touch") ? this.removePointerListener(t, e, s) : o.Browser.touch && "dblclick" === e && this.removeDoubleTapListener ? this.removeDoubleTapListener(t, s) : "removeEventListener" in t ? "mousewheel" === e ? (t.removeEventListener("DOMMouseScroll", r, !1), t.removeEventListener(e, r, !1)) : t.removeEventListener("mouseenter" === e ? "mouseover" : "mouseleave" === e ? "mouseout" : e, r, !1) : "detachEvent" in t && t.detachEvent("on" + e, r), t[a][s] = null, this) : this }, stopPropagation: function(t) { return t.stopPropagation ? t.stopPropagation() : t.originalEvent ? t.originalEvent._stopped = !0 : t.cancelBubble = !0, o.DomEvent._skipped(t), this }, disableScrollPropagation: function(t) { return o.DomEvent.on(t, "mousewheel MozMousePixelScroll", o.DomEvent.stopPropagation) }, disableClickPropagation: function(t) { var e = o.DomEvent.stopPropagation; return o.DomEvent.on(t, o.Draggable.START.join(" "), e), o.DomEvent.on(t, { click: o.DomEvent._fakeStop, dblclick: e }) }, preventDefault: function(t) { return t.preventDefault ? t.preventDefault() : t.returnValue = !1, this }, stop: function(t) { return o.DomEvent.preventDefault(t).stopPropagation(t) }, getMousePosition: function(t, e) { if (!e) return new o.Point(t.clientX, t.clientY); var i = e.getBoundingClientRect(); return new o.Point(t.clientX - i.left - e.clientLeft, t.clientY - i.top - e.clientTop) }, getWheelDelta: function(t) { var e = 0; return t.wheelDelta && (e = t.wheelDelta / 120), t.detail && (e = -t.detail / 3), e }, _skipEvents: {}, _fakeStop: function(t) { o.DomEvent._skipEvents[t.type] = !0 }, _skipped: function(t) { var e = this._skipEvents[t.type]; return this._skipEvents[t.type] = !1, e }, _isExternalTarget: function(t, e) { var i = e.relatedTarget; if (!i) return !0; try { for (; i && i !== t;) i = i.parentNode } catch (n) { return !1 } return i !== t }, _filterClick: function(t, e) { var i = t.timeStamp || t.originalEvent.timeStamp,
+ n = o.DomEvent._lastClick && i - o.DomEvent._lastClick; return n && n > 100 && 500 > n || t.target._simulatedClick && !t._simulated ? void o.DomEvent.stop(t) : (o.DomEvent._lastClick = i, void e(t)) } }, o.DomEvent.addListener = o.DomEvent.on, o.DomEvent.removeListener = o.DomEvent.off, o.Draggable = o.Evented.extend({
+ statics: { START: o.Browser.touch ? ["touchstart", "mousedown"] : ["mousedown"], END: { mousedown: "mouseup", touchstart: "touchend", pointerdown: "touchend", MSPointerDown: "touchend" }, MOVE: { mousedown: "mousemove", touchstart: "touchmove", pointerdown: "touchmove", MSPointerDown: "touchmove" } },
+ initialize: function(t, e, i) { this._element = t, this._dragStartTarget = e || t, this._preventOutline = i },
+ enable: function() { this._enabled || (o.DomEvent.on(this._dragStartTarget, o.Draggable.START.join(" "), this._onDown, this), this._enabled = !0) },
+ disable: function() { this._enabled && (o.DomEvent.off(this._dragStartTarget, o.Draggable.START.join(" "), this._onDown, this), this._enabled = !1, this._moved = !1) },
+ _onDown: function(t) { if (this._moved = !1, !o.DomUtil.hasClass(this._element, "leaflet-zoom-anim") && !(o.Draggable._dragging || t.shiftKey || 1 !== t.which && 1 !== t.button && !t.touches) && this._enabled && (o.Draggable._dragging = !0, this._preventOutline && o.DomUtil.preventOutline(this._element), o.DomUtil.disableImageDrag(), o.DomUtil.disableTextSelection(), !this._moving)) { this.fire("down"); var i = t.touches ? t.touches[0] : t;
+ this._startPoint = new o.Point(i.clientX, i.clientY), this._startPos = this._newPos = o.DomUtil.getPosition(this._element), o.DomEvent.on(e, o.Draggable.MOVE[t.type], this._onMove, this).on(e, o.Draggable.END[t.type], this._onUp, this) } },
+ _onMove: function(t) {
+ if (t.touches && t.touches.length > 1) return void(this._moved = !0);
+ var i = t.touches && 1 === t.touches.length ? t.touches[0] : t,
+ n = new o.Point(i.clientX, i.clientY),
+ s = n.subtract(this._startPoint);
+ (s.x || s.y) && (o.Browser.touch && Math.abs(s.x) + Math.abs(s.y) < 3 || (o.DomEvent.preventDefault(t), this._moved || (this.fire("dragstart"), this._moved = !0, this._startPos = o.DomUtil.getPosition(this._element).subtract(s), o.DomUtil.addClass(e.body, "leaflet-dragging"), this._lastTarget = t.target || t.srcElement, o.DomUtil.addClass(this._lastTarget, "leaflet-drag-target")),
+ this._newPos = this._startPos.add(s), this._moving = !0, o.Util.cancelAnimFrame(this._animRequest), this._lastEvent = t, this._animRequest = o.Util.requestAnimFrame(this._updatePosition, this, !0)))
+ },
+ _updatePosition: function() { var t = { originalEvent: this._lastEvent };
+ this.fire("predrag", t), o.DomUtil.setPosition(this._element, this._newPos), this.fire("drag", t) },
+ _onUp: function() { o.DomUtil.removeClass(e.body, "leaflet-dragging"), this._lastTarget && (o.DomUtil.removeClass(this._lastTarget, "leaflet-drag-target"), this._lastTarget = null); for (var t in o.Draggable.MOVE) o.DomEvent.off(e, o.Draggable.MOVE[t], this._onMove, this).off(e, o.Draggable.END[t], this._onUp, this);
+ o.DomUtil.enableImageDrag(), o.DomUtil.enableTextSelection(), this._moved && this._moving && (o.Util.cancelAnimFrame(this._animRequest), this.fire("dragend", { distance: this._newPos.distanceTo(this._startPos) })), this._moving = !1, o.Draggable._dragging = !1 }
+ }), o.Handler = o.Class.extend({ initialize: function(t) { this._map = t }, enable: function() { this._enabled || (this._enabled = !0, this.addHooks()) }, disable: function() { this._enabled && (this._enabled = !1, this.removeHooks()) }, enabled: function() { return !!this._enabled } }), o.Map.mergeOptions({ dragging: !0, inertia: !o.Browser.android23, inertiaDeceleration: 3400, inertiaMaxSpeed: 1 / 0, easeLinearity: .2, worldCopyJump: !1 }), o.Map.Drag = o.Handler.extend({ addHooks: function() { if (!this._draggable) { var t = this._map;
+ this._draggable = new o.Draggable(t._mapPane, t._container), this._draggable.on({ down: this._onDown, dragstart: this._onDragStart, drag: this._onDrag, dragend: this._onDragEnd }, this), this._draggable.on("predrag", this._onPreDragLimit, this), t.options.worldCopyJump && (this._draggable.on("predrag", this._onPreDragWrap, this), t.on("zoomend", this._onZoomEnd, this), t.whenReady(this._onZoomEnd, this)) }
+ o.DomUtil.addClass(this._map._container, "leaflet-grab"), this._draggable.enable() }, removeHooks: function() { o.DomUtil.removeClass(this._map._container, "leaflet-grab"), this._draggable.disable() }, moved: function() { return this._draggable && this._draggable._moved }, _onDown: function() { this._map.stop() }, _onDragStart: function() { var t = this._map; if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) { var e = o.latLngBounds(this._map.options.maxBounds);
+ this._offsetLimit = o.bounds(this._map.latLngToContainerPoint(e.getNorthWest()).multiplyBy(-1), this._map.latLngToContainerPoint(e.getSouthEast()).multiplyBy(-1).add(this._map.getSize())), this._viscosity = Math.min(1, Math.max(0, this._map.options.maxBoundsViscosity)) } else this._offsetLimit = null;
+ t.fire("movestart").fire("dragstart"), t.options.inertia && (this._positions = [], this._times = []) }, _onDrag: function(t) { if (this._map.options.inertia) { var e = this._lastTime = +new Date,
+ i = this._lastPos = this._draggable._absPos || this._draggable._newPos;
+ this._positions.push(i), this._times.push(e), e - this._times[0] > 50 && (this._positions.shift(), this._times.shift()) }
+ this._map.fire("move", t).fire("drag", t) }, _onZoomEnd: function() { var t = this._map.getSize().divideBy(2),
+ e = this._map.latLngToLayerPoint([0, 0]);
+ this._initialWorldOffset = e.subtract(t).x, this._worldWidth = this._map.getPixelWorldBounds().getSize().x }, _viscousLimit: function(t, e) { return t - (t - e) * this._viscosity }, _onPreDragLimit: function() { if (this._viscosity && this._offsetLimit) { var t = this._draggable._newPos.subtract(this._draggable._startPos),
+ e = this._offsetLimit;
+ t.x < e.min.x && (t.x = this._viscousLimit(t.x, e.min.x)), t.y < e.min.y && (t.y = this._viscousLimit(t.y, e.min.y)), t.x > e.max.x && (t.x = this._viscousLimit(t.x, e.max.x)), t.y > e.max.y && (t.y = this._viscousLimit(t.y, e.max.y)), this._draggable._newPos = this._draggable._startPos.add(t) } }, _onPreDragWrap: function() { var t = this._worldWidth,
+ e = Math.round(t / 2),
+ i = this._initialWorldOffset,
+ n = this._draggable._newPos.x,
+ o = (n - e + i) % t + e - i,
+ s = (n + e + i) % t - e - i,
+ r = Math.abs(o + i) < Math.abs(s + i) ? o : s;
+ this._draggable._absPos = this._draggable._newPos.clone(), this._draggable._newPos.x = r }, _onDragEnd: function(t) { var e = this._map,
+ i = e.options,
+ n = !i.inertia || this._times.length < 2; if (e.fire("dragend", t), n) e.fire("moveend");
+ else { var s = this._lastPos.subtract(this._positions[0]),
+ r = (this._lastTime - this._times[0]) / 1e3,
+ a = i.easeLinearity,
+ h = s.multiplyBy(a / r),
+ l = h.distanceTo([0, 0]),
+ u = Math.min(i.inertiaMaxSpeed, l),
+ c = h.multiplyBy(u / l),
+ d = u / (i.inertiaDeceleration * a),
+ _ = c.multiplyBy(-d / 2).round();
+ _.x || _.y ? (_ = e._limitOffset(_, e.options.maxBounds), o.Util.requestAnimFrame(function() { e.panBy(_, { duration: d, easeLinearity: a, noMoveStart: !0, animate: !0 }) })) : e.fire("moveend") } } }), o.Map.addInitHook("addHandler", "dragging", o.Map.Drag), o.Map.mergeOptions({ doubleClickZoom: !0 }), o.Map.DoubleClickZoom = o.Handler.extend({ addHooks: function() { this._map.on("dblclick", this._onDoubleClick, this) }, removeHooks: function() { this._map.off("dblclick", this._onDoubleClick, this) }, _onDoubleClick: function(t) { var e = this._map,
+ i = e.getZoom(),
+ n = t.originalEvent.shiftKey ? Math.ceil(i) - 1 : Math.floor(i) + 1; "center" === e.options.doubleClickZoom ? e.setZoom(n) : e.setZoomAround(t.containerPoint, n) } }), o.Map.addInitHook("addHandler", "doubleClickZoom", o.Map.DoubleClickZoom), o.Map.mergeOptions({ scrollWheelZoom: !0, wheelDebounceTime: 40 }), o.Map.ScrollWheelZoom = o.Handler.extend({ addHooks: function() { o.DomEvent.on(this._map._container, { mousewheel: this._onWheelScroll, MozMousePixelScroll: o.DomEvent.preventDefault }, this), this._delta = 0 }, removeHooks: function() { o.DomEvent.off(this._map._container, { mousewheel: this._onWheelScroll, MozMousePixelScroll: o.DomEvent.preventDefault }, this) }, _onWheelScroll: function(t) { var e = o.DomEvent.getWheelDelta(t),
+ i = this._map.options.wheelDebounceTime;
+ this._delta += e, this._lastMousePos = this._map.mouseEventToContainerPoint(t), this._startTime || (this._startTime = +new Date); var n = Math.max(i - (+new Date - this._startTime), 0);
+ clearTimeout(this._timer), this._timer = setTimeout(o.bind(this._performZoom, this), n), o.DomEvent.stop(t) }, _performZoom: function() { var t = this._map,
+ e = this._delta,
+ i = t.getZoom();
+ t.stop(), e = e > 0 ? Math.ceil(e) : Math.floor(e), e = Math.max(Math.min(e, 4), -4), e = t._limitZoom(i + e) - i, this._delta = 0, this._startTime = null, e && ("center" === t.options.scrollWheelZoom ? t.setZoom(i + e) : t.setZoomAround(this._lastMousePos, i + e)) } }), o.Map.addInitHook("addHandler", "scrollWheelZoom", o.Map.ScrollWheelZoom), o.extend(o.DomEvent, { _touchstart: o.Browser.msPointer ? "MSPointerDown" : o.Browser.pointer ? "pointerdown" : "touchstart", _touchend: o.Browser.msPointer ? "MSPointerUp" : o.Browser.pointer ? "pointerup" : "touchend", addDoubleTapListener: function(t, e, i) {
+ function n(t) { var e; if (e = o.Browser.pointer ? o.DomEvent._pointersCount : t.touches.length, !(e > 1)) { var i = Date.now(),
+ n = i - (r || i);
+ a = t.touches ? t.touches[0] : t, h = n > 0 && l >= n, r = i } }
+
+ function s() { if (h && !a.cancelBubble) { if (o.Browser.pointer) { var t, i, n = {}; for (i in a) t = a[i], n[i] = t && t.bind ? t.bind(a) : t;
+ a = n }
+ a.type = "dblclick", e(a), r = null } } var r, a, h = !1,
+ l = 250,
+ u = "_leaflet_",
+ c = this._touchstart,
+ d = this._touchend; return t[u + c + i] = n, t[u + d + i] = s, t.addEventListener(c, n, !1), t.addEventListener(d, s, !1), this }, removeDoubleTapListener: function(t, e) { var i = "_leaflet_",
+ n = t[i + this._touchend + e]; return t.removeEventListener(this._touchstart, t[i + this._touchstart + e], !1), t.removeEventListener(this._touchend, n, !1), this } }), o.extend(o.DomEvent, { POINTER_DOWN: o.Browser.msPointer ? "MSPointerDown" : "pointerdown", POINTER_MOVE: o.Browser.msPointer ? "MSPointerMove" : "pointermove", POINTER_UP: o.Browser.msPointer ? "MSPointerUp" : "pointerup", POINTER_CANCEL: o.Browser.msPointer ? "MSPointerCancel" : "pointercancel", _pointers: {}, _pointersCount: 0, addPointerListener: function(t, e, i, n) { return "touchstart" === e ? this._addPointerStart(t, i, n) : "touchmove" === e ? this._addPointerMove(t, i, n) : "touchend" === e && this._addPointerEnd(t, i, n), this }, removePointerListener: function(t, e, i) { var n = t["_leaflet_" + e + i]; return "touchstart" === e ? t.removeEventListener(this.POINTER_DOWN, n, !1) : "touchmove" === e ? t.removeEventListener(this.POINTER_MOVE, n, !1) : "touchend" === e && (t.removeEventListener(this.POINTER_UP, n, !1), t.removeEventListener(this.POINTER_CANCEL, n, !1)), this }, _addPointerStart: function(t, i, n) { var s = o.bind(function(t) { "mouse" !== t.pointerType && t.pointerType !== t.MSPOINTER_TYPE_MOUSE && o.DomEvent.preventDefault(t), this._handlePointer(t, i) }, this); if (t["_leaflet_touchstart" + n] = s, t.addEventListener(this.POINTER_DOWN, s, !1), !this._pointerDocListener) { var r = o.bind(this._globalPointerUp, this);
+ e.documentElement.addEventListener(this.POINTER_DOWN, o.bind(this._globalPointerDown, this), !0), e.documentElement.addEventListener(this.POINTER_MOVE, o.bind(this._globalPointerMove, this), !0), e.documentElement.addEventListener(this.POINTER_UP, r, !0), e.documentElement.addEventListener(this.POINTER_CANCEL, r, !0), this._pointerDocListener = !0 } }, _globalPointerDown: function(t) { this._pointers[t.pointerId] = t, this._pointersCount++ }, _globalPointerMove: function(t) { this._pointers[t.pointerId] && (this._pointers[t.pointerId] = t) }, _globalPointerUp: function(t) { delete this._pointers[t.pointerId], this._pointersCount-- }, _handlePointer: function(t, e) { t.touches = []; for (var i in this._pointers) t.touches.push(this._pointers[i]);
+ t.changedTouches = [t], e(t) }, _addPointerMove: function(t, e, i) { var n = o.bind(function(t) {
+ (t.pointerType !== t.MSPOINTER_TYPE_MOUSE && "mouse" !== t.pointerType || 0 !== t.buttons) && this._handlePointer(t, e) }, this);
+ t["_leaflet_touchmove" + i] = n, t.addEventListener(this.POINTER_MOVE, n, !1) }, _addPointerEnd: function(t, e, i) { var n = o.bind(function(t) { this._handlePointer(t, e) }, this);
+ t["_leaflet_touchend" + i] = n, t.addEventListener(this.POINTER_UP, n, !1), t.addEventListener(this.POINTER_CANCEL, n, !1) } }), o.Map.mergeOptions({ touchZoom: o.Browser.touch && !o.Browser.android23, bounceAtZoomLimits: !0 }), o.Map.TouchZoom = o.Handler.extend({ addHooks: function() { o.DomEvent.on(this._map._container, "touchstart", this._onTouchStart, this) }, removeHooks: function() { o.DomEvent.off(this._map._container, "touchstart", this._onTouchStart, this) }, _onTouchStart: function(t) { var i = this._map; if (t.touches && 2 === t.touches.length && !i._animatingZoom && !this._zooming) { var n = i.mouseEventToContainerPoint(t.touches[0]),
+ s = i.mouseEventToContainerPoint(t.touches[1]);
+ this._centerPoint = i.getSize()._divideBy(2), this._startLatLng = i.containerPointToLatLng(this._centerPoint), "center" !== i.options.touchZoom && (this._pinchStartLatLng = i.containerPointToLatLng(n.add(s)._divideBy(2))), this._startDist = n.distanceTo(s), this._startZoom = i.getZoom(), this._moved = !1, this._zooming = !0, i.stop(), o.DomEvent.on(e, "touchmove", this._onTouchMove, this).on(e, "touchend", this._onTouchEnd, this), o.DomEvent.preventDefault(t) } }, _onTouchMove: function(t) { if (t.touches && 2 === t.touches.length && this._zooming) { var e = this._map,
+ i = e.mouseEventToContainerPoint(t.touches[0]),
+ n = e.mouseEventToContainerPoint(t.touches[1]),
+ s = i.distanceTo(n) / this._startDist; if (this._zoom = e.getScaleZoom(s, this._startZoom), "center" === e.options.touchZoom) { if (this._center = this._startLatLng, 1 === s) return } else { var r = i._add(n)._divideBy(2)._subtract(this._centerPoint); if (1 === s && 0 === r.x && 0 === r.y) return;
+ this._center = e.unproject(e.project(this._pinchStartLatLng).subtract(r)) } if (e.options.bounceAtZoomLimits || !(this._zoom <= e.getMinZoom() && 1 > s || this._zoom >= e.getMaxZoom() && s > 1)) { this._moved || (e._moveStart(!0), this._moved = !0), o.Util.cancelAnimFrame(this._animRequest); var a = o.bind(e._move, e, this._center, this._zoom, { pinch: !0, round: !1 });
+ this._animRequest = o.Util.requestAnimFrame(a, this, !0), o.DomEvent.preventDefault(t) } } }, _onTouchEnd: function() { if (!this._moved || !this._zooming) return void(this._zooming = !1);
+ this._zooming = !1, o.Util.cancelAnimFrame(this._animRequest), o.DomEvent.off(e, "touchmove", this._onTouchMove).off(e, "touchend", this._onTouchEnd); var t = this._zoom;
+ t = this._map._limitZoom(t - this._startZoom > 0 ? Math.ceil(t) : Math.floor(t)), this._map._animateZoom(this._center, t, !0, !0) } }), o.Map.addInitHook("addHandler", "touchZoom", o.Map.TouchZoom), o.Map.mergeOptions({ tap: !0, tapTolerance: 15 }), o.Map.Tap = o.Handler.extend({ addHooks: function() { o.DomEvent.on(this._map._container, "touchstart", this._onDown, this) }, removeHooks: function() { o.DomEvent.off(this._map._container, "touchstart", this._onDown, this) }, _onDown: function(t) { if (t.touches) { if (o.DomEvent.preventDefault(t), this._fireClick = !0, t.touches.length > 1) return this._fireClick = !1, void clearTimeout(this._holdTimeout); var i = t.touches[0],
+ n = i.target;
+ this._startPos = this._newPos = new o.Point(i.clientX, i.clientY), n.tagName && "a" === n.tagName.toLowerCase() && o.DomUtil.addClass(n, "leaflet-active"), this._holdTimeout = setTimeout(o.bind(function() { this._isTapValid() && (this._fireClick = !1, this._onUp(), this._simulateEvent("contextmenu", i)) }, this), 1e3), this._simulateEvent("mousedown", i), o.DomEvent.on(e, { touchmove: this._onMove, touchend: this._onUp }, this) } }, _onUp: function(t) { if (clearTimeout(this._holdTimeout), o.DomEvent.off(e, { touchmove: this._onMove, touchend: this._onUp }, this), this._fireClick && t && t.changedTouches) { var i = t.changedTouches[0],
+ n = i.target;
+ n && n.tagName && "a" === n.tagName.toLowerCase() && o.DomUtil.removeClass(n, "leaflet-active"), this._simulateEvent("mouseup", i), this._isTapValid() && this._simulateEvent("click", i) } }, _isTapValid: function() { return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance }, _onMove: function(t) { var e = t.touches[0];
+ this._newPos = new o.Point(e.clientX, e.clientY), this._simulateEvent("mousemove", e) }, _simulateEvent: function(i, n) { var o = e.createEvent("MouseEvents");
+ o._simulated = !0, n.target._simulatedClick = !0, o.initMouseEvent(i, !0, !0, t, 1, n.screenX, n.screenY, n.clientX, n.clientY, !1, !1, !1, !1, 0, null), n.target.dispatchEvent(o) } }), o.Browser.touch && !o.Browser.pointer && o.Map.addInitHook("addHandler", "tap", o.Map.Tap), o.Map.mergeOptions({ boxZoom: !0 }), o.Map.BoxZoom = o.Handler.extend({ initialize: function(t) { this._map = t, this._container = t._container, this._pane = t._panes.overlayPane }, addHooks: function() { o.DomEvent.on(this._container, "mousedown", this._onMouseDown, this) }, removeHooks: function() { o.DomEvent.off(this._container, "mousedown", this._onMouseDown, this) }, moved: function() { return this._moved }, _resetState: function() { this._moved = !1 }, _onMouseDown: function(t) { return !t.shiftKey || 1 !== t.which && 1 !== t.button ? !1 : (this._resetState(), o.DomUtil.disableTextSelection(), o.DomUtil.disableImageDrag(), this._startPoint = this._map.mouseEventToContainerPoint(t), void o.DomEvent.on(e, { contextmenu: o.DomEvent.stop, mousemove: this._onMouseMove, mouseup: this._onMouseUp, keydown: this._onKeyDown }, this)) }, _onMouseMove: function(t) { this._moved || (this._moved = !0, this._box = o.DomUtil.create("div", "leaflet-zoom-box", this._container), o.DomUtil.addClass(this._container, "leaflet-crosshair"), this._map.fire("boxzoomstart")), this._point = this._map.mouseEventToContainerPoint(t); var e = new o.Bounds(this._point, this._startPoint),
+ i = e.getSize();
+ o.DomUtil.setPosition(this._box, e.min), this._box.style.width = i.x + "px", this._box.style.height = i.y + "px" }, _finish: function() { this._moved && (o.DomUtil.remove(this._box), o.DomUtil.removeClass(this._container, "leaflet-crosshair")), o.DomUtil.enableTextSelection(), o.DomUtil.enableImageDrag(), o.DomEvent.off(e, { contextmenu: o.DomEvent.stop, mousemove: this._onMouseMove, mouseup: this._onMouseUp, keydown: this._onKeyDown }, this) }, _onMouseUp: function(t) { if ((1 === t.which || 1 === t.button) && (this._finish(), this._moved)) { setTimeout(o.bind(this._resetState, this), 0); var e = new o.LatLngBounds(this._map.containerPointToLatLng(this._startPoint), this._map.containerPointToLatLng(this._point));
+ this._map.fitBounds(e).fire("boxzoomend", { boxZoomBounds: e }) } }, _onKeyDown: function(t) { 27 === t.keyCode && this._finish() } }), o.Map.addInitHook("addHandler", "boxZoom", o.Map.BoxZoom), o.Map.mergeOptions({ keyboard: !0, keyboardPanOffset: 80, keyboardZoomOffset: 1 }), o.Map.Keyboard = o.Handler.extend({ keyCodes: { left: [37], right: [39], down: [40], up: [38], zoomIn: [187, 107, 61, 171], zoomOut: [189, 109, 54, 173] }, initialize: function(t) { this._map = t, this._setPanOffset(t.options.keyboardPanOffset), this._setZoomOffset(t.options.keyboardZoomOffset) }, addHooks: function() { var t = this._map._container;
+ t.tabIndex <= 0 && (t.tabIndex = "0"), o.DomEvent.on(t, { focus: this._onFocus, blur: this._onBlur, mousedown: this._onMouseDown }, this), this._map.on({ focus: this._addHooks, blur: this._removeHooks }, this) }, removeHooks: function() { this._removeHooks(), o.DomEvent.off(this._map._container, { focus: this._onFocus, blur: this._onBlur, mousedown: this._onMouseDown }, this), this._map.off({ focus: this._addHooks, blur: this._removeHooks }, this) }, _onMouseDown: function() { if (!this._focused) { var i = e.body,
+ n = e.documentElement,
+ o = i.scrollTop || n.scrollTop,
+ s = i.scrollLeft || n.scrollLeft;
+ this._map._container.focus(), t.scrollTo(s, o) } }, _onFocus: function() { this._focused = !0, this._map.fire("focus") }, _onBlur: function() { this._focused = !1, this._map.fire("blur") }, _setPanOffset: function(t) { var e, i, n = this._panKeys = {},
+ o = this.keyCodes; for (e = 0, i = o.left.length; i > e; e++) n[o.left[e]] = [-1 * t, 0]; for (e = 0, i = o.right.length; i > e; e++) n[o.right[e]] = [t, 0]; for (e = 0, i = o.down.length; i > e; e++) n[o.down[e]] = [0, t]; for (e = 0, i = o.up.length; i > e; e++) n[o.up[e]] = [0, -1 * t] }, _setZoomOffset: function(t) { var e, i, n = this._zoomKeys = {},
+ o = this.keyCodes; for (e = 0, i = o.zoomIn.length; i > e; e++) n[o.zoomIn[e]] = t; for (e = 0, i = o.zoomOut.length; i > e; e++) n[o.zoomOut[e]] = -t }, _addHooks: function() { o.DomEvent.on(e, "keydown", this._onKeyDown, this) }, _removeHooks: function() { o.DomEvent.off(e, "keydown", this._onKeyDown, this) }, _onKeyDown: function(t) { if (!(t.altKey || t.ctrlKey || t.metaKey)) { var e, i = t.keyCode,
+ n = this._map; if (i in this._panKeys) { if (n._panAnim && n._panAnim._inProgress) return;
+ e = this._panKeys[i], t.shiftKey && (e = o.point(e).multiplyBy(3)), n.panBy(e), n.options.maxBounds && n.panInsideBounds(n.options.maxBounds) } else if (i in this._zoomKeys) n.setZoom(n.getZoom() + (t.shiftKey ? 3 : 1) * this._zoomKeys[i]);
+ else { if (27 !== i) return;
+ n.closePopup() }
+ o.DomEvent.stop(t) } } }), o.Map.addInitHook("addHandler", "keyboard", o.Map.Keyboard), o.Handler.MarkerDrag = o.Handler.extend({ initialize: function(t) { this._marker = t }, addHooks: function() { var t = this._marker._icon;
+ this._draggable || (this._draggable = new o.Draggable(t, t, !0)), this._draggable.on({ dragstart: this._onDragStart, drag: this._onDrag, dragend: this._onDragEnd }, this).enable(), o.DomUtil.addClass(t, "leaflet-marker-draggable") }, removeHooks: function() { this._draggable.off({ dragstart: this._onDragStart, drag: this._onDrag, dragend: this._onDragEnd }, this).disable(), this._marker._icon && o.DomUtil.removeClass(this._marker._icon, "leaflet-marker-draggable") }, moved: function() { return this._draggable && this._draggable._moved }, _onDragStart: function() { this._marker.closePopup().fire("movestart").fire("dragstart") }, _onDrag: function(t) { var e = this._marker,
+ i = e._shadow,
+ n = o.DomUtil.getPosition(e._icon),
+ s = e._map.layerPointToLatLng(n);
+ i && o.DomUtil.setPosition(i, n), e._latlng = s, t.latlng = s, e.fire("move", t).fire("drag", t) }, _onDragEnd: function(t) { this._marker.fire("moveend").fire("dragend", t) } }), o.Control = o.Class.extend({ options: { position: "topright" }, initialize: function(t) { o.setOptions(this, t) }, getPosition: function() { return this.options.position }, setPosition: function(t) { var e = this._map; return e && e.removeControl(this), this.options.position = t, e && e.addControl(this), this }, getContainer: function() { return this._container }, addTo: function(t) { this.remove(), this._map = t; var e = this._container = this.onAdd(t),
+ i = this.getPosition(),
+ n = t._controlCorners[i]; return o.DomUtil.addClass(e, "leaflet-control"), -1 !== i.indexOf("bottom") ? n.insertBefore(e, n.firstChild) : n.appendChild(e), this }, remove: function() { return this._map ? (o.DomUtil.remove(this._container), this.onRemove && this.onRemove(this._map), this._map = null, this) : this }, _refocusOnMap: function(t) { this._map && t && t.screenX > 0 && t.screenY > 0 && this._map.getContainer().focus() } }), o.control = function(t) { return new o.Control(t) }, o.Map.include({ addControl: function(t) { return t.addTo(this), this }, removeControl: function(t) { return t.remove(), this }, _initControlPos: function() {
+ function t(t, s) { var r = i + t + " " + i + s;
+ e[t + s] = o.DomUtil.create("div", r, n) } var e = this._controlCorners = {},
+ i = "leaflet-",
+ n = this._controlContainer = o.DomUtil.create("div", i + "control-container", this._container);
+ t("top", "left"), t("top", "right"), t("bottom", "left"), t("bottom", "right") }, _clearControlPos: function() { o.DomUtil.remove(this._controlContainer) } }), o.Control.Zoom = o.Control.extend({ options: { position: "topleft", zoomInText: "+", zoomInTitle: "Zoom in", zoomOutText: "-", zoomOutTitle: "Zoom out" }, onAdd: function(t) { var e = "leaflet-control-zoom",
+ i = o.DomUtil.create("div", e + " leaflet-bar"),
+ n = this.options; return this._zoomInButton = this._createButton(n.zoomInText, n.zoomInTitle, e + "-in", i, this._zoomIn), this._zoomOutButton = this._createButton(n.zoomOutText, n.zoomOutTitle, e + "-out", i, this._zoomOut), this._updateDisabled(), t.on("zoomend zoomlevelschange", this._updateDisabled, this), i }, onRemove: function(t) { t.off("zoomend zoomlevelschange", this._updateDisabled, this) }, disable: function() { return this._disabled = !0, this._updateDisabled(), this }, enable: function() { return this._disabled = !1, this._updateDisabled(), this }, _zoomIn: function(t) { this._disabled || this._map.zoomIn(t.shiftKey ? 3 : 1) }, _zoomOut: function(t) { this._disabled || this._map.zoomOut(t.shiftKey ? 3 : 1) }, _createButton: function(t, e, i, n, s) { var r = o.DomUtil.create("a", i, n); return r.innerHTML = t, r.href = "#", r.title = e, o.DomEvent.on(r, "mousedown dblclick", o.DomEvent.stopPropagation).on(r, "click", o.DomEvent.stop).on(r, "click", s, this).on(r, "click", this._refocusOnMap, this), r }, _updateDisabled: function() { var t = this._map,
+ e = "leaflet-disabled";
+ o.DomUtil.removeClass(this._zoomInButton, e), o.DomUtil.removeClass(this._zoomOutButton, e), (this._disabled || t._zoom === t.getMinZoom()) && o.DomUtil.addClass(this._zoomOutButton, e), (this._disabled || t._zoom === t.getMaxZoom()) && o.DomUtil.addClass(this._zoomInButton, e) } }), o.Map.mergeOptions({ zoomControl: !0 }), o.Map.addInitHook(function() { this.options.zoomControl && (this.zoomControl = new o.Control.Zoom, this.addControl(this.zoomControl)) }), o.control.zoom = function(t) { return new o.Control.Zoom(t) }, o.Control.Attribution = o.Control.extend({ options: { position: "bottomright", prefix: '<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>' }, initialize: function(t) { o.setOptions(this, t), this._attributions = {} }, onAdd: function(t) { this._container = o.DomUtil.create("div", "leaflet-control-attribution"), o.DomEvent && o.DomEvent.disableClickPropagation(this._container); for (var e in t._layers) t._layers[e].getAttribution && this.addAttribution(t._layers[e].getAttribution()); return this._update(), this._container }, setPrefix: function(t) { return this.options.prefix = t, this._update(), this }, addAttribution: function(t) { return t ? (this._attributions[t] || (this._attributions[t] = 0), this._attributions[t]++, this._update(), this) : this }, removeAttribution: function(t) { return t ? (this._attributions[t] && (this._attributions[t]--, this._update()), this) : this }, _update: function() { if (this._map) { var t = []; for (var e in this._attributions) this._attributions[e] && t.push(e); var i = [];
+ this.options.prefix && i.push(this.options.prefix), t.length && i.push(t.join(", ")), this._container.innerHTML = i.join(" | ") } } }), o.Map.mergeOptions({ attributionControl: !0 }), o.Map.addInitHook(function() { this.options.attributionControl && (this.attributionControl = (new o.Control.Attribution).addTo(this)) }), o.control.attribution = function(t) { return new o.Control.Attribution(t) }, o.Control.Scale = o.Control.extend({ options: { position: "bottomleft", maxWidth: 100, metric: !0, imperial: !0 }, onAdd: function(t) { var e = "leaflet-control-scale",
+ i = o.DomUtil.create("div", e),
+ n = this.options; return this._addScales(n, e + "-line", i), t.on(n.updateWhenIdle ? "moveend" : "move", this._update, this), t.whenReady(this._update, this), i }, onRemove: function(t) { t.off(this.options.updateWhenIdle ? "moveend" : "move", this._update, this) }, _addScales: function(t, e, i) { t.metric && (this._mScale = o.DomUtil.create("div", e, i)), t.imperial && (this._iScale = o.DomUtil.create("div", e, i)) }, _update: function() { var t = this._map,
+ e = t.getSize().y / 2,
+ i = t.distance(t.containerPointToLatLng([0, e]), t.containerPointToLatLng([this.options.maxWidth, e]));
+ this._updateScales(i) }, _updateScales: function(t) { this.options.metric && t && this._updateMetric(t), this.options.imperial && t && this._updateImperial(t) }, _updateMetric: function(t) { var e = this._getRoundNum(t),
+ i = 1e3 > e ? e + " m" : e / 1e3 + " km";
+ this._updateScale(this._mScale, i, e / t) }, _updateImperial: function(t) { var e, i, n, o = 3.2808399 * t;
+ o > 5280 ? (e = o / 5280, i = this._getRoundNum(e), this._updateScale(this._iScale, i + " mi", i / e)) : (n = this._getRoundNum(o), this._updateScale(this._iScale, n + " ft", n / o)) }, _updateScale: function(t, e, i) { t.style.width = Math.round(this.options.maxWidth * i) + "px", t.innerHTML = e }, _getRoundNum: function(t) { var e = Math.pow(10, (Math.floor(t) + "").length - 1),
+ i = t / e; return i = i >= 10 ? 10 : i >= 5 ? 5 : i >= 3 ? 3 : i >= 2 ? 2 : 1, e * i } }), o.control.scale = function(t) { return new o.Control.Scale(t) }, o.Control.Layers = o.Control.extend({ options: { collapsed: !0, position: "topright", autoZIndex: !0, hideSingleBase: !1 }, initialize: function(t, e, i) { o.setOptions(this, i), this._layers = {}, this._lastZIndex = 0, this._handlingClick = !1; for (var n in t) this._addLayer(t[n], n); for (n in e) this._addLayer(e[n], n, !0) }, onAdd: function(t) { return this._initLayout(), this._update(), this._map = t, t.on("zoomend", this._checkDisabledLayers, this), this._container }, onRemove: function() { this._map.off("zoomend", this._checkDisabledLayers, this) }, addBaseLayer: function(t, e) { return this._addLayer(t, e), this._update() }, addOverlay: function(t, e) { return this._addLayer(t, e, !0), this._update() }, removeLayer: function(t) { return t.off("add remove", this._onLayerChange, this), delete this._layers[o.stamp(t)], this._update() }, _initLayout: function() { var t = "leaflet-control-layers",
+ e = this._container = o.DomUtil.create("div", t);
+ e.setAttribute("aria-haspopup", !0), o.DomEvent.disableClickPropagation(e), o.Browser.touch || o.DomEvent.disableScrollPropagation(e); var i = this._form = o.DomUtil.create("form", t + "-list"); if (this.options.collapsed) { o.Browser.android || o.DomEvent.on(e, { mouseenter: this._expand, mouseleave: this._collapse }, this); var n = this._layersLink = o.DomUtil.create("a", t + "-toggle", e);
+ n.href = "#", n.title = "Layers", o.Browser.touch ? o.DomEvent.on(n, "click", o.DomEvent.stop).on(n, "click", this._expand, this) : o.DomEvent.on(n, "focus", this._expand, this), o.DomEvent.on(i, "click", function() { setTimeout(o.bind(this._onInputClick, this), 0) }, this), this._map.on("click", this._collapse, this) } else this._expand();
+ this._baseLayersList = o.DomUtil.create("div", t + "-base", i), this._separator = o.DomUtil.create("div", t + "-separator", i), this._overlaysList = o.DomUtil.create("div", t + "-overlays", i), e.appendChild(i) }, _addLayer: function(t, e, i) { t.on("add remove", this._onLayerChange, this); var n = o.stamp(t);
+ this._layers[n] = { layer: t, name: e, overlay: i }, this.options.autoZIndex && t.setZIndex && (this._lastZIndex++, t.setZIndex(this._lastZIndex)) }, _update: function() { if (!this._container) return this;
+ o.DomUtil.empty(this._baseLayersList), o.DomUtil.empty(this._overlaysList); var t, e, i, n, s = 0; for (i in this._layers) n = this._layers[i], this._addItem(n), e = e || n.overlay, t = t || !n.overlay, s += n.overlay ? 0 : 1; return this.options.hideSingleBase && (t = t && s > 1, this._baseLayersList.style.display = t ? "" : "none"), this._separator.style.display = e && t ? "" : "none", this }, _onLayerChange: function(t) { this._handlingClick || this._update(); var e = this._layers[o.stamp(t.target)],
+ i = e.overlay ? "add" === t.type ? "overlayadd" : "overlayremove" : "add" === t.type ? "baselayerchange" : null;
+ i && this._map.fire(i, e) }, _createRadioElement: function(t, i) { var n = '<input type="radio" class="leaflet-control-layers-selector" name="' + t + '"' + (i ? ' checked="checked"' : "") + "/>",
+ o = e.createElement("div"); return o.innerHTML = n, o.firstChild }, _addItem: function(t) { var i, n = e.createElement("label"),
+ s = this._map.hasLayer(t.layer);
+ t.overlay ? (i = e.createElement("input"), i.type = "checkbox", i.className = "leaflet-control-layers-selector", i.defaultChecked = s) : i = this._createRadioElement("leaflet-base-layers", s), i.layerId = o.stamp(t.layer), o.DomEvent.on(i, "click", this._onInputClick, this); var r = e.createElement("span");
+ r.innerHTML = " " + t.name; var a = e.createElement("div");
+ n.appendChild(a), a.appendChild(i), a.appendChild(r); var h = t.overlay ? this._overlaysList : this._baseLayersList; return h.appendChild(n), this._checkDisabledLayers(), n }, _onInputClick: function() { var t, e, i, n = this._form.getElementsByTagName("input"),
+ o = [],
+ s = [];
+ this._handlingClick = !0; for (var r = n.length - 1; r >= 0; r--) t = n[r], e = this._layers[t.layerId].layer, i = this._map.hasLayer(e), t.checked && !i ? o.push(e) : !t.checked && i && s.push(e); for (r = 0; r < s.length; r++) this._map.removeLayer(s[r]); for (r = 0; r < o.length; r++) this._map.addLayer(o[r]);
+ this._handlingClick = !1, this._refocusOnMap() }, _expand: function() { o.DomUtil.addClass(this._container, "leaflet-control-layers-expanded"), this._form.style.height = null; var t = this._map._size.y - (this._container.offsetTop + 50);
+ t < this._form.clientHeight ? (o.DomUtil.addClass(this._form, "leaflet-control-layers-scrollbar"), this._form.style.height = t + "px") : o.DomUtil.removeClass(this._form, "leaflet-control-layers-scrollbar"), this._checkDisabledLayers() }, _collapse: function() { o.DomUtil.removeClass(this._container, "leaflet-control-layers-expanded") }, _checkDisabledLayers: function() { for (var t, e, n = this._form.getElementsByTagName("input"), o = this._map.getZoom(), s = n.length - 1; s >= 0; s--) t = n[s], e = this._layers[t.layerId].layer, t.disabled = e.options.minZoom !== i && o < e.options.minZoom || e.options.maxZoom !== i && o > e.options.maxZoom } }), o.control.layers = function(t, e, i) { return new o.Control.Layers(t, e, i) }, o.PosAnimation = o.Evented.extend({ run: function(t, e, i, n) { this.stop(), this._el = t, this._inProgress = !0, this._duration = i || .25, this._easeOutPower = 1 / Math.max(n || .5, .2), this._startPos = o.DomUtil.getPosition(t), this._offset = e.subtract(this._startPos), this._startTime = +new Date, this.fire("start"), this._animate() }, stop: function() { this._inProgress && (this._step(!0), this._complete()) }, _animate: function() { this._animId = o.Util.requestAnimFrame(this._animate, this), this._step() }, _step: function(t) { var e = +new Date - this._startTime,
+ i = 1e3 * this._duration;
+ i > e ? this._runFrame(this._easeOut(e / i), t) : (this._runFrame(1), this._complete()) }, _runFrame: function(t, e) { var i = this._startPos.add(this._offset.multiplyBy(t));
+ e && i._round(), o.DomUtil.setPosition(this._el, i), this.fire("step") }, _complete: function() { o.Util.cancelAnimFrame(this._animId), this._inProgress = !1, this.fire("end") }, _easeOut: function(t) { return 1 - Math.pow(1 - t, this._easeOutPower) } }), o.Map.include({ setView: function(t, e, n) { if (e = e === i ? this._zoom : this._limitZoom(e), t = this._limitCenter(o.latLng(t), e, this.options.maxBounds), n = n || {}, this.stop(), this._loaded && !n.reset && n !== !0) { n.animate !== i && (n.zoom = o.extend({ animate: n.animate }, n.zoom), n.pan = o.extend({ animate: n.animate, duration: n.duration }, n.pan)); var s = this._zoom !== e ? this._tryAnimatedZoom && this._tryAnimatedZoom(t, e, n.zoom) : this._tryAnimatedPan(t, n.pan); if (s) return clearTimeout(this._sizeTimer), this } return this._resetView(t, e), this }, panBy: function(t, e) { if (t = o.point(t).round(), e = e || {}, !t.x && !t.y) return this.fire("moveend"); if (e.animate !== !0 && !this.getSize().contains(t)) return this._resetView(this.unproject(this.project(this.getCenter()).add(t)), this.getZoom()), this; if (this._panAnim || (this._panAnim = new o.PosAnimation, this._panAnim.on({ step: this._onPanTransitionStep, end: this._onPanTransitionEnd }, this)), e.noMoveStart || this.fire("movestart"), e.animate !== !1) { o.DomUtil.addClass(this._mapPane, "leaflet-pan-anim"); var i = this._getMapPanePos().subtract(t);
+ this._panAnim.run(this._mapPane, i, e.duration || .25, e.easeLinearity) } else this._rawPanBy(t), this.fire("move").fire("moveend"); return this }, _onPanTransitionStep: function() { this.fire("move") }, _onPanTransitionEnd: function() { o.DomUtil.removeClass(this._mapPane, "leaflet-pan-anim"), this.fire("moveend") }, _tryAnimatedPan: function(t, e) { var i = this._getCenterOffset(t)._floor(); return (e && e.animate) === !0 || this.getSize().contains(i) ? (this.panBy(i, e), !0) : !1 } }), o.Map.mergeOptions({ zoomAnimation: !0, zoomAnimationThreshold: 4 });
+ var h = o.DomUtil.TRANSITION && o.Browser.any3d && !o.Browser.mobileOpera;
+ h && o.Map.addInitHook(function() { this._zoomAnimated = this.options.zoomAnimation, this._zoomAnimated && (this._createAnimProxy(), o.DomEvent.on(this._proxy, o.DomUtil.TRANSITION_END, this._catchTransitionEnd, this)) }), o.Map.include(h ? {
+ _createAnimProxy: function() {
+ var t = this._proxy = o.DomUtil.create("div", "leaflet-proxy leaflet-zoom-animated");
+ this._panes.mapPane.appendChild(t), this.on("zoomanim", function(e) { var i = o.DomUtil.TRANSFORM,
+ n = t.style[i];
+ o.DomUtil.setTransform(t, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1)), n === t.style[i] && this._animatingZoom && this._onZoomTransitionEnd() }, this), this.on("load moveend", function() {
+ var e = this.getCenter(),
+ i = this.getZoom();
+ o.DomUtil.setTransform(t, this.project(e, i), this.getZoomScale(i, 1))
+ }, this)
+ },
+ _catchTransitionEnd: function(t) { this._animatingZoom && t.propertyName.indexOf("transform") >= 0 && this._onZoomTransitionEnd() },
+ _nothingToAnimate: function() { return !this._container.getElementsByClassName("leaflet-zoom-animated").length },
+ _tryAnimatedZoom: function(t, e, i) { if (this._animatingZoom) return !0; if (i = i || {}, !this._zoomAnimated || i.animate === !1 || this._nothingToAnimate() || Math.abs(e - this._zoom) > this.options.zoomAnimationThreshold) return !1; var n = this.getZoomScale(e),
+ s = this._getCenterOffset(t)._divideBy(1 - 1 / n); return i.animate === !0 || this.getSize().contains(s) ? (o.Util.requestAnimFrame(function() { this._moveStart(!0)._animateZoom(t, e, !0) }, this), !0) : !1 },
+ _animateZoom: function(t, e, i, n) { i && (this._animatingZoom = !0, this._animateToCenter = t, this._animateToZoom = e, o.DomUtil.addClass(this._mapPane, "leaflet-zoom-anim")), this.fire("zoomanim", { center: t, zoom: e, noUpdate: n }), setTimeout(o.bind(this._onZoomTransitionEnd, this), 250) },
+ _onZoomTransitionEnd: function() { this._animatingZoom && (o.DomUtil.removeClass(this._mapPane, "leaflet-zoom-anim"), o.Util.requestAnimFrame(function() { this._animatingZoom = !1, this._move(this._animateToCenter, this._animateToZoom)._moveEnd(!0) }, this)) }
+ } : {}), o.Map.include({ flyTo: function(t, e, n) {
+ function s(t) { var e = (v * v - g * g + (t ? -1 : 1) * L * L * y * y) / (2 * (t ? v : g) * L * y); return Math.log(Math.sqrt(e * e + 1) - e) }
+
+ function r(t) { return (Math.exp(t) - Math.exp(-t)) / 2 }
+
+ function a(t) { return (Math.exp(t) + Math.exp(-t)) / 2 }
+
+ function h(t) { return r(t) / a(t) }
+
+ function l(t) { return g * (a(x) / a(x + P * t)) }
+
+ function u(t) { return g * (a(x) * h(x + P * t) - r(x)) / L }
+
+ function c(t) { return 1 - Math.pow(1 - t, 1.5) }
+
+ function d() { var i = (Date.now() - b) / D,
+ n = c(i) * w;
+ 1 >= i ? (this._flyToFrame = o.Util.requestAnimFrame(d, this), this._move(this.unproject(_.add(m.subtract(_).multiplyBy(u(n) / y)), f), this.getScaleZoom(g / l(n), f), { flyTo: !0 })) : this._move(t, e)._moveEnd(!0) } if (n = n || {}, n.animate === !1 || !o.Browser.any3d) return this.setView(t, e, n);
+ this.stop(); var _ = this.project(this.getCenter()),
+ m = this.project(t),
+ p = this.getSize(),
+ f = this._zoom;
+ t = o.latLng(t), e = e === i ? f : e; var g = Math.max(p.x, p.y),
+ v = g * this.getZoomScale(f, e),
+ y = m.distanceTo(_) || 1,
+ P = 1.42,
+ L = P * P,
+ x = s(0),
+ b = Date.now(),
+ w = (s(1) - x) / P,
+ D = n.duration ? 1e3 * n.duration : 1e3 * w * .8; return this._moveStart(!0), d.call(this), this }, flyToBounds: function(t, e) { var i = this._getBoundsCenterZoom(t, e); return this.flyTo(i.center, i.zoom, e) } }), o.Map.include({ _defaultLocateOptions: { timeout: 1e4, watch: !1 }, locate: function(t) { if (t = this._locateOptions = o.extend({}, this._defaultLocateOptions, t), !("geolocation" in navigator)) return this._handleGeolocationError({ code: 0, message: "Geolocation not supported." }), this; var e = o.bind(this._handleGeolocationResponse, this),
+ i = o.bind(this._handleGeolocationError, this); return t.watch ? this._locationWatchId = navigator.geolocation.watchPosition(e, i, t) : navigator.geolocation.getCurrentPosition(e, i, t), this }, stopLocate: function() { return navigator.geolocation && navigator.geolocation.clearWatch && navigator.geolocation.clearWatch(this._locationWatchId), this._locateOptions && (this._locateOptions.setView = !1), this }, _handleGeolocationError: function(t) { var e = t.code,
+ i = t.message || (1 === e ? "permission denied" : 2 === e ? "position unavailable" : "timeout");
+ this._locateOptions.setView && !this._loaded && this.fitWorld(), this.fire("locationerror", { code: e, message: "Geolocation error: " + i + "." }) }, _handleGeolocationResponse: function(t) { var e = t.coords.latitude,
+ i = t.coords.longitude,
+ n = new o.LatLng(e, i),
+ s = n.toBounds(t.coords.accuracy),
+ r = this._locateOptions; if (r.setView) { var a = this.getBoundsZoom(s);
+ this.setView(n, r.maxZoom ? Math.min(a, r.maxZoom) : a) } var h = { latlng: n, bounds: s, timestamp: t.timestamp }; for (var l in t.coords) "number" == typeof t.coords[l] && (h[l] = t.coords[l]);
+ this.fire("locationfound", h) } })
+}(window, document);
\ No newline at end of file
diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js
index 53b7108..9e3a8bf 100644
--- a/erpnext/public/js/setup_wizard.js
+++ b/erpnext/public/js/setup_wizard.js
@@ -15,34 +15,38 @@
{
// Domain
name: 'domain',
- domains: ["all"],
- title: __('Select your Domain'),
+ title: __('Select your Domains'),
fields: [
{
- fieldname: 'domain', label: __('Domain'), fieldtype: 'Select',
+ fieldname: 'domains',
+ label: __('Domains'),
+ fieldtype: 'MultiCheck',
options: [
{ "label": __("Distribution"), "value": "Distribution" },
{ "label": __("Manufacturing"), "value": "Manufacturing" },
{ "label": __("Retail"), "value": "Retail" },
{ "label": __("Services"), "value": "Services" },
+ { "label": __("Healthcare (beta)"), "value": "Healthcare" },
{ "label": __("Education"), "value": "Education" },
- {"label": __("Healthcare (beta)"), "value": "Healthcare"}
+ { "label": __("Agriculture (alpha)"), "value": "Agriculture" },
+ {"label": __("Non Profit (beta)"), "value": "Non Profit"}
], reqd: 1
},
],
// help: __('Select the nature of your business.'),
- onload: function (slide) {
- slide.get_input("domain").on("change", function () {
- frappe.setup.domain = $(this).val();
- frappe.wizard.refresh_slides();
- });
+ validate: function () {
+ if (this.values.domains.length === 0) {
+ frappe.msgprint(__("Please select at least one domain."));
+ return false;
+ }
+ frappe.setup.domains = this.values.domains;
+ return true;
},
},
{
// Brand
name: 'brand',
- domains: ["all"],
icon: "fa fa-bookmark",
title: __("The Brand"),
// help: __('Upload your letter head and logo. (you can edit them later).'),
@@ -56,14 +60,14 @@
},
{
fieldname: 'company_name',
- label: frappe.setup.domain === 'Education' ?
+ label: frappe.setup.domains.includes('Education') ?
__('Institute Name') : __('Company Name'),
fieldtype: 'Data',
reqd: 1
},
{
fieldname: 'company_abbr',
- label: frappe.setup.domain === 'Education' ?
+ label: frappe.setup.domains.includes('Education') ?
__('Institute Abbreviation') : __('Company Abbreviation'),
fieldtype: 'Data'
}
@@ -99,10 +103,9 @@
{
// Organisation
name: 'organisation',
- domains: ["all"],
title: __("Your Organization"),
icon: "fa fa-building",
- // help: (frappe.setup.domain === 'Education' ?
+ // help: frappe.setup.domains.includes('Education') ?
// __('The name of the institute for which you are setting up this system.') :
// __('The name of your company for which you are setting up this system.')),
fields: [
@@ -110,7 +113,7 @@
fieldname: 'company_tagline',
label: __('What does it do?'),
fieldtype: 'Data',
- placeholder: frappe.setup.domain === 'Education' ?
+ placeholder: frappe.setup.domains.includes('Education') ?
__('e.g. "Primary School" or "University"') :
__('e.g. "Build tools for builders"'),
reqd: 1
@@ -222,20 +225,3 @@
"Thailand": ["10-01", "09-30"],
"United Kingdom": ["04-01", "03-31"],
};
-
-// var test_values_edu = {
-// "language": "english",
-// "domain": "Education",
-// "country": "India",
-// "timezone": "Asia/Kolkata",
-// "currency": "INR",
-// "first_name": "Tester",
-// "email": "test@example.com",
-// "password": "test",
-// "company_name": "Hogwarts",
-// "company_abbr": "HS",
-// "company_tagline": "School for magicians",
-// "bank_account": "Gringotts Wizarding Bank",
-// "fy_start_date": "2016-04-01",
-// "fy_end_date": "2017-03-31"
-// }
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index c9e7733..bb6b0a0 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -668,7 +668,7 @@
data = frappe.db.sql("""
select
- `tabSales Order`.name, `tabSales Order`.customer_name, `tabSales Order`.status,
+ distinct `tabSales Order`.name, `tabSales Order`.customer_name, `tabSales Order`.status,
`tabSales Order`.delivery_status, `tabSales Order`.billing_status,
`tabSales Order Item`.delivery_date
from
diff --git a/erpnext/setup/doctype/company/company.json b/erpnext/setup/doctype/company/company.json
index f1b10a9..f5909f4 100644
--- a/erpnext/setup/doctype/company/company.json
+++ b/erpnext/setup/doctype/company/company.json
@@ -1,2148 +1,2147 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "autoname": "field:company_name",
- "beta": 0,
- "creation": "2013-04-10 08:35:39",
- "custom": 0,
- "description": "Legal Entity / Subsidiary with a separate Chart of Accounts belonging to the Organization.",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Setup",
- "editable_grid": 0,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:company_name",
+ "beta": 0,
+ "creation": "2013-04-10 08:35:39",
+ "custom": 0,
+ "description": "Legal Entity / Subsidiary with a separate Chart of Accounts belonging to the Organization.",
+ "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": "details",
- "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": "",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Section Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "details",
+ "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": "",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company_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": "Company",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "company_name",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "company_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": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "company_name",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
- "fieldname": "abbr",
- "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": "Abbr",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "abbr",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "abbr",
+ "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": "Abbr",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "abbr",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal && in_list(frappe.user_roles, \"System Manager\")",
- "fieldname": "change_abbr",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Change Abbreviation",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal && in_list(frappe.user_roles, \"System Manager\")",
+ "fieldname": "change_abbr",
+ "fieldtype": "Button",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Change Abbreviation",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "cb0",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb0",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "domain",
- "fieldtype": "Select",
- "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": "Domain",
- "length": 0,
- "no_copy": 0,
- "options": "Distribution\nManufacturing\nRetail\nServices\nEducation\nHealthcare\nOther",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "domain",
+ "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": "Domain",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Domain",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "sales_settings",
- "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": "Sales",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sales_settings",
+ "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": "Sales",
+ "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": "sales_monthly_history",
- "fieldtype": "Small Text",
- "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": "Sales Monthly History",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sales_monthly_history",
+ "fieldtype": "Small Text",
+ "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": "Sales Monthly History",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "monthly_sales_target",
- "fieldtype": "Currency",
- "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": "Monthly Sales Target",
- "length": 0,
- "no_copy": 0,
- "options": "default_currency",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "monthly_sales_target",
+ "fieldtype": "Currency",
+ "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": "Monthly Sales Target",
+ "length": 0,
+ "no_copy": 0,
+ "options": "default_currency",
+ "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": "column_break_goals",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_goals",
+ "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": "total_monthly_sales",
- "fieldtype": "Currency",
- "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": "Total Monthly Sales",
- "length": 0,
- "no_copy": 1,
- "options": "default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "total_monthly_sales",
+ "fieldtype": "Currency",
+ "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": "Total Monthly Sales",
+ "length": 0,
+ "no_copy": 1,
+ "options": "default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "charts_section",
- "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": "Default Values",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "charts_section",
+ "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": "Default Values",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_letter_head",
- "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": "Default Letter Head",
- "length": 0,
- "no_copy": 0,
- "options": "Letter Head",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_letter_head",
+ "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": "Default Letter Head",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Letter Head",
+ "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": "default_holiday_list",
- "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": "Default Holiday List",
- "length": 0,
- "no_copy": 0,
- "options": "Holiday List",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_holiday_list",
+ "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": "Default Holiday List",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Holiday List",
+ "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": "default_terms",
- "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": "Default Terms",
- "length": 0,
- "no_copy": 0,
- "options": "Terms and Conditions",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_terms",
+ "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": "Default Terms",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Terms and Conditions",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_currency",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Currency",
- "length": 0,
- "no_copy": 0,
- "options": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_currency",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Currency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_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": "country",
- "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": "Country",
- "length": 0,
- "no_copy": 0,
- "options": "Country",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "country",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Country",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Country",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "create_chart_of_accounts_based_on",
- "fieldtype": "Select",
- "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": "Create Chart Of Accounts Based On",
- "length": 0,
- "no_copy": 0,
- "options": "\nStandard Template\nExisting Company",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "create_chart_of_accounts_based_on",
+ "fieldtype": "Select",
+ "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": "Create Chart Of Accounts Based On",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nStandard Template\nExisting Company",
+ "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,
- "depends_on": "eval:doc.create_chart_of_accounts_based_on===\"Standard Template\"",
- "fieldname": "chart_of_accounts",
- "fieldtype": "Select",
- "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": "Chart Of Accounts Template",
- "length": 0,
- "no_copy": 1,
- "options": "",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.create_chart_of_accounts_based_on===\"Standard Template\"",
+ "fieldname": "chart_of_accounts",
+ "fieldtype": "Select",
+ "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": "Chart Of Accounts Template",
+ "length": 0,
+ "no_copy": 1,
+ "options": "",
+ "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,
- "depends_on": "eval:doc.create_chart_of_accounts_based_on===\"Existing Company\"",
- "fieldname": "existing_company",
- "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": "Existing Company ",
- "length": 0,
- "no_copy": 1,
- "options": "Company",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.create_chart_of_accounts_based_on===\"Existing Company\"",
+ "fieldname": "existing_company",
+ "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": "Existing Company ",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Company",
+ "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": "default_settings",
- "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": "Accounts Settings",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Section Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_settings",
+ "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": "Accounts Settings",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "default_bank_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Bank Account",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "default_bank_account",
- "oldfieldtype": "Link",
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "default_bank_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Bank Account",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "default_bank_account",
+ "oldfieldtype": "Link",
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "default_cash_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Cash Account",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "default_cash_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Cash Account",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "default_receivable_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Receivable Account",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "receivables_group",
- "oldfieldtype": "Link",
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "default_receivable_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Receivable Account",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "receivables_group",
+ "oldfieldtype": "Link",
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "round_off_account",
- "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": "Round Off Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "round_off_account",
+ "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": "Round Off Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "write_off_account",
- "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": "Write Off Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "write_off_account",
+ "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": "Write Off Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "exchange_gain_loss_account",
- "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": "Exchange Gain / Loss Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "exchange_gain_loss_account",
+ "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": "Exchange Gain / Loss Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break0",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break0",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "default_payable_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Payable Account",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "payables_group",
- "oldfieldtype": "Link",
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "default_payable_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Payable Account",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "payables_group",
+ "oldfieldtype": "Link",
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "default_expense_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Cost of Goods Sold Account",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "default_expense_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Cost of Goods Sold Account",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "default_income_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Income Account",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "default_income_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Income Account",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "default_payroll_payable_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Payroll Payable Account",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "default_payroll_payable_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Payroll Payable Account",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "round_off_cost_center",
- "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": "Round Off Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "round_off_cost_center",
+ "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": "Round Off Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_22",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_22",
+ "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,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Cost Center",
- "length": 0,
- "no_copy": 1,
- "options": "Cost Center",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "cost_center",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Cost Center",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "credit_limit",
- "fieldtype": "Currency",
- "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": "Credit Limit",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "credit_limit",
- "oldfieldtype": "Currency",
- "options": "default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "credit_limit",
+ "fieldtype": "Currency",
+ "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": "Credit Limit",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "credit_limit",
+ "oldfieldtype": "Currency",
+ "options": "default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_26",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_26",
+ "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": "credit_days_based_on",
- "fieldtype": "Select",
- "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": "Credit Days Based On",
- "length": 0,
- "no_copy": 0,
- "options": "\nFixed Days\nLast Day of the Next Month",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "credit_days_based_on",
+ "fieldtype": "Select",
+ "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": "Credit Days Based On",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nFixed Days\nLast Day of the Next Month",
+ "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,
- "depends_on": "eval:(!doc.__islocal && doc.credit_days_based_on=='Fixed Days')",
- "fieldname": "credit_days",
- "fieldtype": "Int",
- "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": "Credit Days",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "credit_days",
- "oldfieldtype": "Int",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:(!doc.__islocal && doc.credit_days_based_on=='Fixed Days')",
+ "fieldname": "credit_days",
+ "fieldtype": "Int",
+ "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": "Credit Days",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "credit_days",
+ "oldfieldtype": "Int",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "auto_accounting_for_stock_settings",
- "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": "Stock Settings",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "auto_accounting_for_stock_settings",
+ "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": "Stock Settings",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "fieldname": "enable_perpetual_inventory",
- "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": "Enable Perpetual Inventory",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "enable_perpetual_inventory",
+ "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": "Enable Perpetual Inventory",
+ "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": "default_inventory_account",
- "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": "Default Inventory Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_inventory_account",
+ "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": "Default Inventory Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "stock_adjustment_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock Adjustment Account",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "stock_adjustment_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Stock Adjustment Account",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_32",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_32",
+ "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": "stock_received_but_not_billed",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Stock Received But Not Billed",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "stock_received_but_not_billed",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Stock Received But Not Billed",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "expenses_included_in_valuation",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 1,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Expenses Included In Valuation",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expenses_included_in_valuation",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Expenses Included In Valuation",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "fixed_asset_depreciation_settings",
- "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": "Fixed Asset Depreciation Settings",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "fixed_asset_depreciation_settings",
+ "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": "Fixed Asset Depreciation Settings",
+ "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": "accumulated_depreciation_account",
- "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": "Accumulated Depreciation Account",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "accumulated_depreciation_account",
+ "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": "Accumulated Depreciation Account",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "depreciation_expense_account",
- "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": "Depreciation Expense Account",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "depreciation_expense_account",
+ "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": "Depreciation Expense Account",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "series_for_depreciation_entry",
- "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": "Series for Asset Depreciation Entry (Journal Entry)",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "series_for_depreciation_entry",
+ "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": "Series for Asset Depreciation Entry (Journal Entry)",
+ "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": "column_break_40",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_40",
+ "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": "disposal_account",
- "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": "Gain/Loss Account on Asset Disposal",
- "length": 0,
- "no_copy": 1,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "disposal_account",
+ "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": "Gain/Loss Account on Asset Disposal",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "depreciation_cost_center",
- "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": "Asset Depreciation Cost Center",
- "length": 0,
- "no_copy": 1,
- "options": "Cost Center",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "depreciation_cost_center",
+ "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": "Asset Depreciation Cost Center",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "For reference only.",
- "fieldname": "company_info",
- "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": "Company Info",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "For reference only.",
+ "fieldname": "company_info",
+ "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": "Company Info",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "address_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,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "address_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,
+ "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": "column_break1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "phone_no",
- "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": "Phone No",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "phone_no",
- "oldfieldtype": "Data",
- "options": "Phone",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "phone_no",
+ "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": "Phone No",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "phone_no",
+ "oldfieldtype": "Data",
+ "options": "Phone",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "fax",
- "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": "Fax",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "fax",
- "oldfieldtype": "Data",
- "options": "Phone",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "fax",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Fax",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "fax",
+ "oldfieldtype": "Data",
+ "options": "Phone",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "email",
- "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": "Email",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "email",
- "oldfieldtype": "Data",
- "options": "Email",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "email",
+ "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": "Email",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "email",
+ "oldfieldtype": "Data",
+ "options": "Email",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "website",
- "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": "Website",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "website",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "website",
+ "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": "Website",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "website",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "",
- "fieldname": "registration_info",
- "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": "",
- "length": 0,
- "no_copy": 0,
- "oldfieldtype": "Section Break",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "registration_info",
+ "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": "",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
"width": "50%"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Company registration numbers for your reference. Tax numbers etc.",
- "fieldname": "registration_details",
- "fieldtype": "Code",
- "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": "Registration Details",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "registration_details",
- "oldfieldtype": "Code",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Company registration numbers for your reference. Tax numbers etc.",
+ "fieldname": "registration_details",
+ "fieldtype": "Code",
+ "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": "Registration Details",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "registration_details",
+ "oldfieldtype": "Code",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "delete_company_transactions",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Delete Company Transactions",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "delete_company_transactions",
+ "fieldtype": "Button",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Delete Company Transactions",
+ "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,
- "icon": "fa fa-building",
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 0,
- "menu_index": 0,
- "modified": "2017-09-06 15:08:44.360880",
- "modified_by": "mohan@annapurna.com",
- "module": "Setup",
- "name": "Company",
- "owner": "Administrator",
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "fa fa-building",
+ "idx": 1,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "menu_index": 0,
+ "modified_by": "Administrator",
+ "module": "Setup",
+ "name": "Company",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 1,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "Accounts User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Employee",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Employee",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Sales User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Sales User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Purchase User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Purchase User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Stock User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Stock User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "email": 0,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Projects User",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "export": 0,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Projects User",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 0
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 1,
- "sort_order": "ASC",
- "track_changes": 1,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 1,
+ "sort_order": "ASC",
+ "track_changes": 1,
"track_seen": 0
-}
+}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index 8d1fb3d..0cab383 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -232,7 +232,7 @@
"new_quotations","pending_quotations","sales_order","purchase_order","pending_sales_orders","pending_purchase_orders",
"invoiced_amount", "payables", "bank_balance", "credit_balance"):
if self.get(key):
- cache_key = "email_digest:card:{0}:{1}:{2}".format(self.company, self.frequency, key)
+ cache_key = "email_digest:card:{0}:{1}:{2}:{3}".format(self.company, self.frequency, key, self.from_date)
card = cache.get(cache_key)
if card:
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index 364f21a..5d3ef78 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -78,7 +78,7 @@
@frappe.whitelist(allow_guest=True)
def get_product_list_for_group(product_group=None, start=0, limit=10, search=None):
- child_groups = ", ".join(['"' + i[0] + '"' for i in get_child_groups(product_group)])
+ child_groups = ", ".join(['"' + frappe.db.escape(i[0]) + '"' for i in get_child_groups(product_group)])
# base query
query = """select I.name, I.item_name, I.item_code, I.route, I.image, I.website_image, I.thumbnail, I.item_group,
diff --git a/erpnext/setup/setup_wizard/data/test_mfg.json b/erpnext/setup/setup_wizard/data/test_mfg.json
index b6ea665..efc5fa8 100644
--- a/erpnext/setup/setup_wizard/data/test_mfg.json
+++ b/erpnext/setup/setup_wizard/data/test_mfg.json
@@ -8,7 +8,7 @@
"currency": "INR",
"customer_1": "Test Customer 1",
"customer_2": "Test Customer 2",
- "domain": "Manufacturing",
+ "domains": ["Manufacturing"],
"email": "great@example.com",
"full_name": "Great Tester",
"fy_end_date": "2018-03-31",
diff --git a/erpnext/setup/setup_wizard/install_fixtures.py b/erpnext/setup/setup_wizard/install_fixtures.py
index ed89568..68a1578 100644
--- a/erpnext/setup/setup_wizard/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/install_fixtures.py
@@ -20,6 +20,8 @@
{ 'doctype': 'Domain', 'domain': 'Services'},
{ 'doctype': 'Domain', 'domain': 'Education'},
{ 'doctype': 'Domain', 'domain': 'Healthcare'},
+ { 'doctype': 'Domain', 'domain': 'Agriculture'},
+ { 'doctype': 'Domain', 'domain': 'Non Profit'},
# Setup Progress
{'doctype': "Setup Progress", "actions": [
@@ -213,6 +215,7 @@
{'doctype': "Party Type", "party_type": "Customer"},
{'doctype': "Party Type", "party_type": "Supplier"},
{'doctype': "Party Type", "party_type": "Employee"},
+ {'doctype': "Party Type", "party_type": "Member"},
{'doctype': "Opportunity Type", "name": "Hub"},
{'doctype': "Opportunity Type", "name": _("Sales")},
diff --git a/erpnext/setup/setup_wizard/sample_data.py b/erpnext/setup/setup_wizard/sample_data.py
index 5a2fbd3..c302841 100644
--- a/erpnext/setup/setup_wizard/sample_data.py
+++ b/erpnext/setup/setup_wizard/sample_data.py
@@ -10,7 +10,7 @@
from frappe import _
from markdown2 import markdown
-def make_sample_data(domain, make_dependent = False):
+def make_sample_data(domains, make_dependent = False):
"""Create a few opportunities, quotes, material requests, issues, todos, projects
to help the user get started"""
@@ -28,7 +28,7 @@
if items and warehouses:
make_material_request(frappe.get_all("Item"))
- make_projects(domain)
+ make_projects(domains)
import_email_alert()
frappe.db.commit()
@@ -89,7 +89,7 @@
def make_issue():
pass
-def make_projects(domain):
+def make_projects(domains):
current_date = frappe.utils.nowdate()
project = frappe.get_doc({
"doctype": "Project",
@@ -104,7 +104,7 @@
"file": "explore.md"
}]
- if domain == 'Education':
+ if 'Education' in domains:
tasks += [
{
"title": _("Setup your Institute in ERPNext"),
diff --git a/erpnext/setup/setup_wizard/setup_wizard.py b/erpnext/setup/setup_wizard/setup_wizard.py
index ec70c39..e861a96 100644
--- a/erpnext/setup/setup_wizard/setup_wizard.py
+++ b/erpnext/setup/setup_wizard/setup_wizard.py
@@ -39,8 +39,10 @@
create_logo(args)
frappe.local.message_log = []
+
+ domains = args.get('domains')
domain_settings = frappe.get_single('Domain Settings')
- domain_settings.set_active_domains([args.get('domain')])
+ domain_settings.set_active_domains(domains)
frappe.db.commit()
login_as_first_user(args)
@@ -49,7 +51,7 @@
frappe.clear_cache()
try:
- make_sample_data(args.get('domain'))
+ make_sample_data(domains)
frappe.clear_cache()
except:
# clear message
@@ -80,7 +82,7 @@
'country': args.get('country'),
'create_chart_of_accounts_based_on': 'Standard Template',
'chart_of_accounts': args.get('chart_of_accounts'),
- 'domain': args.get('domain')
+ 'domain': args.get('domains')[0]
}).insert()
#Enable shopping cart
diff --git a/erpnext/setup/setup_wizard/test_setup_wizard.py b/erpnext/setup/setup_wizard/test_setup_wizard.py
index 5e2a303..a489133 100644
--- a/erpnext/setup/setup_wizard/test_setup_wizard.py
+++ b/erpnext/setup/setup_wizard/test_setup_wizard.py
@@ -40,8 +40,7 @@
time.sleep(1)
# domain slide
- # time.sleep(3)
- driver.set_select("domain", "Manufacturing")
+ driver.set_multicheck("domains", ["Manufacturing"])
time.sleep(1)
driver.click(".next-btn")
diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py
index ffb3aa6..5fcc3a2 100644
--- a/erpnext/setup/utils.py
+++ b/erpnext/setup/utils.py
@@ -41,7 +41,7 @@
"email" :"test@erpnext.com",
"password" :"test",
"chart_of_accounts" : "Standard",
- "domain" : "Manufacturing",
+ "domains" : ["Manufacturing"],
})
frappe.db.sql("delete from `tabLeave Allocation`")
diff --git a/erpnext/stock/doctype/batch/batch.js b/erpnext/stock/doctype/batch/batch.js
index 20581dc..677d0f0 100644
--- a/erpnext/stock/doctype/batch/batch.js
+++ b/erpnext/stock/doctype/batch/batch.js
@@ -70,31 +70,38 @@
// move - ask for target warehouse and make stock entry
rows.find('.btn-move').on('click', function() {
var $btn = $(this);
- frappe.prompt({
- fieldname: 'to_warehouse',
- label: __('To Warehouse'),
- fieldtype: 'Link',
- options: 'Warehouse'
- },
- (data) => {
- frappe.call({
- method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
- args: {
- item_code: frm.doc.item,
- batch_no: frm.doc.name,
- qty: $btn.attr('data-qty'),
- from_warehouse: $btn.attr('data-warehouse'),
- to_warehouse: data.to_warehouse
- },
- callback: (r) => {
- frappe.show_alert(__('Stock Entry {0} created',
- ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
- frm.refresh();
- },
- });
- },
- __('Select Target Warehouse'),
- __('Move')
+ const fields = [
+ {
+ fieldname: 'to_warehouse',
+ label: __('To Warehouse'),
+ fieldtype: 'Link',
+ options: 'Warehouse'
+ }
+ ];
+
+ frappe.prompt(
+ fields,
+ (data) => {
+ frappe.call({
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry_utils.make_stock_entry',
+ args: {
+ item_code: frm.doc.item,
+ batch_no: frm.doc.name,
+ qty: $btn.attr('data-qty'),
+ from_warehouse: $btn.attr('data-warehouse'),
+ to_warehouse: data.to_warehouse,
+ source_document: frm.doc.reference_name,
+ reference_doctype: frm.doc.reference_doctype
+ },
+ callback: (r) => {
+ frappe.show_alert(__('Stock Entry {0} created',
+ ['<a href="#Form/Stock Entry/'+r.message.name+'">' + r.message.name+ '</a>']));
+ frm.refresh();
+ },
+ });
+ },
+ __('Select Target Warehouse'),
+ __('Move')
);
});
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index 42cdfb8..a75d724 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -1190,6 +1190,38 @@
"collapsible": 0,
"columns": 0,
"depends_on": "has_batch_no",
+ "description": "",
+ "fieldname": "create_new_batch",
+ "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": "Automatically Create New Batch",
+ "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,
+ "depends_on": "has_batch_no",
"fieldname": "has_expiry_date",
"fieldtype": "Check",
"hidden": 0,
@@ -1221,8 +1253,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "has_batch_no",
- "description": "",
- "fieldname": "create_new_batch",
+ "fieldname": "retain_sample",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -1231,7 +1262,39 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Automatically Create New Batch",
+ "label": "Retain Sample",
+ "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,
+ "depends_on": "eval: (doc.retain_sample && doc.has_batch_no)",
+ "description": "Maximum sample quantity that can be retained",
+ "fieldname": "sample_quantity",
+ "fieldtype": "Int",
+ "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": "Max Sample Quantity",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -3360,7 +3423,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 1,
- "modified": "2017-11-20 12:18:07.259756",
+ "modified": "2017-12-04 15:37:58.413290",
"modified_by": "Administrator",
"module": "Stock",
"name": "Item",
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 536f2f4..df90ad9 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -97,6 +97,7 @@
self.validate_website_image()
self.make_thumbnail()
self.validate_fixed_asset()
+ self.validate_retain_sample()
if not self.get("__islocal"):
self.old_item_group = frappe.db.get_value(self.doctype, self.name, "item_group")
@@ -256,6 +257,12 @@
if asset:
frappe.throw(_('"Is Fixed Asset" cannot be unchecked, as Asset record exists against the item'))
+ def validate_retain_sample(self):
+ if self.retain_sample and not frappe.db.get_single_value('Stock Settings', 'sample_retention_warehouse'):
+ frappe.throw(_("Please select Sample Retention Warehouse in Stock Settings first"));
+ if self.retain_sample and not self.has_batch_no:
+ frappe.throw(_(" {0} Retain Sample is based on batch, please check Has Batch No to retain sample of item").format(self.item_code))
+
def get_context(self, context):
context.show_search=True
context.search_link = '/product_search'
diff --git a/erpnext/stock/doctype/price_list/price_list.json b/erpnext/stock/doctype/price_list/price_list.json
index be6673e..d160f8a 100644
--- a/erpnext/stock/doctype/price_list/price_list.json
+++ b/erpnext/stock/doctype/price_list/price_list.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:price_list_name",
@@ -14,6 +15,7 @@
"engine": "InnoDB",
"fields": [
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -43,6 +45,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -70,6 +73,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -100,6 +104,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -129,6 +134,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -157,6 +163,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -185,6 +192,37 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "price_not_uom_dependant",
+ "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": "Price Not UOM Dependant",
+ "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,
@@ -212,6 +250,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -242,18 +281,18 @@
"unique": 0
}
],
+ "has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-tags",
"idx": 1,
"image_view": 0,
"in_create": 0,
- "in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 1,
- "modified": "2017-02-20 13:27:30.431064",
+ "modified": "2017-12-01 16:55:00.243382",
"modified_by": "Administrator",
"module": "Stock",
"name": "Price List",
diff --git a/erpnext/stock/doctype/price_list/test_price_list.js b/erpnext/stock/doctype/price_list/test_price_list.js
new file mode 100644
index 0000000..fe4e07b
--- /dev/null
+++ b/erpnext/stock/doctype/price_list/test_price_list.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Price List", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Price List
+ () => frappe.tests.make('Price List', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/stock/doctype/price_list/test_price_list_uom.js b/erpnext/stock/doctype/price_list/test_price_list_uom.js
new file mode 100644
index 0000000..526d0da
--- /dev/null
+++ b/erpnext/stock/doctype/price_list/test_price_list_uom.js
@@ -0,0 +1,58 @@
+QUnit.module('Price List');
+
+QUnit.test("test price list with uom dependancy", function(assert) {
+ assert.expect(2);
+ let done = assert.async();
+ frappe.run_serially([
+
+ () => frappe.set_route('Form', 'Price List', 'Standard Buying'),
+ () => {
+ cur_frm.set_value('price_not_uom_dependant','1');
+ frappe.timeout(1);
+ },
+ () => cur_frm.save(),
+
+ () => frappe.timeout(1),
+
+ () => {
+ return frappe.tests.make('Item Price', [
+ {price_list:'Standard Buying'},
+ {item_code: 'Test Product 3'},
+ {price_list_rate: 200}
+ ]);
+ },
+
+ () => cur_frm.save(),
+
+ () => {
+ return frappe.tests.make('Purchase Order', [
+ {supplier: 'Test Supplier'},
+ {currency: 'INR'},
+ {buying_price_list: 'Standard Buying'},
+ {items: [
+ [
+ {"item_code": 'Test Product 3'},
+ {"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 2)},
+ {"uom": 'Nos'},
+ {"conversion_factor": 3}
+ ]
+ ]},
+
+ ]);
+ },
+
+ () => cur_frm.save(),
+ () => frappe.timeout(0.3),
+
+ () => {
+ assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 3', "Item code correct");
+ assert.ok(cur_frm.doc.items[0].price_list_rate == 200, "Price list rate correct");
+ },
+
+ () => frappe.tests.click_button('Submit'),
+ () => frappe.tests.click_button('Yes'),
+ () => frappe.timeout(1),
+
+ () => done()
+ ]);
+});
\ No newline at end of file
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
index 4447fb8..791b253 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.js
@@ -98,6 +98,7 @@
if(flt(this.frm.doc.per_billed) < 100) {
cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice, __("Make"));
}
+ cur_frm.add_custom_button(__('Retention Stock Entry'), this.make_retention_stock_entry, __("Make"));
if(!this.frm.doc.subscription) {
cur_frm.add_custom_button(__('Subscription'), function() {
@@ -137,7 +138,26 @@
reopen_purchase_receipt: function() {
cur_frm.cscript.update_status("Submitted");
- }
+ },
+
+ make_retention_stock_entry: function() {
+ frappe.call({
+ method: "erpnext.stock.doctype.stock_entry.stock_entry.move_sample_to_retention_warehouse",
+ args:{
+ "company": cur_frm.doc.company,
+ "items": cur_frm.doc.items
+ },
+ callback: function (r) {
+ if (r.message) {
+ var doc = frappe.model.sync(r.message)[0];
+ frappe.set_route("Form", doc.doctype, doc.name);
+ }
+ else {
+ frappe.msgprint(__("Retention Stock Entry already created or Sample Quantity not provided"));
+ }
+ }
+ });
+ },
});
@@ -206,3 +226,36 @@
}
frm.toggle_reqd("supplier_warehouse", frm.doc.is_subcontracted==="Yes");
});
+
+frappe.ui.form.on('Purchase Receipt Item', {
+ item_code: function(frm, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ frappe.db.get_value('Item', {name: d.item_code}, 'sample_quantity', (r) => {
+ frappe.model.set_value(cdt, cdn, "sample_quantity", r.sample_quantity);
+ });
+ },
+ sample_quantity: function(frm, cdt, cdn) {
+ validate_sample_quantity(frm, cdt, cdn);
+ },
+ batch_no: function(frm, cdt, cdn) {
+ validate_sample_quantity(frm, cdt, cdn);
+ },
+});
+
+var validate_sample_quantity = function(frm, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ if (d.sample_quantity) {
+ frappe.call({
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry.validate_sample_quantity',
+ args: {
+ batch_no: d.batch_no,
+ item_code: d.item_code,
+ sample_quantity: d.sample_quantity,
+ qty: d.qty
+ },
+ callback: (r) => {
+ frappe.model.set_value(cdt, cdn, "sample_quantity", r.message);
+ }
+ });
+ }
+};
\ No newline at end of file
diff --git a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
index 6af8c09..b656c3f 100644
--- a/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -12,6 +12,7 @@
from erpnext.stock.doctype.serial_no.serial_no import SerialNoDuplicateError
from erpnext.accounts.doctype.account.test_account import get_inventory_account
+
class TestPurchaseReceipt(unittest.TestCase):
def setUp(self):
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
@@ -259,7 +260,7 @@
item_code = frappe.db.get_value('Item', {'has_serial_no': 1})
if not item_code:
- item = make_item("Test Serial Item 1", dict(has_serial_no = 1))
+ item = make_item("Test Serial Item 1", dict(has_serial_no=1))
item_code = item.name
serial_no = random_string(5)
@@ -273,11 +274,13 @@
serial_no=serial_no, basic_rate=100, do_not_submit=True)
self.assertRaises(SerialNoDuplicateError, se.submit)
+
def get_gl_entries(voucher_type, voucher_no):
return frappe.db.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
order by account desc""", (voucher_type, voucher_no), as_dict=1)
+
def make_purchase_receipt(**args):
frappe.db.set_value("Buying Settings", None, "allow_multiple_items", 1)
pr = frappe.new_doc("Purchase Receipt")
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index 070a9ef..1b4cfd9 100755
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -613,6 +613,69 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "retain_sample",
+ "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": "Retain Sample",
+ "length": 0,
+ "no_copy": 0,
+ "options": "item_code.retain_sample",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "retain_sample",
+ "fieldname": "sample_quantity",
+ "fieldtype": "Int",
+ "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": "Sample Quantity",
+ "length": 0,
+ "no_copy": 0,
+ "options": "item_code.sample_quantity",
+ "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": "rate_and_amount",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2227,7 +2290,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-11-30 14:19:14.276376",
+ "modified": "2017-12-06 13:50:08.201145",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.js b/erpnext/stock/doctype/stock_entry/stock_entry.js
index b089d7f..e8f5bd9 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.js
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.js
@@ -86,6 +86,12 @@
if(frm.doc.company) {
frm.trigger("toggle_display_account_head");
}
+
+ if(frm.doc.docstatus==1 && frm.doc.purpose == "Material Receipt") {
+ frm.add_custom_button(__('Make Retention Stock Entry'), function () {
+ frm.trigger("make_retention_stock_entry");
+ });
+ }
},
purpose: function(frm) {
@@ -122,6 +128,25 @@
});
},
+ make_retention_stock_entry: function(frm) {
+ frappe.call({
+ method: "erpnext.stock.doctype.stock_entry.stock_entry.move_sample_to_retention_warehouse",
+ args:{
+ "company": frm.doc.company,
+ "items": frm.doc.items
+ },
+ callback: function (r) {
+ if (r.message) {
+ var doc = frappe.model.sync(r.message)[0];
+ frappe.set_route("Form", doc.doctype, doc.name);
+ }
+ else {
+ frappe.msgprint(__("Retention Stock Entry already created or Sample Quantity not provided"));
+ }
+ }
+ });
+ },
+
toggle_display_account_head: function(frm) {
var enabled = erpnext.is_perpetual_inventory_enabled(frm.doc.company);
frm.fields_dict["items"].grid.set_column_disp(["cost_center", "expense_account"], enabled);
@@ -327,9 +352,33 @@
},
cost_center: function(frm, cdt, cdn) {
erpnext.utils.copy_value_in_all_row(frm.doc, cdt, cdn, "items", "cost_center");
- }
+ },
+ sample_quantity: function(frm, cdt, cdn) {
+ validate_sample_quantity(frm, cdt, cdn);
+ },
+ batch_no: function(frm, cdt, cdn) {
+ validate_sample_quantity(frm, cdt, cdn);
+ },
});
+var validate_sample_quantity = function(frm, cdt, cdn) {
+ var d = locals[cdt][cdn];
+ if (d.sample_quantity && frm.doc.purpose == "Material Receipt") {
+ frappe.call({
+ method: 'erpnext.stock.doctype.stock_entry.stock_entry.validate_sample_quantity',
+ args: {
+ batch_no: d.batch_no,
+ item_code: d.item_code,
+ sample_quantity: d.sample_quantity,
+ qty: d.transfer_qty
+ },
+ callback: (r) => {
+ frappe.model.set_value(cdt, cdn, "sample_quantity", r.message);
+ }
+ });
+ }
+};
+
frappe.ui.form.on('Landed Cost Taxes and Charges', {
amount: function(frm) {
frm.events.calculate_amount(frm);
@@ -575,6 +624,8 @@
this.frm.fields_dict["items"].grid.set_column_disp("s_warehouse", doc.purpose!='Material Receipt');
this.frm.fields_dict["items"].grid.set_column_disp("t_warehouse", doc.purpose!='Material Issue');
+ this.frm.fields_dict["items"].grid.set_column_disp("retain_sample", doc.purpose=='Material Receipt');
+ this.frm.fields_dict["items"].grid.set_column_disp("sample_quantity", doc.purpose=='Material Receipt');
this.frm.cscript.toggle_enable_bom();
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 368e869..a7e958b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -9,13 +9,14 @@
from erpnext.stock.utils import get_incoming_rate
from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError
from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor
-from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos
+from erpnext.stock.doctype.batch.batch import get_batch_no, set_batch_nos, get_batch_qty
from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
import json
class IncorrectValuationRateError(frappe.ValidationError): pass
class DuplicateEntryForProductionOrderError(frappe.ValidationError): pass
class OperationsNotCompleteError(frappe.ValidationError): pass
+class MaxSampleAlreadyRetainedError(frappe.ValidationError): pass
from erpnext.controllers.stock_controller import StockController
@@ -472,7 +473,7 @@
def get_item_details(self, args=None, for_update=False):
item = frappe.db.sql("""select stock_uom, description, image, item_name,
expense_account, buying_cost_center, item_group, has_serial_no,
- has_batch_no
+ has_batch_no, sample_quantity
from `tabItem`
where name = %s
and disabled=0
@@ -499,7 +500,8 @@
'basic_rate' : 0,
'serial_no' : '',
'has_serial_no' : item.has_serial_no,
- 'has_batch_no' : item.has_batch_no
+ 'has_batch_no' : item.has_batch_no,
+ 'sample_quantity' : item.sample_quantity
})
for d in [["Account", "expense_account", "default_expense_account"],
["Cost Center", "cost_center", "cost_center"]]:
@@ -803,6 +805,40 @@
if getdate(self.posting_date) > getdate(expiry_date):
frappe.throw(_("Batch {0} of Item {1} has expired.").format(item.batch_no, item.item_code))
+
+@frappe.whitelist()
+def move_sample_to_retention_warehouse(company, items):
+ if isinstance(items, basestring):
+ items = json.loads(items)
+ retention_warehouse = frappe.db.get_single_value('Stock Settings', 'sample_retention_warehouse')
+ stock_entry = frappe.new_doc("Stock Entry")
+ stock_entry.company = company
+ stock_entry.purpose = "Material Transfer"
+ for item in items:
+ if item.get('sample_quantity') and item.get('batch_no'):
+ sample_quantity = validate_sample_quantity(item.get('item_code'), item.get('sample_quantity'), item.get('transfer_qty') or item.get('qty'), item.get('batch_no'))
+ if sample_quantity:
+ sample_serial_nos = ''
+ if item.get('serial_no'):
+ serial_nos = (item.get('serial_no')).split()
+ if serial_nos and len(serial_nos) > item.get('sample_quantity'):
+ serial_no_list = serial_nos[:-(len(serial_nos)-item.get('sample_quantity'))]
+ sample_serial_nos = '\n'.join(serial_no_list)
+ stock_entry.append("items", {
+ "item_code": item.get('item_code'),
+ "s_warehouse": item.get('t_warehouse'),
+ "t_warehouse": retention_warehouse,
+ "qty": item.get('sample_quantity'),
+ "basic_rate": item.get('valuation_rate'),
+ 'uom': item.get('uom'),
+ 'stock_uom': item.get('stock_uom'),
+ "conversion_factor": 1.0,
+ "serial_no": sample_serial_nos,
+ 'batch_no': item.get('batch_no')
+ })
+ if stock_entry.get('items'):
+ return stock_entry.as_dict()
+
@frappe.whitelist()
def get_production_order_details(production_order):
production_order = frappe.get_doc("Production Order", production_order)
@@ -893,5 +929,24 @@
"actual_qty" : get_previous_sle(args).get("qty_after_transaction") or 0,
"basic_rate" : get_incoming_rate(args)
}
-
return ret
+
+@frappe.whitelist()
+def validate_sample_quantity(item_code, sample_quantity, qty, batch_no = None):
+ if cint(qty) < cint(sample_quantity):
+ frappe.throw(_("Sample quantity {0} cannot be more than received quantity {1}").format(sample_quantity, qty), alert=True)
+ retention_warehouse = frappe.db.get_single_value('Stock Settings', 'sample_retention_warehouse')
+ retainted_qty = 0
+ if batch_no:
+ retainted_qty = get_batch_qty(batch_no, retention_warehouse, item_code)
+ max_retain_qty = frappe.get_value('Item', item_code, 'sample_quantity')
+ if retainted_qty >= max_retain_qty:
+ frappe.msgprint(_("Maximum Samples - {0} have already been retained for Batch {1} and Item {2} in Batch {3}.").
+ format(retainted_qty, batch_no, item_code, batch_no), alert=True)
+ sample_quantity = 0
+ qty_diff = max_retain_qty-retainted_qty
+ if cint(sample_quantity) > cint(qty_diff):
+ frappe.msgprint(_("Maximum Samples - {0} can be retained for Batch {1} and Item {2}.").
+ format(max_retain_qty, batch_no, item_code), alert=True)
+ sample_quantity = qty_diff
+ return sample_quantity
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
index e1ec3ee..446f718 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry_utils.py
@@ -20,6 +20,16 @@
:do_not_save: Optional flag
:do_not_submit: Optional flag
'''
+
+ def process_serial_numbers(serial_nos_list):
+ serial_nos_list = [
+ '\n'.join(serial_num['serial_no'] for serial_num in serial_nos_list)
+ ]
+
+ uniques = list(set(serial_nos_list[0].split('\n')))
+
+ return '\n'.join(uniques)
+
s = frappe.new_doc("Stock Entry")
args = frappe._dict(args)
@@ -77,6 +87,25 @@
if not args.cost_center:
args.cost_center = frappe.get_value('Company', s.company, 'cost_center')
+ if not args.expense_account:
+ args.expense_account = frappe.get_value('Company', s.company, 'stock_adjustment_account')
+
+ # We can find out the serial number using the batch source document
+ serial_number = args.serial_no
+
+ if not args.serial_no and args.qty and args.batch_no:
+ serial_number_list = frappe.get_list(
+ doctype='Stock Ledger Entry',
+ fields=['serial_no'],
+ filters={
+ 'batch_no': args.batch_no,
+ 'warehouse': args.from_warehouse
+ }
+ )
+ serial_number = process_serial_numbers(serial_number_list)
+
+ args.serial_no = serial_number
+
s.append("items", {
"item_code": args.item,
"s_warehouse": args.source,
diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
index 0aecb78..551ad9f2 100644
--- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py
@@ -15,6 +15,7 @@
from frappe.tests.test_permissions import set_user_permission_doctypes
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
from erpnext.accounts.doctype.account.test_account import get_inventory_account
+from erpnext.stock.doctype.stock_entry.stock_entry import move_sample_to_retention_warehouse
def get_sle(**args):
condition, values = "", []
@@ -613,6 +614,61 @@
s2.submit()
s2.cancel()
+ def test_retain_sample(self):
+ from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
+ from erpnext.stock.doctype.batch.batch import get_batch_qty
+
+ create_warehouse("Test Warehouse for Sample Retention")
+ frappe.db.set_value("Stock Settings", None, "sample_retention_warehouse", "Test Warehouse for Sample Retention - _TC")
+
+ item = frappe.new_doc("Item")
+ item.item_code = "Retain Sample Item"
+ item.item_name = "Retain Sample Item"
+ item.description = "Retain Sample Item"
+ item.item_group = "All Item Groups"
+ item.is_stock_item = 1
+ item.has_batch_no = 1
+ item.create_new_batch = 1
+ item.retain_sample = 1
+ item.sample_quantity = 4
+ item.save()
+
+ receipt_entry = frappe.new_doc("Stock Entry")
+ receipt_entry.company = "_Test Company"
+ receipt_entry.purpose = "Material Receipt"
+ receipt_entry.append("items", {
+ "item_code": item.item_code,
+ "t_warehouse": "_Test Warehouse - _TC",
+ "qty": 40,
+ "basic_rate": 12,
+ "cost_center": "_Test Cost Center - _TC",
+ "sample_quantity": 4
+ })
+ receipt_entry.insert()
+ receipt_entry.submit()
+
+ retention_data = move_sample_to_retention_warehouse(receipt_entry.company, receipt_entry.get("items"))
+ retention_entry = frappe.new_doc("Stock Entry")
+ retention_entry.company = retention_data.company
+ retention_entry.purpose = retention_data.purpose
+ retention_entry.append("items", {
+ "item_code": item.item_code,
+ "t_warehouse": "Test Warehouse for Sample Retention - _TC",
+ "s_warehouse": "_Test Warehouse - _TC",
+ "qty": 4,
+ "basic_rate": 12,
+ "cost_center": "_Test Cost Center - _TC",
+ "batch_no": receipt_entry.get("items")[0].batch_no
+ })
+ retention_entry.insert()
+ retention_entry.submit()
+
+ qty_in_usable_warehouse = get_batch_qty(receipt_entry.get("items")[0].batch_no, "_Test Warehouse - _TC", "_Test Item")
+ qty_in_retention_warehouse = get_batch_qty(receipt_entry.get("items")[0].batch_no, "Test Warehouse for Sample Retention - _TC", "_Test Item")
+
+ self.assertEquals(qty_in_usable_warehouse, 36)
+ self.assertEquals(qty_in_retention_warehouse, 4)
+
def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None):
se = frappe.copy_doc(test_records[0])
se.get("items")[0].item_code = item_code or "_Test Serialized Item With Series"
diff --git a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
index 6afb54e..c7566d9 100644
--- a/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
+++ b/erpnext/stock/doctype/stock_entry_detail/stock_entry_detail.json
@@ -1,1282 +1,1345 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "hash",
- "beta": 0,
- "creation": "2013-03-29 18:22:12",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Other",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "hash",
+ "beta": 0,
+ "creation": "2013-03-29 18:22:12",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Other",
+ "editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "barcode",
- "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": "Barcode",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "barcode",
+ "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": "Barcode",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "section_break_2",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_2",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 2,
- "fieldname": "s_warehouse",
- "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": "Source Warehouse",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "s_warehouse",
- "oldfieldtype": "Link",
- "options": "Warehouse",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 2,
+ "fieldname": "s_warehouse",
+ "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": "Source Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "s_warehouse",
+ "oldfieldtype": "Link",
+ "options": "Warehouse",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "col_break1",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "col_break1",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 2,
- "fieldname": "t_warehouse",
- "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": "Target Warehouse",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "t_warehouse",
- "oldfieldtype": "Link",
- "options": "Warehouse",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 2,
+ "fieldname": "t_warehouse",
+ "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": "Target Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "t_warehouse",
+ "oldfieldtype": "Link",
+ "options": "Warehouse",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 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": "sec_break1",
- "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,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sec_break1",
+ "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,
+ "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": 1,
- "collapsible": 0,
- "columns": 3,
- "fieldname": "item_code",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Item Code",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "item_code",
- "oldfieldtype": "Link",
- "options": "Item",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 3,
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Item Code",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "item_code",
+ "oldfieldtype": "Link",
+ "options": "Item",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 1,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "col_break2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "col_break2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "item_name",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Item Name",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 1,
- "columns": 0,
- "fieldname": "section_break_8",
- "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": "Description",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "columns": 0,
+ "fieldname": "section_break_8",
+ "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": "Description",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "description",
- "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": "Description",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "description",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": "300px",
- "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": "description",
+ "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": "Description",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "description",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": "300px",
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0,
"width": "300px"
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_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": "image",
- "fieldtype": "Attach",
- "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": "Image",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "image",
+ "fieldtype": "Attach",
+ "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": "Image",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "image_view",
- "fieldtype": "Image",
- "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": "Image View",
- "length": 0,
- "no_copy": 0,
- "options": "image",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "image_view",
+ "fieldtype": "Image",
+ "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": "Image View",
+ "length": 0,
+ "no_copy": 0,
+ "options": "image",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "quantity_and_rate",
- "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": "Quantity and Rate",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "quantity_and_rate",
+ "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": "Quantity and Rate",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 3,
- "fieldname": "qty",
- "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": "Qty",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "qty",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 3,
+ "fieldname": "qty",
+ "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": "Qty",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "qty",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 1,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "basic_rate",
- "fieldtype": "Currency",
- "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": "Basic Rate (as per Stock UOM)",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "incoming_rate",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "basic_rate",
+ "fieldtype": "Currency",
+ "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": "Basic Rate (as per Stock UOM)",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "incoming_rate",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "basic_amount",
- "fieldtype": "Currency",
- "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": "Basic Amount",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "basic_amount",
+ "fieldtype": "Currency",
+ "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": "Basic Amount",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "additional_cost",
- "fieldtype": "Currency",
- "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": "Additional Cost",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "additional_cost",
+ "fieldtype": "Currency",
+ "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": "Additional Cost",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "amount",
- "fieldtype": "Currency",
- "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": "Amount",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "amount",
- "oldfieldtype": "Currency",
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "amount",
+ "fieldtype": "Currency",
+ "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": "Amount",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "amount",
+ "oldfieldtype": "Currency",
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "valuation_rate",
- "fieldtype": "Currency",
- "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": "Valuation Rate",
- "length": 0,
- "no_copy": 0,
- "options": "Company:company:default_currency",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "valuation_rate",
+ "fieldtype": "Currency",
+ "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": "Valuation Rate",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company:company:default_currency",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "col_break3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "col_break3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "uom",
- "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": "UOM",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "uom",
- "oldfieldtype": "Link",
- "options": "UOM",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "uom",
+ "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": "UOM",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "uom",
+ "oldfieldtype": "Link",
+ "options": "UOM",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "conversion_factor",
- "fieldtype": "Float",
- "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": "Conversion Factor",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "conversion_factor",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 1,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "conversion_factor",
+ "fieldtype": "Float",
+ "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": "Conversion Factor",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "conversion_factor",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 1,
+ "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,
- "fieldname": "stock_uom",
- "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": "Stock UOM",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "stock_uom",
- "oldfieldtype": "Link",
- "options": "UOM",
- "permlevel": 0,
- "print_hide": 1,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "stock_uom",
+ "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": "Stock UOM",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "stock_uom",
+ "oldfieldtype": "Link",
+ "options": "UOM",
+ "permlevel": 0,
+ "print_hide": 1,
+ "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,
- "fieldname": "transfer_qty",
- "fieldtype": "Float",
- "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": "Qty as per Stock UOM",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "transfer_qty",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 1,
- "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,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "transfer_qty",
+ "fieldtype": "Float",
+ "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": "Qty as per Stock UOM",
+ "length": 0,
+ "no_copy": 0,
+ "oldfieldname": "transfer_qty",
+ "oldfieldtype": "Currency",
+ "permlevel": 0,
+ "print_hide": 1,
+ "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,
- "fieldname": "serial_no_batch",
- "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": "Serial No / Batch",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "retain_sample",
+ "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": "Retain Sample",
+ "length": 0,
+ "no_copy": 0,
+ "options": "item_code.retain_sample",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "serial_no",
- "fieldtype": "Small Text",
- "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": "Serial No",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "serial_no",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "retain_sample",
+ "fieldname": "sample_quantity",
+ "fieldtype": "Int",
+ "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": "Sample Quantity",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "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": "col_break4",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "serial_no_batch",
+ "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": "Serial No / Batch",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "batch_no",
- "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": "Batch No",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "batch_no",
- "oldfieldtype": "Link",
- "options": "Batch",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "serial_no",
+ "fieldtype": "Small Text",
+ "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": "Serial No",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "serial_no",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "accounting",
- "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": "Accounting",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "col_break4",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:cint(erpnext.is_perpetual_inventory_enabled(parent.company))",
- "fieldname": "expense_account",
- "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": "Difference Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "batch_no",
+ "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": "Batch No",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "batch_no",
+ "oldfieldtype": "Link",
+ "options": "Batch",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "col_break5",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "accounting",
+ "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": "Accounting",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": ":Company",
- "depends_on": "eval:cint(erpnext.is_perpetual_inventory_enabled(parent.company))",
- "fieldname": "cost_center",
- "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": "Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:cint(erpnext.is_perpetual_inventory_enabled(parent.company))",
+ "fieldname": "expense_account",
+ "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": "Difference Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "more_info",
- "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": "More Information",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "col_break5",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "allow_zero_valuation_rate",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow Zero Valuation Rate",
- "length": 0,
- "no_copy": 1,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": ":Company",
+ "depends_on": "eval:cint(erpnext.is_perpetual_inventory_enabled(parent.company))",
+ "fieldname": "cost_center",
+ "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": "Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "actual_qty",
- "fieldtype": "Float",
- "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": "Actual Qty (at source/target)",
- "length": 0,
- "no_copy": 1,
- "oldfieldname": "actual_qty",
- "oldfieldtype": "Read Only",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 1,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "more_info",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "More Information",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "BOM No. for a Finished Good Item",
- "fieldname": "bom_no",
- "fieldtype": "Link",
- "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": "BOM No",
- "length": 0,
- "no_copy": 0,
- "options": "BOM",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "allow_zero_valuation_rate",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow Zero Valuation Rate",
+ "length": 0,
+ "no_copy": 1,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "col_break6",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "actual_qty",
+ "fieldtype": "Float",
+ "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": "Actual Qty (at source/target)",
+ "length": 0,
+ "no_copy": 1,
+ "oldfieldname": "actual_qty",
+ "oldfieldtype": "Read Only",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "description": "Material Request used to make this Stock Entry",
- "fieldname": "material_request",
- "fieldtype": "Link",
- "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": "Material Request",
- "length": 0,
- "no_copy": 1,
- "options": "Material Request",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "BOM No. for a Finished Good Item",
+ "fieldname": "bom_no",
+ "fieldtype": "Link",
+ "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": "BOM No",
+ "length": 0,
+ "no_copy": 0,
+ "options": "BOM",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "material_request_item",
- "fieldtype": "Link",
- "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": "Material Request Item",
- "length": 0,
- "no_copy": 1,
- "options": "Material Request Item",
- "permlevel": 0,
- "print_hide": 1,
- "print_hide_if_no_value": 0,
- "read_only": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "col_break6",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "Material Request used to make this Stock Entry",
+ "fieldname": "material_request",
+ "fieldtype": "Link",
+ "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": "Material Request",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Material Request",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "material_request_item",
+ "fieldtype": "Link",
+ "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": "Material Request Item",
+ "length": 0,
+ "no_copy": 1,
+ "options": "Material Request Item",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 1,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2017-07-10 06:29:22.805345",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Stock Entry Detail",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_order": "ASC",
- "track_changes": 0,
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 1,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2017-11-14 12:46:51.828176",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Stock Entry Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_order": "ASC",
+ "track_changes": 0,
"track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_settings/stock_settings.json b/erpnext/stock/doctype/stock_settings/stock_settings.json
index 16726be..761f807 100644
--- a/erpnext/stock/doctype/stock_settings/stock_settings.json
+++ b/erpnext/stock/doctype/stock_settings/stock_settings.json
@@ -140,9 +140,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "1",
- "fieldname": "clean_description_html",
- "fieldtype": "Check",
+ "fieldname": "sample_retention_warehouse",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -150,9 +149,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Convert Item Description to Clean HTML",
+ "label": "Sample Retention Warehouse",
"length": 0,
"no_copy": 0,
+ "options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -290,6 +290,37 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "1",
+ "fieldname": "clean_description_html",
+ "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": "Convert Item Description to Clean 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
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_7",
"fieldtype": "Section Break",
"hidden": 0,
@@ -648,7 +679,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-11-14 16:19:50.274518",
+ "modified": "2017-11-17 01:35:49.562613",
"modified_by": "Administrator",
"module": "Stock",
"name": "Stock Settings",
diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py
index 790be71..2ceed97 100644
--- a/erpnext/stock/get_item_details.py
+++ b/erpnext/stock/get_item_details.py
@@ -155,6 +155,7 @@
"conversion_rate": 1.0,
"selling_price_list": None,
"price_list_currency": None,
+ "price_list_uom_dependant": None,
"plc_conversion_rate": 1.0,
"doctype": "",
"name": "",
@@ -311,8 +312,8 @@
out.price_list_rate = flt(price_list_rate) * flt(args.plc_conversion_rate) \
/ flt(args.conversion_rate)
-
- out.price_list_rate = flt(out.price_list_rate * (args.conversion_factor or 1.0))
+ if args.price_list_uom_dependant == 0:
+ out.price_list_rate = flt(out.price_list_rate * (args.conversion_factor or 1.0))
if not out.price_list_rate and args.transaction_type=="buying":
from erpnext.stock.doctype.item.item import get_last_purchase_details
@@ -504,6 +505,7 @@
"conversion_rate": 1.0,
"selling_price_list": None,
"price_list_currency": None,
+ "price_list_uom_dependant": None,
"plc_conversion_rate": 1.0,
"doctype": "",
"name": "",
@@ -530,7 +532,7 @@
children.append(item_details)
if as_doc:
- args.price_list_currency = parent.price_list_currency
+ args.price_list_currency = parent.price_list_currency,
args.plc_conversion_rate = parent.plc_conversion_rate
if args.get('items'):
for i, item in enumerate(args.get('items')):
@@ -565,11 +567,23 @@
return result.currency
+def get_price_list_uom_dependant(price_list):
+ if price_list:
+ result = frappe.db.get_value("Price List", {"name": price_list,
+ "enabled": 1}, ["name", "price_not_uom_dependant"], as_dict=True)
+
+ if not result:
+ throw(_("Price List {0} is disabled or does not exist").format(price_list))
+
+ return result.price_not_uom_dependant
+
+
def get_price_list_currency_and_exchange_rate(args):
if not args.price_list:
return {}
price_list_currency = get_price_list_currency(args.price_list)
+ price_list_uom_dependant = get_price_list_uom_dependant(args.price_list)
plc_conversion_rate = args.plc_conversion_rate
if (not plc_conversion_rate) or (price_list_currency and args.price_list_currency \
@@ -580,6 +594,7 @@
return frappe._dict({
"price_list_currency": price_list_currency,
+ "price_list_uom_dependant": price_list_uom_dependant,
"plc_conversion_rate": plc_conversion_rate
})
diff --git a/erpnext/templates/pages/non_profit/__init__.py b/erpnext/templates/pages/non_profit/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/templates/pages/non_profit/__init__.py
diff --git a/erpnext/templates/pages/non_profit/join-chapter.html b/erpnext/templates/pages/non_profit/join-chapter.html
new file mode 100644
index 0000000..284e9c4
--- /dev/null
+++ b/erpnext/templates/pages/non_profit/join-chapter.html
@@ -0,0 +1,59 @@
+{% extends "templates/web.html" %}
+
+{% block page_content %}
+
+{% macro chapter_button() %}
+ <p><a href="/{{ chapter.route }}" class='btn btn-primary'>
+ Go to Chapter Page</a></p>
+{% endmacro %}
+{% if frappe.session.user=='Guest' %}
+ <p>Please signup and login to join this chapter</p>
+ <p><a href="/login?redirect-to=/{{ chapter.route }}" class='btn btn-primary'>Login</a></p>
+{% else %}
+ {% if already_member %}
+ <p>You are already a member of {{ chapter.title }}!</p>
+ {{ chapter_button() }}
+ <p><a href="">Leave Chapter</a></p>
+ {% else %}
+ {% if frappe.local.request.method=='POST' %}
+ <p>Welcome to chapter {{ chapter.title }}!</p>
+ {{ chapter_button() }}
+ {% else %}
+ <div style="padding: 20px 0;">
+ <div class="row">
+ <div class="col-lg-8 col-md-8">
+ <form name="user-intro" action="/join-chapter" method='POST'>
+ <div class="form-group">
+ <input name="name" class="hidden form-control" type="text"
+ value="{{chapter.name}}">
+ <input name="csrf_token" class="hidden form-control" type="text"
+ value="{{frappe.session.csrf_token}}">
+ </div>
+ <div class="form-group">
+ <label for="user" class="">User Name</label>
+ <input name="user" class="form-control" type="text" value="{{ frappe.session.user }}">
+ </div>
+ <div class="form-group">
+ <label for="website_url" class="">Website URL</label>
+ <input name="website_url" required class="form-control" type="text"
+ placeholder="https://example.com" />
+ </div>
+ <div class="form-group">
+ <label for="introduction" class="">Introduction</label>
+ <textarea name="introduction" required class="form-control"
+ placeholder="Your profession and how you are associated with ERPNext"></textarea>
+ </div>
+ <div class="form-group">
+ <button type="Submit" id="update_member" class="btn btn-primary">
+ Submit</button>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ {% endif %}
+ {% endif %}
+
+{% endif %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/non_profit/join_chapter.js b/erpnext/templates/pages/non_profit/join_chapter.js
new file mode 100644
index 0000000..e2bc8bc
--- /dev/null
+++ b/erpnext/templates/pages/non_profit/join_chapter.js
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, EOSSF and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Chapter Member', {
+ onsubmit: function (frm) {
+ console.log("here" + frappe.session.user)
+ // body...
+ }
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/templates/pages/non_profit/join_chapter.py b/erpnext/templates/pages/non_profit/join_chapter.py
new file mode 100644
index 0000000..78ef053
--- /dev/null
+++ b/erpnext/templates/pages/non_profit/join_chapter.py
@@ -0,0 +1,22 @@
+import frappe
+
+def get_context(context):
+ context.no_cache = True
+ chapter = frappe.get_doc('Chapter', frappe.form_dict.name)
+ if frappe.session.user!='Guest':
+ if frappe.session.user in [d.user for d in chapter.members]:
+ context.already_member = True
+ else:
+ if frappe.request.method=='GET':
+ pass
+ elif frappe.request.method=='POST':
+ chapter.append('members', dict(
+ user=frappe.session.user,
+ introduction=frappe.form_dict.introduction,
+ website_url=frappe.form_dict.website_url,
+ enabled=1
+ ))
+ chapter.save(ignore_permissions=1)
+ frappe.db.commit()
+
+ context.chapter = chapter
diff --git a/erpnext/templates/pages/non_profit/leave-chapter.html b/erpnext/templates/pages/non_profit/leave-chapter.html
new file mode 100644
index 0000000..2f8452d
--- /dev/null
+++ b/erpnext/templates/pages/non_profit/leave-chapter.html
@@ -0,0 +1,16 @@
+{% extends "templates/web.html" %}
+<!--
+{% macro chapter_button() %}
+ <p><a href="/{{ chapter.route }}" class='btn btn-primary'>
+ Go to Chapter Page</a></p>
+{% endmacro %}
+ -->
+{% block page_content %}
+
+ {% if member_deleted %}
+ <p>You are not a member of {{ chapter.title }}!</p>
+ <p>Please signup and login to join this chapter</p>
+
+ <p><a href="/join-chapter?name={{ chapter.name }}" class='btn btn-primary'>Become Member agian</a></p>
+ {% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/templates/pages/non_profit/leave_chapter.py b/erpnext/templates/pages/non_profit/leave_chapter.py
new file mode 100644
index 0000000..6dbdeca
--- /dev/null
+++ b/erpnext/templates/pages/non_profit/leave_chapter.py
@@ -0,0 +1,15 @@
+import frappe
+
+def get_context(context):
+ context.no_cache = True
+ chapter = frappe.get_doc('Chapter', frappe.form_dict.name)
+ # if frappe.session.user!='Guest':
+ if frappe.session.user in [d.user for d in chapter.members]:
+ user = frappe.session.user
+ parent = frappe.form_dict.name
+ frappe.db.sql("""delete from `tabChapter Member` where parent = %s and user = %s """, (parent, user))
+ frappe.db.commit()
+
+ context.member_deleted = True
+
+ context.chapter = chapter
diff --git a/erpnext/tests/server/agriculture.txt b/erpnext/tests/server/agriculture.txt
new file mode 100644
index 0000000..3aae85a
--- /dev/null
+++ b/erpnext/tests/server/agriculture.txt
@@ -0,0 +1,5 @@
+Disease
+Crop
+Land Unit
+Crop Cycle
+Soil Texture
\ No newline at end of file
diff --git a/erpnext/tests/ui/agriculture.txt b/erpnext/tests/ui/agriculture.txt
new file mode 100644
index 0000000..4622bc0
--- /dev/null
+++ b/erpnext/tests/ui/agriculture.txt
@@ -0,0 +1,7 @@
+erpnext/agriculture/doctype/land_unit/test_land_unit.js
+erpnext/agriculture/doctype/fertilizer/test_fertilizer.js
+erpnext/agriculture/doctype/water_analysis/test_water_analysis.js
+erpnext/agriculture/doctype/disease/test_disease.js
+erpnext/agriculture/doctype/soil_texture/test_soil_texture.js
+erpnext/agriculture/doctype/crop/test_crop.js
+erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.js
\ No newline at end of file
diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt
index 9040b12..d02cae1 100644
--- a/erpnext/tests/ui/tests.txt
+++ b/erpnext/tests/ui/tests.txt
@@ -141,3 +141,17 @@
erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_margin.js
erpnext/hr/doctype/payroll_entry/test_set_salary_components.js
erpnext/hr/doctype/payroll_entry/test_payroll_entry.js
+erpnext/agriculture/doctype/land_unit/test_land_unit.js
+erpnext/agriculture/doctype/fertilizer/test_fertilizer.js
+erpnext/agriculture/doctype/water_analysis/test_water_analysis.js
+erpnext/agriculture/doctype/disease/test_disease.js
+erpnext/agriculture/doctype/soil_texture/test_soil_texture.js
+erpnext/agriculture/doctype/crop/test_crop.js
+erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.js
+erpnext/non_profit/doctype/membership_type/test_membership_type.js
+erpnext/non_profit/doctype/member/test_member.js
+erpnext/non_profit/doctype/volunteer_type/test_volunteer_type.js
+erpnext/non_profit/doctype/volunteer/test_volunteer.js
+erpnext/non_profit/doctype/donor_type/test_donor_type.js
+erpnext/non_profit/doctype/donor/test_donor.js
+erpnext/non_profit/doctype/grant_application/test_grant_application.js
\ No newline at end of file
diff --git a/erpnext/utilities/user_progress.py b/erpnext/utilities/user_progress.py
index e84377e..aa93c65 100644
--- a/erpnext/utilities/user_progress.py
+++ b/erpnext/utilities/user_progress.py
@@ -272,10 +272,9 @@
slides = []
slide_settings = get_slide_settings()
- domain = frappe.db.get_value('Company', erpnext.get_default_company(), 'domain')
-
+ domains = frappe.get_active_domains()
for s in slide_settings:
- if not s.domains or (domain and domain in s.domains):
+ if not s.domains or any(d in domains for d in s.domains):
s.mark_as_done_method = "erpnext.setup.doctype.setup_progress.setup_progress.set_action_completed_state"
s.done = get_action_completed_state(s.action_name) or 0
slides.append(s)