def cancel_authorisation(
        request: HttpRequest,
        third_party_authorisation_id: str) -> HttpResponseRedirect:
    third_party_authorisation = get_object_or_404(
        ThirdPartyAuthorisation, id=third_party_authorisation_id)
    report_auth = third_party_authorisation.patient_report_auth

    third_party_authorisation.expired_date = datetime.datetime.now().date()
    third_party_authorisation.expired = True
    third_party_authorisation.locked_report = False
    third_party_authorisation.save()
    event_logger.info(
        'CANCELED third party authorised model ID {model_id}'.format(
            model_id=third_party_authorisation.id))

    send_mail(
        'Medical Report Authorisation',
        'Your access to the SAR report for {ref_number} has expired. Please contact your client if a third party access extension is required.'
        .format(ref_number=obj.patient_report_auth.patient_report_auth.
                instruction.medi_ref, ),
        'Medidata', [third_party_authorisation.email],
        fail_silently=True)

    return redirect('report:select-report',
                    access_type=PatientReportAuth.ACCESS_TYPE_PATIENT)
def renew_authorisation(
        request: HttpRequest,
        third_party_authorisation_id: str) -> HttpResponseRedirect:
    third_party_authorisation = get_object_or_404(
        ThirdPartyAuthorisation, id=third_party_authorisation_id)
    report_auth = third_party_authorisation.patient_report_auth

    third_party_authorisation.expired_date = datetime.datetime.now().date(
    ) + datetime.timedelta(days=30)
    third_party_authorisation.expired = False
    third_party_authorisation.save()
    event_logger.info(
        'RENEW third party authorised model ID {model_id}'.format(
            model_id=third_party_authorisation.id))
    send_mail(
        'Medical Report Authorisation',
        'Your access to the SAR report for {ref_number} has been extended. Please click {link} to access the report'
        .format(ref_number=report_auth.instruction.medi_ref,
                link=request.scheme + '://' + request.get_host() +
                reverse('report:request-code',
                        kwargs={
                            'instruction_id': report_auth.instruction.id,
                            'access_type':
                            PatientReportAuth.ACCESS_TYPE_THIRD_PARTY,
                            'url': third_party_authorisation.unique
                        })),
        'Medidata', [third_party_authorisation.email],
        fail_silently=True)

    return redirect('report:select-report',
                    access_type=PatientReportAuth.ACCESS_TYPE_PATIENT)
def notify_admins(request):
    user = User.objects.get(pk=request.user.pk)
    to_emails = []
    profiles = UserProfileBase.all_objects.all()
    if hasattr(user, 'userprofilebase'):
        if hasattr(user.userprofilebase, 'clientuser'):
            organisation = user.userprofilebase.clientuser.organisation
            to_emails = [
                client.email for client in User.objects.filter(
                    userprofilebase__in=profiles.alive(),
                    userprofilebase__clientuser__organisation=organisation,
                    userprofilebase__clientuser__role=ClientUser.CLIENT_MANAGER
                )
            ]
        elif hasattr(user.userprofilebase, 'generalpracticeuser'):
            organisation = user.userprofilebase.generalpracticeuser.organisation
            to_emails = [
                client.email for client in User.objects.filter(
                    userprofilebase__in=profiles.alive(),
                    userprofilebase__generalpracticeuser__organisation=
                    organisation,
                    userprofilebase__generalpracticeuser__role=
                    GeneralPracticeUser.PRACTICE_MANAGER)
            ]
    if to_emails:
        send_mail(
            'Reset password',
            'FYI %s has reset their password' % user.get_full_name(),
            'MediData',
            to_emails,
            fail_silently=True,
        )
def send_third_party_message(third_party_form, request_scheme,
                             request_get_host, report_auth):
    phone_number = ''

    if third_party_form.office_phone_number:
        phone_number = third_party_form.get_office_phone_e164()
    elif third_party_form.family_phone_number:
        phone_number = third_party_form.get_family_phone_e164()

    if phone_number:
        last_three_digits = phone_number[-3:]

    send_mail('Completed SAR Request',
              '',
              'Medidata', [third_party_form.email],
              fail_silently=True,
              html_message=loader.render_to_string(
                  'third_parties_email.html', {
                      'ref_number':
                      third_party_form.case_reference,
                      'report_link':
                      request_scheme + '://' + request_get_host +
                      reverse('report:request-code',
                              kwargs={
                                  'instruction_id': report_auth.instruction.id,
                                  'access_type':
                                  PatientReportAuth.ACCESS_TYPE_THIRD_PARTY,
                                  'url': third_party_form.unique
                              }),
                      'last_three_digits':
                      last_three_digits
                  }))
def auto_reject_amra_after_23days(instruction):
    email_user = '******'
    auto_reject_user, created = User.objects.get_or_create(
        email=email_user, username=email_user, first_name='auto-reject')

    instruction.status = INSTRUCTION_STATUS_REJECT
    instruction.rejected_reason = LONG_TIMES
    instruction.rejected_by = auto_reject_user
    instruction.rejected_timestamp = timezone.now()
    instruction.rejected_note = 'Instruction not process until dute date'
    instruction.save()

    instruction_link = settings.MDX_URL + reverse(
        'instructions:view_reject', kwargs={'instruction_id': instruction.id})
    instruction_med_ref = instruction.medi_ref
    subject_reject_email = 'AMRA instruction was not processed'

    # Send Email for client.
    client_email = [instruction.client_user.user.email]
    try:
        send_mail(subject_reject_email,
                  'Your instruction has been reject',
                  'MediData',
                  client_email,
                  fail_silently=True,
                  html_message=loader.render_to_string(
                      'instructions/amra_reject_email.html', {
                          'med_ref': instruction_med_ref,
                          'link': instruction_link
                      }))
    except SMTPException:
        event_logger.info('"AMRA" Send mail to client FAILED')
def send_email_amra(instruction):
    subject_email = 'AMRA instruction not processed'

    # Send Email for GP.
    gp_email = set()
    instruction_link = settings.EMR_URL + reverse(
        'instructions:view_reject', kwargs={'instruction_id': instruction.id})
    gp_managers = User.objects.filter(
        userprofilebase__generalpracticeuser__organisation=instruction.
        gp_practice.pk,
        userprofilebase__generalpracticeuser__role=GeneralPracticeUser.
        PRACTICE_MANAGER).values('email')
    for email in gp_managers:
        gp_email.add(email['email'])

    if instruction.gp_user:
        gp_email.add(instruction.gp_user.user.email)

    try:
        send_mail(subject_email,
                  'Outstanding Instruction- Optimise your fees!',
                  'MediData',
                  list(gp_email),
                  fail_silently=True,
                  html_message=loader.render_to_string(
                      'instructions/amra_chasing_email.html',
                      {'link': instruction_link}))
    except SMTPException:
        event_logger.info('"AMRA" Send mail to GP FAILED')
Пример #7
0
 def send_reject_email_to_patient(self, patient_email: str) -> None:
     send_mail(
         'Rejected Instruction',
         'Unfortunately your instruction could not be completed on this occasion. Please contact your GP Surgery for more information',
         'MediData',
         patient_email,
         fail_silently=True,
         auth_user=settings.EMAIL_HOST_USER,
         auth_password=settings.EMAIL_HOST_PASSWORD,
     )
Пример #8
0
def send_patient_mail(patient, gp_practice):
    send_mail('Notification from your GP surgery',
              'Your instruction has been submitted',
              'MediData', [patient.email],
              fail_silently=True,
              html_message=loader.render_to_string(
                  'medicalreport/patient_email.html', {
                      'gp': gp_practice.name,
                      'link': 'just a link'
                  }))
def send_surgery_email(instruction: Instruction) -> None:
    send_mail(
        'Your medical report has been finalised',
        'Your instruction has been submitted',
        'MediData', [instruction.gp_practice.organisation_email],
        fail_silently=True,
        html_message=loader.render_to_string(
            'medicalreport/surgery_email.html', {
                'name': instruction.patient_information.patient_first_name,
                'gp': instruction.gp_user.user.first_name,
            }))
Пример #10
0
    def save_model(self, request, obj, form, change):

        if obj.expired:
            send_mail(
                'Medical Report Authorisation Expired',
                'Your access to the SAR report for {ref_number} has expired. Please contact your client if a third party access extension is required.'
                .format(ref_number=obj.patient_report_auth.patient_report_auth.
                        instruction.medi_ref, ),
                'Medidata', [obj.email],
                fail_silently=True)
            super().save_model(request, obj, form, change)
Пример #11
0
 def send_reject_email(self, to_email: str) -> None:
     send_mail(
         'Rejected Instruction',
         'You have a rejected instruction. Click here {link}?status=4&type=allType to see it.'
         .format(link=PIPELINE_INSTRUCTION_LINK),
         'MediData',
         to_email,
         fail_silently=True,
         auth_user=settings.EMAIL_HOST_USER,
         auth_password=settings.EMAIL_HOST_PASSWORD,
     )
def step2(request: HttpRequest, practice_code: str) -> HttpResponse:
    gp_organisation = get_object_or_404(OrganisationGeneralPractice,
                                        pk=practice_code)
    pm_form = PMForm()
    UserEmrSetUpStage2Formset = formset_factory(UserEmrSetUpStage2Form,
                                                validate_min=True,
                                                extra=4)
    user_formset = UserEmrSetUpStage2Formset()
    if request.method == 'POST':
        home_page_link = request.scheme + '://' + get_url_page('home',
                                                               request=request)
        pm_form = PMForm(request.POST)
        user_formset = UserEmrSetUpStage2Formset(request.POST)
        if pm_form.is_valid() and user_formset.is_valid():
            created_user_list = []
            pm_form.save__with_gp(gp_organisation=gp_organisation)

            for user in user_formset:
                if user.is_valid() and user.cleaned_data:
                    created_user_dict = create_gp_user(
                        gp_organisation, user_form=user.cleaned_data)
                    if created_user_dict:
                        created_user_list.append(created_user_dict)

            for user in created_user_list:
                html_message = loader.render_to_string(
                    'onboarding/emr_setup_2_email.html', {
                        'user_email': user['general_pratice_user'].user.email,
                        'user_password': user['password'],
                        'home_page_link': home_page_link
                    })
                send_mail(
                    'eMR New User Account information',
                    '',
                    settings.DEFAULT_FROM,
                    [user['general_pratice_user'].user.email],
                    fail_silently=True,
                    html_message=html_message,
                )

            new_pm_user = authenticate(
                request,
                email=pm_form.cleaned_data['email1'],
                password=pm_form.cleaned_data['password1'],
            )
            login(request, new_pm_user)
            return redirect('onboarding:step3',
                            practice_code=gp_organisation.practcode)

    return render(request, 'onboarding/step2.html', {
        'pm_form': pm_form,
        'user_formset': user_formset,
    })
Пример #13
0
def send_patient_mail(scheme: str, host: str, unique_url: str,
                      instruction: Instruction) -> None:
    report_link = scheme + '://' + host + '/report/' + str(
        instruction.pk) + '/patient/' + unique_url
    send_mail('Notification from your GP surgery',
              '',
              'MediData', [instruction.patient_information.patient_email],
              fail_silently=False,
              html_message=loader.render_to_string(
                  'medicalreport/patient_email.html', {
                      'surgery_name': instruction.gp_practice,
                      'report_link': report_link
                  }))
Пример #14
0
 def sending_surgery_email(self) -> None:
     if self.organisation and self.organisation.organisation_email:
         html_message = loader.render_to_string(
             'accounts/email_message_new_user.html', {
                 'name': self.user.get_full_name(),
                 'role': self.get_role_display()
             })
         send_mail(
             'eMR New user',
             '',
             'MediData',
             [self.organisation.organisation_email],
             fail_silently=True,
             html_message=html_message,
         )
def instruction_notification_sars():
    now = timezone.now()
    new_or_pending_instructions = Instruction.objects.filter(
        status__in=(INSTRUCTION_STATUS_NEW, INSTRUCTION_STATUS_PROGRESS),
        type=SARS_TYPE)

    date_period_admin = [3, 7, 14]
    date_period_surgery = [7, 14, 21, 30]
    for instruction in new_or_pending_instructions:
        diff_date = now - instruction.created
        if diff_date.days in date_period_admin or diff_date.days in date_period_surgery:
            gp_managers = User.objects.filter(
                userprofilebase__generalpracticeuser__organisation=instruction.
                gp_practice.pk,
                userprofilebase__generalpracticeuser__role=GeneralPracticeUser.
                PRACTICE_MANAGER).values('email')
            try:
                if gp_managers and diff_date.days in date_period_admin:
                    send_mail(
                        'Outstanding  Instruction',
                        'You have an outstanding instruction. Click here {link} to see it.'
                        .format(link=settings.EMR_URL +
                                reverse('instructions:view_pipeline')),
                        'MediData',
                        [gp['email'] for gp in gp_managers],
                        fail_silently=True,
                        auth_user=settings.EMAIL_HOST_USER,
                        auth_password=settings.EMAIL_HOST_PASSWORD,
                    )
                if instruction.gp_practice and instruction.gp_practice.organisation_email and diff_date.days in date_period_surgery:
                    send_mail(
                        'Outstanding  Instruction',
                        'You have an outstanding instruction. Click here {link} to see it.'
                        .format(link=settings.EMR_URL +
                                reverse('instructions:view_pipeline')),
                        'MediData',
                        [instruction.gp_practice.organisation_email],
                        fail_silently=True,
                        auth_user=settings.EMAIL_HOST_USER,
                        auth_password=settings.EMAIL_HOST_PASSWORD,
                    )
                InstructionReminder.objects.create(
                    instruction_id=instruction.id,
                    note="note added to instruction for %s day reminder" %
                    diff_date.days,
                    reminder_day=diff_date.days)
            except SMTPException:
                logging.error('Send mail FAILED to send message')
Пример #16
0
def send_notification_org_email(request, gp_user, status):
    gp_organisation = gp_user.organisation
    gp_name = " ".join([gp_user.user.first_name, gp_user.user.last_name])
    if status == 'is_fee_changed':
        subject = 'New Fee Band Selected'
        message = 'A fee band was selected for your Surgery by "{username}". To review please click here {protocol}://{link}'.format(
            username=gp_name,
            protocol=request.scheme,
            link=request.get_host() + reverse('accounts:view_account'))
    elif status == 'update_bank_details':
        subject = 'Changed Bank Account details'
        message = 'Your Surgery bank account details have been changed by "{username}".'.format(
            username=gp_name)

    org_email = gp_organisation.organisation_email
    send_mail(subject, message, 'MediData', [org_email], fail_silently=True)
def reset_password(request):
    emails = request.POST.getlist("users[]")
    PASSWORD = '******'
    user_cnt = len(emails)
    organisations = set()
    for email in emails:
        user = User.objects.get(email=email)
        if user.type == GENERAL_PRACTICE_USER and hasattr(user, 'userprofilebase') and\
            hasattr(user.userprofilebase, 'generalpracticeuser') and\
            user.userprofilebase.generalpracticeuser.organisation:
            organisations.add(user.userprofilebase.generalpracticeuser.
                              organisation.organisation_email)
        user.set_password(PASSWORD)
        user.save()
        # send_mail(
        #     'Your account password has been changed',
        #     'Your account password has been changed by your manager. Password: {}'.format(PASSWORD),
        #     DEFAULT_FROM,
        #     [user.email],
        #     fail_silently=True,
        #     auth_user=get_env_variable('SENDGRID_USER'),
        #     auth_password=get_env_variable('SENDGRID_PASS'),
        # )

    for organisation_email in organisations:
        send_mail(
            'Reset password',
            'Your eMR account password has been changed by your manager.',
            DEFAULT_FROM,
            [organisation_email],
            fail_silently=True,
        )
    notify_admins(request)

    if user_cnt == 1:
        messages.success(
            request,
            "The selected user's password has been reset. Password: {}".format(
                PASSWORD))
    else:
        messages.success(
            request,
            "All the passwords of the selected users have been reset. Password: {}"
            .format(PASSWORD))
def send_email_to_practice_job():
    unstarted_instructions = Instruction.objects.filter(
        status=INSTRUCTION_STATUS_NEW)
    for instruction in unstarted_instructions:
        gp_practice = instruction.gp_practice
        practice_preferences = PracticePreferences.objects.get(
            gp_organisation=gp_practice)
        if practice_preferences.notification == 'DIGEST':
            send_mail(
                'New Instruction',
                'You have a New Instruction(s). Click here {link} to view'.
                format(link=settings.EMR_URL +
                       reverse('instructions:view_pipeline')),
                'MediData',
                [gp_practice.organisation_email],
                fail_silently=True,
                auth_user=settings.EMAIL_HOST_USER,
                auth_password=settings.EMAIL_HOST_PASSWORD,
            )
 def wrapper(request, *args, **kwargs):
     if request.method == 'POST':
         email = request.POST.get("email")
         user = User.objects.filter(email=email).first()
         surgery_email = None
         if user and user.type == GENERAL_PRACTICE_USER and hasattr(user, 'userprofilebase') and\
             hasattr(user.userprofilebase, 'generalpracticeuser') and\
             user.userprofilebase.generalpracticeuser.organisation:
             surgery_email = user.userprofilebase.generalpracticeuser.organisation.organisation_email
             if surgery_email:
                 send_mail(
                     'Reset password',
                     '{username} has requested a password reset..'.format(
                         username=user.__str__()),
                     DEFAULT_FROM,
                     [surgery_email],
                     fail_silently=True,
                 )
     return func(request, *args, **kwargs)
def report_notification_expired_authorisation_job():
    current_date = timezone.now().date()
    third_party_authorisations = ThirdPartyAuthorisation.objects.all()
    for authorisation in third_party_authorisations:
        if authorisation.expired_date and current_date > authorisation.expired_date and not authorisation.expired:
            authorisation.expired = True
            authorisation.save()
            try:
                send_mail(
                    'Medical Report Authorisation Expired',
                    'Your access to the SAR report for {ref_number} has expired. Please contact your client if a third party access extension is required.'
                    .format(ref_number=authorisation.patient_report_auth.
                            instruction.medi_ref, ),
                    'MediData',
                    [authorisation.email],
                    fail_silently=True,
                    auth_user=settings.EMAIL_HOST_USER,
                    auth_password=settings.EMAIL_HOST_PASSWORD,
                )
            except SMTPException:
                event_logger.error('Notification mail expired')
def step1(request: HttpRequest) -> HttpResponse:
    surgery_form = SurgeryForm()
    surgery_email_form = SurgeryEmailForm()
    if request.method == "POST":
        surgery_form = SurgeryForm(request.POST)
        if surgery_form.is_valid():
            gp_organisation = surgery_form.save()
            if not surgery_form.cleaned_data.get(
                    'operating_system') == 'EMISWeb':
                message_1 = 'Thank you for completing part one of the eMR registration process. It’s great to have you on board.'
                message_2 = 'We will be in touch with you shortly to complete the set up process so that you can process SARs in seconds.'
                message_3 = 'We look forward to working with you in the very near future. eMR Support Team'
                return render(request,
                              'onboarding/emr_message.html',
                              context={
                                  'message_1': message_1,
                                  'message_2': message_2,
                                  'message_3': message_3
                              })
            if gp_organisation.practcode[:4] == 'TEST':
                gp_organisation.operating_system_username = '******'
                gp_organisation.operating_system_salt_and_encrypted_password = '******'
            else:
                password = generate_password(initial_range=1,
                                             body_rage=12,
                                             tail_rage=1)
                gp_organisation.operating_system_salt_and_encrypted_password = password
                gp_organisation.operating_system_username = PREFIX_EMIS_USER + gp_organisation.operating_system_organisation_code
            gp_organisation.save()

            if not OrganisationFeeRate.objects.filter(default=True).exists():
                OrganisationFeeRate.objects.create(name='Default Band',
                                                   amount_rate_lvl_1=60,
                                                   amount_rate_lvl_2=57,
                                                   amount_rate_lvl_3=51,
                                                   amount_rate_lvl_4=45,
                                                   default=True)

            # setup default fee policy
            GpOrganisationFee.objects.create(
                gp_practice=gp_organisation,
                organisation_fee=OrganisationFeeRate.objects.filter(
                    default=True).first())

            surgery_email_form = SurgeryEmailForm(request.POST,
                                                  instance=gp_organisation)

            if surgery_email_form.is_valid():
                surgery_email = surgery_email_form.save()
                if surgery_email.organisation_email:
                    html_message = loader.render_to_string(
                        'onboarding/surgery_email.html')
                    send_mail(
                        'eMR successful set up',
                        '',
                        settings.DEFAULT_FROM,
                        [surgery_email.organisation_email],
                        fail_silently=True,
                        html_message=html_message,
                    )

                return redirect('onboarding:step2',
                                practice_code=gp_organisation.practcode)

    return render(request, 'onboarding/step1.html', {
        'surgery_form': surgery_form,
        'surgery_email_form': surgery_email_form,
    })
Пример #22
0
def prepare_medicalreport_data(self, instruction_id, notify_mail=True):
    """
        1. Keep XML to our DB.
        2. Prepare Relations third party data
        3. Redaction attachment and keep it with instruction
    :return:
    """
    try:
        instruction = Instruction.objects.get(id=instruction_id)
        time.sleep(5)
        amendments = AmendmentsForRecord.objects.filter(
            instruction=instruction).first()

        if not amendments:
            aes_key = uuid.uuid4().hex
            # create AmendmentsForRecord with aes_key first then save raw_xml and encrypted with self aes_key
            amendments = AmendmentsForRecord.objects.create(
                instruction=instruction, raw_medical_xml_aes_key=aes_key)

        raw_xml = services.GetMedicalRecord(
            amendments.patient_emis_number,
            gp_organisation=instruction.gp_practice).call()
        if isinstance(raw_xml, str):
            amendments.raw_medical_xml_encrypted = raw_xml
            amendments.save()
            medical_record_decorator = MedicalReportDecorator(
                raw_xml, instruction)
            for attachment in medical_record_decorator.attachments():
                pdf_path = ''
                pdf_byte = b''

                attachment_id = attachment.dds_identifier()
                raw_attachment_xml = services.GetAttachment(
                    instruction.patient_information.patient_emis_number,
                    attachment_id,
                    gp_organisation=instruction.gp_practice).call()
                raw_attachment_byte = Base64Attachment(
                    raw_attachment_xml).data()

                file_name = Base64Attachment(
                    raw_attachment_xml).filename().split('\\')[-1]
                file_type = file_name.split('.')[-1]

                # for each type of attachment we want to set "pdf_path" or "pdf_byte"
                if file_type == 'pdf':
                    # set pdf_byte
                    pdf_byte = raw_attachment_byte

                elif file_type in ['doc', 'docx', 'rtf']:
                    # set pdf_path
                    buffer = io.BytesIO()
                    buffer.write(raw_attachment_byte)
                    tmp_file = '%s_tmp.%s' % (instruction.pk, file_type)
                    f = open(TEMP_DIR + tmp_file, 'wb')
                    f.write(buffer.getvalue())
                    f.close()
                    subprocess.call((
                        "export HOME=/tmp && libreoffice --headless --convert-to pdf --outdir "
                        + TEMP_DIR + " " + TEMP_DIR + "/" + tmp_file),
                                    shell=True)
                    pdf_path = TEMP_DIR + '%s_tmp.pdf' % instruction.pk

                elif file_type in ['jpg', 'jpeg', 'png', 'tiff', 'tif']:
                    # set pdf_byte
                    buffer = io.BytesIO(raw_attachment_byte)
                    image = Image.open(buffer)
                    image_format = image.format
                    if image_format == "TIFF":
                        max_pages = 200
                        height = image.tag[0x101][0]
                        width = image.tag[0x100][0]
                        out_pdf_io = io.BytesIO()
                        c = reportlab.pdfgen.canvas.Canvas(
                            out_pdf_io, pagesize=pdf_sizes.letter)
                        pdf_width, pdf_height = pdf_sizes.letter
                        page = 0
                        while True:
                            try:
                                image.seek(page)
                            except EOFError:
                                break
                            if pdf_width * height / width <= pdf_height:
                                c.drawInlineImage(image, 0, 0, pdf_width,
                                                  pdf_width * height / width)
                            else:
                                c.drawInlineImage(image, 0, 0,
                                                  pdf_height * width / height,
                                                  pdf_height)
                            c.showPage()
                            if max_pages and page > max_pages:
                                break
                            page += 1
                        c.save()
                        pdf_byte = out_pdf_io.getvalue()
                    else:
                        image.save(TEMP_DIR + 'img_temp_%s.' % instruction.pk +
                                   image_format)
                        pdf_byte = img2pdf.convert(TEMP_DIR + 'img_temp_%s.' %
                                                   instruction.pk +
                                                   image_format)

                else:
                    # Unsupported file type
                    pass

                if pdf_path or pdf_byte:
                    # redacted attachment
                    redacted_count, pdf_page_buffer = generate_redact_pdf(
                        instruction.patient_information.patient_first_name,
                        instruction.patient_information.patient_last_name,
                        pdf_byte=pdf_byte,
                        pdf_path=pdf_path)

                    # keep redacted attachment
                    RedactedAttachment.objects.create(
                        instruction=instruction,
                        name=file_name,
                        dds_identifier=attachment_id,
                        raw_attachment_file_content=pdf_page_buffer.getvalue(),
                        redacted_count=redacted_count)
                else:
                    RedactedAttachment.objects.create(
                        instruction=instruction,
                        name=file_name,
                        dds_identifier=attachment_id,
                        raw_attachment_file_content=b'',
                    )
        else:
            EVENT_LOGGER.error(
                'Unable to connect to EMIS for instruction No. (%s).' %
                instruction.id)

        # set IN_PROGRESS status and notify by email to gp
        instruction.status = INSTRUCTION_STATUS_PROGRESS
        instruction.save()
        if notify_mail:
            body_message_1 = 'The redaction process is now complete for instruction {medi_ref}.'.format(
                medi_ref=instruction.medi_ref)
            body_message_2 = ' Click here {link} to complete the report.'.format(
                link=settings.EMR_URL + reverse('instructions:view_pipeline'))
            body_message = body_message_1 + body_message_2
            send_mail('Redaction Process now Complete {medi_ref}'.format(
                medi_ref=instruction.medi_ref),
                      body_message,
                      'MediData', [
                          instruction.gp_user.user.email,
                          instruction.gp_practice.organisation_email
                      ],
                      fail_silently=False)
    except Exception as e:
        EVENT_LOGGER.error(
            'Preparing asynchronous medical report data hit and unexpected err (%s).'
            % repr(e))