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

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

View File

@ -0,0 +1,74 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2017-11-22 14:34:59.461273",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "location",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "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": 1,
"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": 1,
"max_attachments": 0,
"modified": "2018-06-20 04:35:59.514281",
"modified_by": "Administrator",
"module": "Assets",
"name": "Linked Location",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
}

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# 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 LinkedLocation(Document):
pass

View File

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

View File

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

View File

@ -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 @@ def get_children(doctype, parent=None, location=None, is_root=False):
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 @@ def add_node():
if args.parent_location == 'All Locations':
args.parent_location = None
frappe.get_doc(args).insert()
frappe.get_doc(args).insert()
def on_doctype_update():
frappe.db.add_index("Location", ["lft", "rgt"])

View File

@ -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 @@ frappe.treeview_settings["Location"] = {
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();
}
};

View File

@ -12,10 +12,10 @@ QUnit.test("test: Location", function (assert) {
// 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()
]);

View File

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

View File

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

View File

@ -16,7 +16,7 @@ def get_data():
},
{
"type": "doctype",
"name": "Land Unit",
"name": "Location"
}
]
},

View File

@ -398,13 +398,13 @@ def get_data():
"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
},
{

View File

@ -5,7 +5,7 @@ data = {
'Crop Cycle',
'Fertilizer',
'Item',
'Land Unit',
'Location',
'Disease',
'Plant Analysis',
'Soil Analysis',

View File

@ -553,4 +553,5 @@ erpnext.patches.v11_0.rename_asset_adjustment_doctype
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
erpnext.patches.v11_0.hr_ux_cleanups
erpnext.patches.v11_0.merge_land_unit_with_location

View File

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

View File

@ -1,5 +1,4 @@
Disease
Crop
Land Unit
Crop Cycle
Soil Texture