@hestia-earth/data-validation 0.37.7 → 0.37.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (411) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +17 -0
  3. package/dist/validations.d.ts +10 -0
  4. package/dist/validations.js +10 -0
  5. package/package.json +4 -3
  6. package/search-results.json +1 -1
  7. package/src/version.ts +1 -1
  8. package/validation.json +639 -0
  9. package/.coveragerc +0 -14
  10. package/.dockerignore +0 -19
  11. package/.eslintignore +0 -17
  12. package/.eslintrc.js +0 -11
  13. package/.flake8 +0 -5
  14. package/.gitlab/issue_templates/new validation.md +0 -82
  15. package/.gitlab-ci.yml +0 -216
  16. package/.readthedocs.yml +0 -24
  17. package/CODEOWNERS +0 -11
  18. package/Dockerfile +0 -13
  19. package/MANIFEST.in +0 -2
  20. package/bin/hestia-validate-data +0 -80
  21. package/build_mocking.py +0 -14
  22. package/commitlint.config.js +0 -1
  23. package/docs/Makefile +0 -20
  24. package/docs/_static/styles.css +0 -4
  25. package/docs/_templates/custom-class-template.rst +0 -34
  26. package/docs/_templates/custom-module-template.rst +0 -66
  27. package/docs/_templates/layout.html +0 -4
  28. package/docs/conf.py +0 -74
  29. package/docs/index.rst +0 -42
  30. package/docs/make.bat +0 -35
  31. package/docs/requirements.txt +0 -13
  32. package/envs/.develop.env +0 -1
  33. package/envs/.master.env +0 -1
  34. package/guide-assets/.gitkeep +0 -0
  35. package/hestia_earth/validation/README.md +0 -5
  36. package/hestia_earth/validation/__init__.py +0 -32
  37. package/hestia_earth/validation/distribution.py +0 -22
  38. package/hestia_earth/validation/gee.py +0 -162
  39. package/hestia_earth/validation/log.py +0 -44
  40. package/hestia_earth/validation/models.py +0 -141
  41. package/hestia_earth/validation/preload_requests.py +0 -61
  42. package/hestia_earth/validation/terms.py +0 -88
  43. package/hestia_earth/validation/utils.py +0 -444
  44. package/hestia_earth/validation/validators/__init__.py +0 -141
  45. package/hestia_earth/validation/validators/aggregated_cycle.py +0 -32
  46. package/hestia_earth/validation/validators/aggregated_shared.py +0 -37
  47. package/hestia_earth/validation/validators/animal.py +0 -88
  48. package/hestia_earth/validation/validators/completeness.py +0 -252
  49. package/hestia_earth/validation/validators/cycle.py +0 -1123
  50. package/hestia_earth/validation/validators/distribution.py +0 -86
  51. package/hestia_earth/validation/validators/emission.py +0 -109
  52. package/hestia_earth/validation/validators/impact_assessment.py +0 -138
  53. package/hestia_earth/validation/validators/indicator.py +0 -154
  54. package/hestia_earth/validation/validators/infrastructure.py +0 -25
  55. package/hestia_earth/validation/validators/input.py +0 -268
  56. package/hestia_earth/validation/validators/management.py +0 -131
  57. package/hestia_earth/validation/validators/measurement.py +0 -368
  58. package/hestia_earth/validation/validators/organisation.py +0 -43
  59. package/hestia_earth/validation/validators/practice.py +0 -590
  60. package/hestia_earth/validation/validators/product.py +0 -263
  61. package/hestia_earth/validation/validators/property.py +0 -266
  62. package/hestia_earth/validation/validators/shared.py +0 -940
  63. package/hestia_earth/validation/validators/site.py +0 -312
  64. package/hestia_earth/validation/validators/source.py +0 -20
  65. package/hestia_earth/validation/validators/transformation.py +0 -250
  66. package/hestia_earth/validation/version.py +0 -1
  67. package/layer/build.sh +0 -34
  68. package/layer/deploy.sh +0 -18
  69. package/release.sh +0 -11
  70. package/requirements-ci.txt +0 -6
  71. package/requirements-test.txt +0 -4
  72. package/requirements.txt +0 -2
  73. package/run-docker-test.sh +0 -7
  74. package/run-docker.sh +0 -9
  75. package/run.py +0 -99
  76. package/scripts/build_docs.py +0 -283
  77. package/scripts/build_validation_list.py +0 -160
  78. package/scripts/guide-create-branch.sh +0 -15
  79. package/scripts/update-package-version.js +0 -28
  80. package/setup.py +0 -35
  81. package/tests/Dockerfile +0 -13
  82. package/tests/__init__.py +0 -3
  83. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-no-impactAssessment.json +0 -64
  84. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/invalid-world.json +0 -69
  85. package/tests/fixtures/aggregated/cycle/inputs-impactAssessment/valid.json +0 -69
  86. package/tests/fixtures/animal/duplicated-input-cycle/invalid.json +0 -98
  87. package/tests/fixtures/animal/duplicated-input-cycle/valid.json +0 -91
  88. package/tests/fixtures/animal/pregnancyRateTotal/invalid.json +0 -49
  89. package/tests/fixtures/animal/pregnancyRateTotal/valid.json +0 -60
  90. package/tests/fixtures/animal/required/invalid.json +0 -59
  91. package/tests/fixtures/animal/required/valid.json +0 -72
  92. package/tests/fixtures/completeness/all-values/warning.json +0 -22
  93. package/tests/fixtures/completeness/animalPopulation/invalid.json +0 -58
  94. package/tests/fixtures/completeness/animalPopulation/valid-animals.json +0 -71
  95. package/tests/fixtures/completeness/animalPopulation/valid-incomplete.json +0 -58
  96. package/tests/fixtures/completeness/animalPopulation/valid-no-liveAnimals.json +0 -37
  97. package/tests/fixtures/completeness/blank-nodes/agri-food processor-invalid.json +0 -52
  98. package/tests/fixtures/completeness/blank-nodes/invalid.json +0 -124
  99. package/tests/fixtures/completeness/blank-nodes/valid.json +0 -128
  100. package/tests/fixtures/completeness/cropland/site.json +0 -16
  101. package/tests/fixtures/completeness/cropland/valid.json +0 -22
  102. package/tests/fixtures/completeness/cropland/warning.json +0 -22
  103. package/tests/fixtures/completeness/freshForage/error-animals.json +0 -63
  104. package/tests/fixtures/completeness/freshForage/error-products.json +0 -65
  105. package/tests/fixtures/completeness/freshForage/valid-animal-inputs.json +0 -63
  106. package/tests/fixtures/completeness/freshForage/valid-animals.json +0 -63
  107. package/tests/fixtures/completeness/freshForage/valid-not-grazing-liveAnimal.json +0 -55
  108. package/tests/fixtures/completeness/freshForage/valid-not-liveAnimal.json +0 -47
  109. package/tests/fixtures/completeness/freshForage/valid-products.json +0 -68
  110. package/tests/fixtures/completeness/ingredient/invalid-agri-food-processor.json +0 -37
  111. package/tests/fixtures/completeness/ingredient/invalid.json +0 -49
  112. package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-complete.json +0 -49
  113. package/tests/fixtures/completeness/ingredient/valid-agri-food-processor-incomplete.json +0 -37
  114. package/tests/fixtures/completeness/ingredient/valid.json +0 -49
  115. package/tests/fixtures/completeness/material/error.json +0 -49
  116. package/tests/fixtures/completeness/material/valid-fuel-material.json +0 -60
  117. package/tests/fixtures/completeness/material/valid-incomplete.json +0 -36
  118. package/tests/fixtures/completeness/material/valid-no-fuel.json +0 -36
  119. package/tests/fixtures/completeness/valid.json +0 -22
  120. package/tests/fixtures/cycle/aboveGroundCropResidue/invalid.json +0 -76
  121. package/tests/fixtures/cycle/aboveGroundCropResidue/valid.json +0 -76
  122. package/tests/fixtures/cycle/aggregated-valid.json +0 -102
  123. package/tests/fixtures/cycle/coverCrop/invalid.json +0 -64
  124. package/tests/fixtures/cycle/coverCrop/valid-not-coverCrop.json +0 -54
  125. package/tests/fixtures/cycle/coverCrop/valid.json +0 -64
  126. package/tests/fixtures/cycle/cropResidue/complete/invalid.json +0 -56
  127. package/tests/fixtures/cycle/cropResidue/complete/valid.json +0 -82
  128. package/tests/fixtures/cycle/cropResidue/incomplete/invalid.json +0 -42
  129. package/tests/fixtures/cycle/cropResidue/incomplete/valid.json +0 -56
  130. package/tests/fixtures/cycle/dates/invalid-emissions.json +0 -70
  131. package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/invalid.json +0 -63
  132. package/tests/fixtures/cycle/liveAnimal-animalProduct-mapping/valid.json +0 -63
  133. package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates-year-only.json +0 -48
  134. package/tests/fixtures/cycle/maximumCycleDuration/invalid-dates.json +0 -48
  135. package/tests/fixtures/cycle/maximumCycleDuration/invalid.json +0 -48
  136. package/tests/fixtures/cycle/maximumCycleDuration/valid-dates-year-only.json +0 -48
  137. package/tests/fixtures/cycle/maximumCycleDuration/valid-dates.json +0 -48
  138. package/tests/fixtures/cycle/maximumCycleDuration/valid.json +0 -48
  139. package/tests/fixtures/cycle/otherSites/cycleDuration/invalid.json +0 -52
  140. package/tests/fixtures/cycle/otherSites/cycleDuration/valid-no-siteDuration.json +0 -40
  141. package/tests/fixtures/cycle/otherSites/cycleDuration/valid.json +0 -52
  142. package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/invalid.json +0 -56
  143. package/tests/fixtures/cycle/practices/stockingDensityPermanentPastureAverage/valid.json +0 -65
  144. package/tests/fixtures/cycle/primary-product-as-input/invalid.json +0 -59
  145. package/tests/fixtures/cycle/primary-product-as-input/valid.json +0 -48
  146. package/tests/fixtures/cycle/product-linked-ia/cycle.json +0 -66
  147. package/tests/fixtures/cycle/product-linked-ia/invalid-multiple.json +0 -58
  148. package/tests/fixtures/cycle/product-linked-ia/valid.json +0 -57
  149. package/tests/fixtures/cycle/products/animals/invalid.json +0 -69
  150. package/tests/fixtures/cycle/products/animals/valid.json +0 -58
  151. package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/invalid.json +0 -53
  152. package/tests/fixtures/cycle/riceGrainInHuskFlooded-minimumCycleDuration/valid.json +0 -53
  153. package/tests/fixtures/cycle/siteDuration/crop/invalid.json +0 -53
  154. package/tests/fixtures/cycle/siteDuration/crop/valid-different-duration.json +0 -53
  155. package/tests/fixtures/cycle/siteDuration/crop/valid-same-duration.json +0 -53
  156. package/tests/fixtures/cycle/siteDuration/invalid.json +0 -41
  157. package/tests/fixtures/cycle/siteDuration/valid-no-siteDuration.json +0 -40
  158. package/tests/fixtures/cycle/siteDuration/valid-otherSites.json +0 -48
  159. package/tests/fixtures/cycle/siteDuration/valid.json +0 -45
  160. package/tests/fixtures/cycle/substrate/required/invalid.json +0 -50
  161. package/tests/fixtures/cycle/substrate/required/valid.json +0 -60
  162. package/tests/fixtures/cycle/valid.json +0 -343
  163. package/tests/fixtures/emission/linked-terms/inputs/invalid.json +0 -78
  164. package/tests/fixtures/emission/linked-terms/inputs/valid.json +0 -106
  165. package/tests/fixtures/emission/linked-terms/transformation/error.json +0 -104
  166. package/tests/fixtures/emission/linked-terms/transformation/valid.json +0 -107
  167. package/tests/fixtures/emission/linked-terms/transformation/warning.json +0 -76
  168. package/tests/fixtures/emission/methodTier-background/invalid.json +0 -60
  169. package/tests/fixtures/emission/methodTier-background/valid.json +0 -60
  170. package/tests/fixtures/emission/not-relevant/invalid.json +0 -71
  171. package/tests/fixtures/emission/not-relevant/valid.json +0 -95
  172. package/tests/fixtures/emission/not-relevant-methodTier/invalid.json +0 -70
  173. package/tests/fixtures/emission/not-relevant-methodTier/valid.json +0 -95
  174. package/tests/fixtures/impactAssessment/aggregated-valid.json +0 -43
  175. package/tests/fixtures/impactAssessment/cycle-contains-product/invalid.json +0 -34
  176. package/tests/fixtures/impactAssessment/cycle-contains-product/valid.json +0 -34
  177. package/tests/fixtures/impactAssessment/cycle-endDate/invalid.json +0 -26
  178. package/tests/fixtures/impactAssessment/cycle-endDate/valid.json +0 -26
  179. package/tests/fixtures/impactAssessment/valid.json +0 -93
  180. package/tests/fixtures/indicator/characterisedIndicator-methodModel/invalid.json +0 -52
  181. package/tests/fixtures/indicator/characterisedIndicator-methodModel/valid.json +0 -52
  182. package/tests/fixtures/indicator/ionisingCompounds/invalid.json +0 -23
  183. package/tests/fixtures/indicator/ionisingCompounds/valid.json +0 -23
  184. package/tests/fixtures/indicator/landTransformation/invalid-grouped.json +0 -257
  185. package/tests/fixtures/indicator/landTransformation/invalid.json +0 -100
  186. package/tests/fixtures/indicator/landTransformation/valid-grouped-full.json +0 -507
  187. package/tests/fixtures/indicator/landTransformation/valid-grouped.json +0 -507
  188. package/tests/fixtures/indicator/landTransformation/valid.json +0 -100
  189. package/tests/fixtures/infrastructure/lifespan/invalid.json +0 -26
  190. package/tests/fixtures/infrastructure/lifespan/valid.json +0 -45
  191. package/tests/fixtures/input/animalFeed-fate/invalid.json +0 -103
  192. package/tests/fixtures/input/animalFeed-fate/valid.json +0 -90
  193. package/tests/fixtures/input/country/invalid.json +0 -64
  194. package/tests/fixtures/input/country/valid.json +0 -64
  195. package/tests/fixtures/input/distribution/animalHousing.json +0 -103
  196. package/tests/fixtures/input/distribution/complete/invalid.json +0 -177
  197. package/tests/fixtures/input/distribution/complete/valid.json +0 -163
  198. package/tests/fixtures/input/distribution/incomplete/valid.json +0 -139
  199. package/tests/fixtures/input/impactAssessment/invalid.json +0 -99
  200. package/tests/fixtures/input/impactAssessment/valid.json +0 -89
  201. package/tests/fixtures/input/input-as-product/invalid.json +0 -57
  202. package/tests/fixtures/input/input-as-product/valid.json +0 -59
  203. package/tests/fixtures/input/mustIncludeId/invalid.json +0 -13
  204. package/tests/fixtures/input/mustIncludeId/valid-multiple-ids.json +0 -31
  205. package/tests/fixtures/input/mustIncludeId/valid.json +0 -22
  206. package/tests/fixtures/input/saplings/invalid.json +0 -58
  207. package/tests/fixtures/input/saplings/valid-no-saplings.json +0 -58
  208. package/tests/fixtures/input/saplings/valid-not-plantation.json +0 -58
  209. package/tests/fixtures/input/saplings/valid.json +0 -58
  210. package/tests/fixtures/integration/distribution/product-yield-invalid.json +0 -54
  211. package/tests/fixtures/management/cycle-overlap/cycles.json +0 -39
  212. package/tests/fixtures/management/cycle-overlap/invalid.json +0 -26
  213. package/tests/fixtures/management/cycle-overlap/valid.json +0 -26
  214. package/tests/fixtures/management/exists/invalid.json +0 -13
  215. package/tests/fixtures/management/exists/valid.json +0 -25
  216. package/tests/fixtures/management/fallow-dates/invalid.json +0 -24
  217. package/tests/fixtures/management/fallow-dates/valid.json +0 -24
  218. package/tests/fixtures/management/termType/invalid-cropland.json +0 -35
  219. package/tests/fixtures/management/termType/invalid-permanent-pasture.json +0 -25
  220. package/tests/fixtures/management/termType/valid-cropland.json +0 -55
  221. package/tests/fixtures/management/termType/valid-no-management.json +0 -13
  222. package/tests/fixtures/management/termType/valid-permanent-pasture.json +0 -35
  223. package/tests/fixtures/measurement/depths/invalid.json +0 -44
  224. package/tests/fixtures/measurement/depths/valid.json +0 -50
  225. package/tests/fixtures/measurement/models/valid.json +0 -33
  226. package/tests/fixtures/measurement/models/warning-no-value.json +0 -30
  227. package/tests/fixtures/measurement/models/warning.json +0 -33
  228. package/tests/fixtures/measurement/pond-measurements/invalid.json +0 -11
  229. package/tests/fixtures/measurement/pond-measurements/valid.json +0 -23
  230. package/tests/fixtures/measurement/required-depths/error.json +0 -71
  231. package/tests/fixtures/measurement/required-depths/valid.json +0 -126
  232. package/tests/fixtures/measurement/required-depths/warning.json +0 -29
  233. package/tests/fixtures/measurement/soilTexture/missing-texture-value.json +0 -227
  234. package/tests/fixtures/measurement/soilTexture/percent-invalid.json +0 -110
  235. package/tests/fixtures/measurement/soilTexture/percent-missing-value.json +0 -43
  236. package/tests/fixtures/measurement/soilTexture/percent-valid.json +0 -110
  237. package/tests/fixtures/measurement/startDate-endDate-required/invalid.json +0 -32
  238. package/tests/fixtures/measurement/startDate-endDate-required/valid.json +0 -46
  239. package/tests/fixtures/measurement/unique/invalid.json +0 -28
  240. package/tests/fixtures/measurement/unique/valid.json +0 -16
  241. package/tests/fixtures/measurement/value-length/invalid.json +0 -46
  242. package/tests/fixtures/measurement/value-length/valid.json +0 -44
  243. package/tests/fixtures/measurement/water-salinity/invalid.json +0 -33
  244. package/tests/fixtures/measurement/water-salinity/valid-brakish.json +0 -40
  245. package/tests/fixtures/measurement/water-salinity/valid.json +0 -33
  246. package/tests/fixtures/organisation/valid.json +0 -26
  247. package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/invalid.json +0 -63
  248. package/tests/fixtures/practice/croppingDuration/riceGrainInHuskFlooded/valid.json +0 -63
  249. package/tests/fixtures/practice/defaultValue/invalid.json +0 -12
  250. package/tests/fixtures/practice/defaultValue/valid.json +0 -15
  251. package/tests/fixtures/practice/excretaManagement/invalid.json +0 -50
  252. package/tests/fixtures/practice/excretaManagement/valid.json +0 -60
  253. package/tests/fixtures/practice/irrigated-complete/invalid.json +0 -47
  254. package/tests/fixtures/practice/irrigated-complete/valid-incomplete.json +0 -47
  255. package/tests/fixtures/practice/irrigated-complete/valid.json +0 -60
  256. package/tests/fixtures/practice/landCover-products/invalid.json +0 -58
  257. package/tests/fixtures/practice/landCover-products/valid-coverCrop.json +0 -69
  258. package/tests/fixtures/practice/landCover-products/valid.json +0 -58
  259. package/tests/fixtures/practice/liveAnimal-system/invalid.json +0 -58
  260. package/tests/fixtures/practice/liveAnimal-system/valid.json +0 -69
  261. package/tests/fixtures/practice/longFallowDuration/invalid.json +0 -20
  262. package/tests/fixtures/practice/longFallowDuration/valid.json +0 -20
  263. package/tests/fixtures/practice/noTillage/invalid.json +0 -23
  264. package/tests/fixtures/practice/noTillage/valid-value-not-100.json +0 -23
  265. package/tests/fixtures/practice/noTillage/valid.json +0 -21
  266. package/tests/fixtures/practice/pastureGrass/key-termType/invalid.json +0 -16
  267. package/tests/fixtures/practice/pastureGrass/key-termType/valid.json +0 -16
  268. package/tests/fixtures/practice/pastureGrass/key-value/invalid-numbers.json +0 -67
  269. package/tests/fixtures/practice/pastureGrass/key-value/invalid.json +0 -67
  270. package/tests/fixtures/practice/pastureGrass/key-value/valid.json +0 -67
  271. package/tests/fixtures/practice/pastureGrass/permanent-pasture/invalid.json +0 -37
  272. package/tests/fixtures/practice/pastureGrass/permanent-pasture/valid.json +0 -47
  273. package/tests/fixtures/practice/primaryPercent/invalid.json +0 -49
  274. package/tests/fixtures/practice/primaryPercent/valid.json +0 -49
  275. package/tests/fixtures/practice/processingOperation/invalid-no-primary.json +0 -48
  276. package/tests/fixtures/practice/processingOperation/invalid.json +0 -49
  277. package/tests/fixtures/practice/processingOperation/valid-cropland.json +0 -37
  278. package/tests/fixtures/practice/processingOperation/valid.json +0 -49
  279. package/tests/fixtures/practice/productivePhasePermanentCrops/invalid.json +0 -48
  280. package/tests/fixtures/practice/productivePhasePermanentCrops/valid-0-value.json +0 -58
  281. package/tests/fixtures/practice/productivePhasePermanentCrops/valid-no-value.json +0 -47
  282. package/tests/fixtures/practice/productivePhasePermanentCrops/valid.json +0 -48
  283. package/tests/fixtures/practice/site-management/invalid.json +0 -75
  284. package/tests/fixtures/practice/site-management/valid.json +0 -75
  285. package/tests/fixtures/practice/tillage-siteType/valid.json +0 -51
  286. package/tests/fixtures/practice/tillage-siteType/warning.json +0 -42
  287. package/tests/fixtures/practice/tillage-values/invalid-fullTillage.json +0 -61
  288. package/tests/fixtures/practice/tillage-values/invalid-noTillage.json +0 -61
  289. package/tests/fixtures/practice/tillage-values/valid.json +0 -61
  290. package/tests/fixtures/practice/waterRegime/rice/invalid.json +0 -59
  291. package/tests/fixtures/practice/waterRegime/rice/valid-0-value.json +0 -59
  292. package/tests/fixtures/practice/waterRegime/rice/valid.json +0 -58
  293. package/tests/fixtures/product/economicValueShare/invalid.json +0 -31
  294. package/tests/fixtures/product/economicValueShare/valid.json +0 -22
  295. package/tests/fixtures/product/excreta/invalid.json +0 -62
  296. package/tests/fixtures/product/excreta/valid.json +0 -62
  297. package/tests/fixtures/product/excreta/warning.json +0 -53
  298. package/tests/fixtures/product/excreta/with-system/invalid.json +0 -79
  299. package/tests/fixtures/product/excreta/with-system/valid.json +0 -88
  300. package/tests/fixtures/product/excreta/with-system/warning.json +0 -70
  301. package/tests/fixtures/product/fu_ha/invalid.json +0 -49
  302. package/tests/fixtures/product/fu_ha/valid.json +0 -49
  303. package/tests/fixtures/product/primary/invalid.json +0 -22
  304. package/tests/fixtures/product/primary/valid.json +0 -22
  305. package/tests/fixtures/product/value/valid.json +0 -26
  306. package/tests/fixtures/product/value/value-0/error.json +0 -40
  307. package/tests/fixtures/product/value/value-empty/warning.json +0 -23
  308. package/tests/fixtures/product/yield/invalid.json +0 -54
  309. package/tests/fixtures/product/yield/no-value.json +0 -75
  310. package/tests/fixtures/product/yield/valid.json +0 -54
  311. package/tests/fixtures/property/default-value/valid-allowed-exception.json +0 -61
  312. package/tests/fixtures/property/default-value/valid.json +0 -61
  313. package/tests/fixtures/property/default-value/warning.json +0 -61
  314. package/tests/fixtures/property/termType/invalid.json +0 -60
  315. package/tests/fixtures/property/termType/valid.json +0 -60
  316. package/tests/fixtures/property/value-min-max/invalid.json +0 -77
  317. package/tests/fixtures/property/value-min-max/valid-skip-maximum.json +0 -57
  318. package/tests/fixtures/property/value-min-max/valid.json +0 -78
  319. package/tests/fixtures/property/valueType/invalid.json +0 -79
  320. package/tests/fixtures/property/valueType/valid.json +0 -79
  321. package/tests/fixtures/property/volatileSolidsContent/invalid.json +0 -99
  322. package/tests/fixtures/property/volatileSolidsContent/valid.json +0 -99
  323. package/tests/fixtures/shared/coordinates/invalid.json +0 -18
  324. package/tests/fixtures/shared/coordinates/valid.json +0 -18
  325. package/tests/fixtures/shared/data-duplicates/valid.json +0 -113
  326. package/tests/fixtures/shared/data-duplicates/warning.json +0 -172
  327. package/tests/fixtures/shared/duplicated-term-units/invalid-animalProduct.json +0 -61
  328. package/tests/fixtures/shared/duplicated-term-units/invalid-organicFertiliser.json +0 -61
  329. package/tests/fixtures/shared/duplicated-term-units/valid.json +0 -49
  330. package/tests/fixtures/shared/list-country-region/invalid.json +0 -54
  331. package/tests/fixtures/shared/list-country-region/valid.json +0 -54
  332. package/tests/fixtures/shared/list-percent-value/invalid.json +0 -49
  333. package/tests/fixtures/shared/list-percent-value/valid.json +0 -52
  334. package/tests/fixtures/shared/list-valueType/invalid.json +0 -49
  335. package/tests/fixtures/shared/list-valueType/valid.json +0 -49
  336. package/tests/fixtures/shared/list-values-sum-100/management/with-properties/valid.json +0 -91
  337. package/tests/fixtures/shared/list-values-sum-100/measurements/missing-soil.json +0 -46
  338. package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-high-value.json +0 -63
  339. package/tests/fixtures/shared/list-values-sum-100/measurements/no-depth-valid.json +0 -40
  340. package/tests/fixtures/shared/list-values-sum-100/measurements/with-depth-high-value.json +0 -71
  341. package/tests/fixtures/shared/list-values-sum-100/practices/total-100.json +0 -61
  342. package/tests/fixtures/shared/list-values-sum-100/practices/total-110.json +0 -61
  343. package/tests/fixtures/shared/list-values-sum-100/practices/total-90.json +0 -61
  344. package/tests/fixtures/shared/min-max/value-above.json +0 -31
  345. package/tests/fixtures/shared/min-max/value-below.json +0 -31
  346. package/tests/fixtures/shared/min-max/value-valid.json +0 -45
  347. package/tests/fixtures/shared/model/emissions/invalid.json +0 -102
  348. package/tests/fixtures/shared/model/emissions/valid-variable-tolerance.json +0 -180
  349. package/tests/fixtures/shared/model/emissions/valid.json +0 -102
  350. package/tests/fixtures/shared/model/impacts/invalid.json +0 -75
  351. package/tests/fixtures/shared/model/impacts/valid.json +0 -75
  352. package/tests/fixtures/shared/model/inputs/valid-no-value.json +0 -84
  353. package/tests/fixtures/shared/model/inputs/valid.json +0 -87
  354. package/tests/fixtures/shared/model/inputs/warning.json +0 -87
  355. package/tests/fixtures/shared/model/products/valid-no-value.json +0 -88
  356. package/tests/fixtures/shared/model/products/valid.json +0 -91
  357. package/tests/fixtures/shared/model/products/warning.json +0 -91
  358. package/tests/fixtures/shared/otherModel/invalid.json +0 -69
  359. package/tests/fixtures/shared/otherModel/valid.json +0 -70
  360. package/tests/fixtures/shared/properties-duplicate-values/invalid.json +0 -61
  361. package/tests/fixtures/shared/properties-duplicate-values/valid.json +0 -57
  362. package/tests/fixtures/shared/properties-same-length/invalid.json +0 -62
  363. package/tests/fixtures/shared/properties-same-length/valid.json +0 -52
  364. package/tests/fixtures/shared/unit-percent/invalid.json +0 -34
  365. package/tests/fixtures/shared/unit-percent/valid.json +0 -60
  366. package/tests/fixtures/shared/unit-percent/warning.json +0 -52
  367. package/tests/fixtures/site/cycles-linked-ia/invalid.json +0 -129
  368. package/tests/fixtures/site/cycles-linked-ia/valid.json +0 -129
  369. package/tests/fixtures/site/valid.json +0 -138
  370. package/tests/fixtures/source/valid.json +0 -19
  371. package/tests/fixtures/transformation/excretaManagement/invalid.json +0 -47
  372. package/tests/fixtures/transformation/excretaManagement/valid.json +0 -59
  373. package/tests/fixtures/transformation/inputs-products/invalid.json +0 -43
  374. package/tests/fixtures/transformation/inputs-products/valid.json +0 -43
  375. package/tests/fixtures/transformation/linked-emission/invalid.json +0 -101
  376. package/tests/fixtures/transformation/linked-emission/valid.json +0 -107
  377. package/tests/fixtures/transformation/previousTransformationId/invalid-no-previous.json +0 -127
  378. package/tests/fixtures/transformation/previousTransformationId/invalid-previous-input.json +0 -100
  379. package/tests/fixtures/transformation/previousTransformationId/invalid-product-input.json +0 -106
  380. package/tests/fixtures/transformation/previousTransformationId/invalid-wrong-order.json +0 -136
  381. package/tests/fixtures/transformation/previousTransformationId/valid.json +0 -171
  382. package/tests/integration/__init__.py +0 -0
  383. package/tests/integration/test_product.py +0 -17
  384. package/tests/test_gee.py +0 -10
  385. package/tests/test_utils.py +0 -36
  386. package/tests/test_validation.py +0 -11
  387. package/tests/utils.py +0 -28
  388. package/tests/validators/__init__.py +0 -0
  389. package/tests/validators/test_aggregated_cycle.py +0 -44
  390. package/tests/validators/test_aggregated_shared.py +0 -63
  391. package/tests/validators/test_animal.py +0 -72
  392. package/tests/validators/test_completeness.py +0 -337
  393. package/tests/validators/test_cycle.py +0 -600
  394. package/tests/validators/test_emission.py +0 -170
  395. package/tests/validators/test_impact_assessment.py +0 -80
  396. package/tests/validators/test_indicator.py +0 -120
  397. package/tests/validators/test_infrastructure.py +0 -26
  398. package/tests/validators/test_input.py +0 -434
  399. package/tests/validators/test_management.py +0 -177
  400. package/tests/validators/test_measurement.py +0 -317
  401. package/tests/validators/test_organisation.py +0 -32
  402. package/tests/validators/test_practice.py +0 -490
  403. package/tests/validators/test_product.py +0 -291
  404. package/tests/validators/test_property.py +0 -143
  405. package/tests/validators/test_shared.py +0 -1139
  406. package/tests/validators/test_site.py +0 -151
  407. package/tests/validators/test_source.py +0 -15
  408. package/tests/validators/test_transformation.py +0 -151
  409. package/tests/validators/test_validators.py +0 -74
  410. package/tsconfig.dist.json +0 -9
  411. package/tsconfig.json +0 -25
