66# it under the terms of the MIT License; see LICENSE file for more details.
77"""Subcommunities request implementation for ZenodoRDM."""
88
9+ from copy import deepcopy
10+
911import invenio_communities .notifications .builders as notifications
1012from invenio_access .permissions import system_identity
13+ from invenio_checks .models import CheckConfig , Severity
1114from invenio_communities .proxies import current_communities
1215from invenio_communities .subcommunities .services .request import (
1316 AcceptSubcommunity ,
2326 current_community_records_service ,
2427 current_rdm_records ,
2528)
26- from invenio_records_resources .services .uow import RecordCommitOp
29+ from invenio_records_resources .services .uow import ModelCommitOp , RecordCommitOp
2730from invenio_requests .customizations import actions
2831from invenio_requests .customizations .event_types import CommentEventType
2932from invenio_requests .proxies import current_events_service
33+ from invenio_vocabularies .contrib .awards .api import Award
3034from marshmallow import fields
3135
3236
@@ -42,6 +46,80 @@ def _add_community_records(child_id, parent_id, uow):
4246 )
4347
4448
49+ FUNDING_RULE_TEMPLATE = {
50+ "id" : "funding:project" ,
51+ "title" : "Project Funding" ,
52+ "message" : "Submissions must have the __AWARD_ACRONYM__ (__AWARD_NUMBER__) grant/award" ,
53+ "description" : 'You are submitting to an EU project community for __AWARD_ACRONYM__ (__AWARD_NUMBER__) and you must therefore add the grant/award. <a href="/communities/eu/pages/open-science" target="_blank">Learn more</a>' ,
54+ "level" : "error" ,
55+ "checks" : [
56+ {
57+ "type" : "list" ,
58+ "operator" : "any" ,
59+ "path" : "metadata.funding" ,
60+ "predicate" : {
61+ "type" : "comparison" ,
62+ "left" : {"type" : "field" , "path" : "award.id" },
63+ "operator" : "==" ,
64+ "right" : None ,
65+ },
66+ }
67+ ],
68+ }
69+
70+
71+ def _add_subcommunity_funding_check (request , subcommunity , uow ):
72+ """Add a check to the subcommunity to ensure project funding is specified."""
73+ project_id = request .get ("payload" , {}).get ("project_id" )
74+ if not project_id :
75+ return
76+ # Resolve the project ID to get the award acronym and number
77+ award = Award .pid .resolve (project_id )
78+ award_acronym = award ["acronym" ]
79+ award_number = award ["number" ]
80+
81+ # Update the award information in the rule template
82+ funding_rule = deepcopy (FUNDING_RULE_TEMPLATE )
83+
84+ funding_rule ["checks" ][0 ]["predicate" ]["right" ] = project_id
85+ message = funding_rule ["message" ]
86+ message = message .replace ("__AWARD_ACRONYM__" , award_acronym )
87+ message = message .replace ("__AWARD_NUMBER__" , award_number )
88+ funding_rule ["message" ] = message
89+
90+ description = funding_rule ["description" ]
91+ description = description .replace ("__AWARD_ACRONYM__" , award_acronym )
92+ description = description .replace ("__AWARD_NUMBER__" , award_number )
93+ funding_rule ["description" ] = description
94+
95+ # Create or update the check config on the subcommunity
96+ check_config = CheckConfig .query .filter_by (
97+ community_id = subcommunity .id , check_id = "metadata"
98+ ).one_or_none ()
99+ if check_config :
100+ params = check_config .params or {}
101+ rules = params .get ("rules" , [])
102+ for rule in rules :
103+ if rule ["id" ] == funding_rule ["id" ]:
104+ rule .update (funding_rule )
105+ break
106+ else : # If the rule was not found, append it
107+ rules .append (funding_rule )
108+ params ["rules" ] = rules
109+
110+ # Set the field on the model to trigger an UPDATE
111+ check_config .params = params
112+ else :
113+ check_config = CheckConfig (
114+ community_id = subcommunity .id ,
115+ check_id = "metadata" ,
116+ params = {"rules" : [funding_rule ]},
117+ severity = Severity .INFO ,
118+ enabled = True ,
119+ )
120+ uow .register (ModelCommitOp (check_config ))
121+
122+
45123def _update_subcommunity_funding (request , subcommunity , uow ):
46124 """Update the subcommunity funding metadata."""
47125 project_id = request .get ("payload" , {}).get ("project_id" )
@@ -67,15 +145,17 @@ class SubcommunityAcceptAction(AcceptSubcommunity):
67145
68146 def execute (self , identity , uow ):
69147 """Execute approve action."""
70- to_be_moved = self .request .topic .resolve ().id
71- move_to = self .request .receiver .resolve ().id
148+ subcommunity = self .request .topic .resolve ()
149+ parent = self .request .receiver .resolve ()
150+
151+ _add_community_records (subcommunity .id , parent .id , uow )
152+ _add_subcommunity_funding_check (self .request , subcommunity , uow )
72153
73- _add_community_records (to_be_moved , move_to , uow )
74154 super ().execute (identity , uow )
75155
76156
77157class SubcommunityCreateAction (actions .CreateAndSubmitAction ):
78- """Represents an create action used to create a subcommunity request.
158+ """Represents a create action used to create a subcommunity request.
79159
80160 Zenodo re-implementation of the create action, to also create the system comment.
81161 """
@@ -94,7 +174,7 @@ def execute(self, identity, uow):
94174 payload = {
95175 "content" : f"""
96176 <p>
97- We have created your community for your project <a href='/communities/{ subcommunity .slug } '>{ subcommunity [' metadata' ][ ' title' ]} </a>.
177+ We have created your community for your project <a href='/communities/{ subcommunity .slug } '>{ subcommunity [" metadata" ][ " title" ]} </a>.
98178 </p>
99179
100180 <p>
@@ -192,6 +272,7 @@ def execute(self, identity, uow):
192272
193273 _add_community_records (child .id , parent .id , uow )
194274 _update_subcommunity_funding (self .request , child , uow )
275+ _add_subcommunity_funding_check (self .request , child , uow )
195276 # moving the community is handled by super()
196277
197278 super ().execute (identity , uow )
@@ -212,6 +293,7 @@ def execute(self, identity, uow):
212293 )
213294
214295 _update_subcommunity_funding (self .request , child , uow )
296+ _add_subcommunity_funding_check (self .request , child , uow )
215297
216298 super ().execute (identity , uow )
217299
0 commit comments