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