diff --git a/commentaries/constants.py b/commentaries/constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..5fe492bf1f29a6f2d63f6d10742f5ee9c8ba05e2
--- /dev/null
+++ b/commentaries/constants.py
@@ -0,0 +1,6 @@
+COMMENTARY_PUBLISHED = 'published'
+COMMENTARY_PREPRINT = 'preprint'
+COMMENTARY_TYPES = (
+    (COMMENTARY_PUBLISHED, 'published paper'),
+    (COMMENTARY_PREPRINT, 'arXiv preprint'),
+)
diff --git a/commentaries/factories.py b/commentaries/factories.py
index 60f1625f2f365bd240db1d1aa7e5d7beb2a9fa73..1f9a3fd2844931cad7b986eb92d695ffd72f46c9 100644
--- a/commentaries/factories.py
+++ b/commentaries/factories.py
@@ -1,42 +1,54 @@
 import factory
 
-from scipost.constants import DISCIPLINE_PHYSICS, SCIPOST_SUBJECT_AREAS
+from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS
 from scipost.factories import ContributorFactory
+from scipost.models import Contributor
 from journals.constants import SCIPOST_JOURNALS_DOMAINS
-from common.helpers import random_arxiv_identifier_with_version_number
+from common.helpers import random_arxiv_identifier_with_version_number, random_external_doi
 
-from .models import Commentary, COMMENTARY_TYPES
+from .constants import COMMENTARY_TYPES
+from .models import Commentary
+
+from faker import Faker
 
 
 class CommentaryFactory(factory.django.DjangoModelFactory):
     class Meta:
         model = Commentary
-        abstract = True
 
     requested_by = factory.SubFactory(ContributorFactory)
-    vetted_by = factory.SubFactory(ContributorFactory)
-    type = COMMENTARY_TYPES[0][0]
-    discipline = DISCIPLINE_PHYSICS
-    domain = SCIPOST_JOURNALS_DOMAINS[0][0]
-    subject_area = SCIPOST_SUBJECT_AREAS[0][1][0][0]
-    pub_title = factory.Faker('bs')
-    pub_DOI = '10.1103/PhysRevB.92.214427'
+    type = factory.Iterator(COMMENTARY_TYPES, getter=lambda c: c[0])
+    discipline = factory.Iterator(SCIPOST_DISCIPLINES, getter=lambda c: c[0])
+    domain = factory.Iterator(SCIPOST_JOURNALS_DOMAINS, getter=lambda c: c[0])
+    subject_area = factory.Iterator(SCIPOST_SUBJECT_AREAS[0][1], getter=lambda c: c[0])
+    pub_title = factory.Faker('text')
+    pub_DOI = factory.Sequence(lambda n: random_external_doi())
     arxiv_identifier = factory.Sequence(lambda n: random_arxiv_identifier_with_version_number())
-    author_list = factory.Faker('name')
-    pub_abstract = factory.Faker('text')
+    arxiv_link = factory.Faker('uri')
+    pub_abstract = factory.lazy_attribute(lambda x: Faker().paragraph())
+
+    @factory.post_generation
+    def arxiv_link(self, create, extracted, **kwargs):
+        self.arxiv_link = 'https://arxiv.org/abs/%s' % self.arxiv_identifier
+        self.arxiv_or_DOI_string = self.arxiv_identifier
 
     @factory.post_generation
     def create_urls(self, create, extracted, **kwargs):
         self.parse_links_into_urls(commit=create)
 
-
-class EmptyCommentaryFactory(CommentaryFactory):
-    pub_DOI = None
-    arxiv_identifier = None
+    @factory.post_generation
+    def add_authors(self, create, extracted, **kwargs):
+        contributors = list(Contributor.objects.order_by('?')
+                            .exclude(pk=self.requested_by.pk).all()[:4])
+        for contrib in contributors:
+            self.author_list += ', %s %s' % (contrib.user.first_name, contrib.user.last_name)
+            if create:
+                self.authors.add(contrib)
 
 
 class VettedCommentaryFactory(CommentaryFactory):
     vetted = True
+    vetted_by = factory.SubFactory(ContributorFactory)
 
 
 class UnpublishedVettedCommentaryFactory(VettedCommentaryFactory):
