diff --git a/scipost_django/journals/constants.py b/scipost_django/journals/constants.py
index e485dbf61b18b8d828f8e39bf269b60a619e21ad..8b0a66a28b9b480d9d9b29bf8c2cc63998240790 100644
--- a/scipost_django/journals/constants.py
+++ b/scipost_django/journals/constants.py
@@ -34,6 +34,35 @@ CC_LICENSES_URI = (
 )
 
 
+PUBLISHABLE_OBJECT_TYPE_ARTICLE = "article"
+PUBLISHABLE_OBJECT_TYPE_CODEBASE = "codebase"
+PUBLISHABLE_OBJECT_TYPE_DATASET = "dataset"
+PUBLISHABLE_OBJECT_TYPE_CHOICES = (
+    (PUBLISHABLE_OBJECT_TYPE_ARTICLE, "Article"),
+    (PUBLISHABLE_OBJECT_TYPE_CODEBASE, "Codebase release"),
+    (PUBLISHABLE_OBJECT_TYPE_DATASET, "Dataset"),
+)
+
+def get_publishable_object_types_default_list():
+    return [PUBLISHABLE_OBJECT_TYPE_ARTICLE,]
+
+def get_submission_object_types_default():
+    return {
+        "options": [
+            ' + '.join(l) for l in [
+                [PUBLISHABLE_OBJECT_TYPE_ARTICLE,],
+                [PUBLISHABLE_OBJECT_TYPE_ARTICLE, PUBLISHABLE_OBJECT_TYPE_CODEBASE],
+                [PUBLISHABLE_OBJECT_TYPE_ARTICLE, PUBLISHABLE_OBJECT_TYPE_DATASET],
+                [
+                    PUBLISHABLE_OBJECT_TYPE_ARTICLE,
+                    PUBLISHABLE_OBJECT_TYPE_CODEBASE,
+                    PUBLISHABLE_OBJECT_TYPE_DATASET,
+                ],
+            ]
+        ]
+    }
+
+
 ISSUES_AND_VOLUMES = "IV"
 ISSUES_ONLY = "IO"
 INDIVIDUAL_PUBLICATIONS = "IP"
diff --git a/scipost_django/journals/migrations/0125_journal_publishable_object_types.py b/scipost_django/journals/migrations/0125_journal_publishable_object_types.py
new file mode 100644
index 0000000000000000000000000000000000000000..bee75146a05004eddb0982f59d426c54ca9b1fd5
--- /dev/null
+++ b/scipost_django/journals/migrations/0125_journal_publishable_object_types.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.2.16 on 2023-01-21 08:29
+
+from django.db import migrations, models
+import journals.constants
+import scipost.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0124_journal_has_clockss'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='journal',
+            name='publishable_object_types',
+            field=scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('article', 'Article'), ('codebase', 'Codebase release'), ('dataset', 'Dataset')], max_length=24), default=journals.constants.get_publishable_object_types_default_list, size=None),
+        ),
+    ]
diff --git a/scipost_django/journals/migrations/0126_populate_journal_publishable_object_types.py b/scipost_django/journals/migrations/0126_populate_journal_publishable_object_types.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6183966ea61e46f111e4fe94094aed813363186
--- /dev/null
+++ b/scipost_django/journals/migrations/0126_populate_journal_publishable_object_types.py
@@ -0,0 +1,27 @@
+# Generated by Django 3.2.16 on 2023-01-21 08:33
+
+from django.db import migrations
+
+from journals.constants import PUBLISHABLE_OBJECT_TYPE_CODEBASE
+
+def populate_codebases(apps, schema_editor):
+    Journal = apps.get_model("journals.Journal")
+
+    for j in Journal.objects.all():
+        if "Codebases" in j.name:
+            j.publishable_object_types.append(PUBLISHABLE_OBJECT_TYPE_CODEBASE)
+            j.save()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0125_journal_publishable_object_types'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            populate_codebases,
+            reverse_code=migrations.RunPython.noop,
+        )
+    ]
diff --git a/scipost_django/journals/migrations/0127_journal_submission_object_types.py b/scipost_django/journals/migrations/0127_journal_submission_object_types.py
new file mode 100644
index 0000000000000000000000000000000000000000..7baeab5721a1870891328750f35e7a8a04c87441
--- /dev/null
+++ b/scipost_django/journals/migrations/0127_journal_submission_object_types.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.2.16 on 2023-01-21 13:29
+
+from django.db import migrations, models
+import journals.constants
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0126_populate_journal_publishable_object_types'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='journal',
+            name='submission_object_types',
+            field=models.JSONField(default=journals.constants.get_submission_object_types_default),
+        ),
+    ]
diff --git a/scipost_django/journals/migrations/0128_populate_submission_object_types.py b/scipost_django/journals/migrations/0128_populate_submission_object_types.py
new file mode 100644
index 0000000000000000000000000000000000000000..27658db48d6f0a2856d8e48e4df3ca657091b692
--- /dev/null
+++ b/scipost_django/journals/migrations/0128_populate_submission_object_types.py
@@ -0,0 +1,52 @@
+# Generated by Django 3.2.16 on 2023-01-21 13:30
+
+from django.db import migrations
+
+
+from journals.constants import (
+    PUBLISHABLE_OBJECT_TYPE_ARTICLE,
+    PUBLISHABLE_OBJECT_TYPE_CODEBASE,
+    PUBLISHABLE_OBJECT_TYPE_DATASET,
+)
+
+
+def populate_codebases(apps, schema_editor):
+    Journal = apps.get_model("journals.Journal")
+
+    for j in Journal.objects.all():
+        if "Codebases" in j.name:
+            j.submission_object_types = {
+                "options": [
+                    ' + '.join(l) for l in [
+                        [PUBLISHABLE_OBJECT_TYPE_CODEBASE,],
+                        [
+                            PUBLISHABLE_OBJECT_TYPE_ARTICLE,
+                            PUBLISHABLE_OBJECT_TYPE_CODEBASE,
+                        ],
+                        [
+                            PUBLISHABLE_OBJECT_TYPE_CODEBASE,
+                            PUBLISHABLE_OBJECT_TYPE_DATASET,
+                        ],
+                        [
+                            PUBLISHABLE_OBJECT_TYPE_ARTICLE,
+                            PUBLISHABLE_OBJECT_TYPE_CODEBASE,
+                            PUBLISHABLE_OBJECT_TYPE_DATASET,
+                        ],
+                    ]
+                ]
+            }
+            j.save()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('journals', '0127_journal_submission_object_types'),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            populate_codebases,
+            reverse_code=migrations.RunPython.noop,
+        )
+    ]
diff --git a/scipost_django/journals/models/journal.py b/scipost_django/journals/models/journal.py
index b7c17a861965194d804d22526fff3749fe264a5a..0b3d519a12da317a86c03707dc427008854c6b73 100644
--- a/scipost_django/journals/models/journal.py
+++ b/scipost_django/journals/models/journal.py
@@ -9,9 +9,17 @@ from django.db.models import Avg, F
 from django.urls import reverse
 from django.utils import timezone
 
