Пример #1
0
    def handle(self, *args, **options):
        try:
            user = EmailUser.objects.get(email=settings.CRON_EMAIL)
        except:
            user = EmailUser.objects.create(email=settings.CRON_EMAIL, password='')

        errors = []
        updates = []
        today = timezone.localtime(timezone.now()).date()

        # Retrieve the number of days before expiry date of the approvals to email
        days_type = NumberOfDaysType.objects.get(code=CODE_DAYS_IN_PERIOD_MLA)
        days_setting = NumberOfDaysSetting.get_setting_by_date(days_type, today)
        if not days_setting:
            # No number of days found
            raise ImproperlyConfigured("NumberOfDays: {} is not defined for the date: {}".format(days_type.name, today))
        boundary_date = today - timedelta(days=days_setting.number_of_days)

        logger.info('Running command {}'.format(__name__))

        # Construct queries
        # MLA and associated documents must be submitted within X days period after invitation
        queries = Q()
        queries &= Q(processing_status__in=(Proposal.PROCESSING_STATUS_DRAFT, Proposal.PROCESSING_STATUS_AWAITING_DOCUMENTS))
        queries &= Q(date_invited__lt=boundary_date)

        # For debug
        # params = options.get('params')
        # debug = True if params.get('debug', 'f').lower() in ['true', 't', 'yes', 'y'] else False
        # approval_lodgement_number = params.get('expire_mooring_licence_application_due_to_no_submit_lodgement_number', 'no-lodgement-number')
        # if debug:
        #     queries = queries | Q(lodgement_number__iexact=approval_lodgement_number)

        for a in MooringLicenceApplication.objects.filter(queries):
            try:
                a.processing_status = Proposal.PROCESSING_STATUS_EXPIRED
                a.save()
                # update WLA internal_status and queue date
                a.waiting_list_allocation.internal_status = 'waiting'
                a.waiting_list_allocation.wla_queue_date = today
                a.waiting_list_allocation.save()
                # reset Waiting List order
                a.waiting_list_allocation.set_wla_order()

                due_date = a.date_invited + timedelta(days=days_setting.number_of_days)
                send_expire_mooring_licence_application_email(a, MooringLicenceApplication.REASON_FOR_EXPIRY_NOT_SUBMITTED, due_date)
                send_expire_mla_notification_to_assessor(a, MooringLicenceApplication.REASON_FOR_EXPIRY_NO_DOCUMENTS, due_date)
                logger.info('Expired notification sent for Proposal {}'.format(a.lodgement_number))
                updates.append(a.lodgement_number)
            except Exception as e:
                err_msg = 'Error sending expired notification for Proposal {}'.format(a.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors) > 0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
