diff --git a/requirements.txt b/requirements.txt index c1c2113e..f7306ea3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ jsonfield django-tastypie==0.9.14 django-waffle==0.9.1 git+git://github.com/scieloorg/django-htmlmin.git -git+git://github.com/scieloorg/django-cache-machine.git#egg=django-cache-machine +-e git+git://github.com/scieloorg/django-cache-machine.git#egg=django-cache-machine git+git://github.com/scieloorg/packtools.git#egg=packtools Celery django-celery diff --git a/scielomanager/api/tests.py b/scielomanager/api/tests.py index 1b51223b..e9c82e4f 100644 --- a/scielomanager/api/tests.py +++ b/scielomanager/api/tests.py @@ -1236,6 +1236,7 @@ def test_api_v1_data_checkin(self): u'accepted_at', u'article', u'attempt_ref', + u'checked_out', u'created_at', u'expiration_at', u'id', @@ -1243,6 +1244,7 @@ def test_api_v1_data_checkin(self): u'rejected_at', u'rejected_cause', u'reviewed_at', + u'scielo_reviewed_at', u'resource_uri', u'status', u'uploaded_at' diff --git a/scielomanager/articletrack/admin.py b/scielomanager/articletrack/admin.py index 1944655b..e30cb226 100644 --- a/scielomanager/articletrack/admin.py +++ b/scielomanager/articletrack/admin.py @@ -22,7 +22,7 @@ def display_member(self, obj): class CheckinAdmin(admin.ModelAdmin): - list_display = ('package_name', 'attempt_ref', 'uploaded_at', 'created_at') + list_display = ('package_name', 'attempt_ref', 'uploaded_at', 'created_at', 'status',) search_fields = ('package_name',) readonly_fields = ('created_at',) diff --git a/scielomanager/articletrack/balaio.py b/scielomanager/articletrack/balaio.py index b004293b..8b3fd2dc 100644 --- a/scielomanager/articletrack/balaio.py +++ b/scielomanager/articletrack/balaio.py @@ -135,7 +135,7 @@ def is_up(self): """ try: return self.call('status') - except xmlrpclib.Error: + except Exception: # any exception, such as "CONNECTION REFUESED" means API is down return False def get_server(self, uri): diff --git a/scielomanager/articletrack/migrations/0012_auto__add_field_checkin_scielo_reviewed_by__add_field_checkin_scielo_r.py b/scielomanager/articletrack/migrations/0012_auto__add_field_checkin_scielo_reviewed_by__add_field_checkin_scielo_r.py new file mode 100644 index 00000000..74ff4af1 --- /dev/null +++ b/scielomanager/articletrack/migrations/0012_auto__add_field_checkin_scielo_reviewed_by__add_field_checkin_scielo_r.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Checkin.scielo_reviewed_by' + db.add_column('articletrack_checkin', 'scielo_reviewed_by', + self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='checkins_scielo_reviewed', null=True, to=orm['auth.User']), + keep_default=False) + + # Adding field 'Checkin.scielo_reviewed_at' + db.add_column('articletrack_checkin', 'scielo_reviewed_at', + self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Checkin.scielo_reviewed_by' + db.delete_column('articletrack_checkin', 'scielo_reviewed_by_id') + + # Deleting field 'Checkin.scielo_reviewed_at' + db.delete_column('articletrack_checkin', 'scielo_reviewed_at') + + + models = { + 'articletrack.article': { + 'Meta': {'object_name': 'Article'}, + 'article_title': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'articlepkg_ref': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'eissn': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '9'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issue_label': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'journal_title': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'journals': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'checkin_articles'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'pissn': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '9'}) + }, + 'articletrack.checkin': { + 'Meta': {'ordering': "['-created_at']", 'object_name': 'Checkin'}, + 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'accepted_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'checkins'", 'null': 'True', 'to': "orm['articletrack.Article']"}), + 'attempt_ref': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'expiration_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'package_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'rejected_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'rejected_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_rejected'", 'null': 'True', 'to': "orm['auth.User']"}), + 'rejected_cause': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'reviewed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'reviewed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_reviewed'", 'null': 'True', 'to': "orm['auth.User']"}), + 'scielo_reviewed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'scielo_reviewed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_scielo_reviewed'", 'null': 'True', 'to': "orm['auth.User']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '10'}), + 'submitted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_submitted_by'", 'null': 'True', 'to': "orm['auth.User']"}), + 'uploaded_at': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'articletrack.checkinworkflowlog': { + 'Meta': {'ordering': "['created_at']", 'object_name': 'CheckinWorkflowLog'}, + 'checkin': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'submission_log'", 'to': "orm['articletrack.Checkin']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '10'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkin_log_responsible'", 'null': 'True', 'to': "orm['auth.User']"}) + }, + 'articletrack.comment': { + 'Meta': {'ordering': "['created_at']", 'object_name': 'Comment'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments_author'", 'to': "orm['auth.User']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['articletrack.Ticket']"}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'articletrack.notice': { + 'Meta': {'ordering': "['-created_at']", 'object_name': 'Notice'}, + 'checkin': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notices'", 'to': "orm['articletrack.Checkin']"}), + 'checkpoint': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'stage': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '64'}) + }, + 'articletrack.team': { + 'Meta': {'object_name': 'Team'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'member': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'team'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}) + }, + 'articletrack.ticket': { + 'Meta': {'ordering': "['started_at']", 'object_name': 'Ticket'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': "orm['articletrack.Article']"}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': "orm['auth.User']"}), + 'finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'started_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'journalmanager.collection': { + 'Meta': {'ordering': "['name']", 'object_name': 'Collection'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'collection': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'user_collection'", 'to': "orm['auth.User']", 'through': "orm['journalmanager.UserCollections']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}), + 'name_slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.institution': { + 'Meta': {'ordering': "['name']", 'object_name': 'Institution'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'cel': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'complement': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.journal': { + 'Meta': {'ordering': "['title']", 'object_name': 'Journal'}, + 'abstract_keyword_languages': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'abstract_keyword_languages'", 'symmetrical': 'False', 'to': "orm['journalmanager.Language']"}), + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'through': "orm['journalmanager.Membership']", 'symmetrical': 'False'}), + 'copyrighter': ('django.db.models.fields.CharField', [], {'max_length': '254'}), + 'cover': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'enjoy_creator'", 'to': "orm['auth.User']"}), + 'ctrl_vocabulary': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'current_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'null': 'True', 'blank': 'True'}), + 'editor_address': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_address_city': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'editor_address_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'editor_address_state': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'editor_address_zip': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'editor_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'editor_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_phone1': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'editor_phone2': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'editorial_standard': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'editors': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'user_editors'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'eletronic_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'final_num': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'final_vol': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'final_year': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'frequency': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index_coverage': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'init_num': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'init_vol': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'init_year': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'is_indexed_aehci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_scie': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_ssci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'languages': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Language']", 'symmetrical': 'False'}), + 'logo': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'medline_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'medline_title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}), + 'national_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'notes': ('django.db.models.fields.TextField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}), + 'other_previous_title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'previous_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'null': 'True', 'blank': 'True'}), + 'previous_title': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'prev_title'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'print_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'pub_level': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publication_city': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publisher_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'publisher_name': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'publisher_state': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'scielo_issn': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'secs_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'short_title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'db_index': 'True'}), + 'sponsor': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'journal_sponsor'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['journalmanager.Sponsor']"}), + 'study_areas': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals_migration_tmp'", 'null': 'True', 'to': "orm['journalmanager.StudyArea']"}), + 'subject_categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals'", 'null': 'True', 'to': "orm['journalmanager.SubjectCategory']"}), + 'subject_descriptors': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'title_iso': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'twitter_user': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'url_journal': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'url_online_submission': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.UseLicense']"}) + }, + 'journalmanager.language': { + 'Meta': {'ordering': "['name']", 'object_name': 'Language'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iso_code': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}) + }, + 'journalmanager.membership': { + 'Meta': {'unique_together': "(('journal', 'collection'),)", 'object_name': 'Membership'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'reason': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'since': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'inprogress'", 'max_length': '16'}) + }, + 'journalmanager.sponsor': { + 'Meta': {'ordering': "['name']", 'object_name': 'Sponsor', '_ormbases': ['journalmanager.Institution']}, + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'symmetrical': 'False'}), + 'institution_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.Institution']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.studyarea': { + 'Meta': {'object_name': 'StudyArea'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'study_area': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.subjectcategory': { + 'Meta': {'object_name': 'SubjectCategory'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'term': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}) + }, + 'journalmanager.uselicense': { + 'Meta': {'ordering': "['license_code']", 'object_name': 'UseLicense'}, + 'disclaimer': ('django.db.models.fields.TextField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'license_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'reference_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.usercollections': { + 'Meta': {'unique_together': "(('user', 'collection'),)", 'object_name': 'UserCollections'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_manager': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + } + } + + complete_apps = ['articletrack'] \ No newline at end of file diff --git a/scielomanager/articletrack/migrations/0013_auto__add_field_checkin_checked_out.py b/scielomanager/articletrack/migrations/0013_auto__add_field_checkin_checked_out.py new file mode 100644 index 00000000..9061ffe3 --- /dev/null +++ b/scielomanager/articletrack/migrations/0013_auto__add_field_checkin_checked_out.py @@ -0,0 +1,292 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Checkin.checked_out' + db.add_column('articletrack_checkin', 'checked_out', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Checkin.checked_out' + db.delete_column('articletrack_checkin', 'checked_out') + + + models = { + 'articletrack.article': { + 'Meta': {'object_name': 'Article'}, + 'article_title': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'articlepkg_ref': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'eissn': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '9'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issue_label': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'journal_title': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'journals': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'checkin_articles'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'pissn': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '9'}) + }, + 'articletrack.checkin': { + 'Meta': {'ordering': "['-created_at']", 'object_name': 'Checkin'}, + 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'accepted_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'checkins'", 'null': 'True', 'to': "orm['articletrack.Article']"}), + 'attempt_ref': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'checked_out': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'expiration_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'package_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'rejected_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'rejected_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_rejected'", 'null': 'True', 'to': "orm['auth.User']"}), + 'rejected_cause': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'reviewed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'reviewed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_reviewed'", 'null': 'True', 'to': "orm['auth.User']"}), + 'scielo_reviewed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'scielo_reviewed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_scielo_reviewed'", 'null': 'True', 'to': "orm['auth.User']"}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '10'}), + 'submitted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkins_submitted_by'", 'null': 'True', 'to': "orm['auth.User']"}), + 'uploaded_at': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'articletrack.checkinworkflowlog': { + 'Meta': {'ordering': "['created_at']", 'object_name': 'CheckinWorkflowLog'}, + 'checkin': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'submission_log'", 'to': "orm['articletrack.Checkin']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'pending'", 'max_length': '10'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'checkin_log_responsible'", 'null': 'True', 'to': "orm['auth.User']"}) + }, + 'articletrack.comment': { + 'Meta': {'ordering': "['created_at']", 'object_name': 'Comment'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments_author'", 'to': "orm['auth.User']"}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'ticket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['articletrack.Ticket']"}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'articletrack.notice': { + 'Meta': {'ordering': "['-created_at']", 'object_name': 'Notice'}, + 'checkin': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notices'", 'to': "orm['articletrack.Checkin']"}), + 'checkpoint': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'stage': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '64'}) + }, + 'articletrack.team': { + 'Meta': {'object_name': 'Team'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'member': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'team'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}) + }, + 'articletrack.ticket': { + 'Meta': {'ordering': "['started_at']", 'object_name': 'Ticket'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': "orm['articletrack.Article']"}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tickets'", 'to': "orm['auth.User']"}), + 'finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'started_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'journalmanager.collection': { + 'Meta': {'ordering': "['name']", 'object_name': 'Collection'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'collection': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'user_collection'", 'to': "orm['auth.User']", 'through': "orm['journalmanager.UserCollections']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}), + 'name_slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.institution': { + 'Meta': {'ordering': "['name']", 'object_name': 'Institution'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'cel': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'complement': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.journal': { + 'Meta': {'ordering': "['title']", 'object_name': 'Journal'}, + 'abstract_keyword_languages': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'abstract_keyword_languages'", 'symmetrical': 'False', 'to': "orm['journalmanager.Language']"}), + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'through': "orm['journalmanager.Membership']", 'symmetrical': 'False'}), + 'copyrighter': ('django.db.models.fields.CharField', [], {'max_length': '254'}), + 'cover': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'enjoy_creator'", 'to': "orm['auth.User']"}), + 'ctrl_vocabulary': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'current_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'null': 'True', 'blank': 'True'}), + 'editor_address': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_address_city': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'editor_address_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'editor_address_state': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'editor_address_zip': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'editor_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'editor_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_phone1': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'editor_phone2': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'editorial_standard': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'editors': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'user_editors'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'eletronic_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'final_num': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'final_vol': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'final_year': ('django.db.models.fields.CharField', [], {'max_length': '4', 'null': 'True', 'blank': 'True'}), + 'frequency': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index_coverage': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'init_num': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'init_vol': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'init_year': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'is_indexed_aehci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_scie': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_ssci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'languages': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Language']", 'symmetrical': 'False'}), + 'logo': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'medline_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'medline_title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}), + 'national_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'notes': ('django.db.models.fields.TextField', [], {'max_length': '254', 'null': 'True', 'blank': 'True'}), + 'other_previous_title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), + 'previous_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'null': 'True', 'blank': 'True'}), + 'previous_title': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'prev_title'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'print_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'pub_level': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publication_city': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publisher_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'publisher_name': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'publisher_state': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'scielo_issn': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'secs_code': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'short_title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'db_index': 'True'}), + 'sponsor': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'journal_sponsor'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['journalmanager.Sponsor']"}), + 'study_areas': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals_migration_tmp'", 'null': 'True', 'to': "orm['journalmanager.StudyArea']"}), + 'subject_categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals'", 'null': 'True', 'to': "orm['journalmanager.SubjectCategory']"}), + 'subject_descriptors': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'title_iso': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'twitter_user': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'url_journal': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'url_online_submission': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.UseLicense']"}) + }, + 'journalmanager.language': { + 'Meta': {'ordering': "['name']", 'object_name': 'Language'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iso_code': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}) + }, + 'journalmanager.membership': { + 'Meta': {'unique_together': "(('journal', 'collection'),)", 'object_name': 'Membership'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'reason': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'since': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'inprogress'", 'max_length': '16'}) + }, + 'journalmanager.sponsor': { + 'Meta': {'ordering': "['name']", 'object_name': 'Sponsor', '_ormbases': ['journalmanager.Institution']}, + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'symmetrical': 'False'}), + 'institution_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.Institution']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.studyarea': { + 'Meta': {'object_name': 'StudyArea'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'study_area': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.subjectcategory': { + 'Meta': {'object_name': 'SubjectCategory'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'term': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}) + }, + 'journalmanager.uselicense': { + 'Meta': {'ordering': "['license_code']", 'object_name': 'UseLicense'}, + 'disclaimer': ('django.db.models.fields.TextField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'license_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'reference_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.usercollections': { + 'Meta': {'unique_together': "(('user', 'collection'),)", 'object_name': 'UserCollections'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_manager': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + } + } + + complete_apps = ['articletrack'] \ No newline at end of file diff --git a/scielomanager/articletrack/models.py b/scielomanager/articletrack/models.py index ef19697b..f561a6b0 100644 --- a/scielomanager/articletrack/models.py +++ b/scielomanager/articletrack/models.py @@ -2,14 +2,13 @@ import caching.base import datetime import logging -from collections import deque from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.models import User -from django.core.exceptions import SuspiciousOperation, ValidationError +from django.core.exceptions import ValidationError from django.conf import settings from articletrack import modelmanagers @@ -22,10 +21,12 @@ MSG_WORKFLOW_ACCEPTED = 'Checkin Accepted' MSG_WORKFLOW_REJECTED = 'Checkin Rejected' -MSG_WORKFLOW_REVIEWED = 'Checkin Reviewed' +MSG_WORKFLOW_REVIEWED_QAL1 = 'Checkin Reviewed - Level 1' +MSG_WORKFLOW_REVIEWED_QAL2 = 'Checkin Reviewed - Level 2 (SciELO)' MSG_WORKFLOW_SENT_TO_PENDING = 'Checkin Sent to Pending' MSG_WORKFLOW_SENT_TO_REVIEW = 'Checkin Sent to Review' MSG_WORKFLOW_EXPIRED = 'Checkin Expired' +MSG_WORKFLOW_CHECKED_OUT = 'Checkin Checked Out' class Team(caching.base.CachingMixin, models.Model): @@ -106,9 +107,12 @@ class Checkin(caching.base.CachingMixin, models.Model): accepted_by = models.ForeignKey(User, null=True, blank=True) accepted_at = models.DateTimeField(null=True, blank=True) - + # QAL1 reviewed_by = models.ForeignKey(User, related_name='checkins_reviewed', null=True, blank=True) reviewed_at = models.DateTimeField(null=True, blank=True) + # QAL2 + scielo_reviewed_by = models.ForeignKey(User, related_name='checkins_scielo_reviewed', null=True, blank=True) + scielo_reviewed_at = models.DateTimeField(null=True, blank=True) rejected_by = models.ForeignKey(User, related_name='checkins_rejected', null=True, blank=True) rejected_at = models.DateTimeField(null=True, blank=True) @@ -118,6 +122,8 @@ class Checkin(caching.base.CachingMixin, models.Model): expiration_at = models.DateTimeField(_(u'Expiration Date'), null=True, blank=True) + checked_out = models.BooleanField(_(u'Checked Out'), default=False) + class Meta: ordering = ['-created_at'] permissions = (("list_checkin", "Can list Checkin"),) @@ -141,19 +147,13 @@ def team_members(self): @property def is_serv_status_completed(self): """ - If: - the count of SERV_END < SERVICE_STATUS_MAX_STAGES, or - the count of SERV_BEGIN < SERVICE_STATUS_MAX_STAGES - then: - the checkin's notices sequence is UNCOMPLETED (possible more notices will arrive) - -> Return False + If the checkin's notices sequence is UNCOMPLETED (probably more notices will arrive) + Return False Else: - if the count of SERV_* is equal to 2 * SERVICE_STATUS_MAX_STAGES, then - call the ``misc.validate_sequence`` function - to check if the checkin's notices sequence is COMPLETED - -> Return True + if the quantity of SERV_* is ok then + Return the result of validate the order of SERV_. else: - -> Return False + Return False """ count_serv_end_notices = self.notices.filter(status__iexact="SERV_END").count() count_serv_begin_notices = self.notices.filter(status__iexact="SERV_BEGIN").count() @@ -212,14 +212,31 @@ def is_accepted(self): return self.status == 'accepted' and bool(self.accepted_by and self.accepted_at) @property - def is_reviewed(self): + def is_level1_reviewed(self): + """ + Checks if this checkin has been reviewed by a QAL1 user + + The condicional is ``status = review`` and has been ``reviewed_by`` and + has any date in ``reviewed_at`` + """ + return bool(self.reviewed_by and self.reviewed_at) + + @property + def is_level2_reviewed(self): + """ + Checks if this checkin has been reviewed by a QAL2 user + + The condicional is ``status = review`` and has been ``scielo_reviewed_by`` and + has any date in ``reviewed_at`` """ - Checks if this checkin has been reviewed + return bool(self.scielo_reviewed_by and self.scielo_reviewed_at) - The condicional is ``status = review`` and has been reviewed_by and - has any date in reviewed_at + @property + def is_full_reviewed(self): """ - return self.status == 'review' and bool(self.reviewed_by and self.reviewed_at) + Checks if this checkin has been reviewed by both user's roles: QAL1 and QAL2 + """ + return self.status == 'review' and self.is_level1_reviewed and self.is_level2_reviewed @property def is_rejected(self): @@ -237,7 +254,7 @@ def can_be_send_to_pending(self): Return True if this checkin have status ``rejected`` does not exist another checkin accepted for the related article. """ - return self.status == 'rejected' and not self.article.is_accepted() + return self.status == 'rejected' @property def can_be_send_to_review(self): @@ -246,7 +263,7 @@ def can_be_send_to_review(self): Return True if this checkin have status ``pending`` and have no errors and does not exist another checkin accepted for the related article. """ - return self.status == 'pending' and self.get_error_level != 'error' and not self.article.is_accepted() + return self.status == 'pending' and self.get_error_level in ['ok', 'warning'] @property def can_be_reviewed(self): @@ -255,16 +272,22 @@ def can_be_reviewed(self): Return True if this checkin is in status ``pending`` and have no errors and does not exist another checkin accepted for the related article. """ - return self.status == 'review' and self.get_error_level != 'error' and not self.article.is_accepted() + return self.status == 'review' and self.get_error_level in ['ok', 'warning'] @property def can_be_accepted(self): """ Check the conditions to enable the process of 'accept' action. - Return True if this checkin is in status ``review`` and self.is_reviewed == True and - does not exist another checkin accepted for the related article. + Return True if this checkin has been reviwed by both (scielo and non scielo parts). """ - return self.status == 'review' and self.is_reviewed and not self.article.is_accepted() + return self.is_full_reviewed + + @property + def can_be_send_to_checkout(self): + """ + Only if status == 'accepted' and self.checked_out == False + """ + return self.status == 'accepted' and not self.checked_out @property def can_be_rejected(self): @@ -274,108 +297,171 @@ def can_be_rejected(self): """ return self.status == 'review' + # ########### # + # VALIDATIONS # + # ########### # + + def _do_basic_validation(self, responsible, action): + """ + Do some general validations required to modify a checkin. + Return a tuple: + - (True, None) if validation is successful + - (False, "Error message") if not. + + Will not be valid when: + - exist any accepted article already, or + - the user `responsible` is not active or + - the user `responsible` dont belong to the corresponding auth.group (depends on `action`) + :param responsible: instance of django.contrib.auth.User + :param action: could be: + ['accept', 'reject', 'review_l1', 'review_l2', 'send_to_review', 'send_to_pending'] + """ + if not responsible.is_active: + return (False, 'User must be active') + + profile = responsible.get_profile() + + if action == 'accept' and not profile.can_accept_checkins: + return (False, 'User can\'t ACCEPT checkins, because doesn\'t have enough permissions') + elif action == 'reject' and not profile.can_reject_checkins: + return (False, 'User can\'t REJECT checkins, because doesn\'t have enough permissions') + elif action == 'review_l1' and not profile.can_review_l1_checkins: + return (False, 'User can\'t REVIEW (Level 1) checkins, because doesn\'t have enough permissions') + elif action == 'review_l2' and not profile.can_review_l2_checkins: + return (False, 'User can\'t REVIEW (Level 2) checkins, because doesn\'t have enough permissions') + elif action == 'send_to_review' and not profile.can_send_checkins_to_review: + return (False, 'User can\'t SEND checkins TO REVIEW, because doesn\'t have enough permissions') + elif action == 'send_to_pending' and not profile.can_send_checkins_to_pending: + return (False, 'User can\'t SEND checkins TO PENDING, because doesn\'t have enough permissions') + + if self.article.is_accepted(): + return (False, 'Can\'t accept more than one checkin per article') + + return (True, None) + + def _do_review_validation(self, responsible, action): + """ + Do some validations required to do a checkin review. + Return a tuple: + - (True, None) if validation is successful + - (False, "Error message") if not: + + if the user `responsible` is not active or if exist any accepted article already, or + :param responsible: instance of django.contrib.auth.User + :param action: could be: + ['review_l1', 'review_l2'] + """ + + if not self.can_be_reviewed: + return (False, 'This checkin does not comply with the conditions to be reviewed') + + return self._do_basic_validation(responsible, action) + + # ####### # + # ACTIONS # + # ####### # + @log_workflow_status(MSG_WORKFLOW_ACCEPTED) def accept(self, responsible): """ Accept the checkin as ready to be part of the collection. Change status of this checkin from 'review' to 'accepted'. - Raises ValueError if self relates to an already accepted article or - if the user `responsible` is not active or if exist any accepted article already. + Raises ValueError if don't comply with required validations. :param responsible: instance of django.contrib.auth.User """ - if not responsible.is_active: - raise ValueError('User must be active') + is_valid, errors = self._do_basic_validation(responsible, 'accept') - if self.article.is_accepted(): - raise ValueError('Cannot accept more than one checkin per article') + if not is_valid: + raise ValueError(errors) elif self.can_be_accepted: self.accepted_by = responsible self.accepted_at = datetime.datetime.now() self.status = 'accepted' self.save() else: - raise ValueError('This checkin does not comply with the conditions to be accepted') + raise ValueError('This checkin do not comply with the conditions to be accepted') @log_workflow_status(MSG_WORKFLOW_SENT_TO_PENDING) def send_to_pending(self, responsible): """ - Send to pending list: change the status to 'pending' if self.can_be_send_to_pending == True else raise - ValueError. + Send to pending list (change the status to 'pending'). - Raises ValueError if self relates to an already accepted article or - if the user `responsible` is not active or if exist any accepted article already. + Raises ValueError if don't comply with required validations. :param responsible: instance of django.contrib.auth.User """ - if not responsible.is_active: - raise ValueError('User must be active') - - if self.article.is_accepted(): - raise ValueError('Cannot accept more than one checkin per article') + is_valid, errors = self._do_basic_validation(responsible, 'send_to_pending') + if not is_valid: + raise ValueError(errors) elif self.can_be_send_to_pending: self.status = 'pending' self.save() else: - raise ValueError('This checkin does not comply with the conditions to change status to "review"') + raise ValueError('This checkin do not comply with the conditions to be moved to pending list') @log_workflow_status(MSG_WORKFLOW_SENT_TO_REVIEW) def send_to_review(self, responsible): """ - Send to review list: change the status to review if self.can_be_send_to_review == True else raise - ValueError. + Send to review list (change the status to 'review') - Raises ValueError if self relates to an already accepted article or - if the user `responsible` is not active or if exist any accepted article already. + Raises ValueError if don't comply with required validations. :param responsible: instance of django.contrib.auth.User """ - if not responsible.is_active: - raise ValueError('User must be active') - - if self.article.is_accepted(): - raise ValueError('Cannot accept more than one checkin per article') + is_valid, errors = self._do_basic_validation(responsible, 'send_to_review') + if not is_valid: + raise ValueError(errors) elif self.can_be_send_to_review: self.status = 'review' self.save() else: - raise ValueError('This checkin does not comply with the conditions to change status to "review"') + raise ValueError('This checkin does not comply with the conditions to be moved to review list') - @log_workflow_status(MSG_WORKFLOW_REVIEWED) - def do_review(self, responsible): + @log_workflow_status(MSG_WORKFLOW_REVIEWED_QAL1) + def do_review_by_level_1(self, responsible): """ - Checkin with status review, are filled with review information (saves reviewer and revisition data) + Checkin with status review, are filled with review information (reviewed_by and reviewed_at) - Raises ValueError if self relates to an already accepted article or - if the user `responsible` is not active or if exist any accepted article already. + Raises ValueError if don't comply with required validations. :param responsible: instance of django.contrib.auth.User """ - if not responsible.is_active: - raise ValueError('User must be active') - - if self.article.is_accepted(): - raise ValueError('Cannot accept more than one checkin per article') - elif self.can_be_reviewed: + is_valid, errors = self._do_review_validation(responsible, 'review_l1') + if is_valid: self.status = 'review' self.reviewed_by = responsible self.reviewed_at = datetime.datetime.now() self.save() else: - raise ValueError('This checkin does not comply with the conditions to be reviewed') + raise ValueError(errors) + + @log_workflow_status(MSG_WORKFLOW_REVIEWED_QAL2) + def do_review_by_level_2(self, responsible): + """ + Checkin with status review, are filled with review information (scielo_reviewed_by and scielo_reviewed_at) + + Raises ValueError if don't comply with required validations. + :param responsible: instance of django.contrib.auth.User + """ + is_valid, errors = self._do_review_validation(responsible, 'review_l2') + if is_valid: + self.status = 'review' + self.scielo_reviewed_by = responsible + self.scielo_reviewed_at = datetime.datetime.now() + self.save() + else: + raise ValueError(errors) @log_workflow_status(MSG_WORKFLOW_REJECTED) def do_reject(self, responsible, reason): """ - Checkins that can_be_rejected == True, is changed to status == 'rejected' - Must be saved the date, the responsible of the action and a reason of rejection. + Reject the checkin. (change the status to 'rejected') + If can be rejected must be saved the date, the responsible of the action and a reason of rejection. - Raises ValueError if self relates to an already accepted article or - if the user `responsible` is not active or if exist any accepted article already. + Raises ValueError if don't comply with required validations. :param responsible: instance of django.contrib.auth.User """ - if not responsible.is_active: - raise ValueError('User must be active') - - if self.article.is_accepted(): - raise ValueError('Cannot accept more than one checkin per article') + is_valid, errors = self._do_basic_validation(responsible, 'reject') + if not is_valid: + raise ValueError(errors) elif self.can_be_rejected: self.status = 'rejected' self.rejected_by = responsible @@ -383,7 +469,7 @@ def do_reject(self, responsible, reason): self.rejected_cause = reason self.save() else: - raise ValueError('This checkin does not comply with the conditions to change status to "rejected"') + raise ValueError('This checkin does not comply with the conditions to be rejected') @log_workflow_status(MSG_WORKFLOW_EXPIRED) def do_expires(self, responsible=None): @@ -397,12 +483,23 @@ def do_expires(self, responsible=None): self.expiration_at = datetime.datetime.now() self.save() + @log_workflow_status(MSG_WORKFLOW_CHECKED_OUT) + def do_mark_as_checked_out(self, responsible=None): + """ + This method will be call before successfully checked out via BalaioRPC api. + Will change to True self.checked_out field only with self.status == accepted. + """ + if self.can_be_send_to_checkout: + self.checked_out = True + self.save() + def clean(self): # validation for status "accepted" if self.status == 'accepted' and not bool(self.accepted_by and self.accepted_at and self.reviewed_by and self.reviewed_at): raise ValidationError('Checkin with "accepted" status must have filled: "accepted_by", \ "accepted_at", "reviewed_by" and "reviewed_at" fields.') + # validation for status "rejected" if self.status == 'rejected' and not bool(self.rejected_by and self.rejected_at and self.rejected_cause): raise ValidationError('Checkin with "rejected" status must have filled: "rejected_by", \ "rejected_at" and "reviewed_cause" fields.') @@ -418,6 +515,8 @@ def save(self, *args, **kwargs): # clear 'review' fields self.reviewed_by = None self.reviewed_at = None + self.scielo_reviewed_by = None + self.scielo_reviewed_at = None # clear 'accepted' fields self.accepted_by = None self.accepted_at = None @@ -441,6 +540,8 @@ def save(self, *args, **kwargs): # clear 'review' fields self.reviewed_by = None self.reviewed_at = None + self.scielo_reviewed_by = None + self.scielo_reviewed_at = None # clear 'accepted' fields self.accepted_by = None self.accepted_at = None diff --git a/scielomanager/articletrack/templates/articletrack/checkin_list.html b/scielomanager/articletrack/templates/articletrack/checkin_list.html index bdb51fee..0d0d6517 100644 --- a/scielomanager/articletrack/templates/articletrack/checkin_list.html +++ b/scielomanager/articletrack/templates/articletrack/checkin_list.html @@ -12,42 +12,61 @@
-{# PENDING LIST #} -{% with status="pending" icon_class="icon-time" list_title="Pending" checkins_collection=checkins_pending pagination_prefix="pending_page" filter_form=pending_filter_form %} - {% include "articletrack/includes/checkin_list_and_filterform.html" %} -{% endwith %} - -{# REJECTED LIST #} -{% with status="rejected" icon_class="icon-eye-close" list_title="Rejected" checkins_collection=checkins_rejected pagination_prefix="rejected_page" filter_form=rejected_filter_form %} - {% include "articletrack/includes/checkin_list_and_filterform.html" %} -{% endwith %} - -{# REVIEW LIST #} -{% with status="review" icon_class="icon-eye-open" list_title="Review" checkins_collection=checkins_review pagination_prefix="review_page" filter_form=review_filter_form %} - {% include "articletrack/includes/checkin_list_and_filterform.html" %} -{% endwith %} - -{# ACCEPTED LIST #} -{% with status="accepted" icon_class="icon-ok-circle" list_title="Accepted" checkins_collection=checkins_accepted pagination_prefix="accepted_page" filter_form=accepted_filter_form %} - {% include "articletrack/includes/checkin_list_and_filterform.html" %} -{% endwith %} + +- {% trans "This checkin is rejected by" %} + {% trans "This checkin was rejected by" %} {% with checkin.rejected_by as user %} {% include "articletrack/includes/gravatar_tooltip.html" %} {% endwith %} @@ -44,7 +44,7 @@
- {% trans "Before that date, the checkin will be unreachable." %} + {% trans "After that date, the checkin will be unreachable." %}