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')
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, )
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, }))
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)
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, })
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 }))
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')
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, })
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))