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