Пример #2
0
    def handle(self, *args, **options):
        try:
            user = EmailUser.objects.get(email=settings.CRON_EMAIL)
        except:
            user = EmailUser.objects.create(email=settings.CRON_EMAIL,
                                            password='')

        errors = []
        updates = []
        today = timezone.localtime(timezone.now()).date()
        logger.info('Running command {}'.format(__name__))

        for c in Compliance.objects.filter(
                processing_status=Compliance.PROCESSING_STATUS_DUE):
            try:
                c.send_reminder(user)
                c.save()
                updates.append(c.lodgement_number)
            except Exception as e:
                err_msg = 'Error sending Reminder Compliance'.format(
                    c.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors)>0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
    def handle(self, *args, **options):
        errors, updates = import_mooring_bookings_data()

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors)>0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. Errors: {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
Пример #4
0
    def handle(self, *args, **options):
        updates, errors = sticker_export()
        success_filenames, error_filenames = email_stickers_document()

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        error_count = len(errors) + len(error_filenames)
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(error_count) if error_count else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
    def handle(self, *args, **options):
        try:
            user = EmailUser.objects.get(email=settings.CRON_EMAIL)
        except:
            user = EmailUser.objects.create(email=settings.CRON_EMAIL, password='')

        errors = []
        updates = []
        today = timezone.localtime(timezone.now()).date()

        # Retrieve the number of days before expiry date of the approvals to email
        days_type = NumberOfDaysType.objects.get(code=CODE_DAYS_FOR_ENDORSER_AUA)
        days_setting = NumberOfDaysSetting.get_setting_by_date(days_type, today)
        if not days_setting:
            # No number of days found
            raise ImproperlyConfigured("NumberOfDays: {} is not defined for the date: {}".format(days_type.name, today))
        boundary_date = today - timedelta(days=days_setting.number_of_days)

        logger.info('Running command {}'.format(__name__))

        # For debug
        # params = options.get('params')
        # debug = True if params.get('debug', 'f').lower() in ['true', 't', 'yes', 'y'] else False
        # proposal_id = int(params.get('send_endorser_reminder_id', 0))

        # Construct queries
        queries = Q()
        queries &= Q(processing_status=Proposal.PROCESSING_STATUS_AWAITING_ENDORSEMENT)
        queries &= Q(lodgement_date__lt=boundary_date)
        queries &= Q(endorser_reminder_sent=False)
        # if debug:
        #     queries = queries | Q(id=proposal_id)

        for a in AuthorisedUserApplication.objects.filter(queries):
            try:
                send_endorser_reminder_email(a)
                a.endorser_reminder_sent = True
                a.save()
                logger.info('Reminder to endorser sent for Proposal {}'.format(a.lodgement_number))
                updates.append(a.lodgement_number)
            except Exception as e:
                err_msg = 'Error sending reminder to endorser for Proposal {}'.format(a.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors) > 0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
Пример #6
0
    def handle(self, *args, **options):
        try:
            user = EmailUser.objects.get(email=settings.CRON_EMAIL)
        except:
            user = EmailUser.objects.create(email=settings.CRON_EMAIL,
                                            password='')

        updates, errors = [], []

        self.perform_per_type(CODE_DAYS_FOR_RENEWAL_WLA, WaitingListAllocation,
                              updates, errors)
        self.perform_per_type(CODE_DAYS_FOR_RENEWAL_AAP, AnnualAdmissionPermit,
                              updates, errors)
        self.perform_per_type(CODE_DAYS_FOR_RENEWAL_AUP, AuthorisedUserPermit,
                              updates, errors)
        self.perform_per_type(CODE_DAYS_FOR_RENEWAL_ML, MooringLicence,
                              updates, errors)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors)>0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
    def handle(self, *args, **options):
        try:
            user = EmailUser.objects.get(email=settings.CRON_EMAIL)
        except:
            user = EmailUser.objects.create(email=settings.CRON_EMAIL, password = '')

        errors = []
        updates = []
        today = timezone.localtime(timezone.now()).date()
        logger.info('Running command {}'.format(__name__))

        # Expiry
        queries = Q()
        queries &= (Q(status=Approval.APPROVAL_STATUS_CURRENT) & Q(replaced_by__isnull=True))
        queries &= Q(expiry_date__lt=today)

        approvals = Approval.objects.filter(queries)
        for approval in approvals:
            try:
                approval.expire_approval(user)
                # a.save()  # Saved in the above function...?
                logger.info('Updated Approval {} status to {}'.format(approval.id, approval.status))
                updates.append(approval.lodgement_number)
            except Exception as e:
                err_msg = 'Error updating Approval {} status'.format(approval.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        # Current --> suspend, cancel, surrender
        for a in Approval.objects.filter(status=Approval.APPROVAL_STATUS_CURRENT):
            if a.suspension_details and a.set_to_suspend:
                from_date = datetime.datetime.strptime(a.suspension_details['from_date'], '%d/%m/%Y')
                from_date = from_date.date()                
                if from_date <= today:
                    try:
                        a.status = Approval.APPROVAL_STATUS_SUSPENDED
                        a.set_to_suspend = False
                        a.save()
                        send_approval_suspend_email_notification(a)

                        proposal = a.current_proposal
                        ApprovalUserAction.log_action(a, ApprovalUserAction.ACTION_SUSPEND_APPROVAL.format(a.id), user)
                        ProposalUserAction.log_action(proposal, ProposalUserAction.ACTION_SUSPEND_APPROVAL.format(proposal.lodgement_number), user)
                        logger.info('Updated Approval {} status to {}'.format(a.id, a.status))
                        updates.append(dict(suspended=a.lodgement_number))
                    except Exception as e:
                        err_msg = 'Error suspending Approval {} status'.format(a.lodgement_number)
                        logger.error('{}\n{}'.format(err_msg, str(e)))
                        errors.append(err_msg)

            if a.cancellation_date and a.set_to_cancel:                              
                if a.cancellation_date <= today:
                    try:
                        a.status = Approval.APPROVAL_STATUS_CANCELLED
                        a.set_to_cancel = False
                        a.save()
                        send_approval_cancel_email_notification(a)

                        proposal = a.current_proposal
                        ApprovalUserAction.log_action(a, ApprovalUserAction.ACTION_CANCEL_APPROVAL.format(a.id), user)
                        ProposalUserAction.log_action(proposal, ProposalUserAction.ACTION_CANCEL_APPROVAL.format(proposal.lodgement_number), user)
                        logger.info('Updated Approval {} status to {}'.format(a.id, a.status))
                        updates.append(dict(cancelled=a.lodgement_number))
                    except Exception as e:
                        err_msg = 'Error cancelling Approval {} status'.format(a.lodgement_number)
                        logger.error('{}\n{}'.format(err_msg, str(e)))
                        errors.append(err_msg)

            if a.surrender_details and a.set_to_surrender:
                surrender_date = datetime.datetime.strptime(a.surrender_details['surrender_date'], '%d/%m/%Y')
                surrender_date = surrender_date.date()                
                if surrender_date <= today:
                    try:
                        a.status = Approval.APPROVAL_STATUS_SURRENDERED
                        a.set_to_surrender = False
                        a.save()
                        send_approval_surrender_email_notification(a)

                        proposal = a.current_proposal
                        ApprovalUserAction.log_action(a, ApprovalUserAction.ACTION_SURRENDER_APPROVAL.format(a.id), user)
                        ProposalUserAction.log_action(proposal, ProposalUserAction.ACTION_SURRENDER_APPROVAL.format(proposal.lodgement_number), user)
                        logger.info('Updated Approval {} status to {}'.format(a.id, a.status))
                        updates.append(dict(surrendered=a.lodgement_number))
                    except Exception as e:
                        err_msg = 'Error surrendering Approval {} status'.format(a.lodgement_number)
                        logger.error('{}\n{}'.format(err_msg, str(e)))
                        errors.append(err_msg)

        # Suspended --> current, cancel, surrender
        for a in Approval.objects.filter(status=Approval.APPROVAL_STATUS_SUSPENDED):
            if a.suspension_details and a.suspension_details['to_date']:               
                to_date = datetime.datetime.strptime(a.suspension_details['to_date'], '%d/%m/%Y')
                to_date = to_date.date()
                if to_date <= today < a.expiry_date:
                    try:
                        a.status = Approval.APPROVAL_STATUS_CURRENT
                        a.save()

                        proposal = a.current_proposal
                        ApprovalUserAction.log_action(a, ApprovalUserAction.ACTION_REINSTATE_APPROVAL.format(a.id), user)
                        ProposalUserAction.log_action(proposal, ProposalUserAction.ACTION_REINSTATE_APPROVAL.format(proposal.lodgement_number), user)
                        logger.info('Updated Approval {} status to {}'.format(a.id, a.status))
                        updates.append(dict(current=a.lodgement_number))
                    except Exception as e:
                        err_msg = 'Error suspending Approval {} status'.format(a.lodgement_number)
                        logger.error('{}\n{}'.format(err_msg, str(e)))
                        errors.append(err_msg)

            if a.cancellation_date and a.set_to_cancel:                              
                if a.cancellation_date <= today:
                    try:
                        a.status = Approval.STATUS_CANCELLED
                        a.set_to_cancel = False
                        a.save()

                        send_approval_cancel_email_notification(a)
                        proposal = a.current_proposal
                        ApprovalUserAction.log_action(a, ApprovalUserAction.ACTION_CANCEL_APPROVAL.format(a.id), user)
                        ProposalUserAction.log_action(proposal, ProposalUserAction.ACTION_CANCEL_APPROVAL.format(proposal.lodgement_number), user)
                        logger.info('Updated Approval {} status to {}'.format(a.id,a.status))
                        updates.append(dict(cancelled=a.lodgement_number))
                    except Exception as e:
                        err_msg = 'Error cancelling Approval {} status'.format(a.lodgement_number)
                        logger.error('{}\n{}'.format(err_msg, str(e)))
                        errors.append(err_msg)

            if a.surrender_details and a.set_to_surrender:
                surrender_date = datetime.datetime.strptime(a.surrender_details['surrender_date'], '%d/%m/%Y')
                surrender_date = surrender_date.date()                
                if surrender_date <= today:
                    try:
                        a.status = Approval.APPROVAL_STATUS_SURRENDERED
                        a.set_to_surrender = False
                        a.save()

                        send_approval_surrender_email_notification(a)
                        proposal = a.current_proposal
                        ApprovalUserAction.log_action(a, ApprovalUserAction.ACTION_SURRENDER_APPROVAL.format(a.id), user)
                        ProposalUserAction.log_action(proposal, ProposalUserAction.ACTION_SURRENDER_APPROVAL.format(proposal.lodgement_number), user)
                        logger.info('Updated Approval {} status to {}'.format(a.id, a.status))
                        updates.append(dict(surrendered=a.lodgement_number))
                    except Exception as e:
                        err_msg = 'Error surrendering Approval {} status'.format(a.lodgement_number)
                        logger.error('{}\n{}'.format(err_msg, str(e)))
                        errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors)>0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
    def handle(self, *args, **options):
        try:
            user = EmailUser.objects.get(email=settings.CRON_EMAIL)
        except:
            user = EmailUser.objects.create(email=settings.CRON_EMAIL,
                                            password='')

        errors = []
        updates = []
        today = timezone.localtime(timezone.now()).date()

        # Retrieve the number of days before expiry date of the approvals to email
        days_type_period = NumberOfDaysType.objects.get(
            code=CODE_DAYS_IN_PERIOD_MLA)
        days_setting_period = NumberOfDaysSetting.get_setting_by_date(
            days_type_period, today)
        if not days_setting_period:
            raise ImproperlyConfigured(
                "NumberOfDays: {} is not defined for the date: {}".format(
                    days_type_period.name, today))

        days_type_before = NumberOfDaysType.objects.get(
            code=CODE_DAYS_BEFORE_PERIOD_MLA)
        days_setting_before = NumberOfDaysSetting.get_setting_by_date(
            days_type_before, today)
        if not days_setting_before:
            raise ImproperlyConfigured(
                "NumberOfDays: {} is not defined for the date: {}".format(
                    days_type_before.name, today))

        boundary_date = today - timedelta(
            days=days_setting_period.number_of_days) + timedelta(
                days=days_setting_before.number_of_days)

        logger.info('Running command {}'.format(__name__))

        # Construct queries
        queries = Q()
        queries &= Q(processing_status=Proposal.PROCESSING_STATUS_DRAFT)
        queries &= Q(lodgement_date__lt=boundary_date)
        queries &= Q(invitee_reminder_sent=False)

        for a in MooringLicenceApplication.objects.filter(queries):
            try:
                due_date = a.lodgement_date + timedelta(
                    days=days_setting_period.number_of_days)
                send_invitee_reminder_email(a, due_date,
                                            days_setting_before.number_of_days)
                a.invitee_reminder_sent = True
                a.save()
                logger.info('Reminder to invitee sent for Proposal {}'.format(
                    a.lodgement_number))
                updates.append(a.lodgement_number)
            except Exception as e:
                err_msg = 'Error sending reminder to invitee for Proposal {}'.format(
                    a.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors) > 0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
