{"action":"created","comment":{"url":"https://api.github.com/repos/uclouvain/osis/pulls/comments/234649051","pull_request_review_id":176334944,"id":234649051,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzNDY0OTA1MQ==","diff_hunk":"@@ -23,17 +23,109 @@\n #    see http://www.gnu.org/licenses/.\n #\n ##############################################################################\n+import re\n+\n from django import forms\n from django.utils.translation import ugettext_lazy as _\n \n-from base.models.prerequisite import Prerequisite\n+from base.models import learning_unit_year\n+from base.models import prerequisite_item\n+from base.models.enums.prerequisite_operator import OR, AND\n+from base.models.prerequisite import Prerequisite, prerequisite_syntax_validator, MULTIPLE_PREREQUISITES_REGEX_OR, \\\n+    MULTIPLE_PREREQUISITES_REGEX_AND\n \n \n class LearningUnitPrerequisiteForm(forms.ModelForm):\n+    main_operator = None\n+\n+    prerequisite_string = forms.CharField(\n+        label=_(\"Prerequisite\"),\n+        validators=[prerequisite_syntax_validator],\n+        help_text=_(\"prerequisites_syntax_rules\"),\n+    )\n \n     class Meta:\n         model = Prerequisite\n-        fields = ('prerequisite', )\n-        help_texts = {\n-            'prerequisite': _(\"prerequisites_syntax_rules\"),\n-        }\n+        fields = ()\n+\n+    def __init__(self, *args, **kwargs):\n+        super().__init__(*args, **kwargs)\n+        self.fields['prerequisite_string'].initial = self.instance.prerequisite_string\n+\n+    def clean_prerequisite_string(self):\n+        prerequisite_string = self.cleaned_data['prerequisite_string']\n+        self.main_operator = _detect_main_operator_in_string(prerequisite_string)\n+\n+        return self.get_grouped_items_from_string(\n+            prerequisite_string=prerequisite_string,\n+            main_operator=self.main_operator\n+        )\n+\n+    def save(self, commit=True):\n+        grouped_items = self.cleaned_data['prerequisite_string']\n+\n+        self.instance.main_operator = self.main_operator or AND\n+        self.instance.save()\n+\n+        _delete_related_items(prerequisite=self.instance)\n+\n+        _create_prerequisite_items(\n+            grouped_items=grouped_items,\n+            prerequisite=self.instance\n+        )\n+\n+    def get_grouped_items_from_string(self, prerequisite_string, main_operator):\n+        main_operator_splitter = ' ET ' if main_operator == AND else ' OU '\n+        secondary_operator_splitter = ' OU ' if main_operator == AND else ' ET '\n+\n+        groups = prerequisite_string.split(main_operator_splitter)\n+\n+        return [\n+            self.split_group_to_learning_units(group, secondary_operator_splitter)\n+            for group in groups\n+        ]\n+\n+    def split_group_to_learning_units(self, group, operator):\n+        group = _remove_parenthesis(group)\n+        group = group.split(operator)\n+        group_of_learning_units = []\n+\n+        for item in group:\n+            luy = learning_unit_year.get_by_acronym_with_highest_academic_year(item)","path":"base/forms/prerequisite.py","position":77,"original_position":77,"commit_id":"94c6ebe586287fdf1c33467728f692886f71e09c","original_commit_id":"94c6ebe586287fdf1c33467728f692886f71e09c","user":{"login":"matgerard","id":14902946,"node_id":"MDQ6VXNlcjE0OTAyOTQ2","avatar_url":"https://avatars3.githubusercontent.com/u/14902946?v=4","gravatar_id":"","url":"https://api.github.com/users/matgerard","html_url":"https://github.com/matgerard","followers_url":"https://api.github.com/users/matgerard/followers","following_url":"https://api.github.com/users/matgerard/following{/other_user}","gists_url":"https://api.github.com/users/matgerard/gists{/gist_id}","starred_url":"https://api.github.com/users/matgerard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matgerard/subscriptions","organizations_url":"https://api.github.com/users/matgerard/orgs","repos_url":"https://api.github.com/users/matgerard/repos","events_url":"https://api.github.com/users/matgerard/events{/privacy}","received_events_url":"https://api.github.com/users/matgerard/received_events","type":"User","site_admin":false},"body":"J'ai besoin du luy plus loin : \r\n```\r\ngroup_of_learning_units.append(luy.learning_unit)\r\n```\r\n\r\net j'ai fait une fonction dans le modèle car il me semblait qu'on n'écrivait le moins possible de queryset sur un modèle ailleurs que dans le fichier modèle... Qu'en penses-tu ? ","created_at":"2018-11-19T14:57:03Z","updated_at":"2018-11-19T14:57:03Z","html_url":"https://github.com/uclouvain/osis/pull/4557#discussion_r234649051","pull_request_url":"https://api.github.com/repos/uclouvain/osis/pulls/4557","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/uclouvain/osis/pulls/comments/234649051"},"html":{"href":"https://github.com/uclouvain/osis/pull/4557#discussion_r234649051"},"pull_request":{"href":"https://api.github.com/repos/uclouvain/osis/pulls/4557"}},"in_reply_to_id":234646369},"pull_request":{"url":"https://api.github.com/repos/uclouvain/osis/pulls/4557","id":231995185,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMxOTk1MTg1","html_url":"https://github.com/uclouvain/osis/pull/4557","diff_url":"https://github.com/uclouvain/osis/pull/4557.diff","patch_url":"https://github.com/uclouvain/osis/pull/4557.patch","issue_url":"https://api.github.com/repos/uclouvain/osis/issues/4557","number":4557,"state":"open","locked":false,"title":"Osis 2203 Adapter l'enregistrement / la modif des prérequis suite au changement de modèle","user":{"login":"matgerard","id":14902946,"node_id":"MDQ6VXNlcjE0OTAyOTQ2","avatar_url":"https://avatars3.githubusercontent.com/u/14902946?v=4","gravatar_id":"","url":"https://api.github.com/users/matgerard","html_url":"https://github.com/matgerard","followers_url":"https://api.github.com/users/matgerard/followers","following_url":"https://api.github.com/users/matgerard/following{/other_user}","gists_url":"https://api.github.com/users/matgerard/gists{/gist_id}","starred_url":"https://api.github.com/users/matgerard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/matgerard/subscriptions","organizations_url":"https://api.github.com/users/matgerard/orgs","repos_url":"https://api.github.com/users/matgerard/repos","events_url":"https://api.github.com/users/matgerard/events{/privacy}","received_events_url":"https://api.github.com/users/matgerard/received_events","type":"User","site_admin":false},"body":"Référence Jira : OSIS-2203\r\n\r\nVérifier les points suivants : \r\n- [ ] Ouvrir une release task Jira si le ticket génère une tâche pour la release : \r\n    - modification de configuration\r\n    - table à synchroniser en entier, etc.\r\n- [ ] Uniformiser les modèles osis-portal avec les changements effectués dans osis si nécessaire\r\n- [ ] Permissions et droits d’accès mettre à jour la documentation si : \r\n    - on rajoute/modifie une permission\r\n    - on rajoute/modifie un groupe d’utilisateurs, etc.\r\n","created_at":"2018-11-19T14:37:01Z","updated_at":"2018-11-19T14:57:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"907c60c25e8a047996ffc8aa3040537abb774f0b","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/uclouvain/osis/pulls/4557/commits","review_comments_url":"https://api.github.com/repos/uclouvain/osis/pulls/4557/comments","review_comment_url":"https://api.github.com/repos/uclouvain/osis/pulls/comments{/number}","comments_url":"https://api.github.com/repos/uclouvain/osis/issues/4557/comments","statuses_url":"https://api.github.com/repos/uclouvain/osis/statuses/94c6ebe586287fdf1c33467728f692886f71e09c","head":{"label":"uclouvain:OSIS-2203","ref":"OSIS-2203","sha":"94c6ebe586287fdf1c33467728f692886f71e09c","user":{"login":"uclouvain","id":9862060,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk4NjIwNjA=","avatar_url":"https://avatars0.githubusercontent.com/u/9862060?v=4","gravatar_id":"","url":"https://api.github.com/users/uclouvain","html_url":"https://github.com/uclouvain","followers_url":"https://api.github.com/users/uclouvain/followers","following_url":"https://api.github.com/users/uclouvain/following{/other_user}","gists_url":"https://api.github.com/users/uclouvain/gists{/gist_id}","starred_url":"https://api.github.com/users/uclouvain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclouvain/subscriptions","organizations_url":"https://api.github.com/users/uclouvain/orgs","repos_url":"https://api.github.com/users/uclouvain/repos","events_url":"https://api.github.com/users/uclouvain/events{/privacy}","received_events_url":"https://api.github.com/users/uclouvain/received_events","type":"Organization","site_admin":false},"repo":{"id":37489388,"node_id":"MDEwOlJlcG9zaXRvcnkzNzQ4OTM4OA==","name":"osis","full_name":"uclouvain/osis","private":false,"owner":{"login":"uclouvain","id":9862060,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk4NjIwNjA=","avatar_url":"https://avatars0.githubusercontent.com/u/9862060?v=4","gravatar_id":"","url":"https://api.github.com/users/uclouvain","html_url":"https://github.com/uclouvain","followers_url":"https://api.github.com/users/uclouvain/followers","following_url":"https://api.github.com/users/uclouvain/following{/other_user}","gists_url":"https://api.github.com/users/uclouvain/gists{/gist_id}","starred_url":"https://api.github.com/users/uclouvain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclouvain/subscriptions","organizations_url":"https://api.github.com/users/uclouvain/orgs","repos_url":"https://api.github.com/users/uclouvain/repos","events_url":"https://api.github.com/users/uclouvain/events{/privacy}","received_events_url":"https://api.github.com/users/uclouvain/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/uclouvain/osis","description":"Open Student Information System Backoffice","fork":false,"url":"https://api.github.com/repos/uclouvain/osis","forks_url":"https://api.github.com/repos/uclouvain/osis/forks","keys_url":"https://api.github.com/repos/uclouvain/osis/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uclouvain/osis/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uclouvain/osis/teams","hooks_url":"https://api.github.com/repos/uclouvain/osis/hooks","issue_events_url":"https://api.github.com/repos/uclouvain/osis/issues/events{/number}","events_url":"https://api.github.com/repos/uclouvain/osis/events","assignees_url":"https://api.github.com/repos/uclouvain/osis/assignees{/user}","branches_url":"https://api.github.com/repos/uclouvain/osis/branches{/branch}","tags_url":"https://api.github.com/repos/uclouvain/osis/tags","blobs_url":"https://api.github.com/repos/uclouvain/osis/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uclouvain/osis/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uclouvain/osis/git/refs{/sha}","trees_url":"https://api.github.com/repos/uclouvain/osis/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uclouvain/osis/statuses/{sha}","languages_url":"https://api.github.com/repos/uclouvain/osis/languages","stargazers_url":"https://api.github.com/repos/uclouvain/osis/stargazers","contributors_url":"https://api.github.com/repos/uclouvain/osis/contributors","subscribers_url":"https://api.github.com/repos/uclouvain/osis/subscribers","subscription_url":"https://api.github.com/repos/uclouvain/osis/subscription","commits_url":"https://api.github.com/repos/uclouvain/osis/commits{/sha}","git_commits_url":"https://api.github.com/repos/uclouvain/osis/git/commits{/sha}","comments_url":"https://api.github.com/repos/uclouvain/osis/comments{/number}","issue_comment_url":"https://api.github.com/repos/uclouvain/osis/issues/comments{/number}","contents_url":"https://api.github.com/repos/uclouvain/osis/contents/{+path}","compare_url":"https://api.github.com/repos/uclouvain/osis/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uclouvain/osis/merges","archive_url":"https://api.github.com/repos/uclouvain/osis/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uclouvain/osis/downloads","issues_url":"https://api.github.com/repos/uclouvain/osis/issues{/number}","pulls_url":"https://api.github.com/repos/uclouvain/osis/pulls{/number}","milestones_url":"https://api.github.com/repos/uclouvain/osis/milestones{/number}","notifications_url":"https://api.github.com/repos/uclouvain/osis/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uclouvain/osis/labels{/name}","releases_url":"https://api.github.com/repos/uclouvain/osis/releases{/id}","deployments_url":"https://api.github.com/repos/uclouvain/osis/deployments","created_at":"2015-06-15T20:25:28Z","updated_at":"2018-11-19T14:53:51Z","pushed_at":"2018-11-19T14:53:55Z","git_url":"git://github.com/uclouvain/osis.git","ssh_url":"git@github.com:uclouvain/osis.git","clone_url":"https://github.com/uclouvain/osis.git","svn_url":"https://github.com/uclouvain/osis","homepage":"http://uclouvain.github.io/osis","size":69898,"stargazers_count":39,"watchers_count":39,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":18,"mirror_url":null,"archived":false,"open_issues_count":17,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0","node_id":"MDc6TGljZW5zZTE="},"forks":18,"open_issues":17,"watchers":39,"default_branch":"dev"}},"base":{"label":"uclouvain:dev","ref":"dev","sha":"a6138404a9bc9aaa6ce1000bed2017ea259399c6","user":{"login":"uclouvain","id":9862060,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk4NjIwNjA=","avatar_url":"https://avatars0.githubusercontent.com/u/9862060?v=4","gravatar_id":"","url":"https://api.github.com/users/uclouvain","html_url":"https://github.com/uclouvain","followers_url":"https://api.github.com/users/uclouvain/followers","following_url":"https://api.github.com/users/uclouvain/following{/other_user}","gists_url":"https://api.github.com/users/uclouvain/gists{/gist_id}","starred_url":"https://api.github.com/users/uclouvain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclouvain/subscriptions","organizations_url":"https://api.github.com/users/uclouvain/orgs","repos_url":"https://api.github.com/users/uclouvain/repos","events_url":"https://api.github.com/users/uclouvain/events{/privacy}","received_events_url":"https://api.github.com/users/uclouvain/received_events","type":"Organization","site_admin":false},"repo":{"id":37489388,"node_id":"MDEwOlJlcG9zaXRvcnkzNzQ4OTM4OA==","name":"osis","full_name":"uclouvain/osis","private":false,"owner":{"login":"uclouvain","id":9862060,"node_id":"MDEyOk9yZ2FuaXphdGlvbjk4NjIwNjA=","avatar_url":"https://avatars0.githubusercontent.com/u/9862060?v=4","gravatar_id":"","url":"https://api.github.com/users/uclouvain","html_url":"https://github.com/uclouvain","followers_url":"https://api.github.com/users/uclouvain/followers","following_url":"https://api.github.com/users/uclouvain/following{/other_user}","gists_url":"https://api.github.com/users/uclouvain/gists{/gist_id}","starred_url":"https://api.github.com/users/uclouvain/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uclouvain/subscriptions","organizations_url":"https://api.github.com/users/uclouvain/orgs","repos_url":"https://api.github.com/users/uclouvain/repos","events_url":"https://api.github.com/users/uclouvain/events{/privacy}","received_events_url":"https://api.github.com/users/uclouvain/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/uclouvain/osis","description":"Open Student Information System Backoffice","fork":false,"url":"https://api.github.com/repos/uclouvain/osis","forks_url":"https://api.github.com/repos/uclouvain/osis/forks","keys_url":"https://api.github.com/repos/uclouvain/osis/keys{/key_id}","collaborators_url":"https://api.github.com/repos/uclouvain/osis/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/uclouvain/osis/teams","hooks_url":"https://api.github.com/repos/uclouvain/osis/hooks","issue_events_url":"https://api.github.com/repos/uclouvain/osis/issues/events{/number}","events_url":"https://api.github.com/repos/uclouvain/osis/events","assignees_url":"https://api.github.com/repos/uclouvain/osis/assignees{/user}","branches_url":"https://api.github.com/repos/uclouvain/osis/branches{/branch}","tags_url":"https://api.github.com/repos/uclouvain/osis/tags","blobs_url":"https://api.github.com/repos/uclouvain/osis/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/uclouvain/osis/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/uclouvain/osis/git/refs{/sha}","trees_url":"https://api.github.com/repos/uclouvain/osis/git/trees{/sha}","statuses_url":"https://api.github.com/repos/uclouvain/osis/statuses/{sha}","languages_url":"https://api.github.com/repos/uclouvain/osis/languages","stargazers_url":"https://api.github.com/repos/uclouvain/osis/stargazers","contributors_url":"https://api.github.com/repos/uclouvain/osis/contributors","subscribers_url":"https://api.github.com/repos/uclouvain/osis/subscribers","subscription_url":"https://api.github.com/repos/uclouvain/osis/subscription","commits_url":"https://api.github.com/repos/uclouvain/osis/commits{/sha}","git_commits_url":"https://api.github.com/repos/uclouvain/osis/git/commits{/sha}","comments_url":"https://api.github.com/repos/uclouvain/osis/comments{/number}","issue_comment_url":"https://api.github.com/repos/uclouvain/osis/issues/comments{/number}","contents_url":"https://api.github.com/repos/uclouvain/osis/contents/{+path}","compare_url":"https://api.github.com/repos/uclouvain/osis/compare/{base}...{head}","merges_url":"https://api.github.com/repos/uclouvain/osis/merges","archive_url":"https://api.github.com/repos/uclouvain/osis/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/uclouvain/osis/downloads","issues_url":"https://api.github.com/repos/uclouvain/osis/issues{/number}","pulls_url":"https://api.github.com/repos/uclouvain/osis/pulls{/number}","milestones_url":"https://api.github.com/repos/uclouvain/osis/milestones{/number}","notifications_url":"https://api.github.com/repos/uclouvain/osis/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/uclouvain/osis/labels{/name}","releases_url":"https://api.github.com/repos/uclouvain/osis/releases{/id}","deployments_url":"https://api.github.com/repos/uclouvain/osis/deployments","created_at":"2015-06-15T20:25:28Z","updated_at":"2018-11-19T14:53:51Z","pushed_at":"2018-11-19T14:53:55Z","git_url":"git://github.com/uclouvain/osis.git","ssh_url":"git@github.com:uclouvain/osis.git","clone_url":"https://github.com/uclouvain/osis.git","svn_url":"https://github.com/uclouvain/osis","homepage":"http://uclouvain.github.io/osis","size":69898,"stargazers_count":39,"watchers_count":39,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":18,"mirror_url":null,"archived":false,"open_issues_count":17,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0","node_id":"MDc6TGljZW5zZTE="},"forks":18,"open_issues":17,"watchers":39,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/uclouvain/osis/pulls/4557"},"html":{"href":"https://github.com/uclouvain/osis/pull/4557"},"issue":{"href":"https://api.github.com/repos/uclouvain/osis/issues/4557"},"comments":{"href":"https://api.github.com/repos/uclouvain/osis/issues/4557/comments"},"review_comments":{"href":"https://api.github.com/repos/uclouvain/osis/pulls/4557/comments"},"review_comment":{"href":"https://api.github.com/repos/uclouvain/osis/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/uclouvain/osis/pulls/4557/commits"},"statuses":{"href":"https://api.github.com/repos/uclouvain/osis/statuses/94c6ebe586287fdf1c33467728f692886f71e09c"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"matgerard"}}