diff --git a/farm_water_source/README.rst b/farm_water_source/README.rst new file mode 100644 index 0000000..d1b78e8 --- /dev/null +++ b/farm_water_source/README.rst @@ -0,0 +1,120 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================= +Farm Water Source +================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:9d5ee627395550f366a82fe33508898dd73e25e55d39a5ce9a86027ddb10409c + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-ledoent%2Ffarm--pack-lightgray.png?logo=github + :target: https://github.com/ledoent/farm-pack/tree/19.0/farm_water_source + :alt: ledoent/farm-pack + +|badge1| |badge2| |badge3| + +Tracks water sources on the farm — wells, surface tanks, ponds, streams, +troughs, springs, hydrants — with their location, capacity, last-tested +date, and which fields they serve. + +The ``geom`` column is a ``GeoPoint``. All source types are represented +as a single point: the well-head, the tank tap, the centroid of the +pond, the access point on the stream. We picked this in v1 because +base_geoengine 19.0 doesn't ship a "any geometry" type — adding a +polygon footprint for ponds (surface-area, depth contours) or a +linestring for streams would need a follow-up +``farm_water_source_polygon`` extension model. + +The ``field_ids`` many2many answers "which fields does this source +serve?", useful when planning rotational grazing or drought contingency. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +1. Open Farm → Water Sources. + +2. Click **New** and fill the name, type, optional capacity. + +3. Tick the fields this source serves under **Fields Served**. + +4. Open the **Location** tab and place the geometry on the map: + + ============================= ============================== + Type Geometry + ============================= ============================== + Well, Trough, Spring, Hydrant Single point + Stream / Creek LineString (multiple vertices) + Pond, Surface Tank Polygon (closed area) + ============================= ============================== + +5. Save. Switch to the Map view to see every source on the field map. + +Day-to-day: + +- **Annual water testing**: filter by "Not Tested in 1 Year" to find + sources due for a potability test. +- **Rotational grazing planning**: open a field's map, see which sources + serve which paddocks, plan moves accordingly. +- **Drought contingency**: switch the action to the Map view to see all + active sources at once and identify backup options. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Ledo Enterprises + +Contributors +------------ + +- Daniel Kendall + +Maintainers +----------- + +.. |maintainer-dnplkndll| image:: https://github.com/dnplkndll.png?size=40px + :target: https://github.com/dnplkndll + :alt: dnplkndll + +Current maintainer: + +|maintainer-dnplkndll| + +This module is part of the `ledoent/farm-pack `_ project on GitHub. + +You are welcome to contribute. diff --git a/farm_water_source/__init__.py b/farm_water_source/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/farm_water_source/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/farm_water_source/__manifest__.py b/farm_water_source/__manifest__.py new file mode 100644 index 0000000..2df9353 --- /dev/null +++ b/farm_water_source/__manifest__.py @@ -0,0 +1,25 @@ +{ + "name": "Farm Water Source", + "version": "19.0.1.0.0", + "summary": "Wells, ponds, troughs, springs — geometry + which fields they serve", + "author": "Ledo Enterprises, Odoo Community Association (OCA)", + "maintainers": ["dnplkndll"], + "website": "https://github.com/ledoent/farm-pack", + "license": "AGPL-3", + "category": "Vertical/Agriculture", + # Alpha matches farm_field_geo's chain — OCA check-dev-status gate. + "development_status": "Alpha", + "depends": [ + "farm_field_geo", + ], + "external_dependencies": { + "python": ["shapely"], + }, + "data": [ + "security/ir.model.access.csv", + "views/farm_water_source_views.xml", + "views/farm_water_source_menu.xml", + ], + "installable": True, + "application": False, +} diff --git a/farm_water_source/models/__init__.py b/farm_water_source/models/__init__.py new file mode 100644 index 0000000..f92b509 --- /dev/null +++ b/farm_water_source/models/__init__.py @@ -0,0 +1 @@ +from . import farm_water_source diff --git a/farm_water_source/models/farm_water_source.py b/farm_water_source/models/farm_water_source.py new file mode 100644 index 0000000..d7b60a1 --- /dev/null +++ b/farm_water_source/models/farm_water_source.py @@ -0,0 +1,48 @@ +from odoo import fields, models + + +class FarmWaterSource(models.Model): + _name = "farm.water.source" + _description = "Water Source" + _order = "name" + + name = fields.Char(required=True) + source_type = fields.Selection( + [ + ("well", "Well"), + ("tank", "Surface Tank"), + ("pond", "Pond"), + ("stream", "Stream / Creek"), + ("trough", "Trough"), + ("spring", "Spring"), + ("hydrant", "Hydrant / Spigot"), + ], + required=True, + ) + # All source types record a single point: the well-head, the tank tap, + # the centroid of the pond, the access point on the stream. We picked + # this in v1 because base_geoengine 19.0 (PR #446 head) doesn't ship a + # GeoAnyGeometry type — a future farm_water_source_polygon module can + # add an optional polygon footprint for ponds / streams when a customer + # asks for surface-area calculations. + geom = fields.GeoPoint(string="Location", srid=4326) + field_ids = fields.Many2many( + "farm.field", + string="Fields Served", + help="Which fields draw from this source. Drives the 'where is this " + "field's water coming from' query.", + ) + capacity_gallons = fields.Float( + digits=(10, 0), + help="Practical usable volume in gallons. Leave blank for streams / " + "springs where flow rate matters more than reservoir capacity.", + ) + last_tested_date = fields.Date(help="Most recent potability / coliform test.") + quality_notes = fields.Text() + active = fields.Boolean(default=True) + company_id = fields.Many2one( + "res.company", + required=True, + default=lambda self: self.env.company, + index=True, + ) diff --git a/farm_water_source/pyproject.toml b/farm_water_source/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/farm_water_source/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/farm_water_source/readme/CONTRIBUTORS.md b/farm_water_source/readme/CONTRIBUTORS.md new file mode 100644 index 0000000..c71b705 --- /dev/null +++ b/farm_water_source/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Daniel Kendall <dkendall@ledoweb.com> diff --git a/farm_water_source/readme/DESCRIPTION.md b/farm_water_source/readme/DESCRIPTION.md new file mode 100644 index 0000000..96a2c29 --- /dev/null +++ b/farm_water_source/readme/DESCRIPTION.md @@ -0,0 +1,13 @@ +Tracks water sources on the farm — wells, surface tanks, ponds, streams, +troughs, springs, hydrants — with their location, capacity, last-tested +date, and which fields they serve. + +The `geom` column is a `GeoPoint`. All source types are represented as a +single point: the well-head, the tank tap, the centroid of the pond, the +access point on the stream. We picked this in v1 because base_geoengine +19.0 doesn't ship a "any geometry" type — adding a polygon footprint for +ponds (surface-area, depth contours) or a linestring for streams would +need a follow-up `farm_water_source_polygon` extension model. + +The `field_ids` many2many answers "which fields does this source serve?", +useful when planning rotational grazing or drought contingency. diff --git a/farm_water_source/readme/USAGE.md b/farm_water_source/readme/USAGE.md new file mode 100644 index 0000000..781b5b0 --- /dev/null +++ b/farm_water_source/readme/USAGE.md @@ -0,0 +1,21 @@ +1. Open Farm → Water Sources. +2. Click **New** and fill the name, type, optional capacity. +3. Tick the fields this source serves under **Fields Served**. +4. Open the **Location** tab and place the geometry on the map: + + | Type | Geometry | + |---|---| + | Well, Trough, Spring, Hydrant | Single point | + | Stream / Creek | LineString (multiple vertices) | + | Pond, Surface Tank | Polygon (closed area) | + +5. Save. Switch to the Map view to see every source on the field map. + +Day-to-day: + +- **Annual water testing**: filter by "Not Tested in 1 Year" to find sources + due for a potability test. +- **Rotational grazing planning**: open a field's map, see which sources + serve which paddocks, plan moves accordingly. +- **Drought contingency**: switch the action to the Map view to see all + active sources at once and identify backup options. diff --git a/farm_water_source/readme/newsfragments/.gitkeep b/farm_water_source/readme/newsfragments/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/farm_water_source/security/ir.model.access.csv b/farm_water_source/security/ir.model.access.csv new file mode 100644 index 0000000..a63a234 --- /dev/null +++ b/farm_water_source/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_farm_water_source_user,farm.water.source user,model_farm_water_source,base.group_user,1,1,1,1 diff --git a/farm_water_source/static/description/index.html b/farm_water_source/static/description/index.html new file mode 100644 index 0000000..bfb011e --- /dev/null +++ b/farm_water_source/static/description/index.html @@ -0,0 +1,488 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Farm Water Source

