diff --git a/requirements-dev.txt b/requirements-dev.txt index 6bb7efc7e..a0c619e2b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -40,9 +40,9 @@ boto3==1.34.14 \ --hash=sha256:1f94042f4efb5133b6b9b8b3243afc01143a81d21b3197a3afadf5780f97b05d \ --hash=sha256:5c1bb487c68120aae236354d81b8a1a55d0aa3395d30748a01825ef90891921e # via moto -botocore==1.34.14 \ - --hash=sha256:041bed0852649cab7e4dcd4d87f9d1cc084467fb846e5b60015e014761d96414 \ - --hash=sha256:3b592f50f0406e236782a3a0a9ad1c3976060fdb2e04a23d18c3df5b7dfad3e0 +botocore==1.34.23 \ + --hash=sha256:1980411306593bbc2b0cd9b8d1dcacbd418b758077b82f68b932070ad902cfe9 \ + --hash=sha256:898fa169679782f396613f50a88b9b033845625c931275832063266110ea4297 # via # boto3 # moto @@ -346,9 +346,9 @@ jedi==0.19.1 \ --hash=sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd \ --hash=sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0 # via ipython -jinja2==3.1.2 \ - --hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \ - --hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61 +jinja2==3.1.3 \ + --hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \ + --hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90 # via moto jmespath==1.0.1 \ --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ @@ -356,71 +356,71 @@ jmespath==1.0.1 \ # via # boto3 # botocore -jsonpath-ng==1.6.0 \ - --hash=sha256:5483f8e9d74c39c9abfab554c070ae783c1c8cbadf5df60d561bc705ac68a07e \ - --hash=sha256:6fd04833412c4b3d9299edf369542f5e67095ca84efa17cbb7f06a34958adc9f +jsonpath-ng==1.6.1 \ + --hash=sha256:086c37ba4917304850bd837aeab806670224d3f038fe2833ff593a672ef0a5fa \ + --hash=sha256:8f22cd8273d7772eea9aaa84d922e0841aa36fdb8a2c6b7f6c3791a16a9bc0be # via -r requirements/dev.in -markupsafe==2.1.3 \ - --hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \ - --hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \ - --hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \ - --hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \ - --hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \ - --hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \ - --hash=sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc \ - --hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \ - --hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \ - --hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \ - --hash=sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0 \ - --hash=sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4 \ - --hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \ - --hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \ - --hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \ - --hash=sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d \ - --hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \ - --hash=sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3 \ - --hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \ - --hash=sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155 \ - --hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \ - --hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \ - --hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \ - --hash=sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8 \ - --hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \ - --hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \ - --hash=sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24 \ - --hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \ - --hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \ - --hash=sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0 \ - --hash=sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee \ - --hash=sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be \ - --hash=sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2 \ - --hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \ - --hash=sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707 \ - --hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \ - --hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \ - --hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \ - --hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \ - --hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \ - --hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \ - --hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \ - --hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \ - --hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \ - --hash=sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc \ - --hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \ - --hash=sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48 \ - --hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \ - --hash=sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e \ - --hash=sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b \ - --hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \ - --hash=sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5 \ - --hash=sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e \ - --hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \ - --hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \ - --hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \ - --hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \ - --hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \ - --hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \ - --hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11 +markupsafe==2.1.4 \ + --hash=sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69 \ + --hash=sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0 \ + --hash=sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d \ + --hash=sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec \ + --hash=sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5 \ + --hash=sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411 \ + --hash=sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3 \ + --hash=sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74 \ + --hash=sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0 \ + --hash=sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949 \ + --hash=sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d \ + --hash=sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279 \ + --hash=sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f \ + --hash=sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6 \ + --hash=sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc \ + --hash=sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e \ + --hash=sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954 \ + --hash=sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656 \ + --hash=sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc \ + --hash=sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518 \ + --hash=sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56 \ + --hash=sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc \ + --hash=sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa \ + --hash=sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565 \ + --hash=sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4 \ + --hash=sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb \ + --hash=sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250 \ + --hash=sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4 \ + --hash=sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959 \ + --hash=sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc \ + --hash=sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474 \ + --hash=sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863 \ + --hash=sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8 \ + --hash=sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f \ + --hash=sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2 \ + --hash=sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e \ + --hash=sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e \ + --hash=sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb \ + --hash=sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f \ + --hash=sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a \ + --hash=sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26 \ + --hash=sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d \ + --hash=sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2 \ + --hash=sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131 \ + --hash=sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789 \ + --hash=sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6 \ + --hash=sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a \ + --hash=sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858 \ + --hash=sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e \ + --hash=sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb \ + --hash=sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e \ + --hash=sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84 \ + --hash=sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7 \ + --hash=sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea \ + --hash=sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b \ + --hash=sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6 \ + --hash=sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475 \ + --hash=sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74 \ + --hash=sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a \ + --hash=sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00 # via # jinja2 # werkzeug diff --git a/requirements.txt b/requirements.txt index 3a024a885..21fbc1785 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,9 +31,9 @@ boto3==1.34.14 \ # via # -r requirements/base.in # django-ses -botocore==1.34.14 \ - --hash=sha256:041bed0852649cab7e4dcd4d87f9d1cc084467fb846e5b60015e014761d96414 \ - --hash=sha256:3b592f50f0406e236782a3a0a9ad1c3976060fdb2e04a23d18c3df5b7dfad3e0 +botocore==1.34.23 \ + --hash=sha256:1980411306593bbc2b0cd9b8d1dcacbd418b758077b82f68b932070ad902cfe9 \ + --hash=sha256:898fa169679782f396613f50a88b9b033845625c931275832063266110ea4297 # via # boto3 # s3transfer diff --git a/terraso_backend/apps/collaboration/graphql/memberships.py b/terraso_backend/apps/collaboration/graphql/memberships.py index 4a0ce22d0..0e03c46e4 100644 --- a/terraso_backend/apps/collaboration/graphql/memberships.py +++ b/terraso_backend/apps/collaboration/graphql/memberships.py @@ -86,6 +86,20 @@ def resolve_memberships_count(self, info): return 0 return self.memberships.approved_only().count() + def resolve_memberships(self, info, **args): + if self.membership_type == MembershipList.MEMBERSHIP_TYPE_OPEN: + return self.memberships + if hasattr(self, "account_memberships"): + if len(self.account_memberships): + return self.memberships + return self.memberships.none() + user = info.context.user + is_member = self.is_member(user) + + if not is_member: + return self.memberships.none() + return self.memberships + class CollaborationMembershipListNode(MembershipListNodeMixin, DjangoObjectType): class Meta(MembershipListNodeMixin.Meta): diff --git a/terraso_backend/apps/collaboration/migrations/0006_membership_status_approved_lowercase.py b/terraso_backend/apps/collaboration/migrations/0006_membership_status_approved_lowercase.py new file mode 100644 index 000000000..0d7d47f60 --- /dev/null +++ b/terraso_backend/apps/collaboration/migrations/0006_membership_status_approved_lowercase.py @@ -0,0 +1,30 @@ +# Copyright © 2024 Technology Matters +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see https://www.gnu.org/licenses/. + +# Generated by Django 5.0.1 on 2024-01-10 16:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("collaboration", "0005_change_collaborator_to_editor"), + ] + + operations = [ + migrations.RunSQL( + sql="UPDATE collaboration_membership SET membership_status ='approved' WHERE membership_status='APPROVED';" + ), + ] diff --git a/terraso_backend/apps/graphql/schema/data_entries.py b/terraso_backend/apps/graphql/schema/data_entries.py index 83923914f..da8fd8e11 100644 --- a/terraso_backend/apps/graphql/schema/data_entries.py +++ b/terraso_backend/apps/graphql/schema/data_entries.py @@ -100,12 +100,14 @@ def get_queryset(cls, queryset, info): user_pk = getattr(info.context.user, "pk", False) user_groups_ids = Subquery( Group.objects.filter( + membership_list__memberships__deleted_at__isnull=True, membership_list__memberships__user__id=user_pk, membership_list__memberships__membership_status=CollaborationMembership.APPROVED, ).values("id") ) user_landscape_ids = Subquery( Landscape.objects.filter( + membership_list__memberships__deleted_at__isnull=True, membership_list__memberships__user__id=user_pk, membership_list__memberships__membership_status=CollaborationMembership.APPROVED, ).values("id") diff --git a/terraso_backend/apps/graphql/schema/groups_memberships.py b/terraso_backend/apps/graphql/schema/groups_memberships.py index 56adf2cb4..e0465e786 100644 --- a/terraso_backend/apps/graphql/schema/groups_memberships.py +++ b/terraso_backend/apps/graphql/schema/groups_memberships.py @@ -88,7 +88,9 @@ def mutate_and_get_payload(cls, root, info, **kwargs): kwargs={ **kwargs, "user_role": user_role, - "membership_status": membership_status, + "membership_status": CollaborationMembership.get_membership_status_from_text( + membership_status + ), }, ) diff --git a/terraso_backend/apps/graphql/schema/schema.graphql b/terraso_backend/apps/graphql/schema/schema.graphql index 632a1bf97..86acc72f9 100644 --- a/terraso_backend/apps/graphql/schema/schema.graphql +++ b/terraso_backend/apps/graphql/schema/schema.graphql @@ -1111,6 +1111,7 @@ type DepthInterval { type DepthDependentSoilDataNode { texture: SoilIdDepthDependentSoilDataTextureChoices + clayPercent: Int rockFragmentVolume: SoilIdDepthDependentSoilDataRockFragmentVolumeChoices colorHueSubstep: SoilIdDepthDependentSoilDataColorHueSubstepChoices colorHue: SoilIdDepthDependentSoilDataColorHueChoices @@ -2251,6 +2252,7 @@ input DepthDependentSoilDataUpdateMutationInput { siteId: ID! depthInterval: DepthIntervalInput! texture: SoilIdDepthDependentSoilDataTextureChoices + clayPercent: Int rockFragmentVolume: SoilIdDepthDependentSoilDataRockFragmentVolumeChoices colorHueSubstep: SoilIdDepthDependentSoilDataColorHueSubstepChoices colorHue: SoilIdDepthDependentSoilDataColorHueChoices diff --git a/terraso_backend/apps/graphql/schema/shared_resources_mixin.py b/terraso_backend/apps/graphql/schema/shared_resources_mixin.py index 86dffe189..e6912a3e8 100644 --- a/terraso_backend/apps/graphql/schema/shared_resources_mixin.py +++ b/terraso_backend/apps/graphql/schema/shared_resources_mixin.py @@ -14,9 +14,11 @@ # along with this program. If not, see https://www.gnu.org/licenses/. import django_filters +from django.db.models import Q, Subquery from graphene_django.filter import DjangoFilterConnectionField -from apps.core.models import SharedResource +from apps.collaboration.models import Membership as CollaborationMembership +from apps.core.models import Group, Landscape, SharedResource from apps.shared_data.models import DataEntry @@ -51,6 +53,23 @@ class SharedResourcesMixin: ) def resolve_shared_resources(self, info, **kwargs): - return self.shared_resources.prefetch_related( + user_pk = getattr(info.context.user, "pk", False) + user_groups_ids = Subquery( + Group.objects.filter( + membership_list__memberships__deleted_at__isnull=True, + membership_list__memberships__user__id=user_pk, + membership_list__memberships__membership_status=CollaborationMembership.APPROVED, + ).values("id") + ) + user_landscape_ids = Subquery( + Landscape.objects.filter( + membership_list__memberships__deleted_at__isnull=True, + membership_list__memberships__user__id=user_pk, + membership_list__memberships__membership_status=CollaborationMembership.APPROVED, + ).values("id") + ) + return self.shared_resources.filter( + Q(target_object_id__in=user_groups_ids) | Q(target_object_id__in=user_landscape_ids) + ).prefetch_related( "source", ) diff --git a/terraso_backend/apps/graphql/schema/visualization_config.py b/terraso_backend/apps/graphql/schema/visualization_config.py index e0e821f0e..fa68cc7f6 100644 --- a/terraso_backend/apps/graphql/schema/visualization_config.py +++ b/terraso_backend/apps/graphql/schema/visualization_config.py @@ -112,12 +112,14 @@ def get_queryset(cls, queryset, info): user_groups_ids = Subquery( Group.objects.filter( + membership_list__memberships__deleted_at__isnull=True, membership_list__memberships__user__id=user_pk, membership_list__memberships__membership_status=CollaborationMembership.APPROVED, ).values("id") ) user_landscape_ids = Subquery( Landscape.objects.filter( + membership_list__memberships__deleted_at__isnull=True, membership_list__memberships__user__id=user_pk, membership_list__memberships__membership_status=CollaborationMembership.APPROVED, ).values("id") diff --git a/terraso_backend/apps/soil_id/graphql/soil_data.py b/terraso_backend/apps/soil_id/graphql/soil_data.py index 3487b6a2c..901cae297 100644 --- a/terraso_backend/apps/soil_id/graphql/soil_data.py +++ b/terraso_backend/apps/soil_id/graphql/soil_data.py @@ -372,6 +372,7 @@ class Input: site_id = graphene.ID(required=True) depth_interval = graphene.Field(DepthIntervalInput, required=True) texture = DepthDependentSoilDataNode.texture_enum() + clay_percent = graphene.Int() rock_fragment_volume = DepthDependentSoilDataNode.rock_fragment_volume_enum() color_hue_substep = DepthDependentSoilDataNode.color_hue_substep_enum() color_hue = DepthDependentSoilDataNode.color_hue_enum() diff --git a/terraso_backend/apps/soil_id/migrations/0009_depthdependentsoildata_clay_percent_and_more.py b/terraso_backend/apps/soil_id/migrations/0009_depthdependentsoildata_clay_percent_and_more.py new file mode 100644 index 000000000..0d9793000 --- /dev/null +++ b/terraso_backend/apps/soil_id/migrations/0009_depthdependentsoildata_clay_percent_and_more.py @@ -0,0 +1,49 @@ +# Copyright © 2024 Technology Matters +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see https://www.gnu.org/licenses/. + +# Generated by Django 5.0.1 on 2024-01-18 01:02 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("soil_id", "0008_soildata_depth_interval_preset"), + ] + + operations = [ + migrations.AddField( + model_name="depthdependentsoildata", + name="clay_percent", + field=models.IntegerField( + blank=True, + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(100), + ], + ), + ), + migrations.AlterField( + model_name="soildata", + name="depth_interval_preset", + field=models.CharField( + blank=True, + choices=[("LANDPKS", "Landpks"), ("NRCS", "Nrcs"), ("CUSTOM", "Custom")], + null=True, + ), + ), + ] diff --git a/terraso_backend/apps/soil_id/models/depth_dependent_soil_data.py b/terraso_backend/apps/soil_id/models/depth_dependent_soil_data.py index c2532f58d..a513c0962 100644 --- a/terraso_backend/apps/soil_id/models/depth_dependent_soil_data.py +++ b/terraso_backend/apps/soil_id/models/depth_dependent_soil_data.py @@ -46,6 +46,10 @@ class Texture(models.TextChoices): texture = models.CharField(blank=True, null=True, choices=Texture.choices) + clay_percent = models.IntegerField( + blank=True, null=True, validators=[MinValueValidator(0), MaxValueValidator(100)] + ) + class RockFragmentVolume(models.TextChoices): VOLUME_0_1 = "VOLUME_0_1", "0 — 1%" VOLUME_1_15 = "VOLUME_1_15", "1 — 15%" diff --git a/terraso_backend/tests/graphql/test_shared_data.py b/terraso_backend/tests/graphql/test_shared_data.py index a303163d1..25aed428f 100644 --- a/terraso_backend/tests/graphql/test_shared_data.py +++ b/terraso_backend/tests/graphql/test_shared_data.py @@ -128,6 +128,50 @@ def test_data_entries_filter_by_group_slug_filters_successfuly( assert str(data_entry_b.id) in data_entries_result +def test_data_entries_filter_by_closed_group_slug_filters_successfuly( + client_query, data_entries, groups_closed, users +): + data_entry_a = data_entries[0] + data_entry_b = data_entries[1] + + data_entry_a.shared_resources.all().delete() + data_entry_b.shared_resources.all().delete() + + data_entry_a.shared_resources.create(target=groups_closed[-1]) + data_entry_b.shared_resources.create(target=groups_closed[-1]) + + group_filter = groups_closed[-1] + + group_filter.membership_list.save_membership( + users[0].email, group_collaboration_roles.ROLE_MEMBER, CollaborationMembership.APPROVED + ) + + shared_resources = data_entry_a.shared_resources.all() + print(shared_resources) + + response = client_query( + """ + {dataEntries(sharedResources_Target_Slug: "%s", sharedResources_TargetContentType: "%s") { + edges { + node { + id + } + } + }} + """ + % (group_filter.slug, "group") + ) + + json_response = response.json() + + edges = json_response["data"]["dataEntries"]["edges"] + data_entries_result = [edge["node"]["id"] for edge in edges] + + assert len(data_entries_result) == 2 + assert str(data_entry_a.id) in data_entries_result + assert str(data_entry_b.id) in data_entries_result + + def test_data_entries_filter_by_group_id_filters_successfuly( client_query, data_entries, groups, users ): @@ -248,8 +292,15 @@ def data_entries_by_parent(request, group_data_entries, landscape_data_entries): @pytest.mark.parametrize("data_entries_by_parent", ["groups", "landscapes"], indirect=True) -def test_data_entries_from_parent_query(client_query, data_entries_by_parent): +def test_data_entries_from_parent_query(client_query, data_entries_by_parent, users): (parent, data_entries) = data_entries_by_parent + + shared_resources = data_entries[0].shared_resources.all() + parent_entity = shared_resources[0].target + parent_entity.membership_list.save_membership( + users[0].email, group_collaboration_roles.ROLE_MEMBER, CollaborationMembership.APPROVED + ) + response = client_query( """ {%s { @@ -282,9 +333,64 @@ def test_data_entries_from_parent_query(client_query, data_entries_by_parent): assert data_entry.name in entries_result +def test_data_entries_empty_from_closed_group_query(client_query, groups_closed, data_entries): + group = groups_closed[-1] + data_entry_a = data_entries[0] + data_entry_b = data_entries[1] + + data_entry_a.shared_resources.all().delete() + data_entry_b.shared_resources.all().delete() + + data_entry_a.shared_resources.create(target=group) + data_entry_b.shared_resources.create(target=group) + + memberships = group.membership_list.memberships.all() + + print(memberships) + + response = client_query( + """ + {groups(slug: "%s") { + edges { + node { + sharedResources { + edges { + node { + source { + ... on DataEntryNode { + name + } + } + } + } + } + } + } + }} + """ + % group.slug + ) + + json_response = response.json() + + sharedResources = json_response["data"]["groups"]["edges"][0]["node"]["sharedResources"][ + "edges" + ] + assert sharedResources == [] + + @pytest.mark.parametrize("data_entries_by_parent", ["groups", "landscapes"], indirect=True) -def test_data_entries_from_parent_query_by_resource_field(client_query, data_entries_by_parent): +def test_data_entries_from_parent_query_by_resource_field( + client_query, data_entries_by_parent, users +): (parent, data_entries) = data_entries_by_parent + + shared_resources = data_entries[0].shared_resources.all() + parent_entity = shared_resources[0].target + parent_entity.membership_list.save_membership( + users[0].email, group_collaboration_roles.ROLE_MEMBER, CollaborationMembership.APPROVED + ) + response = client_query( """ {%s {