backend/model/entity.rs
1//! Contains all entities used in `PermaplanT`.
2
3pub mod application_settings_impl;
4pub mod areas;
5pub mod areas_impl;
6pub mod base_layer_images;
7pub mod base_layer_images_impl;
8pub mod blossoms_impl;
9pub mod drawings;
10pub mod drawings_impl;
11pub mod guided_tours_impl;
12pub mod layers;
13pub mod layers_impl;
14pub mod map_collaborator_impl;
15pub mod map_impl;
16pub mod plant_layer;
17pub mod plantings;
18pub mod plantings_impl;
19pub mod plants_impl;
20pub mod seed_impl;
21pub mod timeline;
22pub mod users_impl;
23
24use chrono::NaiveDate;
25use chrono::NaiveDateTime;
26
27use diesel::AsChangeset;
28use diesel::QueryableByName;
29use diesel::{Identifiable, Insertable, Queryable};
30use postgis_diesel::types::Point;
31use postgis_diesel::types::Polygon;
32use uuid::Uuid;
33
34use crate::schema::{
35 application_settings, blossoms, gained_blossoms, guided_tours, map_collaborators, maps, plants,
36 seeds, users,
37};
38
39use super::r#enum::experience::Experience;
40use super::r#enum::membership::Membership;
41use super::r#enum::privacy_option::PrivacyOption;
42use super::r#enum::salutation::Salutation;
43use super::r#enum::track::Track;
44use super::r#enum::{
45 herbaceous_or_woody::HerbaceousOrWoody, life_cycle::LifeCycle,
46 light_requirement::LightRequirement, quality::Quality, quantity::Quantity, shade::Shade,
47 soil_texture::SoilTextureEnum, taxonomic_rank::TaxonomicRank,
48 water_requirement::WaterRequirementEnum,
49};
50
51/// The `Plants` entity builds up an hierarchical structure, see `/doc/database/hierarchy.md`:
52///
53#[doc = include_str!("../../../doc/database/hierarchy.md")]
54///
55#[derive(Debug, Identifiable, Queryable, QueryableByName)]
56#[diesel(table_name = plants)]
57pub struct Plants {
58 /// - The internal id of the plant.
59 /// - *Fill ratio:* 100%
60 pub id: i32,
61
62 /// - The unique name of the plant.
63 /// - The structure is described above (`doc/database/hierarchy.md`).
64 /// - *Fill ratio:* 100%
65 pub unique_name: String,
66
67 /// - The list of the common names of the plant in English.
68 /// - *Fetched from* `PracticalPlants` and Permapeople.
69 /// - *Fill ratio:* 90%
70 pub common_name_en: Option<Vec<Option<String>>>,
71
72 /// - The list of the common names of the plant in German.
73 /// - *Fetched from* Wikidata API if not present in any source datasets.
74 /// - *Fill ratio:* 25%
75 pub common_name_de: Option<Vec<Option<String>>>,
76
77 // /// - The edible use of the plant, answering: Which food type can be produced from this plant, e.g. oil?
78 // /// - Interesting for search functionality.
79 // /// - *Fetched from* Permapeople as `edible_uses` and merged with Reinsaat.
80 // /// - *Fill ratio:* 6%
81 // pub edible_uses_en: Option<String>,
82
83 // /// - Not used.
84 // /// - *Fetched from* PracticalPlants as `medicinal_uses` and merged with Permapeople.
85 // /// - *Fill ratio:* 1%
86 //pub medicinal_uses: Option<String>,
87
88 // /// - Only for references.
89 // /// - *Fetched from* PracticalPlants)
90 // /// - *Fill ratio:* 34%
91 // pub material_uses_and_functions: Option<String>,
92
93 // /// - Only for references.
94 // /// - *Fetched from* PracticalPlants)
95 // /// - *Fill ratio:* 63%
96 // pub botanic: Option<String>,
97
98 // /// - Only informational.
99 // /// - *Fetched from* PracticalPlants
100 // /// - Plants are not only used for food but also for other uses, e.g. fiber to produce paper.
101 // /// - *Fill ratio:* 1%
102 // pub material_uses: Option<String>,
103 //
104 /// - TODO: use in search (and attribute)
105 /// - *Used* for search ranking (diversity).
106 /// - ecological and environmental function of the plant, especially nitrogen fixer is relevant for `PermaplanT`.
107 /// - *Fetched from* `PracticalPlants`)
108 /// - *Fill ratio:* 13%
109 pub functions: Option<String>,
110
111 // /// - Not used.
112 // /// - Use `hardiness_zone` instead.
113 // /// - indication of the heat range a plant endures.
114 // /// - *Fetched from* `PracticalPlants`.
115 // /// - *Fill ratio:* 0.05%
116 // pub heat_zone: Option<i16>,
117 //
118 /// - Shade tolerance of the plant, to be used together with `light_requirement`.
119 /// - *Used* in shade layer.
120 /// - *For example* a plant that has "no shade", should get a warning if placed in a shade.
121 /// - No shade: full sun exposure
122 /// - Light shade: moderately shaded throughout the day
123 /// - Partial shade: about 3-6 hours of direct sunlight
124 /// - Permanent shade: less than 3 hours of direct sunlight
125 /// - Shade indicates the shade tolerance. Plants obviously grow better with better light conditions.
126 /// - Warnings should only show if a plant is moved into a too dark spot.
127 /// No warning should be shown when moved into a lighter spot.
128 /// - *Fetched from* `PracticalPlants`.
129 /// - *Fill ratio:* 63%
130 pub shade: Option<Shade>,
131
132 // /// - Currently unused (maybe later used in pH layer).
133 // /// - *See* explanation in `/doc/architecture/context.md`
134 // /// - Soil PH can be tested by the user with simple means (e.g. litmus).
135 // /// - *Fetched from* `PracticalPlants` and Permapeople (merged between Permapeople and `PracticalPlants`).
136 // /// - *Fill ratio:* 1%
137 // pub soil_ph: Option<Vec<Option<SoilPh>>>,
138 //
139 /// - *See* explanation in `/doc/architecture/context.md`
140 /// - *Used* in soil layer.
141 /// - *Fetched from* `PracticalPlants` and Permapeople (merged with `soil_type` of Permapeople).
142 /// - *Fill ratio:* 88%
143 pub soil_texture: Option<Vec<Option<SoilTextureEnum>>>,
144
145 // /// - *NOT used* in hydrology layer
146 // /// as it has poor quality and no additional data compared to water_requirement
147 // /// - *Fill ratio:* 37%
148 // /// - *Fetched from* PracticalPlants
149 // /// - wet = drowned, (often) flooded or in general very moist, e.g. swamp
150 // /// - moist = humid, can hold some water, e.g. flat bed with humus
151 // /// - well drained = dry, low capacity to hold water, e.g. sandhill.
152 // pub soil_water_retention: Option<Vec<Option<SoilWaterRetention>>>,
153
154 // /// - Only informational.
155 // /// - *Fetched from* PracticalPlants
156 // /// - gives information about environmental conditions, such as drought or wind tolerance
157 // /// - *Fill ratio:* 15%
158 //pub environmental_tolerances: Option<Vec<Option<String>>>,
159
160 // /// - Not used.
161 // /// - *Fetched from* PracticalPlants
162 // /// - *Fill ratio:* 0.2%
163 //pub native_geographical_range: Option<String>,
164
165 // /// - Not used.
166 // /// - *Fetched from* `PracticalPlants`
167 // /// - *Fill ratio:* 0.1%
168 //pub native_environment: Option<String>,
169
170 // /// - Interesting for search functionality.
171 // /// - *Fetched from* `PracticalPlants`
172 // /// - informs about the (vertical) layer, that the plant usually inhabits, e.g. soil surface or canopy
173 // /// - *Fill ratio:* 16%
174 // pub ecosystem_niche: Option<String>,
175
176 // /// - Only informational.
177 // /// - deciduous = plants loose leaves in winter.
178 // /// - evergreen = Plants don't throw leaves (e.g. pine tree).
179 // /// - Not applicable for annual plants.
180 // /// - *Fetched from* `PracticalPlants` and merged with `leaves` of Permapeople.
181 // /// - *Fill ratio:* 30%
182 // pub deciduous_or_evergreen: Option<DeciduousOrEvergreen>,
183 //W
184 /// - TODO: use in attribute
185 /// - Only informational.
186 /// - Fetched from `PracticalPlants`
187 /// - informs about the plant physiology
188 /// - woody = grows woody parts
189 /// - herbaceous = doesn't grow wood, shoots remain soft/green.
190 /// - *Fill ratio:* 26%
191 pub herbaceous_or_woody: Option<HerbaceousOrWoody>,
192
193 /// - Use in search and attribute
194 /// - Determines life span of the plant.
195 /// - *Fetched from* `PracticalPlants` and Permapeople (merged with `life_cycle` of Permapeople).
196 /// - *Fill ratio:* 68%
197 pub life_cycle: Option<Vec<Option<LifeCycle>>>,
198
199 // /// - Only informational.
200 // /// - *Fetched from* `PracticalPlants` and Permapeople (merged with `growth` of Permapeople).
201 // /// - *Fill ratio:* 30%
202 // pub growth_rate: Option<Vec<Option<GrowthRate>>>,
203 //
204 /// - Only informational, is in rw attribute
205 /// - *Fetched from* `PracticalPlants` as `mature_size_height` and merged with Permapeople.
206 /// - informs about the maximum height that the plant gains in cm
207 /// - *Fill ratio:* 80%
208 pub height: Option<i32>,
209
210 // /// - Determines how large the plant can grow in diameter.
211 // /// - Other plants should get a warning if planted within this area.
212 // /// - *TODO:* replaced with spread, will keep this for now for information
213 // /// - *Fetched from* `PracticalPlants` as `mature_size_width` and merged with Permapeople.
214 // /// - *Fill ratio:* 22%
215 //pub width: Option<String>,
216
217 // /// - Only informational.
218 // /// - *Fetched from* `PracticalPlants`
219 // /// - *Fill ratio:* 18%
220 // pub fertility: Option<Vec<Option<Fertility>>>,
221
222 // /// - Only informational.
223 // /// - *Fetched from* PracticalPlants
224 // /// - *Fill ratio:* 0.5%
225 //pub flower_colour: Option<String>,
226
227 // /// - Only informational.
228 // /// - *Fetched from* PracticalPlants
229 // /// - a plant can contain flowers of two different sexes, male or female (monoecious), a plant can contain only flowers of one specific sex and therefore needs at least another plant of the other sex to reproduce (dioecious) or can contain flowers that have both the sexes within the same flower (hermaphrodite).
230 // /// - *Fill ratio:* 62%
231 // pub flower_type: Option<FlowerType>,
232 //
233 /// - Is readonly in attribute
234 /// - The creation date of the entry.
235 /// - Only for administration.
236 /// - *Fill ratio:* 100%
237 pub created_at: NaiveDateTime,
238
239 /// - Is readonly in attribute
240 /// - The last update date of the entry.
241 /// - Only for administration.
242 /// - *Fill ratio:* 100%
243 pub updated_at: NaiveDateTime,
244
245 /// - ! TODO: show in attributes and search (icon)
246 /// - Will be used in watering layer.
247 /// - Fetched from `PracticalPlants` and merged with `has_drought_tolerance` of Permapeople.
248 /// - *Fill ratio:* 57%
249 pub has_drought_tolerance: Option<bool>,
250
251 // /// - *Fetched from* `PracticalPlants`.
252 // /// - *Fill ratio:* 10%
253 // pub tolerates_wind: Option<bool>,
254
255 // /// - The list of the references of the plant.
256 // /// - `references` items link to these items.
257 // /// - Only informational.
258 // /// - *Fill ratio:* 58%
259 // pub plant_references: Option<Vec<Option<String>>>,
260
261 // /// - Boolean value indicating whether the plant is a tree.
262 // /// - Plants with `is_tree == true` can be used in the tree layer.
263 // /// - In plants layer all plants can be used.
264 // /// - *Initial value* is to `True` if herbaceous_or_woody (woody) and life_cycle (perennial)
265 // /// - *Fill ratio:* 0.1%
266 // pub is_tree: Option<bool>,
267
268 // /// - Only informational.
269 // /// - *Initial value* is to `light feeder` if "Nutritionally poor soil" in `environmental_tolerances` is present.
270 // /// - *Fill ratio:* 0.04%
271 // pub nutrition_demand: Option<NutritionDemand>,
272
273 // /// - Not used.
274 // /// - Number value between -1..6 (-1 should be printed as 00)
275 // /// - *Fill ratio:* 0%
276 // pub preferable_permaculture_zone: Option<i16>,
277
278 // /// - When article was modified last time.
279 // /// - Only for administration.
280 // /// - Date value fetched from `PracticalPlants` page showing the last modification date of the plant.
281 // /// - *Fill ratio:* 63%
282 // pub article_last_modified_at: Option<NaiveDateTime>,
283 //
284 /// - TODO: show in search
285 /// - USDA Hardiness Zone (without subranges).
286 /// - Important information.
287 /// - Fetched from `PracticalPlants` and Permapeople (merged with `usda_hardiness_zone` of Permapeople).
288 /// - *Fill ratio:* 63%
289 pub hardiness_zone: Option<String>,
290
291 /// - Shade tolerance of the plant, to be used together with shade.
292 /// - *Used* in shade layer.
293 /// - *For example* a plant that has "Full sun", should get a warning if placed in a shade.
294 /// - **Fetched from*** `PracticalPlants` and Permapeople (merged with `sun` of `PracticalPlants`)
295 /// - Full sun: full sun exposure
296 /// - Partial sun/shade: about 3-6 hours of direct sunlight or moderately shaded throughout the day
297 /// - Full shade: less than 3 hours of direct sunlight or almost no sunlight/no direct sunlight
298 /// - *Fill ratio:* 88%
299 pub light_requirement: Option<Vec<Option<LightRequirement>>>,
300
301 /// - *Used* in hydrology layer.
302 /// - *Fetched from* `PracticalPlants` and Permapeople (merged with `water` of `PracticalPlants`).
303 /// - water = completely aquatic;
304 /// - wet = drowned, (often) flooded or in general very moist, e.g. swamp;
305 /// - moist = humid, regular water supply, e.g. flat bed with humus;
306 /// - well drained = dry, little water input.
307 /// - *Fill ratio:* 88%
308 pub water_requirement: Option<Vec<Option<WaterRequirementEnum>>>,
309
310 // /// - Only informational.
311 // /// - *Fetched from* Permapeople (renamed from `propagation`)
312 // /// - How to reproduce a plant: cuttings = cut pieces of wood; layering = let low branches reach the soil to root; Seed - direct sow = sow directly the seeds; division = split the rhizomes (roots) into pieces; Spores = plant reproduces via spores (e.g. ferns, funghi); seed - transplant = raise indoors from seed and transplant to outdoors later
313 // /// - *Fill ratio:* 0.9%
314 // pub propagation_method: Option<Vec<Option<PropagationMethod>>>,
315
316 // /// - Only informational.
317 // /// - May be used in search functionality (low priority).
318 // /// - *Fetched from* Permapeople.
319 // /// - *Fill ratio:* 35%
320 // pub alternate_name: Option<String>,
321
322 // /// - Only informational.
323 // /// - *Fetched from* Permapeople.
324 // /// - *Fill ratio:* 0.02%
325 //pub diseases: Option<String>,
326 //
327 /// - TODO: use in search (and as attribute)
328 /// - Important information.
329 /// - *Fetched from* Permapeople.
330 /// - *Fill ratio:* 62%
331 pub edible: Option<bool>,
332
333 /// - TODO: use as attribute (translation in frontend)
334 /// - Only informational.
335 /// - *Fetched from* Permapeople.
336 /// - which organ of the plant can be eaten, e.g. root, leaves.
337 /// - *Fill ratio:* 61%
338 pub edible_parts: Option<Vec<Option<String>>>,
339
340 // /// - Only informational.
341 // /// - *Fetched from* Permapeople.
342 // /// - Reinsaat: `Keimtemperatur` should be copied to `germination_temperature`
343 // /// - Germination means that all conditions are right for a seed to start growing. Temperature is one essential factor.
344 // /// - *Fill ratio:* 2%
345 //pub germination_temperature: Option<String>,
346
347 // /// - Not used.
348 // /// - *Fetched from* Permapeople.
349 // /// - *Fill ratio:* 36%
350 //pub introduced_into: Option<String>,
351
352 // /// - Only informational.
353 // /// - *Fetched from* Permapeople as \`layer\` and renamed.
354 // /// - Habitus describes the shape of a plant.
355 // /// - *Fill ratio:* 48%
356 //pub habitus: Option<String>,
357
358 // /// - Not used.
359 // /// - *Fetched from* Permapeople.
360 // /// - *Fill ratio:* 0.1%
361 //pub medicinal_parts: Option<String>,
362
363 // /// - Only informational.
364 // /// - *Fetched from* Permapeople.
365 // /// - *Fill ratio:* 80%
366 //pub native_to: Option<String>,
367
368 // /// - Not used.
369 // /// - *Fetched from* Permapeople.
370 // /// - *Fill ratio:* 86%
371 //pub plants_for_a_future: Option<String>,
372
373 // /// - Not used.
374 // /// - *Fetched from* Permapeople.
375 // /// - *Fill ratio:* 86%
376 //pub plants_of_the_world_online_link: Option<String>,
377
378 // /// - Not used.
379 // /// - *Fetched from* Permapeople.
380 // /// - *Fill ratio:* 15%
381 //pub plants_of_the_world_online_link_synonym: Option<String>,
382
383 // /// - Only informational.
384 // /// - *Fetched from* PracticalPlants as `pollinators` and merged with `pollination` of Permapeople.
385 // /// - Pollination is the process that the pollen (male part) gets united with the pistil (female part), e.g. via bees, wind.
386 // /// - *Fill ratio:* 48%
387 //pub pollination: Option<String>,
388
389 // /// - Only informational.
390 // /// - *Fetched from* Permapeople.
391 // /// - *Fill ratio:* 0.1%
392 //pub propagation_transplanting_en: Option<String>,
393
394 // /// - Not used.
395 // /// - Nearly empty.
396 // /// - *Fetched from* Permapeople.
397 // /// - *Fill ratio:* 0.01%
398 //pub resistance: Option<String>,
399
400 // /// - Only informational.
401 // /// - *Fetched from* Permapeople.
402 // /// - Root type describes the shape of the roots.
403 // /// - *Fill ratio:* 0.24%
404 //pub root_type: Option<String>,
405
406 // /// - Only informational.
407 // /// - *Fetched from* Permapeople as `seed_planting_depth` and renamed.
408 // /// - Reinsaat: `Sowing depth` should be copied to `seed_planting_depth_en`
409 // /// - When sowing each plant has a specific value how deep the seeds should be covered with soil.
410 // /// - *Fill ratio:* 0.07%
411 //pub seed_planting_depth_en: Option<String>,
412
413 // /// - Only informational.
414 // /// - *Fetched from* Permapeople.
415 // /// - expected average life span (in years) of a seed of a certain specie.
416 // /// - *Fill ratio:* 0.6%
417 //pub seed_viability: Option<String>,
418
419 // /// - Not used.
420 // /// - The final part of the URL of the plant on the Permapeople website.
421 // /// - This field can be potentially used to construct the `external_url` field traversing through all the parents given by `parent_id`.
422 // /// - *Fetched from* Permapeople.
423 // /// - *Fill ratio:* 90%
424 //pub slug: Option<String>,
425 //
426 /// - **Used**
427 /// - How far a plant spreads (The 'width' of a plant) in cm
428 /// - *Fetched from* Permapeople.
429 /// - *Fill ratio:* 0.1%
430 pub spread: Option<i32>,
431
432 // /// - Not used.
433 // /// - *Fetched from* Permapeople.
434 // /// - *Fill ratio:* 2%
435 //pub utility: Option<String>,
436 //
437 /// - TODO: use in search (and as attribute)
438 /// - Important information.
439 /// - *Fetched from* Permapeople.
440 /// - specific warnings for eather human, animal or environmental well-being, e.g. toxic, invasive.
441 /// - *Fill ratio:* 8%
442 pub warning: Option<String>,
443
444 // /// - Not used.
445 // /// - *Fetched from* Permapeople.
446 // /// - *Fill ratio:* 0.06%
447 //pub when_to_plant_cuttings_en: Option<String>,
448
449 // /// - Not used.
450 // /// - *Fetched from* Permapeople.
451 // /// - *Fill ratio:* 0.07%
452 //pub when_to_plant_division_en: Option<String>,
453
454 // /// - Not used.
455 // /// - *Fetched from* Permapeople.
456 // /// - *Fill ratio:* 0.2%
457 //pub when_to_plant_transplant_en: Option<String>,
458
459 // /// - Only informational.
460 // /// - *Fetched from* Permapeople.
461 // /// - *Fill ratio:* 0.23%
462 //pub when_to_sow_indoors_en: Option<String>,
463
464 // /// - Only informational.
465 // /// - *Fetched from* Permapeople as `when_to_sow_outdoors` and renamed.
466 // /// - Reinsaat: `Sowing` or `Direct Sowing` or `Sowing outdoors` or `Sowing Direct Outdoors` should be copied to `sowing_outdoors_en`
467 // /// - *Fill ratio:* 0.36%
468 //pub sowing_outdoors_en: Option<String>,
469
470 // /// - Only informational.
471 // /// - *Fetched from* Permapeople.
472 // /// - *Fill ratio:* 0.56%
473 //pub when_to_start_indoors_weeks: Option<String>,
474
475 // /// - Only informational.
476 // /// - *Fetched from* Permapeople.
477 // /// - *Fill ratio:* 0.12%
478 //pub when_to_start_outdoors_weeks: Option<String>,
479
480 // /// - Only informational.
481 // /// - *Fetched from* Permapeople.
482 // /// - Stratification is the process that a seed must go through to get triggered for germination, e.g. by a certain threshold of minus degrees.
483 // /// - *Fill ratio:* 0.03%
484 //pub cold_stratification_temperature: Option<String>,
485
486 // /// - Only informational.
487 // /// - *Fetched from* Permapeople.
488 // /// - Suggested change
489 // /// - *Fetched from* Permapeople.
490 // /// - Stratification is the process that a seed must go through to get triggered for germination, e.g. by a certain amount of time under cold temperatures.
491 // /// - *Fill ratio:* 0.05%
492 //pub cold_stratification_time: Option<String>,
493
494 // /// - Only informational.
495 // /// - *Fetched from* Permapeople.
496 // /// - Reinsaat: `1st harvest` should be copied to `days_to_harvest`
497 // /// - *Fill ratio:* 0.1%
498 //pub days_to_harvest: Option<String>,
499
500 // /// - Needed for occupied space and in attributes
501 // /// - *TODO:* should be number and then be used for calender
502 //pub life_cycle_days: Option<int>,
503
504 // /// - Not used.
505 // /// - *Fetched from* Permapeople.
506 // /// - *Fill ratio:* 0.2%
507 //pub habitat: Option<String>,
508
509 // /// - One number means it is spacing between plants and rows. Two numbers means first is spacing between plants, second between rows.
510 // /// - Only informational.
511 // /// - *Fetched from* Permapeople as `spacing` and from Reinsaat as `Distances` and renamed.
512 // /// - Reinsaat: `Distances` or `Spacing` should be copied to `spacing_en`
513 // /// - *Fill ratio:* 0.7%
514 //pub spacing_en: Option<String>,
515
516 // /// - Not used.
517 // /// - *Fetched from* Permapeople as `wikipedia` and renamed.
518 // /// - *Fill ratio:* 47%
519 //pub wikipedia_url: Option<String>,
520
521 // /// - Only informational.
522 // /// - *Fetched from* Permapeople.
523 // /// - *Fill ratio:* 0.3%
524 //pub days_to_maturity: Option<String>,
525
526 // /// - Not used.
527 // /// - Nearly empty.
528 // /// - *Fetched from* Permapeople.
529 // /// - *Fill ratio:* 0.03%
530 //pub pests: Option<String>,
531 //
532 /// - TODO: add to attributes
533 /// - Only for administration.
534 /// - The version of the entry.
535 /// - To be incremented after every relevant change.
536 /// - *Fetched from* Permapeople.
537 /// - *Fill ratio:* 90%
538 pub version: Option<i16>,
539
540 // /// - Only informational.
541 // /// - *Fetched from* Permapeople.
542 // /// - Germination time describes the time (days, weeks, months) that a seed needs to germinate given the right conditions.
543 // /// - *Fill ratio:* 0.5%
544 //pub germination_time: Option<String>,
545
546 // /// - Not used.
547 // /// - The description of the entry.
548 // /// - *Fetched from* Permapeople.
549 // /// - *Fill ratio:* 5%
550 //pub description: Option<String>,
551
552 // /// - TODO: (not yet in database) add to attributes
553 // /// - Short important information to shown.
554 //pub info: Option<String>,
555
556 // /// - Not used.
557 // /// - *Fetched from* permapeople id of the parent entry pointing to the `external_id` column.
558 // /// - *Fill ratio:* 2%
559 //pub parent_id: Option<String>,
560
561 // /// - Not used.
562 // /// - Enum value indicating the source of the entry.
563 // /// - *Fill ratio:* 100%
564 // pub external_source: Option<ExternalSource>,
565
566 // /// - Not used.
567 // /// - The external id of the entry used in combination with the `external_source` column.
568 // /// - *Fill ratio:* 90%
569 //pub external_id: Option<String>,
570
571 // /// - Not used.
572 // /// - The external URL provided by the origin source.
573 // /// - *Fill ratio:* 9%
574 //pub external_url: Option<String>,
575
576 // /// - Only informational.
577 // /// - *Fetched from* PracticalPlants as `root_zone_tendency` and merged with root_depth of Permapeople.
578 // /// - Root depth can be considered when planning polycultures, e.g. combining shallow roots with deep roots.
579 // /// - *Fill ratio:* 0.2%
580 //pub root_depth: Option<String>,
581
582 // /// - Not used.
583 // /// - The article number `Artikelnummer` of the plant in the Reinsaat database.
584 // /// - *Fill ratio:* 7%
585 //pub external_article_number: Option<String>,
586
587 // /// - Not used.
588 // /// - `Portionsinhalt` should be called `external_portion_content`
589 // /// - *Fetched from* Reinsaat.
590 // /// - *Fill ratio:* 7%
591 //pub external_portion_content: Option<String>,
592
593 // /// - Only informational.
594 // /// - *Fetched from* Reinsaat as \`Direktsaat\` and renamed.
595 // /// - `Direktsaat` or `Aussaat` should be called `sowing_outdoors_de`
596 // /// - *Fill ratio:* 3%
597 //pub sowing_outdoors_de: Option<String>,
598 //
599 /// - TODO: use as attribute
600 /// - String array of numbers representing a time period.
601 /// - The year is divided into 24 periods of half a month each.
602 /// - *For example* "\[8,9,10\]" means from the 2nd half of April to the 2nd half of May incl.
603 /// - *Fetched from* Reinsaat
604 /// - `Aussaat/ Pflanzung Freiland` should be called `sowing_outdoors`
605 /// - *Fill ratio:* 5%
606 pub sowing_outdoors: Option<Vec<Option<i16>>>,
607
608 /// - TODO: use as attribute
609 /// - String array of numbers representing a time period.
610 /// - The year is divided into 24 periods of half a month each.
611 /// - *For example* "\[8,9,10\]" means from the 2nd half of April to the 2nd half of May incl.
612 /// - `Ernte` should be called `harvest_time`
613 /// - *Fetched from* Reinsaat
614 /// - *Fill ratio:* 6%
615 pub harvest_time: Option<Vec<Option<i16>>>,
616 /*
617 /// - Only informational.
618 /// - *Fetched from* Reinsaat.
619 /// - `Abstände` should be called `spacing_de`
620 /// - *Fill ratio:* 4%
621 //pub spacing_de: Option<String>,
622
623 /// - Only informational.
624 /// - *Fetched from* Reinsaat.
625 /// - *Fill ratio:* 4%
626 /// - `Saatgutbedarf` should be called `required_quantity_of_seeds_de`
627 //pub required_quantity_of_seeds_de: Option<String>,
628
629 /// - Only informational.
630 /// - *Fetched from* Reinsaat.
631 /// - `Required quantity of seeds` should be called `required_quantity_of_seeds_en`
632 /// - *Fill ratio:* 3%
633 //pub required_quantity_of_seeds_en: Option<String>,
634
635 /// - Only informational.
636 /// - *Fetched from* Reinsaat.
637 /// - `Saattiefe` should be called `seed_planting_depth_de`
638 /// - When sowing, each plant has a specific value how deep the seeds should be covered with soil.
639 /// - *Fill ratio:* 5%
640 //pub seed_planting_depth_de: Option<String>,
641
642 /// - German version of thousand grain weight (German: Tausendkornmasse)
643 /// - Only informational.
644 /// - *Fetched from* Reinsaat.
645 /// - Called `Tausendkornmasse` in Reinsaat
646 /// - *Fill ratio:* 4%
647 //pub seed_weight_1000_de: Option<String>,
648
649 /// - English version of thousand grain weight (German: Tausendkornmasse)
650 /// - Only informational.
651 /// - *Fetched from* Reinsaat.
652 /// - Called `Thousand seeds mass` in Reinsaat
653 /// - *Fill ratio:* 3%
654 //pub seed_weight_1000_en: Option<String>,
655
656 /// - Number for thousand grain weight (German: Tausendkornmasse)
657 /// - *Used* in `doc/usecases/buy_seeds.md` to calculate seed weight based on number of plants.
658 /// - *Fetched from* Permapeople as `1000_seed_weight_g` and renamed.
659 /// - *TODO:* merge with data from reinsaat: `Tausendkorngewicht (TKG)` should be copied to `seed_weight` (remove ` g`)
660 /// - *Fill ratio:* 4%
661 // pub seed_weight_1000: Option<f64>,
662
663 /// - Only informational.
664 /// - *Fetched from* Reinsaat.
665 /// - `Suitable for professional cultivation` should be called `machine_cultivation_possible`
666 /// - *Fill ratio:* 9%
667 //pub machine_cultivation_possible: Option<bool>,
668
669 /// - *Fetched from* Reinsaat.
670 /// - *Used* for plant search and informational.
671 /// - `subcategory` from Reinsaat should be copied to `edible_uses_de` and `edible_uses_en` respectively (DE and EN version)
672 /// - *Fill ratio:* 6%
673 //pub edible_uses_de: Option<String>,
674 */
675 /// - Hierarchy fields
676 /// - Either *Fetched from* `PracticalPlants` and Permapeople
677 /// - Or determined from the unique name
678 /// - Or set by scraper overrides
679 pub rank: Option<TaxonomicRank>,
680 pub family: Option<i32>,
681 pub genus: Option<i32>,
682 pub species: Option<i32>,
683 pub variety: Option<i32>,
684}
685/// The `Seed` entity.
686#[derive(Identifiable, Queryable)]
687#[diesel(table_name = seeds)]
688pub struct Seed {
689 /// The record id of the seed.
690 pub id: i32,
691 /// An additional name for the seed.
692 pub name: String,
693 /// When the seeds were harvested.
694 pub harvest_year: i16,
695 /// When the seeds should be used by.
696 pub use_by: Option<NaiveDate>,
697 /// Where the seeds came from.
698 pub origin: Option<String>,
699 /// What the seeds taste like.
700 pub taste: Option<String>,
701 /// The yield of the seeds.
702 pub yield_: Option<String>,
703 /// How many seeds there are.
704 pub quantity: Quantity,
705 /// The quality of the seeds.
706 pub quality: Option<Quality>,
707 /// How much the seeds cost.
708 pub price: Option<i16>,
709 /// How many generations the seeds have been grown.
710 pub generation: Option<i16>,
711 /// Notes about the seeds.
712 pub notes: Option<String>,
713 /// The id of the plant this seed belongs to.
714 pub plant_id: Option<i32>,
715 /// The id of the creator of the seed.
716 pub created_by: Uuid,
717 /// Timestamp indicating when the seed was archived.
718 /// Empty if the seed was not archived.
719 pub archived_at: Option<NaiveDateTime>,
720}
721
722/// The `NewSeed` entity.
723#[allow(clippy::missing_docs_in_private_items)] // TODO: See #97.
724#[derive(Insertable)]
725#[diesel(table_name = seeds)]
726pub struct NewSeed {
727 pub name: String,
728 pub plant_id: Option<i32>,
729 pub harvest_year: i16,
730 pub use_by: Option<NaiveDate>,
731 pub origin: Option<String>,
732 pub taste: Option<String>,
733 pub yield_: Option<String>,
734 pub quantity: Quantity,
735 pub quality: Option<Quality>,
736 pub price: Option<i16>,
737 pub generation: Option<i16>,
738 pub notes: Option<String>,
739 pub created_by: Uuid,
740}
741
742/// The `Map` entity.
743#[derive(Identifiable, Queryable)]
744#[diesel(table_name = maps)]
745pub struct Map {
746 /// The id of the map.
747 pub id: i32,
748 /// The name of the map.
749 pub name: String,
750 /// The date the map is supposed to be deleted.
751 pub deletion_date: Option<NaiveDate>,
752 /// The date the last time the map view was opened by any user.
753 pub last_visit: Option<NaiveDate>,
754 /// A flag indicating if this map is marked for deletion.
755 pub is_inactive: bool,
756 /// The zoom factor of the map.
757 pub zoom_factor: i16,
758 /// The amount of honors the map received.
759 pub honors: i16,
760 /// The amount of visits the map had.
761 pub visits: i16,
762 /// The amount of plants harvested on the map.
763 pub harvested: i16,
764 /// An enum indicating if this map is private or not.
765 pub privacy: PrivacyOption,
766 /// The description of the map.
767 pub description: Option<String>,
768 /// The location of the map as a latitude/longitude point.
769 pub location: Option<Point>,
770 /// The id of the creator of the map.
771 pub created_by: Uuid,
772 /// The geometry of the map.
773 pub geometry: Polygon<Point>,
774 /// When the map was created.
775 pub created_at: NaiveDateTime,
776 /// When a map was last modified, e.g., by modifying plantings.
777 pub modified_at: NaiveDateTime,
778 /// By whom the map was last modified.
779 pub modified_by: Uuid,
780}
781
782/// The `NewMap` entity.
783#[derive(Insertable)]
784#[diesel(table_name = maps)]
785pub struct NewMap {
786 /// The name of the map.
787 pub name: String,
788 /// For a new map the same as `created_by`.
789 pub deletion_date: Option<NaiveDate>,
790 /// The date the last time the map view was opened by any user.
791 pub last_visit: Option<NaiveDate>,
792 /// A flag indicating if this map is marked for deletion.
793 pub is_inactive: bool,
794 /// The zoom factor of the map.
795 pub zoom_factor: i16,
796 /// The amount of honors the map received.
797 pub honors: i16,
798 /// The amount of visits the map had.
799 pub visits: i16,
800 /// The amount of plants harvested on the map.
801 pub harvested: i16,
802 /// An enum indicating if this map is private or not.
803 pub privacy: PrivacyOption,
804 /// The description of the map.
805 pub description: Option<String>,
806 /// The location of the map as a latitude/longitude point.
807 pub location: Option<Point>,
808 /// The id of the creator of the map.
809 pub created_by: Uuid,
810 /// The geometry of the map.
811 pub geometry: Polygon<Point>,
812 /// The user who last modified the planting.
813 pub modified_by: Uuid,
814}
815
816/// The `UpdateMap` entity.
817#[derive(AsChangeset)]
818#[diesel(table_name = maps)]
819pub struct UpdateMap {
820 /// The name of the map.
821 pub name: Option<String>,
822 /// An enum indicating if this map is private or not.
823 pub privacy: Option<PrivacyOption>,
824 /// The description of the map.
825 pub description: Option<String>,
826 /// The location of the map as a latitude/longitude point.
827 pub location: Option<Point>,
828}
829
830/// The `UpdateMapGeometry` entity.
831#[derive(AsChangeset)]
832#[diesel(table_name = maps)]
833pub struct UpdateMapGeometry {
834 /// New Map Bounds
835 pub geometry: Polygon<Point>,
836}
837
838/// The `Users` entity.
839#[derive(Insertable, Identifiable, Queryable)]
840#[diesel(table_name = users)]
841pub struct Users {
842 /// The id of the user from Keycloak.
843 pub id: Uuid,
844 /// The preferred salutation of the user.
845 pub salutation: Salutation,
846 /// The title(s) of the user.
847 pub title: Option<String>,
848 /// The current country of the user.
849 pub country: String,
850 /// The phone number of the user.
851 pub phone: Option<String>,
852 /// The website of the user.
853 pub website: Option<String>,
854 /// The organization the user belongs to.
855 pub organization: Option<String>,
856 /// The experience level in permaculture of the user.
857 pub experience: Option<Experience>,
858 /// The membership type of the user.
859 pub membership: Option<Membership>,
860 /// A collection of years in which the user was a member.
861 pub member_years: Option<Vec<Option<i32>>>,
862 /// The date since when the user is a member.
863 pub member_since: Option<NaiveDate>,
864 /// The amount of permacoins the user earned in each year as a member.
865 pub permacoins: Option<Vec<Option<i32>>>,
866}
867
868/// The `GuidedTours` entity.
869#[derive(Insertable, Identifiable, Queryable)]
870#[diesel(primary_key(user_id), table_name = guided_tours)]
871pub struct GuidedTours {
872 /// The id of the user from Keycloak.
873 pub user_id: Uuid,
874 /// A flag indicating if the Map Editor Guided Tour was completed.
875 pub editor_tour_completed: bool,
876}
877
878/// The `UpdateGuidedTours` entity.
879#[derive(AsChangeset)]
880#[diesel(table_name = guided_tours)]
881pub struct UpdateGuidedTours {
882 /// A flag indicating if the Map Editor Guided Tour was completed.
883 pub editor_tour_completed: Option<bool>,
884}
885
886/// The `Blossom` entity.
887#[derive(Identifiable, Queryable)]
888#[diesel(primary_key(title), table_name = blossoms)]
889pub struct Blossom {
890 /// The title of the Blossom.
891 pub title: String,
892 /// The description of the Blossom.
893 pub description: Option<String>,
894 /// The track the Blossom is part of.
895 pub track: Track,
896 /// The path to the icon of the Blossom in Nextcloud.
897 pub icon: String,
898 /// A flag indicating if this Blossom is repeatable every season.
899 pub is_seasonal: bool,
900}
901
902/// The `GainedBlossoms` entity.
903#[derive(Insertable, Identifiable, Queryable)]
904#[diesel(primary_key(user_id, blossom), table_name = gained_blossoms)]
905pub struct GainedBlossoms {
906 /// The id of the user from Keycloak.
907 pub user_id: Uuid,
908 /// The title of the Blossom.
909 pub blossom: String,
910 /// The number of times this Blossom was gained by this user.
911 pub times_gained: i32,
912 /// The date on which the user gained this Blossom.
913 pub gained_date: NaiveDate,
914}
915
916/// The `ApplicationSetting` entity.
917#[derive(Identifiable, Queryable)]
918#[diesel(primary_key(id), table_name = application_settings)]
919pub struct ApplicationSetting {
920 /// The id of the setting
921 pub id: i32,
922 /// The unique key of the setting
923 pub key: String,
924 /// The value of the setting
925 pub value: String,
926}
927
928/// The [`MapCollaborator`] entity.
929#[derive(Insertable, Identifiable, Queryable)]
930#[diesel(primary_key(map_id, user_id), table_name = map_collaborators)]
931pub struct MapCollaborator {
932 pub map_id: i32,
933 pub user_id: Uuid,
934 pub created_at: NaiveDateTime,
935}