+from scipost.fields import ChoiceArrayField
 from series.models import Collection
 
-from ..constants import JOURNAL_STRUCTURE, ISSUES_AND_VOLUMES, ISSUES_ONLY
+from ..constants import (
+    PUBLISHABLE_OBJECT_TYPE_CHOICES,
+    get_publishable_object_types_default_list,
+    get_submission_object_types_default,
+    JOURNAL_STRUCTURE,
+    ISSUES_AND_VOLUMES,
+    ISSUES_ONLY,
+)
 from ..managers import JournalQuerySet
 from ..validators import doi_journal_validator
 
@@ -50,15 +58,28 @@ class Journal(models.Model):
         default="SciPost [abbrev]",
         help_text="Abbreviated name (for use in citations)",
     )
+
     doi_label = models.CharField(
         max_length=200, unique=True, db_index=True, validators=[doi_journal_validator]
     )
     issn = models.CharField(max_length=16, default="2542-4653", blank=True)
+
     active = models.BooleanField(default=True)
+
     submission_allowed = models.BooleanField(default=True)
+
+    publishable_object_types = ChoiceArrayField(
+        models.CharField(max_length=24, choices=PUBLISHABLE_OBJECT_TYPE_CHOICES),
+        default=get_publishable_object_types_default_list,
+    )
+    submission_object_types = models.JSONField(
+        default=get_submission_object_types_default,
+    )
+
     structure = models.CharField(
         max_length=2, choices=JOURNAL_STRUCTURE, default=ISSUES_AND_VOLUMES
     )