Пример #9
0
    def perform(self, approval_type, today, **options):
        errors = []
        updates = []

        # Retrieve the number of days before expiry date of the approvals to email
        if approval_type == WaitingListAllocation.code:
            # days_type = NumberOfDaysType.objects.get(code=CODE_DAYS_BEFORE_END_OF_SIX_MONTH_PERIOD_WLA)
            approval_class = WaitingListAllocation
        elif approval_type == MooringLicence.code:
            # days_type = NumberOfDaysType.objects.get(code=CODE_DAYS_BEFORE_END_OF_SIX_MONTH_PERIOD_ML)
            approval_class = MooringLicence
        else:
            # Do nothing
            return

        # days_setting = NumberOfDaysSetting.get_setting_by_date(days_type, today)
        # if not days_setting:
        #     # No number of days found
        #     raise ImproperlyConfigured("NumberOfDays: {} is not defined for the date: {}".format(days_type.name, today))
        # NOTE: When sending the reminder:
        #       sold_date + 6months < today
        #       sold_date < today - 6months
        boundary_date = today - relativedelta(months=+6)

        logger.info('Running command {}'.format(__name__))

        # Get approvals
        if approval_type == WaitingListAllocation.code:
            queries = Q()
            queries &= Q(status__in=(Approval.APPROVAL_STATUS_CURRENT,
                                     Approval.APPROVAL_STATUS_SUSPENDED))
            queries &= Q(
                current_proposal__vessel_ownership__end_date__isnull=False)
            queries &= Q(
                current_proposal__vessel_ownership__end_date__lt=boundary_date)
            queries &= Q(vessel_nomination_reminder_sent=False
                         )  # Is this correct?  SHould be True?
            approvals = approval_class.objects.filter(queries)
        elif approval_type == MooringLicence.code:
            queries = Q()
            queries &= Q(status__in=(Approval.APPROVAL_STATUS_CURRENT,
                                     Approval.APPROVAL_STATUS_SUSPENDED))
            queries &= Q(vessel_nomination_reminder_sent=False
                         )  # Is this correct?  SHould be True?
            possible_approvals = approval_class.objects.filter(queries)

            approvals = []
            for approval in possible_approvals:
                # Check if there is at least one vessel which meets the ML vessel requirement
                if not ml_meet_vessel_requirement(approval, boundary_date):
                    approvals.append(approval)

        for a in approvals:
            try:
                send_approval_cancelled_due_to_no_vessels_nominated_mail(a)
                # a.vessel_nomination_reminder_sent = True
                a.status = Approval.APPROVAL_STATUS_CANCELLED
                a.save()
                logger.info(
                    'Cancel notification to permission holder sent for Approval {}'
                    .format(a.lodgement_number))
                updates.append(a.lodgement_number)
            except Exception as e:
                err_msg = 'Error sending cancel notification to permission holder for Approval {}'.format(
                    a.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(
        #     errors) > 0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} ({}) completed. {}. IDs updated: {}.</p>'.format(cmd_name, approval_type, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
Пример #10
0
    def handle(self, *args, **options):
        today = timezone.localtime(timezone.now()).date()
        days_type = NumberOfDaysType.objects.get(
            code=CODE_DAYS_BEFORE_DUE_COMPLIANCE)
        days_setting = NumberOfDaysSetting.get_setting_by_date(
            days_type, today)
        compare_date = today + datetime.timedelta(
            days=days_setting.number_of_days)

        try:
            user = EmailUser.objects.get(email=settings.CRON_EMAIL)
        except:
            user = EmailUser.objects.create(email=settings.CRON_EMAIL,
                                            password='')

        errors = []
        updates = []
        logger.info('Running command {}'.format(__name__))
        #for c in Compliance.objects.filter(processing_status=Compliance.PROCESSING_STATUS_FUTURE):
        #    if c.due_date <= compare_date and c.due_date <= c.approval.expiry_date and c.approval.status == Approval.APPROVAL_STATUS_CURRENT:
        #        try:
        #            c.processing_status = Compliance.PROCESSING_STATUS_DUE
        #            c.customer_status = Compliance.CUSTOMER_STATUS_DUE
        #            c.save()
        #            ComplianceUserAction.log_action(c, ComplianceUserAction.ACTION_STATUS_CHANGE.format(c.id), user)
        #            logger.info('updated Compliance {} status to {}'.format(c.id, c.processing_status))
        #            updates.append(c.lodgement_number)
        #        except Exception as e:
        #            err_msg = 'Error updating Compliance {} status'.format(c.lodgement_number)
        #            logger.error('{}\n{}'.format(err_msg, str(e)))
        #            errors.append(err_msg)

        # Future --> Due
        queries = Q()
        queries &= Q(due_date__gte=today)
        queries &= Q(due_date__lte=compare_date)
        queries &= Q(lodgement_date__isnull=True)
        queries &= Q(processing_status__in=[
            Compliance.PROCESSING_STATUS_FUTURE,
        ])
        compliances_to_be_due = Compliance.objects.filter(queries)
        for c in compliances_to_be_due:
            try:
                c.processing_status = Compliance.PROCESSING_STATUS_DUE
                c.customer_status = Compliance.CUSTOMER_STATUS_DUE
                c.save()
                ComplianceUserAction.log_action(
                    c, ComplianceUserAction.ACTION_STATUS_CHANGE.format(c.id),
                    user)
                logger.info('updated Compliance {} status to {}'.format(
                    c.id, c.processing_status))
                updates.append(c.lodgement_number)
            except Exception as e:
                err_msg = 'Error updating Compliance {} status'.format(
                    c.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        # Future/Due --> Overdue
        queries = Q()
        queries &= Q(due_date__lt=today)
        queries &= Q(lodgement_date__isnull=True)
        queries &= Q(processing_status__in=[
            Compliance.PROCESSING_STATUS_DUE,
            Compliance.PROCESSING_STATUS_FUTURE,
        ])
        compliances_to_be_overdue = Compliance.objects.filter(queries)
        for c in compliances_to_be_overdue:
            try:
                c.processing_status = Compliance.PROCESSING_STATUS_OVERDUE
                c.customer_status = Compliance.CUSTOMER_STATUS_OVERDUE
                c.save()
                ComplianceUserAction.log_action(
                    c, ComplianceUserAction.ACTION_STATUS_CHANGE.format(c.id),
                    user)
                logger.info('updated Compliance {} status to {}'.format(
                    c.id, c.processing_status))
                updates.append(c.lodgement_number)
            except Exception as e:
                err_msg = 'Error updating Compliance {} status'.format(
                    c.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(errors) > 0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
    def handle(self, *args, **options):
        ##########
        # 1. Save the email-attachment file to the django model (database)
        ##########
        sticker_email_host = env('STICKER_EMAIL_HOST', '')
        sticker_email_port = env('STICKER_EMAIL_PORT', '')
        sticker_email_username = env('STICKER_EMAIL_USERNAME', '')
        sticker_email_password = env('STICKER_EMAIL_PASSWORD', '')

        if not sticker_email_host or not sticker_email_port or not sticker_email_username or not sticker_email_password:
            msg = 'Configure email settings at .env to process sticker responses'
            logger.error(msg)
            cron_email.info(msg)
            raise Exception(msg)

        context = ssl.create_default_context()
        imapclient = imaplib.IMAP4_SSL(sticker_email_host, sticker_email_port, ssl_context=context)

        # login
        imapclient.login(sticker_email_username, sticker_email_password)

        """
        Retrieve messages
        """
        imapclient.select('INBOX')  # Select mail box
        typ, data = imapclient.search(None, "ALL")  # data = [b"1 2 3 4 ..."]
        datas = data[0].split()
        fetch_num = 5000  # The number of messages to fetch

        if (len(datas) - fetch_num) < 0:
            fetch_num = len(datas)

        for num in datas[len(datas) - fetch_num::]:
            try:
                ##########
                # 2. Save the attached files into the database
                ##########
                typ, data = imapclient.fetch(num, '(RFC822)')
                # typ, data = imapclient.fetch(num, '(BODY[HEADER.FIELDS (MESSAGE-ID)])')
                raw_email = data[0][1]

                # converts byte literal to string removing b''
                raw_email_string = raw_email.decode('utf-8')
                email_message = email.message_from_string(raw_email_string)

                email_message_id = str(make_header(decode_header(email_message["Message-ID"])))
                if StickerPrintingResponseEmail.objects.filter(email_message_id=email_message_id):
                    # This email has been saved in the database already.  Skip this email
                    continue

                email_subject = str(make_header(decode_header(email_message["Subject"])))
                email_from = email_message['From']
                body = get_text(email_message)
                email_body = body.decode()
                email_date = email_message['Date']

                sticker_printing_response_email = StickerPrintingResponseEmail.objects.create(
                    email_subject=email_subject,
                    email_from=email_from,
                    email_body=email_body,
                    email_date=email_date,
                    email_message_id=email_message_id,
                )

                # downloading attachments
                for part in email_message.walk():
                    try:
                        # this part comes from the snipped I don't understand yet...
                        if part.get_content_maintype() == 'multipart':
                            continue
                        if part.get('Content-Disposition') is None:
                            continue
                        fileName = part.get_filename()
                        if bool(fileName) and fileName.lower().endswith('.xlsx'):
                            now = timezone.localtime(timezone.now())

                            # Create sticker_printing_response object. File is not saved yet
                            sticker_printing_response = StickerPrintingResponse.objects.create(
                                sticker_printing_response_email=sticker_printing_response_email,
                                name=fileName,
                            )

                            # Load attachment file
                            my_bytes = part.get_payload(decode=True)
                            content_file = ContentFile(my_bytes)

                            # Save file
                            sticker_printing_response._file.save(fileName, content_file)
                    except Exception as e:
                        logger.exception('Exception has been raised when importing .xlsx file')
                        continue

                # imapclient.store(num, "+FLAGS", "\\Deleted")
                imapclient.copy(num, "Archive")
                imapclient.store(num, "+FLAGS", "\\Deleted")
            except:
                logger.exception('Exception has been raised when processing emails')
                continue

        imapclient.close()
        imapclient.logout()

        ##########
        # 3. Process xlsx file saved in django model
        ##########
        process_summary = {'stickers': [], 'errors': [], 'sticker_printing_responses': []}  # To be used for sticker processed email
        updates, errors = process_sticker_printing_response(process_summary)

        # Send sticker import batch emails
        send_sticker_import_batch_email(process_summary)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # error_count = len(errors) + len(error_filenames)
        # error_count = len(errors)
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(error_count) if error_count else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} completed. {}. IDs updated: {}.</p>'.format(cmd_name, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)
Пример #12
0
    def perform(self, approval_type, today, **options):
        errors = []
        updates = []

        # Retrieve the number of days before expiry date of the approvals to email
        if approval_type == WaitingListAllocation.code:
            days_type = NumberOfDaysType.objects.get(code=CODE_DAYS_BEFORE_END_OF_SIX_MONTH_PERIOD_WLA)
            approval_class = WaitingListAllocation
        elif approval_type == MooringLicence.code:
            days_type = NumberOfDaysType.objects.get(code=CODE_DAYS_BEFORE_END_OF_SIX_MONTH_PERIOD_ML)
            approval_class = MooringLicence
        # elif approval_type == AuthorisedUserPermit.code:
        #     days_type = NumberOfDaysType.objects.get(code=CODE_DAYS_BEFORE_END_OF_SIX_MONTH_PERIOD_AUP)
        #     approval_class = AuthorisedUserPermit
        else:
            # Do nothing
            return

        days_setting = NumberOfDaysSetting.get_setting_by_date(days_type, today)
        if not days_setting:
            # No number of days found
            raise ImproperlyConfigured("NumberOfDays: {} is not defined for the date: {}".format(days_type.name, today))
        # NOTE: When sending the reminder:
        #       sold_date + 6months - number_of_days < today
        #       sold_date < today - 6months + number_of_days
        boundary_date = today - relativedelta(months=+6) + relativedelta(days=days_setting.number_of_days)

        logger.info('Running command {}'.format(__name__))

        # For debug
        # params = options.get('params')
        # debug = True if params.get('debug', 'f').lower() in ['true', 't', 'yes', 'y'] else False
        # approval_lodgement_number = params.get('send_vessel_nominate_reminder_lodgement_number', 'no-number')

        # Get approvals
        if approval_type == WaitingListAllocation.code:
            queries = Q()
            queries &= Q(status__in=(Approval.APPROVAL_STATUS_CURRENT, Approval.APPROVAL_STATUS_SUSPENDED))
            queries &= Q(current_proposal__vessel_ownership__end_date__isnull=False)
            queries &= Q(current_proposal__vessel_ownership__end_date__lt=boundary_date)
            queries &= Q(vessel_nomination_reminder_sent=False)
            # if debug:
            #     queries = queries | Q(lodgement_number__iexact=approval_lodgement_number)
            approvals = approval_class.objects.filter(queries)
        elif approval_type == MooringLicence.code:
            queries = Q()
            queries &= Q(status__in=(Approval.APPROVAL_STATUS_CURRENT, Approval.APPROVAL_STATUS_SUSPENDED))
            queries &= Q(vessel_nomination_reminder_sent=False)
            possible_approvals = approval_class.objects.filter(queries)

            approvals = []
            for approval in possible_approvals:
                # Check if there is at least one vessel which meets the ML vessel requirement
                if not ml_meet_vessel_requirement(approval, boundary_date):
                    approvals.append(approval)
            # if debug:
            #     apps = MooringLicence.objects.filter(lodgement_number__iexact=approval_lodgement_number)
            #     if apps:
            #         approvals.append(apps[0])
        elif approval_type == AuthorisedUserPermit.code:
            queries = Q()
            queries &= Q(status__in=(Approval.APPROVAL_STATUS_CURRENT, Approval.APPROVAL_STATUS_SUSPENDED))
            queries &= Q(current_proposal__vessel_ownership__end_date__lt=boundary_date)
            queries &= Q(vessel_nomination_reminder_sent=False)
            # if debug:
            #     queries = queries | Q(lodgement_number__iexact=approval_lodgement_number)
            approvals = approval_class.objects.filter(queries)

        for a in approvals:
            try:
                send_vessel_nomination_reminder_mail(a)
                a.vessel_nomination_reminder_sent = True
                a.save()
                logger.info('Reminder to permission holder sent for Approval {}'.format(a.lodgement_number))
                updates.append(a.lodgement_number)
            except Exception as e:
                err_msg = 'Error sending reminder to permission holder for Approval {}'.format(a.lodgement_number)
                logger.error('{}\n{}'.format(err_msg, str(e)))
                errors.append(err_msg)

        cmd_name = __name__.split('.')[-1].replace('_', ' ').upper()
        # err_str = '<strong style="color: red;">Errors: {}</strong>'.format(len(errors)) if len(
        #     errors) > 0 else '<strong style="color: green;">Errors: 0</strong>'
        # msg = '<p>{} ({}) completed. {}. IDs updated: {}.</p>'.format(cmd_name, approval_type, err_str, updates)
        msg = construct_email_message(cmd_name, errors, updates)
        logger.info(msg)
        cron_email.info(msg)