feat: improve support for exporting quantity, log data
and make the Eggs quick form save to wuttafarm app DB first, then export to farmOS, if app is running as mirror
This commit is contained in:
parent
609a900f39
commit
23af35842d
5 changed files with 427 additions and 41 deletions
|
|
@ -443,6 +443,138 @@ class StructureAssetImporter(ToFarmOSAsset):
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# quantity importers
|
||||||
|
##############################
|
||||||
|
|
||||||
|
|
||||||
|
class ToFarmOSQuantity(ToFarmOS):
|
||||||
|
"""
|
||||||
|
Base class for quantity data importer targeting the farmOS API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
farmos_quantity_type = None
|
||||||
|
|
||||||
|
supported_fields = [
|
||||||
|
"uuid",
|
||||||
|
"measure",
|
||||||
|
"value_numerator",
|
||||||
|
"value_denominator",
|
||||||
|
"label",
|
||||||
|
"quantity_type_uuid",
|
||||||
|
"unit_uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_target_objects(self, **kwargs):
|
||||||
|
return list(
|
||||||
|
self.farmos_client.resource.iterate("quantity", self.farmos_quantity_type)
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_target_object(self, key):
|
||||||
|
|
||||||
|
# fetch from cache, if applicable
|
||||||
|
if self.caches_target:
|
||||||
|
return super().get_target_object(key)
|
||||||
|
|
||||||
|
# okay now must fetch via API
|
||||||
|
if self.get_keys() != ["uuid"]:
|
||||||
|
raise ValueError("must use uuid key for this to work")
|
||||||
|
uuid = key[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
qty = self.farmos_client.resource.get_id(
|
||||||
|
"quantity", self.farmos_quantity_type, str(uuid)
|
||||||
|
)
|
||||||
|
except requests.HTTPError as exc:
|
||||||
|
if exc.response.status_code == 404:
|
||||||
|
return None
|
||||||
|
raise
|
||||||
|
return qty["data"]
|
||||||
|
|
||||||
|
def create_target_object(self, key, source_data):
|
||||||
|
if source_data.get("__ignoreme__"):
|
||||||
|
return None
|
||||||
|
if self.dry_run:
|
||||||
|
return source_data
|
||||||
|
|
||||||
|
payload = self.get_quantity_payload(source_data)
|
||||||
|
result = self.farmos_client.resource.send(
|
||||||
|
"quantity", self.farmos_quantity_type, payload
|
||||||
|
)
|
||||||
|
normal = self.normalize_target_object(result["data"])
|
||||||
|
normal["_new_object"] = result["data"]
|
||||||
|
return normal
|
||||||
|
|
||||||
|
def update_target_object(self, quantity, source_data, target_data=None):
|
||||||
|
if self.dry_run:
|
||||||
|
return quantity
|
||||||
|
|
||||||
|
payload = self.get_quantity_payload(source_data)
|
||||||
|
payload["id"] = str(source_data["uuid"])
|
||||||
|
result = self.farmos_client.resource.send(
|
||||||
|
"quantity", self.farmos_quantity_type, payload
|
||||||
|
)
|
||||||
|
return self.normalize_target_object(result["data"])
|
||||||
|
|
||||||
|
def normalize_target_object(self, qty):
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"uuid": UUID(qty["id"]),
|
||||||
|
"measure": qty["attributes"]["measure"],
|
||||||
|
"value_numerator": qty["attributes"]["value"]["numerator"],
|
||||||
|
"value_denominator": qty["attributes"]["value"]["denominator"],
|
||||||
|
"label": qty["attributes"]["label"],
|
||||||
|
"quantity_type_uuid": UUID(
|
||||||
|
qty["relationships"]["quantity_type"]["data"]["id"]
|
||||||
|
),
|
||||||
|
"unit_uuid": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
if unit := qty["relationships"]["units"]["data"]:
|
||||||
|
result["unit_uuid"] = UUID(unit["id"])
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_quantity_payload(self, source_data):
|
||||||
|
|
||||||
|
attrs = {}
|
||||||
|
if "measure" in self.fields:
|
||||||
|
attrs["measure"] = source_data["measure"]
|
||||||
|
if "value_numerator" in self.fields and "value_denominator" in self.fields:
|
||||||
|
attrs["value"] = {
|
||||||
|
"numerator": source_data["value_numerator"],
|
||||||
|
"denominator": source_data["value_denominator"],
|
||||||
|
}
|
||||||
|
if "label" in self.fields:
|
||||||
|
attrs["label"] = source_data["label"]
|
||||||
|
|
||||||
|
rels = {}
|
||||||
|
if "quantity_type_uuid" in self.fields:
|
||||||
|
rels["quantity_type"] = {
|
||||||
|
"data": {
|
||||||
|
"id": str(source_data["quantity_type_uuid"]),
|
||||||
|
"type": "quantity_type--quantity_type",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if "unit_uuid" in self.fields:
|
||||||
|
rels["units"] = {
|
||||||
|
"data": {
|
||||||
|
"id": str(source_data["unit_uuid"]),
|
||||||
|
"type": "taxonomy_term--unit",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = {"attributes": attrs, "relationships": rels}
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
class StandardQuantityImporter(ToFarmOSQuantity):
|
||||||
|
|
||||||
|
model_title = "StandardQuantity"
|
||||||
|
farmos_quantity_type = "standard"
|
||||||
|
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# log importers
|
# log importers
|
||||||
##############################
|
##############################
|
||||||
|
|
@ -464,8 +596,14 @@ class ToFarmOSLog(ToFarmOS):
|
||||||
"status",
|
"status",
|
||||||
"notes",
|
"notes",
|
||||||
"quick",
|
"quick",
|
||||||
|
"assets",
|
||||||
|
"quantities",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.normal = self.app.get_normalizer(self.farmos_client)
|
||||||
|
|
||||||
def get_target_objects(self, **kwargs):
|
def get_target_objects(self, **kwargs):
|
||||||
result = self.farmos_client.log.get(self.farmos_log_type)
|
result = self.farmos_client.log.get(self.farmos_log_type)
|
||||||
return result["data"]
|
return result["data"]
|
||||||
|
|
@ -511,19 +649,18 @@ class ToFarmOSLog(ToFarmOS):
|
||||||
return self.normalize_target_object(result["data"])
|
return self.normalize_target_object(result["data"])
|
||||||
|
|
||||||
def normalize_target_object(self, log):
|
def normalize_target_object(self, log):
|
||||||
|
normal = self.normal.normalize_farmos_log(log)
|
||||||
if notes := log["attributes"]["notes"]:
|
|
||||||
notes = notes["value"]
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"uuid": UUID(log["id"]),
|
"uuid": UUID(normal["uuid"]),
|
||||||
"name": log["attributes"]["name"],
|
"name": normal["name"],
|
||||||
"timestamp": self.normalize_datetime(log["attributes"]["timestamp"]),
|
"timestamp": self.app.make_utc(normal["timestamp"]),
|
||||||
"is_movement": log["attributes"]["is_movement"],
|
"is_movement": normal["is_movement"],
|
||||||
"is_group_assignment": log["attributes"]["is_group_assignment"],
|
"is_group_assignment": normal["is_group_assignment"],
|
||||||
"status": log["attributes"]["status"],
|
"status": normal["status"],
|
||||||
"notes": notes,
|
"notes": normal["notes"],
|
||||||
"quick": log["attributes"]["quick"],
|
"quick": normal["quick"],
|
||||||
|
"assets": [(a["asset_type"], UUID(a["uuid"])) for a in normal["assets"]],
|
||||||
|
"quantities": [UUID(uuid) for uuid in normal["quantity_uuids"]],
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_log_payload(self, source_data):
|
def get_log_payload(self, source_data):
|
||||||
|
|
@ -542,10 +679,32 @@ class ToFarmOSLog(ToFarmOS):
|
||||||
if "notes" in self.fields:
|
if "notes" in self.fields:
|
||||||
attrs["notes"] = {"value": source_data["notes"]}
|
attrs["notes"] = {"value": source_data["notes"]}
|
||||||
if "quick" in self.fields:
|
if "quick" in self.fields:
|
||||||
attrs["quick"] = {"value": source_data["quick"]}
|
attrs["quick"] = source_data["quick"]
|
||||||
|
|
||||||
payload = {"attributes": attrs}
|
rels = {}
|
||||||
|
if "assets" in self.fields:
|
||||||
|
assets = []
|
||||||
|
for asset_type, uuid in source_data["assets"]:
|
||||||
|
assets.append(
|
||||||
|
{
|
||||||
|
"type": f"asset--{asset_type}",
|
||||||
|
"id": str(uuid),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
rels["asset"] = {"data": assets}
|
||||||
|
if "quantities" in self.fields:
|
||||||
|
quantities = []
|
||||||
|
for uuid in source_data["quantities"]:
|
||||||
|
quantities.append(
|
||||||
|
{
|
||||||
|
# TODO: support other quantity types
|
||||||
|
"type": "quantity--standard",
|
||||||
|
"id": str(uuid),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
rels["quantity"] = {"data": quantities}
|
||||||
|
|
||||||
|
payload = {"attributes": attrs, "relationships": rels}
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ class FromWuttaFarmToFarmOS(FromWuttaFarmHandler, ToFarmOSHandler):
|
||||||
importers["PlantType"] = PlantTypeImporter
|
importers["PlantType"] = PlantTypeImporter
|
||||||
importers["PlantAsset"] = PlantAssetImporter
|
importers["PlantAsset"] = PlantAssetImporter
|
||||||
importers["Unit"] = UnitImporter
|
importers["Unit"] = UnitImporter
|
||||||
|
importers["StandardQuantity"] = StandardQuantityImporter
|
||||||
importers["ActivityLog"] = ActivityLogImporter
|
importers["ActivityLog"] = ActivityLogImporter
|
||||||
importers["HarvestLog"] = HarvestLogImporter
|
importers["HarvestLog"] = HarvestLogImporter
|
||||||
importers["MedicalLog"] = MedicalLogImporter
|
importers["MedicalLog"] = MedicalLogImporter
|
||||||
|
|
@ -347,6 +348,49 @@ class StructureAssetImporter(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# quantity importers
|
||||||
|
##############################
|
||||||
|
|
||||||
|
|
||||||
|
class FromWuttaFarmQuantity(FromWuttaFarm):
|
||||||
|
"""
|
||||||
|
Base class for WuttaFarm -> farmOS quantity importers
|
||||||
|
"""
|
||||||
|
|
||||||
|
supported_fields = [
|
||||||
|
"uuid",
|
||||||
|
"measure",
|
||||||
|
"value_numerator",
|
||||||
|
"value_denominator",
|
||||||
|
"label",
|
||||||
|
"quantity_type_uuid",
|
||||||
|
"unit_uuid",
|
||||||
|
]
|
||||||
|
|
||||||
|
def normalize_source_object(self, qty):
|
||||||
|
return {
|
||||||
|
"uuid": qty.farmos_uuid or self.app.make_true_uuid(),
|
||||||
|
"measure": qty.measure_id,
|
||||||
|
"value_numerator": qty.value_numerator,
|
||||||
|
"value_denominator": qty.value_denominator,
|
||||||
|
"label": qty.label,
|
||||||
|
"quantity_type_uuid": qty.quantity_type.farmos_uuid,
|
||||||
|
"unit_uuid": qty.units.farmos_uuid,
|
||||||
|
"_src_object": qty,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class StandardQuantityImporter(
|
||||||
|
FromWuttaFarmQuantity, farmos_importing.model.StandardQuantityImporter
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
WuttaFarm → farmOS API exporter for Standard Quantities
|
||||||
|
"""
|
||||||
|
|
||||||
|
source_model_class = model.StandardQuantity
|
||||||
|
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# log importers
|
# log importers
|
||||||
##############################
|
##############################
|
||||||
|
|
@ -365,6 +409,9 @@ class FromWuttaFarmLog(FromWuttaFarm):
|
||||||
"is_group_assignment",
|
"is_group_assignment",
|
||||||
"status",
|
"status",
|
||||||
"notes",
|
"notes",
|
||||||
|
"quick",
|
||||||
|
"assets",
|
||||||
|
"quantities",
|
||||||
]
|
]
|
||||||
|
|
||||||
def normalize_source_object(self, log):
|
def normalize_source_object(self, log):
|
||||||
|
|
@ -376,6 +423,9 @@ class FromWuttaFarmLog(FromWuttaFarm):
|
||||||
"is_group_assignment": log.is_group_assignment,
|
"is_group_assignment": log.is_group_assignment,
|
||||||
"status": log.status,
|
"status": log.status,
|
||||||
"notes": log.notes,
|
"notes": log.notes,
|
||||||
|
"quick": self.config.parse_list(log.quick) if log.quick else [],
|
||||||
|
"assets": [(a.asset_type, a.farmos_uuid) for a in log.assets],
|
||||||
|
"quantities": [qty.farmos_uuid for qty in log.quantities],
|
||||||
"_src_object": log,
|
"_src_object": log,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ from wuttaweb.forms.widgets import WuttaDateTimeWidget
|
||||||
|
|
||||||
from wuttafarm.web.views.farmos import FarmOSMasterView
|
from wuttafarm.web.views.farmos import FarmOSMasterView
|
||||||
from wuttafarm.web.forms.schema import FarmOSUnitRef
|
from wuttafarm.web.forms.schema import FarmOSUnitRef
|
||||||
|
from wuttafarm.web.grids import ResourceData
|
||||||
|
|
||||||
|
|
||||||
class QuantityTypeView(FarmOSMasterView):
|
class QuantityTypeView(FarmOSMasterView):
|
||||||
|
|
@ -130,13 +131,15 @@ class QuantityMasterView(FarmOSMasterView):
|
||||||
farmos_quantity_type = None
|
farmos_quantity_type = None
|
||||||
|
|
||||||
grid_columns = [
|
grid_columns = [
|
||||||
|
"drupal_id",
|
||||||
|
"as_text",
|
||||||
"measure",
|
"measure",
|
||||||
"value",
|
"value",
|
||||||
|
"unit",
|
||||||
"label",
|
"label",
|
||||||
"changed",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
sort_defaults = ("changed", "desc")
|
sort_defaults = ("drupal_id", "desc")
|
||||||
|
|
||||||
form_fields = [
|
form_fields = [
|
||||||
"measure",
|
"measure",
|
||||||
|
|
@ -147,20 +150,58 @@ class QuantityMasterView(FarmOSMasterView):
|
||||||
"changed",
|
"changed",
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_grid_data(self, columns=None, session=None):
|
def get_farmos_api_includes(self):
|
||||||
result = self.farmos_client.resource.get("quantity", self.farmos_quantity_type)
|
return {"units"}
|
||||||
return [self.normalize_quantity(t) for t in result["data"]]
|
|
||||||
|
def get_grid_data(self, **kwargs):
|
||||||
|
return ResourceData(
|
||||||
|
self.config,
|
||||||
|
self.farmos_client,
|
||||||
|
f"quantity--{self.farmos_quantity_type}",
|
||||||
|
include=",".join(self.get_farmos_api_includes()),
|
||||||
|
normalizer=self.normalize_quantity,
|
||||||
|
)
|
||||||
|
|
||||||
def configure_grid(self, grid):
|
def configure_grid(self, grid):
|
||||||
g = grid
|
g = grid
|
||||||
super().configure_grid(g)
|
super().configure_grid(g)
|
||||||
|
|
||||||
|
# drupal_id
|
||||||
|
g.set_label("drupal_id", "ID", column_only=True)
|
||||||
|
|
||||||
|
# as_text
|
||||||
|
g.set_renderer("as_text", self.render_as_text_for_grid)
|
||||||
|
|
||||||
|
# measure
|
||||||
|
g.set_renderer("measure", self.render_measure_for_grid)
|
||||||
|
|
||||||
# value
|
# value
|
||||||
g.set_link("value")
|
g.set_renderer("value", self.render_value_for_grid)
|
||||||
|
|
||||||
|
# unit
|
||||||
|
g.set_renderer("unit", self.render_unit_for_grid)
|
||||||
|
|
||||||
# changed
|
# changed
|
||||||
g.set_renderer("changed", "datetime")
|
g.set_renderer("changed", "datetime")
|
||||||
|
|
||||||
|
def render_as_text_for_grid(self, qty, field, value):
|
||||||
|
measure = qty["measure"].capitalize()
|
||||||
|
value = qty["value"]["decimal"]
|
||||||
|
units = qty["unit"]["name"] if qty["unit"] else "??"
|
||||||
|
return f"( {measure} ) {value} {units}"
|
||||||
|
|
||||||
|
def render_measure_for_grid(self, qty, field, value):
|
||||||
|
return qty["measure"].capitalize()
|
||||||
|
|
||||||
|
def render_unit_for_grid(self, qty, field, value):
|
||||||
|
unit = qty[field]
|
||||||
|
if not unit:
|
||||||
|
return ""
|
||||||
|
return unit["name"]
|
||||||
|
|
||||||
|
def render_value_for_grid(self, qty, field, value):
|
||||||
|
return qty["value"]["decimal"]
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
quantity = self.farmos_client.resource.get_id(
|
quantity = self.farmos_client.resource.get_id(
|
||||||
"quantity", self.farmos_quantity_type, self.request.matchdict["uuid"]
|
"quantity", self.farmos_quantity_type, self.request.matchdict["uuid"]
|
||||||
|
|
@ -187,7 +228,7 @@ class QuantityMasterView(FarmOSMasterView):
|
||||||
def get_instance_title(self, quantity):
|
def get_instance_title(self, quantity):
|
||||||
return quantity["value"]
|
return quantity["value"]
|
||||||
|
|
||||||
def normalize_quantity(self, quantity):
|
def normalize_quantity(self, quantity, included={}):
|
||||||
|
|
||||||
if created := quantity["attributes"]["created"]:
|
if created := quantity["attributes"]["created"]:
|
||||||
created = datetime.datetime.fromisoformat(created)
|
created = datetime.datetime.fromisoformat(created)
|
||||||
|
|
@ -197,11 +238,37 @@ class QuantityMasterView(FarmOSMasterView):
|
||||||
changed = datetime.datetime.fromisoformat(changed)
|
changed = datetime.datetime.fromisoformat(changed)
|
||||||
changed = self.app.localtime(changed)
|
changed = self.app.localtime(changed)
|
||||||
|
|
||||||
|
quantity_type_object = None
|
||||||
|
quantity_type_uuid = None
|
||||||
|
unit_object = None
|
||||||
|
unit_uuid = None
|
||||||
|
if relationships := quantity["relationships"]:
|
||||||
|
|
||||||
|
if quantity_type := relationships["quantity_type"]["data"]:
|
||||||
|
quantity_type_uuid = quantity_type["id"]
|
||||||
|
quantity_type_object = {
|
||||||
|
"uuid": quantity_type_uuid,
|
||||||
|
"type": "quantity_type--quantity_type",
|
||||||
|
}
|
||||||
|
|
||||||
|
if unit := relationships["units"]["data"]:
|
||||||
|
unit_uuid = unit["id"]
|
||||||
|
if unit := included.get(unit_uuid):
|
||||||
|
unit_object = {
|
||||||
|
"uuid": unit_uuid,
|
||||||
|
"type": "taxonomy_term--unit",
|
||||||
|
"name": unit["attributes"]["name"],
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"uuid": quantity["id"],
|
"uuid": quantity["id"],
|
||||||
"drupal_id": quantity["attributes"]["drupal_internal__id"],
|
"drupal_id": quantity["attributes"]["drupal_internal__id"],
|
||||||
|
"quantity_type": quantity_type_object,
|
||||||
|
"quantity_type_uuid": quantity_type_uuid,
|
||||||
"measure": quantity["attributes"]["measure"],
|
"measure": quantity["attributes"]["measure"],
|
||||||
"value": quantity["attributes"]["value"],
|
"value": quantity["attributes"]["value"],
|
||||||
|
"unit": unit_object,
|
||||||
|
"unit_uuid": unit_uuid,
|
||||||
"label": quantity["attributes"]["label"] or colander.null,
|
"label": quantity["attributes"]["label"] or colander.null,
|
||||||
"created": created,
|
"created": created,
|
||||||
"changed": changed,
|
"changed": changed,
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import logging
|
||||||
from pyramid.renderers import render_to_response
|
from pyramid.renderers import render_to_response
|
||||||
|
|
||||||
from wuttaweb.views import View
|
from wuttaweb.views import View
|
||||||
|
from wuttaweb.db import Session
|
||||||
|
|
||||||
from wuttafarm.web.util import get_farmos_client_for_user
|
from wuttafarm.web.util import get_farmos_client_for_user
|
||||||
|
|
||||||
|
|
@ -40,6 +41,8 @@ class QuickFormView(View):
|
||||||
Base class for quick form views.
|
Base class for quick form views.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
Session = Session
|
||||||
|
|
||||||
def __init__(self, request, context=None):
|
def __init__(self, request, context=None):
|
||||||
super().__init__(request, context=context)
|
super().__init__(request, context=context)
|
||||||
self.farmos_client = get_farmos_client_for_user(self.request)
|
self.farmos_client = get_farmos_client_for_user(self.request)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ from wuttaweb.forms.schema import WuttaDateTime
|
||||||
from wuttaweb.forms.widgets import WuttaDateTimeWidget
|
from wuttaweb.forms.widgets import WuttaDateTimeWidget
|
||||||
|
|
||||||
from wuttafarm.web.views.quick import QuickFormView
|
from wuttafarm.web.views.quick import QuickFormView
|
||||||
from wuttafarm.web.util import get_farmos_client_for_user
|
|
||||||
|
|
||||||
|
|
||||||
class EggsQuickForm(QuickFormView):
|
class EggsQuickForm(QuickFormView):
|
||||||
|
|
@ -49,6 +48,9 @@ class EggsQuickForm(QuickFormView):
|
||||||
|
|
||||||
_layer_assets = None
|
_layer_assets = None
|
||||||
|
|
||||||
|
# TODO: make this configurable?
|
||||||
|
unit_name = "egg(s)"
|
||||||
|
|
||||||
def make_quick_form(self):
|
def make_quick_form(self):
|
||||||
f = self.make_form(
|
f = self.make_form(
|
||||||
fields=[
|
fields=[
|
||||||
|
|
@ -89,6 +91,47 @@ class EggsQuickForm(QuickFormView):
|
||||||
if self._layer_assets is not None:
|
if self._layer_assets is not None:
|
||||||
return self._layer_assets
|
return self._layer_assets
|
||||||
|
|
||||||
|
if self.app.is_farmos_wrapper():
|
||||||
|
assets = self.get_layer_assets_from_farmos()
|
||||||
|
else:
|
||||||
|
assets = self.get_layer_assets_from_wuttafarm()
|
||||||
|
|
||||||
|
assets.sort(key=lambda a: a["name"])
|
||||||
|
self._layer_assets = assets
|
||||||
|
return assets
|
||||||
|
|
||||||
|
def get_layer_assets_from_wuttafarm(self):
|
||||||
|
model = self.app.model
|
||||||
|
session = self.Session()
|
||||||
|
assets = []
|
||||||
|
|
||||||
|
def normalize(asset):
|
||||||
|
asset_type = asset.__wutta_hint__["farmos_asset_type"]
|
||||||
|
return {
|
||||||
|
"uuid": str(asset.farmos_uuid),
|
||||||
|
"name": asset.asset_name,
|
||||||
|
"type": f"asset--{asset_type}",
|
||||||
|
}
|
||||||
|
|
||||||
|
query = (
|
||||||
|
session.query(model.AnimalAsset)
|
||||||
|
.join(model.Asset)
|
||||||
|
.filter(model.AnimalAsset.produces_eggs == True)
|
||||||
|
.order_by(model.Asset.asset_name)
|
||||||
|
)
|
||||||
|
assets.extend([normalize(a) for a in query])
|
||||||
|
|
||||||
|
query = (
|
||||||
|
session.query(model.GroupAsset)
|
||||||
|
.join(model.Asset)
|
||||||
|
.filter(model.GroupAsset.produces_eggs == True)
|
||||||
|
.order_by(model.Asset.asset_name)
|
||||||
|
)
|
||||||
|
assets.extend([normalize(a) for a in query])
|
||||||
|
|
||||||
|
return assets
|
||||||
|
|
||||||
|
def get_layer_assets_from_farmos(self):
|
||||||
assets = []
|
assets = []
|
||||||
params = {
|
params = {
|
||||||
"filter[produces_eggs]": 1,
|
"filter[produces_eggs]": 1,
|
||||||
|
|
@ -108,24 +151,14 @@ class EggsQuickForm(QuickFormView):
|
||||||
result = self.farmos_client.asset.get("group", params=params)
|
result = self.farmos_client.asset.get("group", params=params)
|
||||||
assets.extend([normalize(a) for a in result["data"]])
|
assets.extend([normalize(a) for a in result["data"]])
|
||||||
|
|
||||||
assets.sort(key=lambda a: a["name"])
|
|
||||||
self._layer_assets = assets
|
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
def save_quick_form(self, form):
|
def save_quick_form(self, form):
|
||||||
|
|
||||||
response = self.save_to_farmos(form)
|
if self.app.is_farmos_wrapper():
|
||||||
log = json.loads(response["create-log#body{0}"]["body"])
|
return self.save_to_farmos(form)
|
||||||
|
|
||||||
if self.app.is_farmos_mirror():
|
return self.save_to_wuttafarm(form)
|
||||||
quantity = json.loads(response["create-quantity"]["body"])
|
|
||||||
client = get_farmos_client_for_user(self.request)
|
|
||||||
self.app.auto_sync_from_farmos(
|
|
||||||
quantity["data"], "StandardQuantity", client=client
|
|
||||||
)
|
|
||||||
self.app.auto_sync_from_farmos(log["data"], "HarvestLog", client=client)
|
|
||||||
|
|
||||||
return log
|
|
||||||
|
|
||||||
def save_to_farmos(self, form):
|
def save_to_farmos(self, form):
|
||||||
data = form.validated
|
data = form.validated
|
||||||
|
|
@ -135,7 +168,7 @@ class EggsQuickForm(QuickFormView):
|
||||||
asset = assets[data["asset"]]
|
asset = assets[data["asset"]]
|
||||||
|
|
||||||
# TODO: make this configurable?
|
# TODO: make this configurable?
|
||||||
unit_name = "egg(s)"
|
unit_name = self.unit_name
|
||||||
|
|
||||||
unit = {"data": {"type": "taxonomy_term--unit"}}
|
unit = {"data": {"type": "taxonomy_term--unit"}}
|
||||||
new_unit = None
|
new_unit = None
|
||||||
|
|
@ -234,13 +267,87 @@ class EggsQuickForm(QuickFormView):
|
||||||
blueprints.insert(0, new_unit)
|
blueprints.insert(0, new_unit)
|
||||||
blueprint = SubrequestsBlueprint.parse_obj(blueprints)
|
blueprint = SubrequestsBlueprint.parse_obj(blueprints)
|
||||||
response = self.farmos_client.subrequests.send(blueprint, format=Format.json)
|
response = self.farmos_client.subrequests.send(blueprint, format=Format.json)
|
||||||
return response
|
|
||||||
|
|
||||||
def redirect_after_save(self, result):
|
log = json.loads(response["create-log#body{0}"]["body"])
|
||||||
return self.redirect(
|
|
||||||
self.request.route_url(
|
if self.app.is_farmos_mirror():
|
||||||
"farmos_logs_harvest.view", uuid=result["data"]["id"]
|
if new_unit:
|
||||||
|
unit = json.loads(response["create-unit"]["body"])
|
||||||
|
self.app.auto_sync_from_farmos(
|
||||||
|
unit["data"], "Unit", client=self.farmos_client
|
||||||
|
)
|
||||||
|
quantity = json.loads(response["create-quantity"]["body"])
|
||||||
|
self.app.auto_sync_from_farmos(
|
||||||
|
quantity["data"], "StandardQuantity", client=self.farmos_client
|
||||||
)
|
)
|
||||||
|
self.app.auto_sync_from_farmos(
|
||||||
|
log["data"], "HarvestLog", client=self.farmos_client
|
||||||
|
)
|
||||||
|
|
||||||
|
return log
|
||||||
|
|
||||||
|
def save_to_wuttafarm(self, form):
|
||||||
|
model = self.app.model
|
||||||
|
session = self.Session()
|
||||||
|
data = form.validated
|
||||||
|
|
||||||
|
asset = (
|
||||||
|
session.query(model.Asset)
|
||||||
|
.filter(model.Asset.farmos_uuid == data["asset"])
|
||||||
|
.one()
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: make this configurable?
|
||||||
|
unit_name = self.unit_name
|
||||||
|
|
||||||
|
new_unit = False
|
||||||
|
unit = session.query(model.Unit).filter(model.Unit.name == unit_name).first()
|
||||||
|
if not unit:
|
||||||
|
unit = model.Unit(name=unit_name)
|
||||||
|
session.add(unit)
|
||||||
|
new_unit = True
|
||||||
|
|
||||||
|
quantity = model.StandardQuantity(
|
||||||
|
quantity_type_id="standard",
|
||||||
|
measure_id="count",
|
||||||
|
value_numerator=data["count"],
|
||||||
|
value_denominator=1,
|
||||||
|
units=unit,
|
||||||
|
)
|
||||||
|
session.add(quantity)
|
||||||
|
|
||||||
|
log = model.HarvestLog(
|
||||||
|
log_type="harvest",
|
||||||
|
message=f"Collected {data['count']} {unit_name}",
|
||||||
|
timestamp=self.app.make_utc(data["timestamp"]),
|
||||||
|
notes=data["notes"] or None,
|
||||||
|
quick="eggs",
|
||||||
|
status="done",
|
||||||
|
)
|
||||||
|
session.add(log)
|
||||||
|
log.assets.append(asset)
|
||||||
|
log.quantities.append(quantity.quantity)
|
||||||
|
log.owners.append(self.request.user)
|
||||||
|
session.flush()
|
||||||
|
|
||||||
|
if self.app.is_farmos_mirror():
|
||||||
|
if new_unit:
|
||||||
|
self.app.auto_sync_to_farmos(unit, client=self.farmos_client)
|
||||||
|
self.app.auto_sync_to_farmos(quantity, client=self.farmos_client)
|
||||||
|
self.app.auto_sync_to_farmos(log, client=self.farmos_client)
|
||||||
|
|
||||||
|
return log
|
||||||
|
|
||||||
|
def redirect_after_save(self, log):
|
||||||
|
model = self.app.model
|
||||||
|
|
||||||
|
if isinstance(log, model.HarvestLog):
|
||||||
|
return self.redirect(
|
||||||
|
self.request.route_url("logs_harvest.view", uuid=log.uuid)
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.redirect(
|
||||||
|
self.request.route_url("farmos_logs_harvest.view", uuid=log["data"]["id"])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue