def handle_editorial_review_assignment( request, book, editors, access_key, due_date, user, email_text, attachment=None, ): obj, created = models.EditorialReviewAssignment.objects.get_or_create( management_editor=user, completed=None, book=book, defaults={'due': due_date}) if obj.editorial_board_access_key: obj.publishing_committee_access_key = access_key else: obj.editorial_board_access_key = access_key obj.save() message = ("A new Editorial Review Assignment for %s has been " "assigned to you by %s ." % (book.title, request.user.username)) for editor in editors: if not obj.editorial_board.filter(username=editor.username).exists(): notification = models.Task( assignee=editor, creator=request.user, text=message, workflow='editorial-review', editorial_review=obj, book=book, ) notification.save() obj.editorial_board.add(editor) obj.save() log.add_log_entry( book=book, user=user, kind='review', message='Editorial member %s %s assigned.' % (editor.first_name, editor.last_name), short_name='Editorial Review Assignment', ) else: messages.add_message( request, messages.WARNING, 'Editorial Review Assignment for user <%s> already exists. ' 'User might already exist in one of the ' 'selected committees' % editor.username) if created: book.editorial_review_assignments.add(obj) send_editorial_review_request(book, obj, email_text, user, attachment) return obj return obj
def notify_editors(book, message, editors, creator, workflow): for editor_details in editors: notification = core_models.Task( book=book, assignee=editor_details['editor'], creator=creator, text=message, workflow=workflow, ) notification.save()
def create_new_task(book, creator, assignee, text, workflow=None): task = models.Task( book=book, creator=creator, assignee=assignee, text=text, workflow=workflow, ) task.save() return task
async def _new_task(self, ctx: SlashContext, content: str, due_date: str, due_time: str = None, tags: str = None): """Create a new task.""" guild = data_manager.get_guild(ctx.guild) checks.does_user_have_permission(guild, ctx.author, 'create/edit tasks') if due_time: # Parse due time. due_time = datetime.strptime(due_time.upper(), TIME_FORMATS[guild.locale]).time() else: # Use default value. due_time = datetime.strptime(Tasks.DEFAULT_DUE_TIME, '%H:%M').time() due_date = dt_utils.string_to_date(due_date, guild.tz, DATE_FORMATS[guild.locale] + '/%Y') due_datetime = datetime.combine(due_date, due_time).replace(tzinfo=guild.tz) checks.has_datetime_passed(due_datetime, guild.tz) # Parse tags. team = await guild.get_user_team(self.bot, ctx) tags = team.parse_tags(tags) if tags is not None else [] # Create the task and add it to the team. new_task = models.Task(content, tags, due_datetime) team.add_task(new_task) # Send confirmation. embed = discord.Embed( title=constants.Emojis.CREATE.value + ' New task due by' ' __{due_date}__ __{due_time}__ created:'.format( due_date=dt_utils.date_to_relative_name( new_task.due_datetime.date(), guild.tz, guild.locale), due_time=new_task.due_datetime.strftime( TIME_FORMATS[guild.locale])), description=f'{new_task.content}\n', color=team.role.color).set_footer(text=team.role.name.upper()) if tags: embed.add_field(name=f'{constants.Emojis.TAGS.value} Tags:', value=f'{iter_utils.format_iter(new_task.tags)}') await ctx.send(embed=embed)
def revision(request, revision_id, submission_id): _revision = get_object_or_404( revision_models.Revision, pk=revision_id, book__owner=request.user, completed__isnull=True, ) book = get_object_or_404(models.Book, pk=submission_id, owner=request.user) form = forms.AuthorRevisionForm(instance=_revision) if request.POST: form = forms.AuthorRevisionForm(request.POST, instance=_revision) if form.is_valid(): _revision = form.save(commit=False) _revision.completed = timezone.now() _revision.save() _task = models.Task( book=_revision.book, creator=request.user, assignee=_revision.requestor, text='Revisions submitted for %s' % _revision.book.title, workflow=_revision.revision_type, ) _task.save() log.add_log_entry( book=book, user=request.user, kind='revisions', message='%s submitted revisions for %s' % ( request.user.profile.full_name(), _revision.book.title, ), short_name='Revisions submitted', ) messages.add_message( request, messages.SUCCESS, 'Revisions recorded, thanks.', ) return redirect(reverse('author_dashboard')) has_manuscript = False has_additional = False for ff in book.files.all(): if ff.kind == 'manuscript': has_manuscript = True elif ff.kind == 'additional': has_additional = True template = 'author/submission.html' context = { 'submission': book, 'revision': _revision, 'form': form, 'has_manuscript': has_manuscript, 'has_additional': has_additional, 'author_include': 'author/revision.html', } return render(request, template, context)
def proposal_revisions(request, proposal_id): proposal_form_id = core_models.Setting.objects.get( name='proposal_form').value proposal = get_object_or_404(submission_models.Proposal, pk=proposal_id, owner=request.user, status='revisions_required') notes = submission_models.ProposalNote.objects.filter(proposal=proposal) email_text = get_email_content(request=request, setting_name='proposal_revision_submit_ack', context={ 'sender': request.user, 'receiver': proposal.owner, 'proposal': proposal, 'press_name': core_models.Setting.objects.get( group__name='general', name='press_name', ).value }) overdue = False if proposal.revision_due_date.date() < datetime.today().date(): overdue = True proposal_form = manager_forms.GeneratedForm( form=core_models.ProposalForm.objects.get(pk=proposal.form.id)) default_fields = manager_forms.DefaultForm( initial={ 'title': proposal.title, 'author': proposal.author, 'subtitle': proposal.subtitle }) data = {} intial_data = {} if proposal.data: data = json.loads(proposal.data) for k, v in data.items(): intial_data[k] = v[0] proposal_form.initial = intial_data if request.POST: proposal_form = manager_forms.GeneratedForm( request.POST, request.FILES, form=core_models.ProposalForm.objects.get(pk=proposal.form.id), ) default_fields = manager_forms.DefaultForm(request.POST) if proposal_form.is_valid() and default_fields.is_valid(): messages.add_message( request, messages.SUCCESS, 'Revisions for Proposal %s submitted' % proposal.id) proposal_data_processing(request, proposal, proposal_form_id) proposal = submission_models.Proposal.objects.get( form=core_models.ProposalForm.objects.get(pk=proposal.form.id), owner=request.user, pk=proposal_id, ) history_proposal = submission_models.HistoryProposal.objects.create( proposal=proposal, title=proposal.title, author=proposal.author, subtitle=proposal.subtitle, date_submitted=proposal.date_submitted, form=proposal.form, data=proposal.data, date_review_started=proposal.date_review_started, review_form=proposal.review_form, requestor=proposal.requestor, revision_due_date=proposal.revision_due_date, date_accepted=proposal.date_accepted, book_type=proposal.book_type, status=proposal.status, owner=proposal.owner, user_edited=request.user, date_edited=timezone.now(), version=proposal.current_version) history_proposal.save() proposal.status = "revisions_submitted" defaults = default_fields.cleaned_data proposal.title = defaults.get("title") proposal.author = defaults.get("author") proposal.subtitle = defaults.get("subtitle") proposal_type = request.POST.get('proposal-type') proposal.current_version = proposal.current_version + 1 if proposal_type: proposal.book_type = proposal_type proposal.save() notification = core_models.Task( assignee=proposal.requestor, creator=request.user, text="Revisions for Proposal '%s' with id %s submitted" % (proposal.title, proposal.id), workflow='proposal', ) notification.save() update_email_text = smart_text(request.POST.get('email_text')) log.add_proposal_log_entry( proposal=proposal, user=request.user, kind='proposal', message=('Revisions for Proposal "%s %s" with id %s ' 'have been submitted.' % (proposal.title, proposal.subtitle, proposal.pk)), short_name='Proposal Revisions Submitted') core_logic.send_proposal_update( proposal, email_text=update_email_text, sender=request.user, receiver=proposal.requestor, ) notification.emailed = True notification.save() messages.add_message(request, messages.SUCCESS, 'Proposal %s submitted' % proposal.id) return redirect(reverse('user_dashboard')) template = "submission/start_proposal.html" context = { 'proposal_form': proposal_form, 'proposal': proposal, 'email_text': email_text, 'default_fields': default_fields, 'data': data, 'revise': True, 'notes': notes, 'overdue': overdue, 'core_proposal': core_models.ProposalForm.objects.get(pk=proposal_form_id), } return render(request, template, context)
def start_proposal(request): submit_proposals = core_models.Setting.objects.get( group__name='general', name='submit_proposals').value if not submit_proposals: return redirect(reverse('user_dashboard')) proposal_form_id = core_models.Setting.objects.get( name='proposal_form').value proposal_form = manager_forms.GeneratedForm( form=core_models.ProposalForm.objects.get(pk=proposal_form_id)) default_fields = manager_forms.DefaultForm() errors = False if request.method == 'POST' and 'book_submit' in request.POST: proposal_form = manager_forms.GeneratedForm( request.POST, request.FILES, form=core_models.ProposalForm.objects.get(pk=proposal_form_id)) default_fields = manager_forms.DefaultForm(request.POST) if proposal_form.is_valid() and default_fields.is_valid(): defaults = {field.name: field.value() for field in default_fields} proposal = submission_models.Proposal( form=core_models.ProposalForm.objects.get(pk=proposal_form_id), data=None, owner=request.user, **defaults) proposal_type = request.POST.get('proposal-type') if proposal_type: proposal.book_type = proposal_type proposal.save() proposal_data_processing(request, proposal, proposal_form_id) editors = User.objects.filter(profile__roles__slug='press-editor') message = ( "A new Proposal '%s' with id %s has been submitted by %s ." % (proposal.title, proposal.pk, request.user.username)) for _editor in editors: notification = core_models.Task( assignee=_editor, creator=request.user, text=message, workflow='proposal', ) notification.save() messages.add_message( request, messages.SUCCESS, 'Proposal %s submitted' % proposal.id, ) email_text = core_models.Setting.objects.get( group__name='email', name='proposal_submission_ack', ).value core_logic.send_proposal_submission_ack( proposal, email_text=email_text, owner=request.user, ) log.add_proposal_log_entry( proposal=proposal, user=request.user, kind='proposal', message='Proposal has been submitted by %s.' % request.user.profile.full_name(), short_name='Proposal Submitted') return redirect(reverse('user_dashboard', kwargs={})) else: errors = True proposal_form = manager_forms.GeneratedForm( request.POST, request.FILES, form=core_models.ProposalForm.objects.get(pk=proposal_form_id)) default_fields = manager_forms.DefaultForm(request.POST) elif request.method == 'POST' and 'incomplete' in request.POST: proposal_form = manager_forms.GeneratedNotRequiredForm( request.POST, request.FILES, form=core_models.ProposalForm.objects.get(pk=proposal_form_id)) default_fields = manager_forms.DefaultNotRequiredForm(request.POST) if proposal_form.is_valid() and default_fields.is_valid(): defaults = {field.name: field.value() for field in default_fields} proposal = submission_models.IncompleteProposal( form=core_models.ProposalForm.objects.get(pk=proposal_form_id), data=None, owner=request.user, **defaults) proposal_type = request.POST.get('proposal-type') if proposal_type: proposal.book_type = proposal_type proposal.save() proposal_data_processing(request, proposal, proposal_form_id) messages.add_message( request, messages.SUCCESS, 'Proposal %s saved' % proposal.id, ) return redirect(reverse('user_dashboard', kwargs={})) template = "submission/start_proposal.html" context = { 'proposal_form': proposal_form, 'errors': errors, 'default_fields': default_fields, 'core_proposal': core_models.ProposalForm.objects.get(pk=proposal_form_id), } return render(request, template, context)
def incomplete_proposal(request, proposal_id): proposal_form_id = core_models.Setting.objects.get( name='proposal_form').value proposal_form = manager_forms.GeneratedForm( form=core_models.ProposalForm.objects.get(pk=proposal_form_id)) _incomplete_journal = get_object_or_404( submission_models.IncompleteProposal, pk=proposal_id, ) proposal_form_validated = manager_forms.GeneratedForm( form=core_models.ProposalForm.objects.get(pk=proposal_form_id)) default_fields_validated = manager_forms.DefaultForm(initial={ 'title': _incomplete_journal.title, 'author': _incomplete_journal.author, 'subtitle': _incomplete_journal.subtitle }, ) default_fields = manager_forms.DefaultForm( initial={ 'title': _incomplete_journal.title, 'author': _incomplete_journal.author, 'subtitle': _incomplete_journal.subtitle }) intial_data = {} if _incomplete_journal.data: data = json.loads(_incomplete_journal.data) for k, v in data.items(): intial_data[k] = v[0] proposal_form.initial = intial_data proposal_form_validated.initial = intial_data if request.method == 'POST' and 'book_submit' in request.POST: proposal_form = manager_forms.GeneratedForm( request.POST, request.FILES, form=core_models.ProposalForm.objects.get(pk=proposal_form_id, )) default_fields = manager_forms.DefaultForm(request.POST) if proposal_form.is_valid() and default_fields.is_valid(): defaults = {field.name: field.value() for field in default_fields} proposal = submission_models.Proposal( form=core_models.ProposalForm.objects.get(pk=proposal_form_id), data=None, owner=request.user, **defaults) proposal_type = request.POST.get('proposal-type') if proposal_type: proposal.book_type = proposal_type proposal.save() proposal_data_processing(request, proposal, proposal_form_id) editors = User.objects.filter(profile__roles__slug='press-editor') message = ( "A new Proposal '%s' with id %s has been submitted by %s ." % (proposal.title, proposal.pk, request.user.username)) for _editor in editors: notification = core_models.Task( assignee=_editor, creator=request.user, text=message, workflow='proposal', ) notification.save() messages.add_message( request, messages.SUCCESS, 'Proposal %s submitted' % proposal.id, ) email_text = core_models.Setting.objects.get( group__name='email', name='proposal_submission_ack').value core_logic.send_proposal_submission_ack( proposal, email_text=email_text, owner=request.user, ) log.add_proposal_log_entry( proposal=proposal, user=request.user, kind='proposal', message='Proposal has been submitted by %s.' % request.user.profile.full_name(), short_name='Proposal Submitted', ) _incomplete_journal.delete() return redirect(reverse('user_dashboard', kwargs={})) else: proposal_form = manager_forms.GeneratedForm( request.POST, request.FILES, form=core_models.ProposalForm.objects.get(pk=proposal_form_id), ) default_fields = manager_forms.DefaultForm(request.POST) elif request.method == 'POST' and 'incomplete' in request.POST: proposal_form = manager_forms.GeneratedNotRequiredForm( request.POST, request.FILES, form=core_models.ProposalForm.objects.get(pk=proposal_form_id)) default_fields = manager_forms.DefaultNotRequiredForm(request.POST) if proposal_form.is_valid() and default_fields.is_valid(): defaults = {field.name: field.value() for field in default_fields} _incomplete_journal.form = core_models.ProposalForm.objects.get( pk=proposal_form_id) _incomplete_journal.owner = request.user _incomplete_journal.title = defaults['title'] _incomplete_journal.subtitle = defaults['subtitle'] _incomplete_journal.author = defaults['author'] proposal_type = request.POST.get('proposal-type') _incomplete_journal.book_type = proposal_type _incomplete_journal.save() proposal_data_processing( request, _incomplete_journal, proposal_form_id, ) messages.add_message(request, messages.SUCCESS, 'Proposal %s saved' % _incomplete_journal.id) return redirect(reverse('user_dashboard', kwargs={})) template = "submission/start_proposal.html" context = { 'proposal_form': proposal_form, 'incomplete_proposal': _incomplete_journal, 'incomplete': True, 'default_fields': default_fields, 'proposal_form_validated': proposal_form_validated, 'default_fields_validated': default_fields_validated, 'core_proposal': core_models.ProposalForm.objects.get(pk=proposal_form_id), } return render(request, template, context)
def editorial_review(request, review_id): """Complete an editorial review.""" review = get_object_or_404(models.EditorialReview, pk=review_id, completed__isnull=True) form = review_forms.GeneratedForm(form=review.review_form) recommendation_form = forms.RecommendationForm(instance=review) submission = review.content_object book = isinstance(submission, core_models.Book) proposal = isinstance(submission, submission_models.Proposal) if book: peer_reviews = core_models.ReviewAssignment.objects.filter( book=submission, completed__isnull=False, ) else: peer_reviews = submission_models.ProposalReview.objects.filter( proposal=submission, completed__isnull=False, ) completed_editorial_reviews = models.EditorialReview.objects.filter( object_id=submission.id, content_type=review.content_type, completed__isnull=False, ) if request.POST: # Handle completed review. form = review_forms.GeneratedForm( request.POST, request.FILES, form=review.review_form, ) recommendation_form = forms.RecommendationForm( request.POST, instance=review, ) if form.is_valid() and recommendation_form.is_valid(): logic.handle_generated_form_post(review, request) review.completed = timezone.now() review.save() # Add to logs and notify editors. message = ("Editorial review assignment for " "'{}' has been completed by {}.".format( submission.title, review.user.profile.full_name(), )) short_message = 'Completed' if book: log.add_log_entry( book=submission, user=review.user, kind='Editorial Review', message=message, short_name=short_message, ) for editor in submission.book_editors.all(): notification = core_models.Task( assignee=editor, creator=review.user, text=message, book=submission, ) notification.save() else: log.add_proposal_log_entry( proposal=submission, user=review.user, kind='Editorial Review', message=message, short_name=short_message, ) # Handle email notification to editors. subject = get_setting( setting_name='editorialreview_completed_email_subject', setting_group_name='email_subject', default='Editorial review completed', ) email_text = get_setting( setting_name='editorialreview_completed_email', setting_group_name='email', default='message', ) email_text.replace('\n', '<br />') from_email = get_setting( setting_name='from_address', setting_group_name='email', default='*****@*****.**', ) press_name = get_setting( setting_name='press_name', setting_group_name='general', default='The publishers', ) try: series_editor_email = [submission.series.editor.email] except AttributeError: series_editor_email = None editors_to_notify = User.objects.filter( profile__roles__slug='press-editor') if submission.book_editors.all(): editors_to_notify = submission.book_editors.all() for editor in editors_to_notify: salutation = editor.profile.full_name() if editor.profile.salutation: salutation = editor.profile.salutation context = { 'salutation': salutation, 'submission': submission, 'review': review, 'base_url': core_models.Setting.objects.get(name='base_url').value, 'authors': [submission.author] if proposal else submission.author.all(), 'press_name': press_name } email.send_email(subject=subject, context=context, html_template=email_text, from_email=from_email, to=editor.email, cc=series_editor_email, book=submission if book else None, proposal=submission if proposal else None) return redirect( reverse('editorial_review_thanks', kwargs={'review_id': review_id})) template = 'editorialreview/editorial_review.html' context = { 'review': review, 'access_key': request.GET.get('access_key'), 'form': form, 'recommendation_form': recommendation_form, 'peer_reviews': peer_reviews, 'completed_editorial_reviews': completed_editorial_reviews } return render(request, template, context)