+ +

Alpha License: AGPL-3 ledoent/farm-pack

+

Tracks water sources on the farm — wells, surface tanks, ponds, streams, +troughs, springs, hydrants — with their location, capacity, last-tested +date, and which fields they serve.

+

The geom column is a GeoPoint. All source types are represented +as a single point: the well-head, the tank tap, the centroid of the +pond, the access point on the stream. We picked this in v1 because +base_geoengine 19.0 doesn’t ship a “any geometry” type — adding a +polygon footprint for ponds (surface-area, depth contours) or a +linestring for streams would need a follow-up +farm_water_source_polygon extension model.

+

The field_ids many2many answers “which fields does this source +serve?”, useful when planning rotational grazing or drought contingency.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Usage

+
    +
  1. Open Farm → Water Sources.

    +
  2. +
  3. Click New and fill the name, type, optional capacity.

    +
  4. +
  5. Tick the fields this source serves under Fields Served.

    +
  6. +
  7. Open the Location tab and place the geometry on the map:

    + ++++ + + + + + + + + + + + + + + + + +
    TypeGeometry
    Well, Trough, Spring, HydrantSingle point
    Stream / CreekLineString (multiple vertices)
    Pond, Surface TankPolygon (closed area)
    +
  8. +
  9. Save. Switch to the Map view to see every source on the field map.

    +
  10. +
