diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..7b3a281 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,11 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/psf/black + rev: 19.3b0 + hooks: + - id: black diff --git a/recording/i18n/fr.po b/recording/i18n/fr.po index 26b5730..824cd59 100644 --- a/recording/i18n/fr.po +++ b/recording/i18n/fr.po @@ -1,21 +1,19 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * sale_warranty +# * recording # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0+e\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-02-07 16:50+0000\n" -"PO-Revision-Date: 2020-02-07 11:59-0500\n" +"POT-Creation-Date: 2020-03-12 18:59+0000\n" +"PO-Revision-Date: 2020-03-12 18:59+0000\n" "Last-Translator: <>\n" "Language-Team: \n" -"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" +"Content-Transfer-Encoding: \n" "Plural-Forms: \n" -"X-Generator: Poedit 2.0.6\n" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__message_needaction @@ -25,7 +23,7 @@ msgstr "Nécessite une action" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__active msgid "Active" -msgstr "Active" +msgstr "Actif" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__activity_ids @@ -40,7 +38,7 @@ msgstr "Status de l'Activité" #. module: recording #: selection:recording,group_type:0 msgid "Album" -msgstr "Album" +msgstr "" #. module: recording #: model_terms:ir.ui.view,arch_db:recording.recording_search @@ -70,12 +68,12 @@ msgstr "Société" #. module: recording #: selection:recording,group_type:0 msgid "Compilation" -msgstr "Compilation" +msgstr "" #. module: recording #: model:ir.ui.menu,name:recording.menu_config msgid "Configuration" -msgstr "Configuration" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__create_uid @@ -107,17 +105,13 @@ msgstr "Durée" #. module: recording #: selection:recording,group_type:0 msgid "EP" -msgstr "EP" - -#. module: recording -#: model:ir.model,name:recording.model_recording_external_catalog_reference -msgid "External Catalog Reference for Recordings" -msgstr "Références de catalogue externe d'enregistrements" +msgstr "" #. module: recording +#: model:ir.model,name:recording.model_musical_catalog_reference #: model:ir.model.fields,field_description:recording.field_recording__musical_catalog_reference_ids msgid "External Catalog References" -msgstr "Références catalogues externes" +msgstr "Références de catalogues externes" #. module: recording #: model:ir.ui.menu,name:recording.musical_catalog_menu @@ -153,9 +147,7 @@ msgstr "Donne accès à gérer les paramètres de l'application Enregistrement." #. module: recording #: model:res.groups,comment:recording.group_user msgid "Grants write access recordings and read access to related object types." -msgstr "" -"Donne accès en écriture sur les enregistrements et en lecture aux types " -"d'objets associés." +msgstr "Donne accès en écriture sur les enregistrements et en lecture aux types d'objets associés." #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__group_duration @@ -179,13 +171,13 @@ msgstr "Regroupement d'enregistrements" #: model:ir.model.fields,field_description:recording.field_recording_other_isrc__id #: model:ir.model.fields,field_description:recording.field_recording_track__id msgid "ID" -msgstr "ID" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__isrc #: model:ir.model.fields,field_description:recording.field_recording_other_isrc__isrc msgid "ISRC" -msgstr "ISRC" +msgstr "" #. module: recording #: model:ir.model.fields,help:recording.field_recording__message_unread @@ -227,7 +219,7 @@ msgstr "Langues" #: model:ir.model.fields,field_description:recording.field_recording_other_isrc____last_update #: model:ir.model.fields,field_description:recording.field_recording_track____last_update msgid "Last Modified on" -msgstr "Dernière Modification le" +msgstr "Dernière modification le" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__write_uid @@ -266,7 +258,7 @@ msgstr "Erreur d'envoi du message" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__message_ids msgid "Messages" -msgstr "Messages" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__activity_date_deadline @@ -296,13 +288,13 @@ msgstr "Prochain numéro de volume" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__note msgid "Note" -msgstr "Note" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording_other_isrc__notes #: model_terms:ir.ui.view,arch_db:recording.recording_form msgid "Notes" -msgstr "Notes" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__message_needaction_counter @@ -447,7 +439,7 @@ msgstr "Séquence" #. module: recording #: selection:recording,group_type:0 msgid "Single" -msgstr "Single" +msgstr "" #. module: recording #: model_terms:ir.ui.view,arch_db:recording.recording_search @@ -463,17 +455,15 @@ msgstr "Enregistrement sonore" #. module: recording #: selection:recording,group_type:0 msgid "Split" -msgstr "Split" +msgstr "" #. module: recording #: model:ir.model.fields,help:recording.field_recording__activity_state -msgid "" -"Status based on activities\n" +msgid "Status based on activities\n" "Overdue: Due date is already passed\n" "Today: Activity date is today\n" "Planned: Future activities." -msgstr "" -"Statut basé sur les activités\n" +msgstr "Statut basé sur les activités\n" "En retard : la date d'échéance est déjà dépassée\n" "Aujourd'hui : la date d'activité est aujourd'hui\n" "Planifiée : activités futures" @@ -481,19 +471,20 @@ msgstr "" #. module: recording #: code:addons/recording/isrc.py:15 #, python-format -msgid "" -"The given ISRC ({}) is invalid. It must contain only letters and digits. No " -"special caracters are authorized." -msgstr "" -"Le code ISRC ({}) est invalide. Il doit contenir seulement des lettres et " -"des chiffres. Aucun caractère spécial n'est autorisé." +msgid "The given ISRC ({}) is invalid. It must contain only letters and digits. No special caracters are authorized." +msgstr "Le code ISRC ({}) est invalide. Il doit contenir seulement des lettres et des chiffres. Aucun caractère spécial n'est autorisé." #. module: recording #: code:addons/recording/isrc.py:24 #, python-format msgid "The given ISRC ({}) is invalid. It must have exactly 12 caracters." -msgstr "" -"Le code ISRC ({}) est invalide. Il doit contenir exactement 12 caractères." +msgstr "Le code ISRC ({}) est invalide. Il doit contenir exactement 12 caractères." + +#. module: recording +#: code:addons/recording/models/recording.py:175 +#, python-format +msgid "The track \"%s\" has been selected twice in the track. It can be selected only once." +msgstr "L'enregistrement \"%s\" a été sélectionné deux fois. Il ne peux être sélectionné qu'une seule fois." #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__name @@ -519,7 +510,7 @@ msgstr "Piste" #. module: recording #: model_terms:ir.ui.view,arch_db:recording.recording_form msgid "Type" -msgstr "Type" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__ttype @@ -529,12 +520,12 @@ msgstr "Type d'enregistrement" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__upc msgid "UPC" -msgstr "UPC" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__upc_packshot msgid "UPC Packshot" -msgstr "UPC Packshot" +msgstr "" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording__message_unread @@ -570,4 +561,5 @@ msgstr "Enregistrements vidéo" #. module: recording #: model:ir.model.fields,field_description:recording.field_recording_track__volume msgid "Volume" -msgstr "Volume" +msgstr "" + diff --git a/recording/models/recording.py b/recording/models/recording.py index 7523dac..f1efaca 100644 --- a/recording/models/recording.py +++ b/recording/models/recording.py @@ -1,8 +1,9 @@ # © 2019 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). -from odoo import api, fields, models +from odoo import api, fields, models, _ from ..isrc import check_isrc_code +from odoo.exceptions import ValidationError SOUND = 'sound' VIDEO = 'video' @@ -162,6 +163,23 @@ class RecordingGroup(models.Model): 'recording.track', 'recording_group_id', 'Related Recordings', ) + @api.constrains("track_ids") + def _unique_couple_recording_group_recording(self): + for record in self: + recording_track_record = [] + + for track in record.track_ids: + + if track.recording_id in recording_track_record: + raise ValidationError( + _( + 'The recording "%s" has been selected twice in the list.' + ' It can be selected only once.' + ) % track.recording_id.name + ) + + recording_track_record.append(track.recording_id) + number_of_tracks = fields.Integer( string="Total Number of Tracks", compute='_compute_number_of_tracks' diff --git a/recording/tests/test_recording.py b/recording/tests/test_recording.py index 3b8dafd..9e13290 100644 --- a/recording/tests/test_recording.py +++ b/recording/tests/test_recording.py @@ -1,47 +1,32 @@ # © 2019 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens) # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). +import pytest from ddt import ddt, data, unpack from odoo.tests.common import SavepointCase +from odoo.exceptions import ValidationError @ddt class TestRecording(SavepointCase): - @classmethod def setUpClass(cls): super().setUpClass() - cls.sound_1 = cls.env['recording'].create({ - 'name': 'Sound 1', - 'ttype': 'sound', - }) - cls.sound_2 = cls.env['recording'].create({ - 'name': 'Sound 2', - 'ttype': 'sound', - }) - cls.video_1 = cls.env['recording'].create({ - 'name': 'Video 1', - 'ttype': 'video', - }) - cls.video_2 = cls.env['recording'].create({ - 'name': 'Video 1', - 'ttype': 'video', - }) - cls.group_1 = cls.env['recording'].create({ - 'name': 'Group 1', - 'ttype': 'group', - 'track_ids': [ - (0, 0, { - 'sequence': 1, - 'recording_id': cls.sound_1.id, - }), - (0, 0, { - 'sequence': 2, - 'recording_id': cls.sound_2.id, - }), - ] - }) + cls.sound_1 = cls.env["recording"].create({"name": "Sound 1", "ttype": "sound"}) + cls.sound_2 = cls.env["recording"].create({"name": "Sound 2", "ttype": "sound"}) + cls.video_1 = cls.env["recording"].create({"name": "Video 1", "ttype": "video"}) + cls.video_2 = cls.env["recording"].create({"name": "Video 1", "ttype": "video"}) + cls.group_1 = cls.env["recording"].create( + { + "name": "Group 1", + "ttype": "group", + "track_ids": [ + (0, 0, {"sequence": 1, "recording_id": cls.sound_1.id}), + (0, 0, {"sequence": 2, "recording_id": cls.sound_2.id}), + ], + } + ) def test_number_of_related_video(self): self.video_1.sound_recording_id = self.sound_1 @@ -59,16 +44,12 @@ def test_group_duration(self): self.sound_2.duration = 2 assert self.group_1.group_duration == 10 - @data('0', '1', '1A') + @data("0", "1", "1A") def test_next_volume(self, volume): self.group_1.track_ids[1].volume = volume assert self.group_1.next_volume_number == volume - @data( - ('0', '1'), - ('2', '3'), - (' 2 ', '3'), - ) + @data(("0", "1"), ("2", "3"), (" 2 ", "3")) @unpack def test_next_track(self, last_track, expected_next_track): self.group_1.track_ids[1].track = last_track @@ -76,8 +57,62 @@ def test_next_track(self, last_track, expected_next_track): def test_if_no_track_next_volume_is_1(self): self.group_1.track_ids.unlink() - assert self.group_1.next_volume_number == '1' + assert self.group_1.next_volume_number == "1" def test_if_no_track_next_track_is_1(self): self.group_1.track_ids.unlink() - assert self.group_1.next_track_number == '1' + assert self.group_1.next_track_number == "1" + + +class TestRecordingGroup(SavepointCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.sound_1 = cls.env["recording"].create({"name": "Sound 1", "ttype": "sound"}) + cls.sound_2 = cls.env["recording"].create({"name": "Sound 2", "ttype": "sound"}) + cls.group_1 = cls.env["recording"].create({"name": "Group 1", "ttype": "group"}) + + cls.track_pool = cls.env["recording.track"] + + def test_whenSameSoundAddedTwice_thenRaiseError(self): + track_1 = self.track_pool.create( + { + "recording_group_id": self.group_1.id, + "volume": 1, + "track": 1, + "recording_id": self.sound_1.id, + } + ) + track_2 = self.track_pool.create( + { + "recording_group_id": self.group_1.id, + "volume": 1, + "track": 2, + "recording_id": self.sound_1.id, + } + ) + + with pytest.raises(ValidationError): + self.group_1.write({"track_ids": [(6, 0, [track_1.id, track_2.id])]}) + + def test_whenTrackWithDifferentRecordings_thenTheyAreAddedToTheGRoup(self): + track_1 = self.track_pool.create( + { + "recording_group_id": self.group_1.id, + "volume": 1, + "track": 1, + "recording_id": self.sound_1.id, + } + ) + track_2 = self.track_pool.create( + { + "recording_group_id": self.group_1.id, + "volume": 1, + "track": 2, + "recording_id": self.sound_2.id, + } + ) + + self.group_1.write({"track_ids": [(6, 0, [track_1.id, track_2.id])]}) + assert 2 == len(self.group_1.track_ids)