diff --git a/commentaries/models.py b/commentaries/models.py
index ac6dab51bf5723cbad95556ed95bfa5c13ec9641..51490c7d8fc3c344e9ed2f3104db5a3cb2b80823 100644
--- a/commentaries/models.py
+++ b/commentaries/models.py
@@ -8,17 +8,10 @@ from scipost.behaviors import ArxivCallable, TimeStampedModel
 from scipost.models import Contributor
 from scipost.constants import SCIPOST_DISCIPLINES, DISCIPLINE_PHYSICS, SCIPOST_SUBJECT_AREAS
 
+from .constants import COMMENTARY_TYPES
 from .managers import CommentaryManager
 
 
-COMMENTARY_PUBLISHED = 'published'
-COMMENTARY_PREPRINT = 'preprint'
-COMMENTARY_TYPES = (
-    (COMMENTARY_PUBLISHED, 'published paper'),
-    (COMMENTARY_PREPRINT, 'arXiv preprint'),
-)
-
-
 class Commentary(ArxivCallable, TimeStampedModel):
     """
     A Commentary contains all the contents of a SciPost Commentary page for a given publication.
diff --git a/comments/factories.py b/comments/factories.py
index 010251601a8ea7186e8df653d3cdef9ff54422ae..de3bf41067008f93d86c590bd583c42884844e56 100644
--- a/comments/factories.py
+++ b/comments/factories.py
@@ -1,16 +1,46 @@
 import factory
+import pytz
 
 from django.utils import timezone
 
+from commentaries.factories import VettedCommentaryFactory
 from scipost.factories import ContributorFactory
+from submissions.factories import EICassignedSubmissionFactory
+from theses.factories import VettedThesisLinkFactory
 
+from .constants import STATUS_VETTED
 from .models import Comment
 
+from faker import Faker
+
+timezone.now()
+
 
 class CommentFactory(factory.django.DjangoModelFactory):
+    author = factory.SubFactory(ContributorFactory)
+    comment_text = factory.lazy_attribute(lambda x: Faker().paragraph())
+    remarks_for_editors = factory.lazy_attribute(lambda x: Faker().paragraph())
+    file_attachment = Faker().file_name(extension='pdf')
+    status = STATUS_VETTED  # All comments will have status vetted!
+    vetted_by = factory.SubFactory(ContributorFactory)
+    date_submitted = Faker().date_time_between(start_date="-3y", end_date="now", tzinfo=pytz.UTC)
+
     class Meta:
         model = Comment
+        abstract = True
 
-    author = factory.SubFactory(ContributorFactory)
-    comment_text = factory.Faker('text')
-    date_submitted = timezone.now()
+
+class CommentaryCommentFactory(CommentFactory):
+    commentary = factory.SubFactory(VettedCommentaryFactory)
+
+
+class SubmissionCommentFactory(CommentFactory):
+    submission = factory.SubFactory(EICassignedSubmissionFactory)
+
+
+class ThesislinkCommentFactory(CommentFactory):
+    thesislink = factory.SubFactory(VettedThesisLinkFactory)
+
+
+class ReplyCommentFactory(CommentFactory):
+    in_reply_to_comment = factory.SubFactory(SubmissionCommentFactory)
diff --git a/common/helpers/__init__.py b/common/helpers/__init__.py
index 78f99d9b8e50de1c0ce2fc15ae82ddf0eb23ef85..abe97df91f6222671cdcf4338f5ac1a39d0073ba 100644
--- a/common/helpers/__init__.py
+++ b/common/helpers/__init__.py
@@ -1,6 +1,8 @@
 import random
 import string
 
+from journals.constants import SCIPOST_JOURNALS_SUBMIT
+
 
 def model_form_data(model, form_class, form_kwargs={}):
     '''
@@ -29,6 +31,7 @@ def model_form_data(model, form_class, form_kwargs={}):
     form_fields = list(form_class(**form_kwargs).fields.keys())
     return filter_keys(model_data, form_fields)
 
+
 def random_arxiv_identifier_with_version_number():
     return random_arxiv_identifier_without_version_number() + "v0"
 
@@ -37,6 +40,34 @@ def random_arxiv_identifier_without_version_number():
     return random_digits(4) + "." + random_digits(5)
 
 
+def random_scipost_journal():
+    return random.choice(SCIPOST_JOURNALS_SUBMIT)[0]
+
+
+def random_external_journal():
+    return random.choice((
+        'PhysRevA.',
+        'PhysRevB.',
+        'PhysRevC.',
+        'nature.'
+        'S0550-3213(01)',
+        '1742-5468/',
+        '0550-3213(96)'
+    ))
+
+
+def random_pub_number():
+    return '%i.%i.%s' % (random.randint(1, 9), random.randint(1, 9), random_digits(3))
+
+
+def random_scipost_doi():
+    return '10.21468/%s.%s' % (random_scipost_journal(), random_pub_number())
+
+
+def random_external_doi():
+    return '10.%s/%s%s' % (random_digits(5), random_external_journal(), random_pub_number())
+
+
 def random_digits(n):
     return "".join(random.choice(string.digits) for _ in range(n))
 
diff --git a/journals/factories.py b/journals/factories.py
new file mode 100644
index 0000000000000000000000000000000000000000..203fe8cb6ca4e14f252ec32dc1d8f9b36660aaba
--- /dev/null
+++ b/journals/factories.py
@@ -0,0 +1,109 @@
+import factory
+import datetime
+import pytz
+
+from django.utils import timezone
+
+from common.helpers import random_digits
+from journals.constants import SCIPOST_JOURNALS
+from submissions.factories import PublishedSubmissionFactory
+
+from .models import Journal, Volume, Issue, Publication
+
+from faker import Faker
+
+
+class JournalFactory(factory.django.DjangoModelFactory):
+    name = factory.Iterator(SCIPOST_JOURNALS, getter=lambda c: c[0])
+    doi_label = factory.Iterator(SCIPOST_JOURNALS, getter=lambda c: c[0])
+    issn = factory.lazy_attribute(lambda n: random_digits(8))
+
+    class Meta:
+        model = Journal
+        django_get_or_create = ('name', 'doi_label',)
+
+
+class VolumeFactory(factory.django.DjangoModelFactory):
+    in_journal = factory.SubFactory(JournalFactory)
+    number = factory.Sequence(lambda n: n + 1)
+    doi_label = factory.Faker('md5')
+
+    @factory.post_generation
+    def doi(self, create, extracted, **kwargs):
+        self.doi_label = self.in_journal.doi_label + '.' + str(self.number)
+
+    @factory.post_generation
+    def dates(self, create, extracted, **kwargs):
+        timezone.now()
+        self.start_date = Faker().date_time_between(start_date="-3y", end_date="now",
+                                                    tzinfo=pytz.UTC)
+        self.until_date = self.start_date + datetime.timedelta(weeks=26)
+
+    class Meta:
+        model = Volume
+        django_get_or_create = ('in_journal', 'number')
+
+
+class IssueFactory(factory.django.DjangoModelFactory):
+    in_volume = factory.SubFactory(VolumeFactory)
+    number = factory.Sequence(lambda n: n + 1)
+    doi_label = factory.Faker('md5')
+
+    @factory.post_generation
+    def doi(self, create, extracted, **kwargs):
+        self.doi_label = self.in_volume.doi_label + '.' + str(self.number)
+
+    @factory.post_generation
+    def dates(self, create, extracted, **kwargs):
+        timezone.now()
+        self.start_date = Faker().date_time_between(start_date=self.in_volume.start_date,
+                                                    end_date=self.in_volume.until_date,
+                                                    tzinfo=pytz.UTC)
+        self.until_date = self.start_date + datetime.timedelta(weeks=4)
+
+    class Meta:
+        model = Issue
+        django_get_or_create = ('in_volume', 'number')
+
+
+class PublicationFactory(factory.django.DjangoModelFactory):
+    accepted_submission = factory.SubFactory(PublishedSubmissionFactory)
+    paper_nr = factory.Sequence(lambda n: n)
+    pdf_file = Faker().file_name(extension='pdf')
+    in_issue = factory.SubFactory(IssueFactory)
+    submission_date = factory.Faker('date')
+    acceptance_date = factory.Faker('date')
+    publication_date = factory.Faker('date')
+    doi_label = factory.Faker('md5')
+
+    @factory.post_generation
+    def doi(self, create, extracted, **kwargs):
+        paper_nr = self.in_issue.publication_set.count() + 1
+        self.paper_nr = paper_nr
+        self.doi_label = self.in_issue.doi_label + '.' + str(paper_nr).rjust(3, '0')
+
+    @factory.post_generation
+    def submission_data(self, create, extracted, **kwargs):
+        # Content
+        self.discipline = self.accepted_submission.discipline
+        self.domain = self.accepted_submission.domain
+        self.subject_area = self.accepted_submission.subject_area
+        self.title = self.accepted_submission.title
+        self.abstract = self.accepted_submission.abstract
+
+        # Authors
+        self.author_list = self.accepted_submission.author_list
+        self.authors.add(*self.accepted_submission.authors.all())
+        self.first_author = self.accepted_submission.authors.first()
+        self.authors_claims.add(*self.accepted_submission.authors_claims.all())
+        self.authors_false_claims.add(*self.accepted_submission.authors_false_claims.all())
+
+        # Dates
+        self.submission_date = self.accepted_submission.latest_activity
+        self.acceptance_date = self.accepted_submission.latest_activity
+        self.publication_date = self.accepted_submission.latest_activity
+        self.latest_activity = self.accepted_submission.latest_activity
+
+    class Meta:
+        model = Publication
+        django_get_or_create = ('accepted_submission', )
diff --git a/journals/helpers.py b/journals/helpers.py
index c31314def9187347421ba9fd7251603d5dd688f5..d1d656c2bad92ed789800d15dbe3685f93ca4d84 100644
--- a/journals/helpers.py
+++ b/journals/helpers.py
@@ -8,6 +8,8 @@ def journal_name_abbrev_citation(journal_name):
         return 'SciPost Phys. Sel.'
     elif journal_name == 'SciPostPhysLectNotes':
         return 'SciPost Phys. Lect. Notes'
+    elif journal_name == 'SciPostPhysProc':
+        return 'SciPost Phys. Proc.'
     else:
         raise JournalNameError(journal_name)
 
diff --git a/requirements.txt b/requirements.txt
index ba25dba1447cf01d84a54298194168b368fbd502..8a82ef7057d72bccf77dc2a8d9aeec140e2861bf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,6 +17,7 @@ django-webpack-loader==0.4.1
 djangorestframework==3.5.3
 docutils==0.12
 factory-boy==2.7.0
+Faker==0.7.11
 fake-factory==0.7.2
 feedparser==5.2.1
 imagesize==0.7.1
diff --git a/scipost/factories.py b/scipost/factories.py
index 7381d6173165155478253327f9aacac1665129c7..a10f06c567ecc6caab4e3ce5b65802f4da100b88 100644
--- a/scipost/factories.py
+++ b/scipost/factories.py
@@ -4,16 +4,16 @@ import random
 from django.contrib.auth import get_user_model
 from django.contrib.auth.models import Group
 
-from django_countries.data import COUNTRIES
+from submissions.models import Submission
 
-from .models import Contributor, EditorialCollege, EditorialCollegeFellowship
+from .models import Contributor, EditorialCollege, EditorialCollegeFellowship, Remark
 from .constants import TITLE_CHOICES
 
+from django_countries.data import COUNTRIES
+from faker import Faker
 
-class ContributorFactory(factory.django.DjangoModelFactory):
-    class Meta:
-        model = Contributor
 
+class ContributorFactory(factory.django.DjangoModelFactory):
     title = random.choice(list(dict(TITLE_CHOICES).keys()))
     user = factory.SubFactory('scipost.factories.UserFactory', contributor=None)
     status = 1  # normal user
@@ -22,6 +22,10 @@ class ContributorFactory(factory.django.DjangoModelFactory):
     country_of_employment = factory.Iterator(list(COUNTRIES))
     affiliation = factory.Faker('company')
 
+    class Meta:
+        model = Contributor
+        django_get_or_create = ('user',)
+
 
 class VettingEditorFactory(ContributorFactory):
     @factory.post_generation
@@ -32,9 +36,6 @@ class VettingEditorFactory(ContributorFactory):
 
 
 class UserFactory(factory.django.DjangoModelFactory):
-    class Meta:
-        model = get_user_model()
-
     username = factory.Faker('user_name')
     password = factory.PostGenerationMethodCall('set_password', 'adm1n')
     email = factory.Faker('safe_email')
@@ -44,6 +45,9 @@ class UserFactory(factory.django.DjangoModelFactory):
     # When user object is created, associate new Contributor object to it.
     contributor = factory.RelatedFactory(ContributorFactory, 'user')
 
+    class Meta:
+        model = get_user_model()
+
     @factory.post_generation
     def groups(self, create, extracted, **kwargs):
         # If the object is not saved, we cannot use many-to-many relationship.
@@ -58,17 +62,27 @@ class UserFactory(factory.django.DjangoModelFactory):
 
 
 class EditorialCollegeFactory(factory.django.DjangoModelFactory):
+    discipline = random.choice(['Physics', 'Chemistry', 'Medicine'])
+
     class Meta:
         model = EditorialCollege
         django_get_or_create = ('discipline', )
 
-    discipline = random.choice(['Physics', 'Chemistry', 'Medicine'])
-
 
 class EditorialCollegeFellowshipFactory(factory.django.DjangoModelFactory):
-    class Meta:
-        model = EditorialCollegeFellowship
-
     college = factory.Iterator(EditorialCollege.objects.all())
     contributor = factory.Iterator(Contributor.objects.exclude(
                                    user__username='deleted').order_by('?'))
+
+    class Meta:
+        model = EditorialCollegeFellowship
+
+
+class SubmissionRemarkFactory(factory.django.DjangoModelFactory):
+    contributor = factory.Iterator(Contributor.objects.all())
+    submission = factory.Iterator(Submission.objects.all())
+    date = factory.Faker('date_time_this_decade')
+    remark = factory.lazy_attribute(lambda x: Faker().paragraph())
+
+    class Meta:
+        model = Remark
diff --git a/scipost/management/commands/populate_db.py b/scipost/management/commands/populate_db.py
index 4880a671c3f06ff63e924fa0ffdb591a89638e89..a8561b693908642e3534433312ad4616b6eb3332 100644
--- a/scipost/management/commands/populate_db.py
+++ b/scipost/management/commands/populate_db.py
@@ -1,8 +1,16 @@
 from django.core.management.base import BaseCommand
 
+from commentaries.factories import VettedCommentaryFactory
+from comments.factories import CommentaryCommentFactory, SubmissionCommentFactory,\
+                               ThesislinkCommentFactory
+from scipost.factories import SubmissionRemarkFactory
+from journals.factories import JournalFactory, IssueFactory, PublicationFactory
 from news.factories import NewsItemFactory
+from submissions.factories import EICassignedSubmissionFactory
+from theses.factories import VettedThesisLinkFactory
 
-from ...factories import ContributorFactory, EditorialCollegeFactory, EditorialCollegeFellowshipFactory
+from ...factories import ContributorFactory, EditorialCollegeFactory,\
+                         EditorialCollegeFellowshipFactory
 
 
 class Command(BaseCommand):
@@ -14,19 +22,68 @@ class Command(BaseCommand):
             default=False,
             help='Add NewsItems',
         )
+        parser.add_argument(
+            '--commentaries',
+            action='store_true',
+            dest='commentaries',
+            default=False,
+            help='Add 5 Commentaries',
+        )
+        parser.add_argument(
+            '--comments',
+            action='store_true',
+            dest='comments',
+            default=False,
+            help='Add 10 Comments',
+        )
         parser.add_argument(
             '--contributor',
             action='store_true',
             dest='contributor',
             default=False,
-            help='Add Contributors',
+            help='Add 5 Contributors',
         )
         parser.add_argument(
             '--college',
             action='store_true',
             dest='editorial-college',
             default=False,
-            help='Add Editorial College and Fellows (Contributors required)',
+            help='Add 5 Editorial College and Fellows (Contributors required)',
+        )
+        parser.add_argument(
+            '--issues',
+            action='store_true',
+            dest='issues',
+            default=False,
+            help='Add 5 sets of {Journal, Volume and Issue}',
+        )
+        parser.add_argument(
+            '--submissions',
+            action='store_true',
+            dest='submissions',
+            default=False,
+            help='Add 5 new submissions status EIC assigned',
+        )
+        parser.add_argument(
+            '--publications',
+            action='store_true',
+            dest='publications',
+            default=False,
+            help='Add 5 Publications (includes --issues action)',
+        )
+        parser.add_argument(
+            '--remarks',
+            action='store_true',
+            dest='remarks',
+            default=False,
+            help='Add 5 new Remarks linked to Submissions',
+        )
+        parser.add_argument(
+            '--theses',
+            action='store_true',
+            dest='theses',
+            default=False,
+            help='Add 5 ThesisLinks',
         )
         parser.add_argument(
             '--all',
@@ -39,24 +96,70 @@ class Command(BaseCommand):
     def handle(self, *args, **kwargs):
         if kwargs['contributor'] or kwargs['all']:
             self.create_contributors()
+        if kwargs['commentaries'] or kwargs['all']:
+            self.create_commentaries()
+        if kwargs['comments'] or kwargs['all']:
+            self.create_comments()
         if kwargs['editorial-college'] or kwargs['all']:
             self.create_editorial_college()
             self.create_editorial_college_fellows()
         if kwargs['news'] or kwargs['all']:
             self.create_news_items()
+        if kwargs['submissions'] or kwargs['all']:
+            self.create_submissions()
+        if kwargs['issues'] or kwargs['all']:
+            self.create_issues()
+        if kwargs['publications'] or kwargs['all']:
+            self.create_publications()
+        if kwargs['remarks'] or kwargs['all']:
+            self.create_remarks()
+        if kwargs['theses'] or kwargs['all']:
+            self.create_theses()
 
     def create_contributors(self):
         ContributorFactory.create_batch(5)
-        self.stdout.write(self.style.SUCCESS('Successfully created Contributors.'))
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 Contributors.'))
+
+    def create_commentaries(self):
+        VettedCommentaryFactory.create_batch(5)
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 Commentaries.'))
+
+    def create_comments(self):
+        CommentaryCommentFactory.create_batch(3)
+        SubmissionCommentFactory.create_batch(4)
+        ThesislinkCommentFactory.create_batch(3)
+        self.stdout.write(self.style.SUCCESS('Successfully created 10 Comments.'))
 
     def create_editorial_college(self):
         EditorialCollegeFactory.create_batch(5)
-        self.stdout.write(self.style.SUCCESS('Successfully created Editorial College\'s.'))
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 Editorial College\'s.'))
 
     def create_editorial_college_fellows(self):
         EditorialCollegeFellowshipFactory.create_batch(5)
-        self.stdout.write(self.style.SUCCESS('Successfully created Editorial College Fellows.'))
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 Editorial College Fellows.'))
 
     def create_news_items(self):
         NewsItemFactory.create_batch(5)
-        self.stdout.write(self.style.SUCCESS('Successfully created News items.'))
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 News items.'))
+
+    def create_submissions(self):
+        EICassignedSubmissionFactory.create_batch(5)
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 Submissions.'))
+
+    def create_issues(self):
+        IssueFactory.create_batch(5)
+        self.stdout.write(self.style.SUCCESS(
+                          'Successfully created 5x {Journal, Volume and Issue}.'))
+
+    def create_publications(self):
+        JournalFactory.create_batch(4)
+        PublicationFactory.create_batch(5)
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 Publications.'))
+
+    def create_remarks(self):
+        SubmissionRemarkFactory.create_batch(5)
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 Remarks.'))
+
+    def create_theses(self):
+        VettedThesisLinkFactory.create_batch(5)
+        self.stdout.write(self.style.SUCCESS('Successfully created 5 ThesisLinks.'))
diff --git a/submissions/constants.py b/submissions/constants.py
index d937973d28acfbcd1e85fce61eb2ba14c0c928de..da15bf7acf1a8dbe0bcf274b62e3e41d00513f2a 100644
--- a/submissions/constants.py
+++ b/submissions/constants.py
@@ -4,6 +4,8 @@ STATUS_REVISION_REQUESTED = 'revision_requested'
 STATUS_EIC_ASSIGNED = 'EICassigned'
 STATUS_AWAITING_ED_REC = 'awaiting_ed_rec'
 STATUS_REVIEW_CLOSED = 'review_closed'
+STATUS_ACCEPTED = 'accepted'
+STATUS_PUBLISHED = 'published'
 SUBMISSION_STATUS = (
     (STATUS_UNASSIGNED, 'Unassigned, undergoing pre-screening'),
     (STATUS_RESUBMISSION_INCOMING, 'Resubmission incoming'),
@@ -21,10 +23,10 @@ SUBMISSION_STATUS = (
     ('put_to_EC_voting', 'Undergoing voting at the Editorial College'),
     (STATUS_AWAITING_ED_REC, 'Awaiting Editorial Recommendation'),
     ('EC_vote_completed', 'Editorial College voting rounded up'),
-    ('accepted', 'Publication decision taken: accept'),
+    (STATUS_ACCEPTED, 'Publication decision taken: accept'),
     ('rejected', 'Publication decision taken: reject'),
     ('rejected_visible', 'Publication decision taken: reject (still publicly visible)'),
-    ('published', 'Published'),
+    (STATUS_PUBLISHED, 'Published'),
     # If withdrawn:
     ('withdrawn', 'Withdrawn by the Authors'),
 )
diff --git a/submissions/factories.py b/submissions/factories.py
index d67299983ce9f4c0221e1dc9d05018289950e8b2..f69a50ec0207ff86b544d8af501ecab264df8e44 100644
--- a/submissions/factories.py
+++ b/submissions/factories.py
@@ -1,12 +1,20 @@
 import factory
+import datetime
+import pytz
+
+from django.utils import timezone
 
 from scipost.factories import ContributorFactory
-from journals.constants import SCIPOST_JOURNAL_PHYSICS
-from common.helpers import random_arxiv_identifier_with_version_number
+from scipost.models import Contributor
+from journals.constants import SCIPOST_JOURNALS_DOMAINS
+from common.helpers import random_arxiv_identifier_without_version_number, random_scipost_journal
 
-from .constants import STATUS_UNASSIGNED, STATUS_EIC_ASSIGNED, STATUS_RESUBMISSION_INCOMING
+from .constants import STATUS_UNASSIGNED, STATUS_EIC_ASSIGNED, STATUS_RESUBMISSION_INCOMING,\
+                       STATUS_PUBLISHED
 from .models import Submission
 
+from faker import Faker
+
 
 class SubmissionFactory(factory.django.DjangoModelFactory):
     class Meta:
@@ -14,18 +22,53 @@ class SubmissionFactory(factory.django.DjangoModelFactory):
 
     author_list = factory.Faker('name')
     submitted_by = factory.SubFactory(ContributorFactory)
-    submitted_to_journal = SCIPOST_JOURNAL_PHYSICS
-    title = factory.Faker('bs')
-    abstract = factory.Faker('text')
+    submitted_to_journal = factory.Sequence(lambda n: random_scipost_journal())
+    title = factory.lazy_attribute(lambda x: Faker().sentence())
+    abstract = factory.lazy_attribute(lambda x: Faker().paragraph())
     arxiv_link = factory.Faker('uri')
-    arxiv_identifier_w_vn_nr = factory.Sequence(lambda n: random_arxiv_identifier_with_version_number())
-    domain = 'E'
+    arxiv_identifier_wo_vn_nr = factory.Sequence(
+                                    lambda n: random_arxiv_identifier_without_version_number())
+    domain = SCIPOST_JOURNALS_DOMAINS[0][0]
+    abstract = Faker().paragraph()
+    author_comments = Faker().paragraph()
+    remarks_for_editors = Faker().paragraph()
+    submission_type = 'Letter'
+
+    @factory.post_generation
+    def fill_arxiv_fields(self, create, extracted, **kwargs):
+        '''Fill empty arxiv fields.'''
+        self.arxiv_link = 'https://arxiv.org/abs/%s' % self.arxiv_identifier_wo_vn_nr
+        self.arxiv_identifier_w_vn_nr = '%sv1' % self.arxiv_identifier_wo_vn_nr
+        self.arxiv_vn_nr = 1
+
+    @factory.post_generation
+    def contributors(self, create, extracted, **kwargs):
+        contributors = list(Contributor.objects.order_by('?')
+                            .exclude(pk=self.submitted_by.pk).all()[:4])
+        if not create:
+            return
+        self.editor_in_charge = contributors.pop()
+        for contrib in contributors:
+            self.authors.add(contrib)
+            self.author_list += ', %s %s' % (contrib.user.first_name, contrib.user.last_name)
+
+    @factory.post_generation
+    def dates(self, create, extracted, **kwargs):
+        timezone.now()
+        self.submission_date = Faker().date_time_between(start_date="-3y", end_date="now",
+                                                         tzinfo=pytz.UTC)
+        self.latest_activity = Faker().date_time_between(start_date=self.submission_date,
+                                                         end_date="now", tzinfo=pytz.UTC)
 
 
 class EICassignedSubmissionFactory(SubmissionFactory):
     status = STATUS_EIC_ASSIGNED
-    editor_in_charge = factory.SubFactory(ContributorFactory)
     open_for_commenting = True
+    open_for_reporting = True
+
+    @factory.post_generation
+    def report_dates(self, create, extracted, **kwargs):
+        self.reporting_deadline = self.latest_activity + datetime.timedelta(weeks=2)
 
 
 class UnassignedSubmissionFactory(SubmissionFactory):
@@ -34,4 +77,10 @@ class UnassignedSubmissionFactory(SubmissionFactory):
 
 class ResubmittedScreeningSubmissionFactory(SubmissionFactory):
     status = STATUS_RESUBMISSION_INCOMING
-    editor_in_charge = factory.SubFactory(ContributorFactory)
+
+
+class PublishedSubmissionFactory(SubmissionFactory):
+    status = STATUS_PUBLISHED
+    open_for_commenting = False
+    open_for_reporting = False
+    is_current = True
diff --git a/theses/factories.py b/theses/factories.py
index fe9091788560fdc69f34f7b65519f0d0772157b9..76bf49969a745b620acbf464707235056f985e73 100644
--- a/theses/factories.py
+++ b/theses/factories.py
@@ -1,11 +1,19 @@
 import factory
 
+from django.utils import timezone
+
 from common.helpers.factories import FormFactory
+from journals.constants import SCIPOST_JOURNALS_DOMAINS
+from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS
 from scipost.factories import ContributorFactory
 
 from .models import ThesisLink
 from .forms import VetThesisLinkForm
-from .constants import MASTER_THESIS
+from .constants import THESIS_TYPES
+
+from faker import Faker
+
+timezone.now()
 
 
 class ThesisLinkFactory(factory.django.DjangoModelFactory):
@@ -13,15 +21,17 @@ class ThesisLinkFactory(factory.django.DjangoModelFactory):
         model = ThesisLink
 
     requested_by = factory.SubFactory(ContributorFactory)
-    type = MASTER_THESIS
-    title = factory.Faker('bs')
+    type = factory.Iterator(THESIS_TYPES, getter=lambda c: c[0])
+    domain = factory.Iterator(SCIPOST_JOURNALS_DOMAINS, getter=lambda c: c[0])
+    discipline = factory.Iterator(SCIPOST_DISCIPLINES, getter=lambda c: c[0])
+    subject_area = factory.Iterator(SCIPOST_SUBJECT_AREAS[0][1], getter=lambda c: c[0])
+    title = factory.Faker('text')
     pub_link = factory.Faker('uri')
     author = factory.Faker('name')
     supervisor = factory.Faker('name')
     institution = factory.Faker('company')
     defense_date = factory.Faker('date')
-    abstract = factory.Faker('text')
-    domain = 'ET'
+    abstract = factory.lazy_attribute(lambda x: Faker().paragraph())
 
 
 class VettedThesisLinkFactory(ThesisLinkFactory):