+

Day-to-day:

+
    +
  • Annual water testing: filter by “Not Tested in 1 Year” to find +sources due for a potability test.
  • +
  • Rotational grazing planning: open a field’s map, see which sources +serve which paddocks, plan moves accordingly.
  • +
  • Drought contingency: switch the action to the Map view to see all +active sources at once and identify backup options.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Ledo Enterprises
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

Current maintainer:

+

dnplkndll

+

This module is part of the ledoent/farm-pack project on GitHub.

+

You are welcome to contribute.

+
+
+
+
+ + diff --git a/farm_water_source/tests/__init__.py b/farm_water_source/tests/__init__.py new file mode 100644 index 0000000..679a889 --- /dev/null +++ b/farm_water_source/tests/__init__.py @@ -0,0 +1 @@ +from . import test_farm_water_source diff --git a/farm_water_source/tests/test_farm_water_source.py b/farm_water_source/tests/test_farm_water_source.py new file mode 100644 index 0000000..864a0f0 --- /dev/null +++ b/farm_water_source/tests/test_farm_water_source.py @@ -0,0 +1,78 @@ +from shapely.geometry import Point + +from odoo.tests.common import TransactionCase + + +class TestFarmWaterSource(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.farm = cls.env["res.partner"].create( + {"name": "Test Farm", "is_company": True} + ) + cls.crop = cls.env["farm.crop"].create({"name": "Pasture"}) + cls.field_north = cls.env["farm.field"].create( + { + "name": "North 40", + "farm_partner_id": cls.farm.id, + "crop_id": cls.crop.id, + } + ) + cls.field_south = cls.env["farm.field"].create( + { + "name": "South Pasture", + "farm_partner_id": cls.farm.id, + "crop_id": cls.crop.id, + } + ) + + def test_well_can_be_a_point(self): + well = self.env["farm.water.source"].create( + { + "name": "House Well", + "source_type": "well", + "geom": Point(-79.245, 40.242), + } + ) + self.assertEqual(well.source_type, "well") + self.assertTrue(well.geom) + + def test_pond_records_a_centroid_point(self): + # v1 represents all source types as a single Point (well-head, tank + # tap, pond centroid). Polygon footprint deferred to a follow-up. + pond = self.env["farm.water.source"].create( + { + "name": "Big Pond", + "source_type": "pond", + "geom": Point(-79.2445, 40.2425), + } + ) + self.assertEqual(pond.source_type, "pond") + self.assertTrue(pond.geom) + + def test_stream_records_an_access_point(self): + # Streams record the access point where the user typically taps water + # — full linestring for the stream itself is out of scope for v1. + stream = self.env["farm.water.source"].create( + { + "name": "Burns Run access", + "source_type": "stream", + "geom": Point(-79.245, 40.242), + } + ) + self.assertEqual(stream.source_type, "stream") + self.assertTrue(stream.geom) + + def test_fields_served_many2many(self): + # Two fields drawing from one hydrant — the canonical use case for + # field_ids: 'what fields does this source serve?' + hydrant = self.env["farm.water.source"].create( + { + "name": "Pasture Hydrant", + "source_type": "hydrant", + "field_ids": [(6, 0, [self.field_north.id, self.field_south.id])], + } + ) + self.assertEqual(len(hydrant.field_ids), 2) + self.assertIn(self.field_north, hydrant.field_ids) + self.assertIn(self.field_south, hydrant.field_ids) diff --git a/farm_water_source/views/farm_water_source_menu.xml b/farm_water_source/views/farm_water_source_menu.xml new file mode 100644 index 0000000..46dae39 --- /dev/null +++ b/farm_water_source/views/farm_water_source_menu.xml @@ -0,0 +1,10 @@ + + + + diff --git a/farm_water_source/views/farm_water_source_views.xml b/farm_water_source/views/farm_water_source_views.xml new file mode 100644 index 0000000..e85f0af --- /dev/null +++ b/farm_water_source/views/farm_water_source_views.xml @@ -0,0 +1,107 @@ + + + + farm.water.source.list + farm.water.source + + + + + + + + + + + + + farm.water.source.form + farm.water.source + +
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + farm.water.source.search + farm.water.source + + + + + + + + + + + + + + + + + farm.water.source.geoengine + farm.water.source + + + + + + + + + + + Water Sources + farm.water.source + list,form,geoengine + +