Merge the Land Unit doctype with the Location doctype (#14613)
* Merge Land Unit with the Location doctype
* Fix patch
* [minor] modification to Location structure
- Create a group node "All Land Units" and place all the land units
under it
- Remove "Linked Analysis" from location
diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.js b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.js
index ae28bb7..94392e7 100644
--- a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.js
+++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.js
@@ -10,7 +10,7 @@
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) => {
+ output['Location'].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;
@@ -31,18 +31,18 @@
function is_in_land_unit(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
index 0263b65..18a3b8c 100644
--- a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.json
+++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.json
@@ -43,7 +43,7 @@
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
- "unique": 0
+ "unique": 1
},
{
"allow_bulk_edit": 0,
@@ -95,7 +95,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Linked Land Unit",
+ "label": "Linked Location",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -118,8 +118,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "A link to all the Land Units in which the Crop is growing",
- "fieldname": "linked_land_unit",
+ "description": "A link to all the Locations in which the Crop is growing",
+ "fieldname": "linked_location",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -128,10 +128,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Linked Land Unit",
+ "label": "Linked Location",
"length": 0,
"no_copy": 0,
- "options": "Linked Land Unit",
+ "options": "Linked Location",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -844,7 +844,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-06-05 03:24:09.054864",
+ "modified": "2018-06-20 04:41:36.148829",
"modified_by": "Administrator",
"module": "Agriculture",
"name": "Crop Cycle",
diff --git a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
index e090706..bb9045c 100644
--- a/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
+++ b/erpnext/agriculture/doctype/crop_cycle/crop_cycle.py
@@ -81,10 +81,10 @@
for doctype in linked_doctypes:
output[doctype] = frappe.get_all(doctype, fields=required_fields)
- output['Land Unit'] = []
+ output['Location'] = []
- for land in self.linked_land_unit:
- output['Land Unit'].append(frappe.get_doc('Land Unit', land.land_unit))
+ for location in self.linked_location:
+ output['Location'].append(frappe.get_doc('Location', location.location))
frappe.publish_realtime("List of Linked Docs",
output, user=frappe.session.user)
@@ -105,7 +105,7 @@
return ast.literal_eval(doc.location).get('features')[0].get('geometry').get('type')
-def is_in_land_unit(point, vs):
+def is_in_location(point, vs):
x, y = point
inside = False
diff --git a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
index 136858b..5510d5a 100644
--- a/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
+++ b/erpnext/agriculture/doctype/crop_cycle/test_crop_cycle.py
@@ -3,66 +3,72 @@
# See license.txt
from __future__ import unicode_literals
-import frappe
import unittest
-test_dependencies = ["Crop", "Fertilizer", "Land Unit", "Disease"]
+import frappe
+from frappe.utils import datetime
+
+test_dependencies = ["Crop", "Fertilizer", "Location", "Disease"]
+
class TestCropCycle(unittest.TestCase):
def test_crop_cycle_creation(self):
cycle = frappe.get_doc('Crop Cycle', 'Basil from seed 2017')
- self.assertEqual(frappe.db.exists('Crop Cycle', 'Basil from seed 2017'), 'Basil from seed 2017')
+ self.assertTrue(frappe.db.exists('Crop Cycle', 'Basil from seed 2017'))
- # check if the tasks were created
+ # check if the tasks were created
self.assertEqual(check_task_creation(), True)
self.assertEqual(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)
+ "exp_start_date": datetime.date(2017, 11, 21),
+ "exp_end_date": 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)
+ "exp_start_date": datetime.date(2017, 11, 23),
+ "exp_end_date": 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)
+ "exp_start_date": datetime.date(2017, 11, 11),
+ "exp_end_date": 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)
+ "exp_start_date": datetime.date(2017, 11, 12),
+ "exp_end_date": 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)
+ "exp_start_date": datetime.date(2017, 11, 14),
+ "exp_end_date": 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)
+ "exp_start_date": datetime.date(2017, 11, 18),
+ "exp_end_date": 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)
+ "exp_start_date": datetime.date(2017, 11, 20),
+ "exp_end_date": 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)
+ "Final cut": {
+ "exp_start_date": datetime.date(2017, 11, 25),
+ "exp_end_date": 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 list(all_task_dict):
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
+
+ return True if not all_task_dict else False
+
def check_project_creation():
- if frappe.db.exists('Project', 'Basil from seed 2017'): return True
- else: return False
\ No newline at end of file
+ return True if frappe.db.exists('Project', 'Basil from seed 2017') else False
diff --git a/erpnext/agriculture/doctype/land_unit/land_unit.js b/erpnext/agriculture/doctype/land_unit/land_unit.js
deleted file mode 100644
index 3bf1434..0000000
--- a/erpnext/agriculture/doctype/land_unit/land_unit.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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");
- frm.set_query("parent_land_unit", function() {
- return {
- "filters": {
- "is_group": 1
- }
- };
- });
- },
-
- 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'];
- }
- },
-});
diff --git a/erpnext/agriculture/doctype/land_unit/land_unit.json b/erpnext/agriculture/doctype/land_unit/land_unit.json
deleted file mode 100644
index 94d350f..0000000
--- a/erpnext/agriculture/doctype/land_unit/land_unit.json
+++ /dev/null
@@ -1,691 +0,0 @@
-{
- "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": 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_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": 1,
- "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": "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": "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-14 18:16:15.124188",
- "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": 1,
- "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
deleted file mode 100644
index 269bbce..0000000
--- a/erpnext/agriculture/doctype/land_unit/land_unit.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# -*- 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.utils import flt
-# 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)
- super(LandUnit, self).on_update()
-
- 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 - flt(self.area)
- self.area = new_area
-
- if self.get('parent_land_unit'):
- 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()
-
- 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 flt(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
-
-@frappe.whitelist()
-def get_children(doctype, parent, is_root=False):
- if is_root:
- parent = ''
-
- land_units = frappe.get_list(doctype,
- fields = ['name as value', 'is_group as expandable'],
- filters= [['ifnull(`parent_land_unit`, "")', '=', parent]],
- order_by='name')
-
- # return nodes
- return land_units
-
-
-def on_doctype_update():
- frappe.db.add_index("Land Unit", ["lft", "rgt"])
\ 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
deleted file mode 100644
index bf64126..0000000
--- a/erpnext/agriculture/doctype/land_unit/land_unit_tree.js
+++ /dev/null
@@ -1,30 +0,0 @@
-frappe.treeview_settings["Land Unit"] = {
- get_tree_nodes: "erpnext.agriculture.doctype.land_unit.land_unit.get_children",
- ignore_fields:["parent_land_unit"],
- get_tree_root: false,
- disable_add_node: true,
- root_label: "All Land Units",
- onload: function(me) {
- me.make_tree();
- },
- toolbar: [
- { toggle_btn: true },
- {
- label:__("Edit"),
- condition: function(node) { return (node.label!='All Land Units'); },
- click: function(node) {
- frappe.set_route('Form', 'Land Unit', node.data.value);
- }
- },
- {
- label:__("Add Child"),
- condition: function(node) { return node.expandable; },
- click: function(node) {
- if(node.label=='All Land Units') node.label='';
- 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
deleted file mode 100644
index f9d3566..0000000
--- a/erpnext/agriculture/doctype/land_unit/test_land_unit.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* 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
- {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
deleted file mode 100644
index 005014e..0000000
--- a/erpnext/agriculture/doctype/land_unit/test_land_unit.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- 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)
- test_land = frappe.get_doc('Land Unit', 'Test Land')
- self.assertEqual(formatted_land_unit_string, str(json.loads(test_land.get('location'))['features']))
- self.assertEqual(area, test_land.get('area'))
diff --git a/erpnext/agriculture/doctype/linked_land_unit/__init__.py b/erpnext/agriculture/doctype/linked_location/__init__.py
similarity index 100%
rename from erpnext/agriculture/doctype/linked_land_unit/__init__.py
rename to erpnext/agriculture/doctype/linked_location/__init__.py
diff --git a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json b/erpnext/agriculture/doctype/linked_location/linked_location.json
similarity index 86%
rename from erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json
rename to erpnext/agriculture/doctype/linked_location/linked_location.json
index 63816b8..56a29d5 100644
--- a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json
+++ b/erpnext/agriculture/doctype/linked_location/linked_location.json
@@ -14,11 +14,12 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "land_unit",
+ "fieldname": "location",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -27,10 +28,10 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Land Unit",
+ "label": "Location",
"length": 0,
"no_copy": 0,
- "options": "Land Unit",
+ "options": "Location",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -41,6 +42,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -54,10 +56,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-12-04 13:25:50.856991",
+ "modified": "2018-06-20 04:35:51.675244",
"modified_by": "Administrator",
"module": "Agriculture",
- "name": "Linked Land Unit",
+ "name": "Linked Location",
"name_case": "",
"owner": "Administrator",
"permissions": [],
diff --git a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py b/erpnext/agriculture/doctype/linked_location/linked_location.py
similarity index 65%
rename from erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py
rename to erpnext/agriculture/doctype/linked_location/linked_location.py
index 266edb9..3e49d3e 100644
--- a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py
+++ b/erpnext/agriculture/doctype/linked_location/linked_location.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2018, 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):
+class LinkedLocation(Document):
pass
diff --git a/erpnext/agriculture/doctype/land_unit/__init__.py b/erpnext/assets/doctype/linked_location/__init__.py
similarity index 100%
rename from erpnext/agriculture/doctype/land_unit/__init__.py
rename to erpnext/assets/doctype/linked_location/__init__.py
diff --git a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json b/erpnext/assets/doctype/linked_location/linked_location.json
similarity index 85%
copy from erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json
copy to erpnext/assets/doctype/linked_location/linked_location.json
index 63816b8..f04a79e 100644
--- a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.json
+++ b/erpnext/assets/doctype/linked_location/linked_location.json
@@ -14,11 +14,12 @@
"fields": [
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "land_unit",
+ "fieldname": "location",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -27,10 +28,10 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
- "label": "Land Unit",
+ "label": "Location",
"length": 0,
"no_copy": 0,
- "options": "Land Unit",
+ "options": "Location",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -41,6 +42,7 @@
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
],
@@ -54,10 +56,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2017-12-04 13:25:50.856991",
+ "modified": "2018-06-20 04:35:59.514281",
"modified_by": "Administrator",
- "module": "Agriculture",
- "name": "Linked Land Unit",
+ "module": "Assets",
+ "name": "Linked Location",
"name_case": "",
"owner": "Administrator",
"permissions": [],
diff --git a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py b/erpnext/assets/doctype/linked_location/linked_location.py
similarity index 65%
copy from erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py
copy to erpnext/assets/doctype/linked_location/linked_location.py
index 266edb9..3e49d3e 100644
--- a/erpnext/agriculture/doctype/linked_land_unit/linked_land_unit.py
+++ b/erpnext/assets/doctype/linked_location/linked_location.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2018, 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):
+class LinkedLocation(Document):
pass
diff --git a/erpnext/assets/doctype/location/location.js b/erpnext/assets/doctype/location/location.js
index c3783df..0f069b2 100644
--- a/erpnext/assets/doctype/location/location.js
+++ b/erpnext/assets/doctype/location/location.js
@@ -2,7 +2,23 @@
// For license information, please see license.txt
frappe.ui.form.on('Location', {
- refresh: function(frm) {
+ setup: function (frm) {
+ frm.set_query("parent_location", function () {
+ return {
+ "filters": {
+ "is_group": 1
+ }
+ };
+ });
+ },
- }
+ 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'];
+ }
+ },
});
diff --git a/erpnext/assets/doctype/location/location.json b/erpnext/assets/doctype/location/location.json
index d83fdf3..5dc1306 100644
--- a/erpnext/assets/doctype/location/location.json
+++ b/erpnext/assets/doctype/location/location.json
@@ -1,306 +1,708 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "autoname": "field:location_name",
- "beta": 0,
- "creation": "2018-05-07 12:49:22.595974",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:location_name",
+ "beta": 0,
+ "creation": "2018-05-07 12:49:22.595974",
+ "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_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": "Location 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,
- "translatable": 0,
- "unique": 0
- },
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "location_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": "Location 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,
+ "translatable": 0,
+ "unique": 1
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "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": 0,
- "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,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "parent_location",
+ "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": "Parent Location",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Location",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 1,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "parent_location",
- "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": "Parent Location",
- "length": 0,
- "no_copy": 0,
- "options": "Location",
- "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": 1,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb_details",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "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": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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,
+ "translatable": 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": 1,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 1,
+ "collapsible": 0,
+ "columns": 0,
+ "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,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "old_parent",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Old Parent",
- "length": 0,
- "no_copy": 1,
- "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,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sb_location_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": "Location 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "parent_location.latitude",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "parent_location.longitude",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "cb_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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.area",
+ "fieldname": "area_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": "Area 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "sb_geolocation",
+ "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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 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": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "old_parent",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Old Parent",
+ "length": 0,
+ "no_copy": 1,
+ "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,
+ "translatable": 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": "2018-05-07 19:21:06.051414",
- "modified_by": "Administrator",
- "module": "Assets",
- "name": "Location",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "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": "2018-07-11 13:36:30.999405",
+ "modified_by": "Administrator",
+ "module": "Assets",
+ "name": "Location",
+ "name_case": "Title Case",
+ "owner": "Administrator",
"permissions": [
{
- "amend": 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,
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Stock User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 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": "Stock User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Accounts User",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Accounts User",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Stock Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
+ "amend": 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": "Stock Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ },
+ {
+ "amend": 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,
+ "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": 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
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/assets/doctype/location/location.py b/erpnext/assets/doctype/location/location.py
index 86542cb..4d73f11 100644
--- a/erpnext/assets/doctype/location/location.py
+++ b/erpnext/assets/doctype/location/location.py
@@ -3,23 +3,197 @@
# For license information, please see license.txt
from __future__ import unicode_literals
+
+import json
+import math
+
import frappe
+from frappe import _
from frappe.model.document import Document
-from frappe.utils.nestedset import NestedSet
+from frappe.utils import flt
+from frappe.utils.nestedset import NestedSet, update_nsm
+
+EARTH_RADIUS = 6378137
+
class Location(NestedSet):
nsm_parent_field = 'parent_location'
+ def validate(self):
+ self.calculate_location_area()
+
+ if not self.is_new() and self.get('parent_location'):
+ self.update_ancestor_location_features()
+
def on_update(self):
+ # super(Location, self).on_update()
NestedSet.on_update(self)
def on_trash(self):
NestedSet.validate_if_child_exists(self)
- frappe.utils.nestedset.update_nsm(self)
+ update_nsm(self)
+ self.remove_ancestor_location_features()
+ # super(Location, self).on_update()
+
+ def calculate_location_area(self):
+ features = self.get_location_features()
+ new_area = compute_area(features)
+
+ self.area_difference = new_area - flt(self.area)
+ self.area = new_area
+
+ def get_location_features(self):
+ if not self.location:
+ return []
+
+ features = json.loads(self.location).get('features')
+
+ if not isinstance(features, list):
+ features = json.loads(features)
+
+ return features
+
+ def set_location_features(self, features):
+ if not self.location:
+ self.location = '{"type":"FeatureCollection","features":[]}'
+
+ location = json.loads(self.location)
+ location['features'] = features
+
+ self.db_set('location', json.dumps(location), commit=True)
+
+ def update_ancestor_location_features(self):
+ self_features = set(self.add_child_property())
+
+ for ancestor in self.get_ancestors():
+ ancestor_doc = frappe.get_doc('Location', ancestor)
+ child_features, ancestor_features = ancestor_doc.feature_seperator(child_feature=self.name)
+
+ ancestor_features = list(set(ancestor_features))
+ child_features = set(child_features)
+
+ if self_features != child_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)
+
+ ancestor_features.extend(list(child_features))
+
+ for index, feature in enumerate(ancestor_features):
+ ancestor_features[index] = json.loads(feature)
+
+ ancestor_doc.set_location_features(features=ancestor_features)
+ ancestor_doc.db_set('area', ancestor_doc.area + self.area_difference, commit=True)
+
+ def remove_ancestor_location_features(self):
+ for ancestor in self.get_ancestors():
+ ancestor_doc = frappe.get_doc('Location', ancestor)
+ child_features, ancestor_features = ancestor_doc.feature_seperator(child_feature=self.name)
+
+ for index, feature in enumerate(ancestor_features):
+ ancestor_features[index] = json.loads(feature)
+
+ ancestor_doc.set_location_features(features=ancestor_features)
+ ancestor_doc.db_set('area', ancestor_doc.area - self.area, commit=True)
+
+ def add_child_property(self):
+ features = self.get_location_features()
+ filter_features = [feature for feature in features if not feature.get('properties').get('child_feature')]
+
+ for index, feature in enumerate(filter_features):
+ feature['properties'].update({'child_feature': True, 'feature_of': self.location_name})
+ filter_features[index] = json.dumps(filter_features[index])
+
+ return filter_features
+
+ def feature_seperator(self, child_feature=None):
+ child_features, non_child_features = [], []
+ features = self.get_location_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):
+ """
+ Calculate the total area for a set of location features.
+ Reference from https://github.com/scisco/area.
+
+ Args:
+ `features` (list of dict): Features marked on the map as
+ GeoJSON data
+
+ Returns:
+ float: The approximate signed geodesic area (in sq. meters)
+ """
+
+ layer_area = 0.0
+
+ for feature in features:
+ feature_type = feature.get('geometry', {}).get('type')
+
+ if feature_type == 'Polygon':
+ layer_area += _polygon_area(coords=feature.get('geometry').get('coordinates'))
+ elif feature_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 _polygon_area(coords):
+ if not coords:
+ return 0
+
+ area = abs(_ring_area(coords[0]))
+
+ for i in range(1, len(coords)):
+ area -= abs(_ring_area(coords[i]))
+
+ return area
+
+
+def _ring_area(coords):
+ area = 0.0
+ coords_length = len(coords)
+
+ if coords_length > 2:
+ for i in range(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 += (math.radians(p3[0]) - math.radians(p1[0])) * math.sin(math.radians(p2[1]))
+
+ area = area * EARTH_RADIUS * EARTH_RADIUS / 2
+
+ return area
+
@frappe.whitelist()
def get_children(doctype, parent=None, location=None, is_root=False):
- if parent == None or parent == "All Locations":
+ if parent is None or parent == "All Locations":
parent = ""
return frappe.db.sql("""
@@ -31,9 +205,10 @@
where
ifnull(parent_location, "")="{parent}"
""".format(
- doctype = frappe.db.escape(doctype),
- parent=frappe.db.escape(parent)
- ), as_dict=1)
+ doctype=frappe.db.escape(doctype),
+ parent=frappe.db.escape(parent)
+ ), as_dict=1)
+
@frappe.whitelist()
def add_node():
@@ -44,4 +219,8 @@
if args.parent_location == 'All Locations':
args.parent_location = None
- frappe.get_doc(args).insert()
\ No newline at end of file
+ frappe.get_doc(args).insert()
+
+
+def on_doctype_update():
+ frappe.db.add_index("Location", ["lft", "rgt"])
diff --git a/erpnext/assets/doctype/location/location_tree.js b/erpnext/assets/doctype/location/location_tree.js
index cbd8f10..b405afd 100644
--- a/erpnext/assets/doctype/location/location_tree.js
+++ b/erpnext/assets/doctype/location/location_tree.js
@@ -1,14 +1,14 @@
frappe.treeview_settings["Location"] = {
- ignore_fields:["parent_location"],
+ ignore_fields: ["parent_location"],
get_tree_nodes: 'erpnext.assets.doctype.location.location.get_children',
add_tree_node: 'erpnext.assets.doctype.location.location.add_node',
filters: [
{
fieldname: "location",
- fieldtype:"Link",
+ fieldtype: "Link",
options: "Location",
label: __("Location"),
- get_query: function() {
+ get_query: function () {
return {
filters: [["Location", "is_group", "=", 1]]
};
@@ -21,13 +21,13 @@
menu_items: [
{
label: __("New Location"),
- action: function() {
+ action: function () {
frappe.new_doc("Location", true);
},
condition: 'frappe.boot.user.can_create.indexOf("Location") !== -1'
}
],
- onload: function(treeview) {
+ onload: function (treeview) {
treeview.make_tree();
}
};
\ No newline at end of file
diff --git a/erpnext/assets/doctype/location/test_location.js b/erpnext/assets/doctype/location/test_location.js
index 236b5c6..3c06b63 100644
--- a/erpnext/assets/doctype/location/test_location.js
+++ b/erpnext/assets/doctype/location/test_location.js
@@ -12,10 +12,10 @@
// insert a new Location
() => frappe.tests.make('Location', [
// values to be set
- {key: 'value'}
+ { location_name: 'Basil Farm' }
]),
() => {
- assert.equal(cur_frm.doc.key, 'value');
+ assert.equal(cur_frm.doc.name, 'Basil Farm');
},
() => done()
]);
diff --git a/erpnext/assets/doctype/location/test_location.py b/erpnext/assets/doctype/location/test_location.py
index 9a46fd9..6d8dd69 100644
--- a/erpnext/assets/doctype/location/test_location.py
+++ b/erpnext/assets/doctype/location/test_location.py
@@ -3,8 +3,29 @@
# See license.txt
from __future__ import unicode_literals
-import frappe
+import json
import unittest
+import frappe
+
+
class TestLocation(unittest.TestCase):
- pass
+ def runTest(self):
+ locations = ['Basil Farm', 'Division 1', 'Field 1', 'Block 1']
+ area = 0
+ formatted_locations = []
+
+ for location in locations:
+ doc = frappe.get_doc('Location', location)
+ doc.save()
+ area += doc.area
+ temp = json.loads(doc.location)
+ temp['features'][0]['properties']['child_feature'] = True
+ temp['features'][0]['properties']['feature_of'] = location
+ formatted_locations.extend(temp['features'])
+
+ formatted_location_string = str(formatted_locations)
+ test_location = frappe.get_doc('Location', 'Test Location')
+
+ self.assertEqual(formatted_location_string, str(json.loads(test_location.get('location'))['features']))
+ self.assertEqual(area, test_location.get('area'))
diff --git a/erpnext/agriculture/doctype/land_unit/test_records.json b/erpnext/assets/doctype/location/test_records.json
similarity index 74%
rename from erpnext/agriculture/doctype/land_unit/test_records.json
rename to erpnext/assets/doctype/location/test_records.json
index e7fed9f..3827225 100644
--- a/erpnext/agriculture/doctype/land_unit/test_records.json
+++ b/erpnext/assets/doctype/location/test_records.json
@@ -1,42 +1,42 @@
[
{
- "doctype": "Land Unit",
- "land_unit_name": "Test Land",
+ "doctype": "Location",
+ "location_name": "Test Location",
"is_group": 1,
"is_container": 1
},
{
- "doctype": "Land Unit",
- "land_unit_name": "Basil Farm",
+ "doctype": "Location",
+ "location_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": "Test Land",
- "parent": "Test Land",
+ "parent_location": "Test Location",
+ "parent": "Test Location",
"is_group": 1,
"is_container": 1
},
{
- "doctype": "Land Unit",
- "land_unit_name": "Division 1",
+ "doctype": "Location",
+ "location_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_location": "Basil Farm",
"parent": "Basil Farm",
"is_group": 1,
"is_container": 1
},
{
- "doctype": "Land Unit",
- "land_unit_name": "Field 1",
+ "doctype": "Location",
+ "location_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_location": "Division 1",
"parent": "Division 1",
"is_group": 1,
"is_container": 1
},
{
- "doctype": "Land Unit",
- "land_unit_name": "Block 1",
+ "doctype": "Location",
+ "location_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_location": "Field 1",
"parent": "Field 1",
"is_group": 0,
"is_container": 1
diff --git a/erpnext/config/agriculture.py b/erpnext/config/agriculture.py
index 20ee7cf..a6bc302 100644
--- a/erpnext/config/agriculture.py
+++ b/erpnext/config/agriculture.py
@@ -16,7 +16,7 @@
},
{
"type": "doctype",
- "name": "Land Unit",
+ "name": "Location"
}
]
},
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index db6975e..f987316 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -398,13 +398,13 @@
"hidden": 1
},
{
- "module_name": "Land Unit",
- "_doctype": "Land Unit",
- "label": _("Land Unit"),
+ "module_name": "Location",
+ "_doctype": "Location",
+ "label": _("Location"),
"color": "#8BC34A",
"icon": "fa fa-map",
"type": "list",
- "link": "List/Land Unit",
+ "link": "List/Location",
"hidden": 1
},
{
diff --git a/erpnext/domains/agriculture.py b/erpnext/domains/agriculture.py
index d605ac7..5946247 100644
--- a/erpnext/domains/agriculture.py
+++ b/erpnext/domains/agriculture.py
@@ -5,7 +5,7 @@
'Crop Cycle',
'Fertilizer',
'Item',
- 'Land Unit',
+ 'Location',
'Disease',
'Plant Analysis',
'Soil Analysis',
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 3be91c0..fa6acd7 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -553,4 +553,5 @@
execute:frappe.db.sql("update `tabDesktop Icon` set type = 'module' where module_name = 'Restaurant'")
erpnext.patches.v11_0.set_salary_component_properties
erpnext.patches.v11_0.set_user_permissions_for_department
-erpnext.patches.v11_0.hr_ux_cleanups
\ No newline at end of file
+erpnext.patches.v11_0.hr_ux_cleanups
+erpnext.patches.v11_0.merge_land_unit_with_location
diff --git a/erpnext/patches/v11_0/merge_land_unit_with_location.py b/erpnext/patches/v11_0/merge_land_unit_with_location.py
new file mode 100644
index 0000000..999fb1f
--- /dev/null
+++ b/erpnext/patches/v11_0/merge_land_unit_with_location.py
@@ -0,0 +1,60 @@
+# Copyright (c) 2018, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+
+import frappe
+from frappe.model.rename_doc import rename_doc
+from frappe.model.utils.rename_field import rename_field
+
+
+def execute():
+ # Rename and reload the Land Unit and Linked Land Unit doctypes
+ if frappe.db.table_exists('Land Unit') and not frappe.db.table_exists('Location'):
+ rename_doc('DocType', 'Land Unit', 'Location', force=True)
+
+ frappe.reload_doc('assets', 'doctype', 'location')
+
+ if frappe.db.table_exists('Linked Land Unit') and not frappe.db.table_exists('Linked Location'):
+ rename_doc('DocType', 'Linked Land Unit', 'Linked Location', force=True)
+
+ frappe.reload_doc('assets', 'doctype', 'linked_location')
+
+ # Rename the fields in related doctypes
+ if 'linked_land_unit' in frappe.db.get_table_columns('Crop Cycle'):
+ rename_field('Crop Cycle', 'linked_land_unit', 'linked_location')
+
+ if 'land_unit' in frappe.db.get_table_columns('Linked Location'):
+ rename_field('Linked Location', 'land_unit', 'location')
+
+ if not frappe.db.exists("Location", "All Land Units"):
+ frappe.get_doc({"doctype": "Location", "is_group": True, "location_name": "All Land Units"}).insert(ignore_permissions=True)
+
+ if frappe.db.table_exists('Land Unit'):
+ land_units = frappe.get_all('Land Unit', fields=['*'], order_by='lft')
+
+ for land_unit in land_units:
+ if not frappe.db.exists('Location', land_unit.get('land_unit_name')):
+ frappe.get_doc({
+ 'doctype': 'Location',
+ 'location_name': land_unit.get('land_unit_name'),
+ 'parent_location': land_unit.get('parent_land_unit') or "All Land Units",
+ 'is_container': land_unit.get('is_container'),
+ 'is_group': land_unit.get('is_group'),
+ 'latitude': land_unit.get('latitude'),
+ 'longitude': land_unit.get('longitude'),
+ 'area': land_unit.get('area'),
+ 'location': land_unit.get('location'),
+ 'lft': land_unit.get('lft'),
+ 'rgt': land_unit.get('rgt')
+ }).insert(ignore_permissions=True)
+
+ # frappe.db.sql("""update `tabDesktop Icon` set label='Location', module_name='Location' where label='Land Unit'""")
+ frappe.db.sql("""update `tabDesktop Icon` set link='List/Location' where link='List/Land Unit'""")
+
+ # Delete the Land Unit and Linked Land Unit doctypes
+ if frappe.db.table_exists('Land Unit'):
+ frappe.delete_doc('DocType', 'Land Unit', force=1)
+
+ if frappe.db.table_exists('Linked Land Unit'):
+ frappe.delete_doc('DocType', 'Linked Land Unit', force=1)
diff --git a/erpnext/tests/server/agriculture.txt b/erpnext/tests/server/agriculture.txt
index 3aae85a..29dc9ab 100644
--- a/erpnext/tests/server/agriculture.txt
+++ b/erpnext/tests/server/agriculture.txt
@@ -1,5 +1,4 @@
Disease
Crop
-Land Unit
Crop Cycle
Soil Texture
\ No newline at end of file