@@ -1,590 +0,0 @@
1
- from hestia_earth.schema import SiteSiteType, TermTermType
2
- from hestia_earth.utils.model import (
3
- filter_list_term_type,
4
- find_term_match,
5
- find_primary_product,
6
- )
7
- from hestia_earth.utils.tools import flatten, list_sum, safe_parse_float, non_empty_list
8
- from hestia_earth.utils.lookup import download_lookup, get_table_value
9
- from hestia_earth.utils.blank_node import get_node_value
10
-
11
- from hestia_earth.validation.utils import (
12
- _filter_list_errors,
13
- get_lookup_value,
14
- is_permanent_crop,
15
- blank_node_properties_group,
16
- )
17
- from hestia_earth.validation.terms import TERMS_QUERY, get_terms
18
- from .shared import valid_list_sum, is_value_below
19
-
20
-
21
- def _is_irrigated(term: dict):
22
- def fallback():
23
- term_id = get_lookup_value(term, "correspondingWaterRegimeTermId")
24
- return (
25
- _is_irrigated({"@id": term_id, "termType": TermTermType.WATERREGIME.value})
26
- if term_id
27
- else False
28
- )
29
-
30
- return not not get_lookup_value(term, "irrigated") or fallback()
31
-
32
-
33
- def validate_defaultValue(data: dict, list_key: str = "practices"):
34
- def validate(values: tuple):
35
- index, practice = values
36
- term = practice.get("term", {})
37
- has_value = len(practice.get("value", [])) > 0
38
- is_value_required = any([term.get("units", "").startswith("%")])
39
- default_value = get_lookup_value(term, "defaultValue")
40
- return (
41
- has_value
42
- or default_value is None
43
- or is_value_required
44
- or {
45
- "level": "warning",
46
- "dataPath": f".{list_key}[{index}]",
47
- "message": "should specify a value when HESTIA has a default one",
48
- "params": {"term": term, "expected": default_value},
49
- }
50
- )
51
-
52
- return _filter_list_errors(
53
- flatten(map(validate, enumerate(data.get(list_key, []))))
54
- )
55
-
56
-
57
- def validate_longFallowDuration(practices: list):
58
- max_nb_years = 5
59
- longFallowDuration = find_term_match(practices, "longFallowDuration", None)
60
- longFallowDuration_index = (
61
- practices.index(longFallowDuration) if longFallowDuration else 0
62
- )
63
- value = list_sum(longFallowDuration.get("value", [0])) if longFallowDuration else 0
64
- rotationDuration = list_sum(
65
- find_term_match(practices, "rotationDuration").get("value", 0)
66
- )
67
- return (
68
- value == 0
69
- or ((rotationDuration - value) / value) < max_nb_years * 365
70
- or {
71
- "level": "error",
72
- "dataPath": f".practices[{longFallowDuration_index}].value",
73
- "message": "longFallowDuration must be lower than 5 years",
74
- }
75
- )
76
-
77
-
78
- def validate_waterRegime_rice_products(cycle: dict, list_key: str = "practices"):
79
- """
80
- Validate corresponding `waterRegime` practices with Rice products
81
-
82
- This validation ensures that the correct `waterRegime` practice can be used with the specified Rice product.
83
- """
84
- all_rice_product_ids = get_terms(TERMS_QUERY.RICE)
85
- primary_product = find_primary_product(cycle) or {}
86
- primary_product_id = primary_product.get("term", {}).get("@id")
87
- is_rice_product = primary_product_id in all_rice_product_ids
88
-
89
- practice_term_type = TermTermType.WATERREGIME.value
90
-
91
- def validate(values: tuple):
92
- index, practice = values
93
- term = practice.get("term", {})
94
- term_type = term.get("termType")
95
- has_value = list_sum(practice.get("value") or [0], 0) > 0
96
- allowed_product_ids = (
97
- get_lookup_value(term, "allowedRiceTermIds") or ""
98
- ).split(";")
99
- is_allowed = primary_product_id in allowed_product_ids
100
- return (
101
- term_type != practice_term_type
102
- or not has_value
103
- or is_allowed
104
- or {
105
- "level": "error",
106
- "dataPath": f".{list_key}[{index}].term",
107
- "message": "rice products not allowed for this water regime practice",
108
- "params": {
109
- "term": term,
110
- "products": [primary_product.get("term", {})],
111
- "expected": allowed_product_ids,
112
- },
113
- }
114
- )
115
-
116
- return not is_rice_product or _filter_list_errors(
117
- flatten(map(validate, enumerate(cycle.get(list_key, []))))
118
- )
119
-
120
-
121
- def validate_croppingDuration_riceGrainInHuskFlooded(
122
- cycle: dict, list_key: str = "practices"
123
- ):
124
- """
125
- Validate "Rice, grain (in husk), flooded" cropping duration
126
-
127
- When "Rice, grain (in husk), flooded" is used as a product, this validation will check the practice
128
- `croppingDuration`, and make sure the value is between
129
- `Rice_croppingDuration_days_min` and `Rice_croppingDuration_days_max` lookup values.
130
- """
131
- has_product = find_term_match(cycle.get("products", []), "riceGrainInHuskFlooded")
132
-
133
- practice_id = "croppingDuration"
134
- practice_index = (
135
- next(
136
- (
137
- i
138
- for i, p in enumerate(cycle.get(list_key, []))
139
- if p.get("term", {}).get("@id") == practice_id
140
- ),
141
- -1,
142
- )
143
- if has_product
144
- else -1
145
- )
146
-
147
- lookup = download_lookup("region-ch4ef-IPCC2019.csv")
148
- country_id = cycle.get("site", {}).get("country", {}).get("@id")
149
- min_value = safe_parse_float(
150
- get_table_value(
151
- lookup, "term.id", country_id, "Rice_croppingDuration_days_min"
152
- ),
153
- None,
154
- )
155
- max_value = safe_parse_float(
156
- get_table_value(
157
- lookup, "term.id", country_id, "Rice_croppingDuration_days_max"
158
- ),
159
- None,
160
- )
161
-
162
- value = (
163
- list_sum(cycle.get(list_key, [])[practice_index].get("value", []))
164
- if practice_index >= 0
165
- else None
166
- )
167
-
168
- return (
169
- practice_index == -1
170
- or all([is_value_below(value, max_value), is_value_below(min_value, value)])
171
- or {
172
- "level": "error",
173
- "dataPath": f".{list_key}[{practice_index}].value",
174
- "message": "croppingDuration must be between min and max",
175
- "params": {"min": min_value, "max": max_value},
176
- }
177
- )
178
-
179
-
180
- def validate_excretaManagement(node: dict, practices: list):
181
- has_input = (
182
- len(filter_list_term_type(node.get("inputs", []), TermTermType.EXCRETA)) > 0
183
- )
184
- has_practice = (
185
- len(filter_list_term_type(practices, TermTermType.EXCRETAMANAGEMENT)) > 0
186
- )
187
- return (
188
- not has_practice
189
- or has_input
190
- or {
191
- "level": "error",
192
- "dataPath": ".practices",
193
- "message": "an excreta input is required when using an excretaManagement practice",
194
- }
195
- )
196
-
197
-
198
- NO_TILLAGE_ID = "noTillage"
199
- FULL_TILLAGE_ID = "fullTillage"
200
- TILLAGE_DEPTH_ID = "tillageDepth"
201
- NB_TILLAGES_ID = "numberOfTillages"
202
-
203
-
204
- def _practice_is_tillage(practice: dict):
205
- term = practice.get("term", {})
206
- term_type = practice.get("term", {}).get("termType")
207
- return (
208
- True
209
- if term_type == TermTermType.OPERATION.value
210
- and get_lookup_value(term, "isTillage")
211
- else False
212
- )
213
-
214
-
215
- def validate_no_tillage(practices: list):
216
- tillage_practices = filter_list_term_type(practices, TermTermType.TILLAGE)
217
- no_tillage = find_term_match(tillage_practices, NO_TILLAGE_ID, None)
218
- no_value = list_sum(no_tillage.get("value", [100]), 100) if no_tillage else 0
219
-
220
- return _filter_list_errors(
221
- [
222
- {
223
- "level": "error",
224
- "dataPath": f".practices[{index}]",
225
- "message": "is not allowed in combination with noTillage",
226
- }
227
- for index, p in enumerate(practices)
228
- if _practice_is_tillage(p)
229
- ]
230
- if no_value == 100
231
- else []
232
- )
233
-
234
-
235
- _TILLAGE_SITE_TYPES = [SiteSiteType.CROPLAND.value]
236
-
237
-
238
- def validate_tillage_site_type(practices: list, site: dict):
239
- has_tillage = len(filter_list_term_type(practices, TermTermType.TILLAGE)) > 0
240
- site_type = site.get("siteType")
241
- return (
242
- site_type not in _TILLAGE_SITE_TYPES
243
- or has_tillage
244
- or {
245
- "level": "warning",
246
- "dataPath": ".practices",
247
- "message": "should contain a tillage practice",
248
- }
249
- )
250
-
251
-
252
- def validate_tillage_values(practices: list):
253
- tillage_100_index = next(
254
- (
255
- index
256
- for index in range(0, len(practices))
257
- if all(
258
- [
259
- practices[index].get("term", {}).get("termType")
260
- == TermTermType.TILLAGE.value,
261
- list_sum(practices[index].get("value", [0])) == 100,
262
- ]
263
- )
264
- ),
265
- -1,
266
- )
267
- tillage_100_practice = (
268
- practices[tillage_100_index] if tillage_100_index >= 0 else None
269
- )
270
- tillage_100_term = (tillage_100_practice or {}).get("term", {})
271
-
272
- tillage_depth_practice = find_term_match(practices, TILLAGE_DEPTH_ID)
273
- nb_tillages_practice = find_term_match(practices, NB_TILLAGES_ID)
274
- error_message = (
275
- (
276
- "cannot use no tillage if depth or number of tillages is not 0"
277
- if all(
278
- [
279
- tillage_100_term.get("@id") == NO_TILLAGE_ID,
280
- any(
281
- [
282
- tillage_depth_practice
283
- and list_sum(tillage_depth_practice.get("value", [0])) > 0,
284
- nb_tillages_practice
285
- and list_sum(nb_tillages_practice.get("value", [0])) > 0,
286
- ]
287
- ),
288
- ]
289
- )
290
- else (
291
- "cannot use full tillage if depth or number of tillages is 0"
292
- if all(
293
- [
294
- tillage_100_term.get("@id") == FULL_TILLAGE_ID,
295
- any(
296
- [
297
- tillage_depth_practice
298
- and list_sum(tillage_depth_practice.get("value", [1]))
299
- == 0,
300
- nb_tillages_practice
301
- and list_sum(nb_tillages_practice.get("value", [1]))
302
- == 0,
303
- ]
304
- ),
305
- ]
306
- )
307
- else None
308
- )
309
- )
310
- if tillage_100_practice
311
- else None
312
- )
313
- return (
314
- {
315
- "level": "error",
316
- "dataPath": f".practices[{tillage_100_index}]",
317
- "message": error_message,
318
- }
319
- if error_message
320
- else True
321
- )
322
-
323
-
324
- def validate_liveAnimal_system(data: dict):
325
- has_animal = (
326
- len(
327
- filter_list_term_type(
328
- data.get("products", []),
329
- [TermTermType.ANIMALPRODUCT, TermTermType.LIVEANIMAL],
330
- )
331
- )
332
- > 0
333
- )
334
- has_system = (
335
- len(filter_list_term_type(data.get("practices", []), TermTermType.SYSTEM)) > 0
336
- )
337
- return (
338
- not has_animal
339
- or has_system
340
- or {
341
- "level": "warning",
342
- "dataPath": ".practices",
343
- "message": "should add an animal production system",
344
- }
345
- )
346
-
347
-
348
- PASTURE_GRASS_TERM_ID = "pastureGrass"
349
-
350
-
351
- def validate_pastureGrass_key_termType(data: dict, list_key: str = "practices"):
352
- validate_key_termType = TermTermType.LANDCOVER.value
353
-
354
- def validate(values: tuple):
355
- index, practice = values
356
- term_id = practice.get("term", {}).get("@id")
357
- key_termType = practice.get("key", {}).get("termType")
358
- return (
359
- term_id != PASTURE_GRASS_TERM_ID
360
- or not key_termType
361
- or key_termType == validate_key_termType
362
- or {
363
- "level": "error",
364
- "dataPath": f".{list_key}[{index}].key",
365
- "message": "pastureGrass key termType must be landCover",
366
- "params": {
367
- "value": key_termType,
368
- "expected": validate_key_termType,
369
- "term": practice.get("key", {}),
370
- },
371
- }
372
- )
373
-
374
- return _filter_list_errors(
375
- flatten(map(validate, enumerate(data.get(list_key, []))))
376
- )
377
-
378
-
379
- def validate_pastureGrass_key_value(data: dict, list_key: str = "practices"):
380
- practices = [
381
- p
382
- for p in data.get(list_key, [])
383
- if p.get("term", {}).get("@id") == PASTURE_GRASS_TERM_ID
384
- ]
385
- total_value, valid_sum = valid_list_sum(practices)
386
- return (
387
- {
388
- "level": "error",
389
- "dataPath": f".{list_key}",
390
- "message": "all values must be numbers",
391
- }
392
- if not valid_sum
393
- else len(practices) == 0
394
- or total_value == 100
395
- or {
396
- "level": "error",
397
- "dataPath": f".{list_key}",
398
- "message": "the sum of all pastureGrass values must be 100",
399
- "params": {"expected": 100, "current": total_value},
400
- }
401
- )
402
-
403
-
404
- def validate_has_pastureGrass(data: dict, site: dict, list_key: str = "practices"):
405
- site_type = site.get("siteType")
406
- has_practice = (
407
- find_term_match(data.get(list_key, []), PASTURE_GRASS_TERM_ID, None) is not None
408
- )
409
- return (
410
- site_type not in [SiteSiteType.PERMANENT_PASTURE.value]
411
- or has_practice
412
- or {
413
- "level": "warning",
414
- "dataPath": f".{list_key}",
415
- "message": "should add the term pastureGrass",
416
- }
417
- )
418
-
419
-
420
- def validate_permanent_crop_productive_phase(cycle: dict, list_key: str = "practices"):
421
- practice_id = "productivePhasePermanentCrops"
422
- permanent_crop = is_permanent_crop(cycle)
423
- primary_product = find_primary_product(cycle) or {}
424
- product_value = list_sum(primary_product.get("value", [-1]), default=-1)
425
- has_practice = (
426
- find_term_match(cycle.get(list_key, []), practice_id, None) is not None
427
- )
428
- return (
429
- not permanent_crop
430
- or product_value != 0
431
- or has_practice
432
- or {
433
- "level": "error",
434
- "dataPath": f".{list_key}",
435
- "message": "must add the term productivePhasePermanentCrops",
436
- }
437
- )
438
-
439
-
440
- _PROCESSING_SITE_TYPES = [SiteSiteType.AGRI_FOOD_PROCESSOR.value]
441
-
442
-
443
- def _is_processing_operation(practice: dict):
444
- return not (not get_lookup_value(practice.get("term", {}), "isProcessingOperation"))
445
-
446
-
447
- def validate_primaryPercent(cycle: dict, site: dict, list_key: str = "practices"):
448
- site_type = site.get("siteType")
449
-
450
- def validate(values: tuple):
451
- index, practice = values
452
- return "primaryPercent" not in practice or {
453
- "level": "error",
454
- "dataPath": f".{list_key}[{index}]",
455
- "message": "primaryPercent not allowed on this siteType",
456
- "params": {"current": site_type, "expected": _PROCESSING_SITE_TYPES},
457
- }
458
-
459
- return site_type in _PROCESSING_SITE_TYPES or (
460
- _filter_list_errors(map(validate, enumerate(cycle.get(list_key, []))))
461
- )
462
-
463
-
464
- def validate_processing_operation(cycle: dict, site: dict, list_key: str = "practices"):
465
- operations = filter_list_term_type(cycle.get(list_key, []), TermTermType.OPERATION)
466
- primary_processing_operations = [
467
- v
468
- for v in operations
469
- if all([_is_processing_operation(v), (v.get("primaryPercent") or 0) > 0])
470
- ]
471
- site_type = site.get("siteType")
472
- is_valid = any(
473
- [
474
- site_type not in _PROCESSING_SITE_TYPES,
475
- len(primary_processing_operations) > 0,
476
- ]
477
- )
478
- return is_valid or {
479
- "level": "error",
480
- "dataPath": f".{list_key}" if operations else "",
481
- "message": "must have a primary processing operation",
482
- }
483
-
484
-
485
- def validate_landCover_match_products(
486
- cycle: dict, site: dict, list_key: str = "practices"
487
- ):
488
- # validate that at least one `landCover` practice matches an equivalent Product
489
- landCover_practice_ids = [
490
- p.get("term", {}).get("@id")
491
- for p in filter_list_term_type(
492
- cycle.get("practices", []), TermTermType.LANDCOVER
493
- )
494
- # ignore any practices with a `blankNodesGroup=Cover crops`
495
- if blank_node_properties_group(p) != "Cover crops"
496
- ]
497
- landCover_product_ids = non_empty_list(
498
- [
499
- get_lookup_value(p.get("term", {}), "landCoverTermId")
500
- for p in cycle.get("products", [])
501
- ]
502
- )
503
- is_cropland = site.get("siteType") == SiteSiteType.CROPLAND.value
504
-
505
- return (
506
- not is_cropland
507
- or not landCover_practice_ids
508
- or not landCover_product_ids
509
- or any(
510
- [(term_id in landCover_product_ids) for term_id in landCover_practice_ids]
511
- )
512
- or {
513
- "level": "error",
514
- "dataPath": f".{list_key}",
515
- "message": "at least one landCover practice must match an equivalent product",
516
- "params": {
517
- "current": landCover_practice_ids,
518
- "expected": landCover_product_ids,
519
- },
520
- }
521
- )
522
-
523
-
524
- def validate_practices_management(cycle: dict, site: dict, list_key: str = "practices"):
525
- # validate that practices and management nodes, with same term and dates, have the same value
526
- management_nodes = site.get("management", [])
527
-
528
- def validate(values: tuple):
529
- index, practice = values
530
- term_id = practice.get("term", {}).get("@id")
531
- value = get_node_value(practice)
532
- management_node = [
533
- v
534
- for v in management_nodes
535
- if all(
536
- [
537
- v.get("term", {}).get("@id") == term_id,
538
- v.get("startDate") == practice.get("startDate"),
539
- v.get("endDate") == practice.get("endDate"),
540
- ]
541
- )
542
- ]
543
- return (
544
- len(management_node) == 0
545
- or management_node[0].get("value") == value
546
- or {
547
- "level": "error",
548
- "dataPath": f".{list_key}[{index}].value",
549
- "message": "should match the site management node value",
550
- "params": {
551
- "current": value,
552
- "expected": management_node[0].get("value"),
553
- },
554
- }
555
- )
556
-
557
- return (
558
- _filter_list_errors(flatten(map(validate, enumerate(cycle.get(list_key, [])))))
559
- if management_nodes
560
- else True
561
- )
562
-
563
-
564
- def validate_irrigated_complete_has_inputs(cycle: dict):
565
- is_complete = cycle.get("completeness", {}).get(TermTermType.WATER.value)
566
- has_irrigated_practice = (
567
- any([_is_irrigated(v.get("term", {})) for v in cycle.get("practices", [])])
568
- if is_complete
569
- else False
570
- )
571
- has_water_inputs = (
572
- list_sum(
573
- list(
574
- map(
575
- get_node_value,
576
- filter_list_term_type(cycle.get("inputs", []), TermTermType.WATER),
577
- )
578
- ),
579
- default=0,
580
- )
581
- > 0
582
- if is_complete
583
- else False
584
- )
585
-
586
- return any([not is_complete, not has_irrigated_practice, has_water_inputs]) or {
587
- "level": "error",
588
- "dataPath": ".inputs",
589
- "message": "must contain water inputs",
590
- }