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
This commit is contained in:
Alchez
2018-07-13 12:50:04 +05:30
committed by Nabin Hait
parent 09e680b4aa
commit df1eae8981
29 changed files with 1141 additions and 1353 deletions

View File

@@ -10,7 +10,7 @@ frappe.ui.form.on('Crop Cycle', {
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 @@ frappe.ui.form.on('Crop Cycle', {
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;
};

View File

@@ -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",

View File

@@ -81,10 +81,10 @@ class CropCycle(Document):
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 @@ def get_geometry_type(doc):
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

View File

@@ -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
return True if frappe.db.exists('Project', 'Basil from seed 2017') else False

View File

@@ -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'];
}
},
});

View File

@@ -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
}

View File

@@ -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"])

View File

@@ -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
});
}
}
],
};

View File

@@ -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()
]);
});

View File

@@ -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'))

View File

@@ -1,44 +0,0 @@
[
{
"doctype": "Land Unit",
"land_unit_name": "Test Land",
"is_group": 1,
"is_container": 1
},
{
"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": "Test Land",
"parent": "Test Land",
"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
}
]

View File

@@ -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": [],

View File

@@ -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