+
     refereeing_period = models.DurationField(default=datetime.timedelta(days=28))
 
     style = models.TextField(
@@ -78,6 +99,7 @@ class Journal(models.Model):
     list_order = models.PositiveSmallIntegerField(default=100)
 
     # For manuscript preparation: templates are given by the SubmissionTemplate related objects
+
     # For the author guidelines page:
     required_article_elements = models.TextField(
         default="[To be filled in; you can use markup]"
@@ -92,6 +114,7 @@ class Journal(models.Model):
     submission_insert = models.TextField(
         blank=True, null=True, default="[Optional; you can use markup]"
     )
+
     minimal_nr_of_reports = models.PositiveSmallIntegerField(
         help_text=(
             "Minimal number of substantial Reports required "
diff --git a/scipost_django/profiles/models.py b/scipost_django/profiles/models.py
index faa723e2e26d0433141fc292beb2e7762321452a..8646d93e08fe843920e70b9e0b905fd7a978e811 100644
--- a/scipost_django/profiles/models.py
+++ b/scipost_django/profiles/models.py
@@ -9,7 +9,6 @@ from django.shortcuts import get_object_or_404
 
 from scipost.behaviors import orcid_validator
 from scipost.constants import TITLE_CHOICES, TITLE_DR
-from scipost.fields import ChoiceArrayField
 from scipost.models import Contributor
 
 from comments.models import Comment
diff --git a/scipost_django/submissions/forms/__init__.py b/scipost_django/submissions/forms/__init__.py
index 0561ddc5b3f60f068f137a101743a26112fc9d35..8d26eb1440a2c0b8a6aee43ce955a07a88e55629 100644
--- a/scipost_django/submissions/forms/__init__.py
+++ b/scipost_django/submissions/forms/__init__.py
@@ -65,6 +65,11 @@ from ..regexes import CHEMRXIV_DOI_PATTERN
 from colleges.models import Fellowship
 from common.utils import Q_with_alternative_spellings
 from journals.models import Journal
+from journals.constants import (
+    PUBLISHABLE_OBJECT_TYPE_ARTICLE,
+    PUBLISHABLE_OBJECT_TYPE_CODEBASE,
+    PUBLISHABLE_OBJECT_TYPE_DATASET,
+)
 from mails.utils import DirectMailUtil
 from ontology.models import AcademicField, Specialty
 from preprints.helpers import get_new_scipost_identifier
@@ -1141,7 +1146,8 @@ class SubmissionForm(forms.ModelForm):
         help_text=(
             "Please submit the processed .pdf (not the source files; "
             "these will only be required at the post-acceptance proofs stage)"
-        )
+        ),
+        required=False,
     )
 
     class Meta:
@@ -1282,13 +1288,7 @@ class SubmissionForm(forms.ModelForm):
                 self.requested_by, cleaned_data["is_resubmission_of"]
             )
 
-        if "Codeb" in cleaned_data["submitted_to"].doi_label:
-            if not ("code_repository_url" in cleaned_data and cleaned_data["code_repository_url"]):
-                msg = (
-                    "You must specify a code repository if you submit to %s"
-                    % cleaned_data["submitted_to"].name
-                )
-                self.add_error("code_repository_url", msg)
+        self.clear_submission_object_types()
 
         if "Proc" not in cleaned_data["submitted_to"].doi_label:
             try:
@@ -1298,6 +1298,31 @@ class SubmissionForm(forms.ModelForm):
                 pass
         return cleaned_data
 
+    def clear_submission_object_types(self):
+        """
+        Check that the submitted material fits one of the Journal's options.
+        """
+        submitted_types = []
+        if (self.cleaned_data.get("preprint_file", None) or
+            self.cleaned_data.get("preprint_link", None)):
+            submitted_types.append(PUBLISHABLE_OBJECT_TYPE_ARTICLE)
+        if self.cleaned_data.get("code_repository_url", None):
+            submitted_types.append(PUBLISHABLE_OBJECT_TYPE_CODEBASE)
+        if self.cleaned_data.get("data_repository_url", None):
+            submitted_types.append(PUBLISHABLE_OBJECT_TYPE_DATASET)
+        submitted_types.sort() # not needed here, but for future safety
+        submitted_types_code = ' + '.join(submitted_types)
+        options = self.cleaned_data["submitted_to"].submission_object_types["options"]
+        if submitted_types_code not in options:
+            self.add_error(
+                None,
+                (
+                    f"You are trying to submit document types: {submitted_types_code}, "
+                    "but this Journal requires one of the following options: "
+                    f"{', '.join(options)}"
+                )
+            )
+
     def clean_author_list(self):
         """
         Check if author list matches the Contributor submitting.
diff --git a/scipost_django/submissions/models/submission.py b/scipost_django/submissions/models/submission.py
index b93705ef96ac5ca1aa901ac87d340a8d931f1d2a..5c3ac7c30aa0b2a1ba8cedd0aa038f4f36df7fe2 100644
--- a/scipost_django/submissions/models/submission.py
+++ b/scipost_django/submissions/models/submission.py
@@ -283,6 +283,7 @@ class Submission(models.Model):
             "to set things up."
         ),
     )
+
     title = models.CharField(max_length=300)
 
     # Authors which have been mapped to contributors:
diff --git a/scipost_django/submissions/views/pool.py b/scipost_django/submissions/views/pool.py
index 4b001a7871119dd4962ea529e8bfd723122d2ed6..eeb35f45707feecc48f0512a04082fb705739718 100644
--- a/scipost_django/submissions/views/pool.py
+++ b/scipost_django/submissions/views/pool.py
@@ -118,7 +118,6 @@ def add_remark(request, identifier_w_vn_nr):
         remark = Remark(
             contributor=request.user.contributor,
             submission=submission,
-            date=timezone.now(),
             remark=remark_form.cleaned_data["remark"],
         )
         remark.save()