Beispiel #1
0
def platform_admin_quarterly_breakdown_csv():
    year_quarter = request.args.get('year_quarter')
    start_date, end_date = SUPPORTED_YEAR_QUARTERS[year_quarter]

    def present_row(billing_data):
        return [
                billing_data.get('service_id'),
                billing_data.get('service_name'),
                start_date,
                end_date,
                billing_data.get('notification_type'),
                billing_data.get('rate'),
                billing_data.get('rate_multiplier'),
                billing_data.get('notifications_sent'),
                billing_data.get('billable_units_sent'),
                billing_data.get('total_billable_units'),
            ]

    data = platform_stats_api_client.get_usage_for_all_services({
        'start_date': start_date,
        'end_date': end_date
    })

    columns = [
        "Service ID", "Service name", "Start date", "End date",
        "Notification type", "Rate", "Rate multiplier",
        "Notifications sent", "Billable units sent", "Total billable units"
    ]

    csv_data = [columns, *(present_row(d) for d in data)]
    return Spreadsheet.from_rows(csv_data).as_csv_data, 200, {
        'Content-Type': 'text/csv; charset=utf-8',
        'Content-Disposition': f'inline; filename="quarterly-usage-{year_quarter}.csv"'
    }
def usage_for_all_services():
    form = RequiredDateFilterForm()

    if form.validate_on_submit():
        start_date = form.start_date.data
        end_date = form.end_date.data
        headers = [
            "organisation_id", "organisation_name", "service_id",
            "service_name", "sms_cost", "sms_fragments", "letter_cost",
            "letter_breakdown"
        ]

        result = billing_api_client.get_usage_for_all_services(
            start_date, end_date)
        rows = [[
            r['organisation_id'], r["organisation_name"], r["service_id"],
            r["service_name"], r["sms_cost"], r['sms_fragments'],
            r["letter_cost"], r["letter_breakdown"].strip()
        ] for r in result]
        if rows:
            return Spreadsheet.from_rows([headers] + rows).as_csv_data, 200, {
                'Content-Type':
                'text/csv; charset=utf-8',
                'Content-Disposition':
                'attachment; filename="Usage for all services from {} to {}.csv"'
                .format(start_date, end_date)
            }
        else:
            flash('No results for dates')
    return render_template('views/platform-admin/usage_for_all_services.html',
                           form=form)
def send_method_stats_by_service():
    form = RequiredDateFilterForm()

    if form.validate_on_submit():
        start_date = form.start_date.data
        end_date = form.end_date.data

        headers = [
            "service_id",
            "service_name",
            "org_name",
            "notification_type",
            "send_method",
            "count",
        ]
        result = platform_stats_api_client.get_send_method_stats_by_service(start_date, end_date)

        return (
            Spreadsheet.from_rows([headers] + result).as_csv_data,
            200,
            {
                "Content-Type": "text/csv; charset=utf-8",
                "Content-Disposition": 'attachment; filename="{} to {} send method per service report.csv"'.format(
                    start_date, end_date
                ),
            },
        )

    return render_template("views/platform-admin/send_method_stats_by_service.html", form=form)
Beispiel #4
0
def returned_letters_report(service_id, reported_at):
    returned_letters = service_api_client.get_returned_letters(
        service_id, reported_at)
    column_names = OrderedDict([
        ('notification_id', 'Notification ID'),
        ('client_reference', 'Reference'), ('created_at', 'Date sent'),
        ('email_address', 'Sent by'), ('template_name', 'Template name'),
        ('template_id', 'Template ID'),
        ('template_version', 'Template version'),
        ('original_file_name', 'Spreadsheet file name'),
        ('job_row_number', 'Spreadsheet row number'),
        ('uploaded_letter_file_name', 'Uploaded letter file name')
    ])

    # initialise with header row
    data = [[x for x in column_names.values()]]

    for row in returned_letters:
        data.append([row[key] for key in column_names.keys()])

    return Spreadsheet.from_rows(data).as_csv_data, 200, {
        'Content-Type':
        'text/csv; charset=utf-8',
        'Content-Disposition':
        'inline; filename="{} returned letters.csv"'.format(reported_at)
    }
Beispiel #5
0
def trial_services_csv():
    results = service_api_client.get_trial_services_data()["data"]
    trial_services_columns = [
        "Service ID", "Created date", "Organisation", "Organisation type",
        "Domains", "Service name", "SMS sent this year",
        "Emails sent this year", "Letters sent this year"
    ]
    trial_services_data = []
    trial_services_data.append(trial_services_columns)
    for row in results:
        trial_services_data.append([
            row["service_id"],
            datetime.strptime(row["created_date"],
                              '%a, %d %b %Y %X %Z').strftime("%d-%m-%Y"),
            row["organisation_name"],
            row.get("organisation_type", "TODO"),
            ', '.join(row["domains"]),
            row["service_name"],
            row["sms_totals"],
            row["email_totals"],
            row["letter_totals"],
        ])

    return Spreadsheet.from_rows(trial_services_data).as_csv_data, 200, {
        'Content-Type':
        'text/csv; charset=utf-8',
        'Content-Disposition':
        'inline; filename="{} trial services report.csv"'.format(
            format_date_numeric(
                datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")), )
    }
Beispiel #6
0
def upload_contact_list(service_id):
    form = CsvUploadForm()

    if form.validate_on_submit():
        try:
            upload_id = ContactList.upload(
                current_service.id,
                Spreadsheet.from_file_form(form).as_dict,
            )
            file_name_metadata = unicode_truncate(
                SanitiseASCII.encode(form.file.data.filename), 1600)
            ContactList.set_metadata(current_service.id,
                                     upload_id,
                                     original_file_name=file_name_metadata)
            return redirect(
                url_for(
                    '.check_contact_list',
                    service_id=service_id,
                    upload_id=upload_id,
                ))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash(
                'Could not read {}. Try using a different file format.'.format(
                    form.file.data.filename))
        except (XLDateError):
            flash((
                '{} contains numbers or dates that Notify cannot understand. '
                'Try formatting all columns as ‘text’ or export your file as CSV.'
            ).format(form.file.data.filename))

    return render_template(
        'views/uploads/contact-list/upload.html',
        form=form,
        allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS,
    )
def notifications_sent_by_service():
    form = RequiredDateFilterForm()

    if form.validate_on_submit():
        start_date = form.start_date.data
        end_date = form.end_date.data

        headers = [
            'date_created', 'service_id', 'service_name', 'notification_type',
            'count_sending', 'count_delivered', 'count_technical_failure',
            'count_temporary_failure', 'count_permanent_failure', 'count_sent'
        ]
        result = notification_api_client.get_notification_status_by_service(
            start_date, end_date)

        for row in result:
            row[0] = datetime.strptime(
                row[0], '%a, %d %b %Y %X %Z').strftime('%Y-%m-%d')

        return Spreadsheet.from_rows([headers] + result).as_csv_data, 200, {
            'Content-Type':
            'text/csv; charset=utf-8',
            'Content-Disposition':
            'attachment; filename="{} to {} notification status per service report.csv"'
            .format(start_date, end_date)
        }

    return render_template(
        'views/platform-admin/notifications_by_service.html', form=form)
 def __call__(self, form, field):
     if not Spreadsheet.can_handle(field.data.filename):
         raise ValidationError(
             "{} {}".format(
                 field.data.filename,
                 _("is not a spreadsheet that GC Notify can read"),
             )
         )
def test_can_create_spreadsheet_from_dict():
    assert Spreadsheet.from_dict(OrderedDict(
        foo='bar',
        name='Jane',
    )).as_csv_data == (
        "foo,name\r\n"
        "bar,Jane\r\n"
    )
def usage_for_all_services_by_organisation():
    form = GetServicesByOrganisationForm()
    list_organisation = [("", "Tous")]

    for org in Organisations():
        list_organisation.append(tuple((org.id, org.name)))

    form.organisations.choices = list_organisation

    if form.validate_on_submit():
        organisation_id = form.organisations.data
        start_date = form.start_date.data
        end_date = form.end_date.data

        headers = [translate("Start Date"), translate("End Date"), translate("Organisation ID"), translate("Organisation name"),
                   translate("Sagir Code"), translate("Service ID"), translate("Service name"), translate("Restricted"),
                   translate("Details Type"), translate("Provider Name"), translate("Number Sent"), translate("Billable Units")]

        result = billing_api_client.get_usage_for_all_services_by_organisation(organisation_id, start_date, end_date)

        rows = []
        if result:
            for key, value in result["PGNUtilization"]["Organisations"].items():
                for servKey, servValue in value["services"].items():
                    details = {}
                    if servValue["email_details"] != {}:
                        details["email"] = servValue["email_details"]

                    if servValue["sms_details"] != {}:
                        details["sms"] = servValue["sms_details"]

                    for detailsKey, detailsValue in details.items():
                        for subDetailsKey, subDetailsValue in detailsValue["providers"].items():
                            if detailsKey == "sms":
                                details_type = "SMS"
                                details_billable = subDetailsValue["billable_units"]
                            else:
                                details_type = "Email"
                                details_billable = ""

                        rows.append([str(start_date), str(end_date), value["organisation_id"], key, value["sagir_code"],
                                    servValue["service_id"], servKey, translate("Trial") if servValue["restricted"] else translate("Live")
                                    , details_type, subDetailsKey, subDetailsValue["number_sent"], details_billable])

            return Spreadsheet.from_rows([headers] + rows).as_excel_file, 200, {
                'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                'Content-Disposition': 'attachment; filename="Usage for all services by organisation from {} to {}.xlsx"'.format(
                    start_date, end_date
                )
            }

        else:
            flash('No results for dates')

    return render_template(
        'views/platform-admin/usage_for_all_services_by_organisation.html',
        form=form
    )
def send_messages(service_id, template_id):
    session['sender_id'] = None
    db_template = service_api_client.get_service_template(service_id, template_id)['data']

    if email_or_sms_not_enabled(db_template['template_type'], current_service['permissions']):
        return redirect(url_for(
            '.action_blocked',
            service_id=service_id,
            notification_type=db_template['template_type'],
            return_to='view_template',
            template_id=template_id
        ))

    template = get_template(
        db_template,
        current_service,
        show_recipient=True,
        expand_emails=True,
        letter_preview_url=url_for(
            '.view_letter_template_preview',
            service_id=service_id,
            template_id=template_id,
            filetype='png',
            page_count=get_page_count_for_letter(db_template),
        ),
    )

    form = CsvUploadForm()
    if form.validate_on_submit():
        try:
            upload_id = s3upload(
                service_id,
                Spreadsheet.from_file(form.file.data, filename=form.file.data.filename).as_dict,
                current_app.config['AWS_REGION']
            )
            session['upload_data'] = {
                "template_id": template_id,
                "original_file_name": form.file.data.filename
            }
            return redirect(url_for('.check_messages',
                                    service_id=service_id,
                                    upload_id=upload_id,
                                    template_type=template.template_type))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash('Couldn’t read {}. Try using a different file format.'.format(
                form.file.data.filename
            ))

    column_headings = first_column_headings[template.template_type] + list(template.placeholders)

    return render_template(
        'views/send.html',
        template=template,
        column_headings=list(ascii_uppercase[:len(column_headings)]),
        example=[column_headings, get_example_csv_rows(template)],
        form=form
    )
Beispiel #12
0
def get_example_csv(service_id, template_id):
    template = Template(service_api_client.get_service_template(service_id, template_id)['data'])
    return Spreadsheet.from_rows([
        [first_column_heading[template.template_type]] + list(template.placeholders),
        get_example_csv_rows(template)
    ]).as_csv_data, 200, {
        'Content-Type': 'text/csv; charset=utf-8',
        'Content-Disposition': 'inline; filename="{}.csv"'.format(template.name)
    }
def get_example_csv(service_id, template_id):
    template = get_template(
        service_api_client.get_service_template(service_id, template_id)['data'], current_service
    )
    return Spreadsheet.from_rows([
        first_column_headings[template.template_type] + list(template.placeholders),
        get_example_csv_rows(template)
    ]).as_csv_data, 200, {
        'Content-Type': 'text/csv; charset=utf-8',
        'Content-Disposition': 'inline; filename="{}.csv"'.format(template.name)
    }
Beispiel #14
0
def make_and_upload_csv_file(service_id, template):
    upload_id = s3upload(
        service_id,
        Spreadsheet.from_dict(
            session['placeholders'],
            filename=current_app.config['TEST_MESSAGE_FILENAME']).as_dict,
        current_app.config['AWS_REGION'],
    )
    return redirect(
        url_for('.check_messages',
                upload_id=upload_id,
                service_id=service_id,
                template_id=template.id,
                from_test=True,
                help=2 if get_help_argument() else 0))
Beispiel #15
0
def activity_download():
    stats = get_latest_stats(get_current_locale(current_app))["monthly_stats"]

    csv_data = [["date", "sms_count", "email_count", "total"]]
    for _, row in stats.items():
        csv_data.append([row["year_month"], row["sms"], row["email"], row["total"]])

    return (
        Spreadsheet.from_rows(csv_data).as_csv_data,
        200,
        {
            "Content-Type": "text/csv; charset=utf-8",
            "Content-Disposition": 'inline; filename="{} activity.csv"'.format(
                datetime.utcnow().strftime("%Y-%m-%d"),
            ),
        },
    )
def inbox_download(service_id):
    return Response(
        Spreadsheet.from_rows([[
            'Phone number',
            'Message',
            'Received',
        ]] + [[
            message['user_number'],
            message['content'].lstrip(('=+-@')),
            format_datetime_numeric(message['created_at']),
        ] for message in service_api_client.get_inbound_sms(service_id)]
                              ).as_csv_data,
        mimetype='text/csv',
        headers={
            'Content-Disposition':
            'inline; filename="Received text messages {}.csv"'.format(
                format_date_numeric(datetime.utcnow().isoformat()))
        })
def get_billing_report():
    form = RequiredDateFilterForm()

    if form.validate_on_submit():
        start_date = form.start_date.data
        end_date = form.end_date.data
        headers = [
            "organisation_id", "organisation_name", "service_id",
            "service_name", "sms_cost", "sms_fragments", "letter_cost",
            "letter_breakdown", "purchase_order_number", "contact_names",
            "contact_email_addresses", "billing_reference"
        ]
        try:
            result = billing_api_client.get_data_for_billing_report(
                start_date, end_date)
        except HTTPError as e:
            message = 'Date must be in a single financial year.'
            if e.status_code == 400 and e.message == message:
                flash(message)
                return render_template(
                    'views/platform-admin/get-billing-report.html', form=form)
            else:
                raise e
        rows = [[
            r["organisation_id"], r["organisation_name"], r["service_id"],
            r["service_name"], r["sms_cost"], r["sms_fragments"],
            r["letter_cost"], r["letter_breakdown"].strip(),
            r.get("purchase_order_number"),
            r.get("contact_names"),
            r.get("contact_email_addresses"),
            r.get("billing_reference")
        ] for r in result]
        if rows:
            return Spreadsheet.from_rows([headers] + rows).as_csv_data, 200, {
                'Content-Type':
                'text/csv; charset=utf-8',
                'Content-Disposition':
                'attachment; filename="Billing Report from {} to {}.csv"'.
                format(start_date, end_date)
            }
        else:
            flash('No results for dates')
    return render_template('views/platform-admin/get-billing-report.html',
                           form=form)
def live_services_csv():
    results = service_api_client.get_live_services_data()["data"]

    column_names = OrderedDict(
        [
            ("service_id", "Service ID"),
            ("organisation_name", "Organisation"),
            ("organisation_type", "Organisation type"),
            ("service_name", "Service name"),
            ("consent_to_research", "Consent to research"),
            ("contact_name", "Main contact"),
            ("contact_email", "Contact email"),
            ("contact_mobile", "Contact mobile"),
            ("live_date", "Live date"),
            ("sms_volume_intent", "SMS volume intent"),
            ("email_volume_intent", "Email volume intent"),
            ("letter_volume_intent", "Letter volume intent"),
            ("sms_totals", "SMS sent this year"),
            ("email_totals", "Emails sent this year"),
            ("letter_totals", "Letters sent this year"),
            ("free_sms_fragment_limit", "Free sms allowance"),
        ]
    )

    # initialise with header row
    live_services_data = [[x for x in column_names.values()]]

    for row in results:
        if row["live_date"]:
            row["live_date"] = datetime.strptime(row["live_date"], "%a, %d %b %Y %X %Z").strftime("%d-%m-%Y")

        live_services_data.append([row[api_key] for api_key in column_names.keys()])

    return (
        Spreadsheet.from_rows(live_services_data).as_csv_data,
        200,
        {
            "Content-Type": "text/csv; charset=utf-8",
            "Content-Disposition": 'inline; filename="{} live services report.csv"'.format(
                format_date_numeric(datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
            ),
        },
    )
Beispiel #19
0
def get_example_csv(service_id, template_id):
    template = get_template(
        service_api_client.get_service_template(service_id,
                                                template_id)["data"],
        current_service,
    )
    return (
        Spreadsheet.from_rows([
            get_spreadsheet_column_headings_from_template(template),
            get_example_csv_rows(template),
        ]).as_csv_data,
        200,
        {
            "Content-Type":
            "text/csv; charset=utf-8",
            "Content-Disposition":
            'inline; filename="{}.csv"'.format(template.name),
        },
    )
Beispiel #20
0
def live_services_csv():
    results = service_api_client.get_live_services_data()["data"]
    live_services_columns = [
        "Service ID", "Organisation", "Organisation type", "Domains",
        "Service name", "Consent to research", "Main contact", "Contact email",
        "Contact mobile", "Live date", "Created date", "SMS volume intent",
        "Email volume intent", "Letter volume intent", "SMS sent this year",
        "Emails sent this year", "Letters sent this year"
    ]
    live_services_data = []
    live_services_data.append(live_services_columns)
    for row in results:
        live_services_data.append([
            row["service_id"],
            row["organisation_name"],
            row.get("organisation_type", "TODO"),
            ', '.join(row["domains"]),
            row["service_name"],
            row.get("consent_to_research", "TODO"),
            row["contact_name"],
            row["contact_email"],
            row["contact_mobile"],
            datetime.strptime(row["live_date"],
                              '%a, %d %b %Y %X %Z').strftime("%d-%m-%Y")
            if row["live_date"] else None,
            datetime.strptime(row["created_date"],
                              '%a, %d %b %Y %X %Z').strftime("%d-%m-%Y"),
            row.get("sms_volume_intent", "TODO"),
            row.get("email_volume_intent", "TODO"),
            row.get("letter_volume_intent", "TODO"),
            row["sms_totals"],
            row["email_totals"],
            row["letter_totals"],
        ])

    return Spreadsheet.from_rows(live_services_data).as_csv_data, 200, {
        'Content-Type':
        'text/csv; charset=utf-8',
        'Content-Disposition':
        'inline; filename="{} live services report.csv"'.format(
            format_date_numeric(
                datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")), )
    }
Beispiel #21
0
def service_users_report(service_id):
    # permissions are structured differently on invited vs accepted-invite users
    def user_permissions(user):
        return {
            permission
            for permission in all_permissions
            if user.has_permission_for_service(service_id, permission)
        }

    def present_row(user):
        logged_in_at = getattr(user, 'logged_in_at', None)
        if logged_in_at:
            logged_in_at = gmt_timezones(logged_in_at)

        return [
            user.email_address,
            getattr(user, 'name', None),  # does not exist on invited user
            getattr(user, 'mobile_number',
                    None),  # does not exist on invited user
            logged_in_at,
            user.auth_type,
            ';'.join(user_permissions(user))
        ]

    users = sorted(
        user_api_client.get_users_for_service(service_id=service_id) + [
            invite for invite in invite_api_client.get_invites_for_service(
                service_id=service_id) if invite.status != 'accepted'
        ],
        key=lambda user: user.email_address,
    )

    columns = [
        "email_address", "name", "mobile_number", "last_login", "auth_type",
        "permissions"
    ]
    csv_data = [columns, *(present_row(user) for user in users)]
    return Spreadsheet.from_rows(csv_data).as_csv_data, 200, {
        'Content-Type': 'text/csv; charset=utf-8',
        'Content-Disposition':
        f'inline; filename="service-{service_id}-users.csv"'
    }
Beispiel #22
0
def send_test(service_id, template_id):

    file_name = current_app.config['TEST_MESSAGE_FILENAME']

    template = Template(service_api_client.get_service_template(
        service_id, template_id)['data'],
                        prefix=current_service['name'],
                        sms_sender=current_service['sms_sender'])

    if len(template.placeholders) == 0 or request.method == 'POST':
        upload_id = s3upload(
            service_id, {
                'file_name':
                file_name,
                'data':
                Spreadsheet.from_rows([
                    [first_column_heading[template.template_type]] +
                    list(template.placeholders),
                    get_example_csv_rows(template,
                                         use_example_as_example=False,
                                         submitted_fields=request.form)
                ]).as_csv_data
            }, current_app.config['AWS_REGION'])
        session['upload_data'] = {
            "template_id": template_id,
            "original_file_name": file_name
        }
        return redirect(
            url_for('.check_messages',
                    upload_id=upload_id,
                    service_id=service_id,
                    template_type=template.template_type,
                    from_test=True,
                    help=2 if request.args.get('help') else 0))

    return render_template(
        'views/send-test.html',
        template=template,
        recipient_column=first_column_heading[template.template_type],
        example=[get_example_csv_rows(template, use_example_as_example=False)],
        help=get_help_argument())
Beispiel #23
0
def send_test(service_id, template_id):

    file_name = current_app.config['TEST_MESSAGE_FILENAME']

    template = Template(
        service_api_client.get_service_template(service_id, template_id)['data'],
        prefix=current_service['name']
    )

    if len(template.placeholders) == 0 or request.method == 'POST':
        upload_id = s3upload(
            service_id,
            {
                'file_name': file_name,
                'data': Spreadsheet.from_rows([
                    [first_column_heading[template.template_type]] + list(template.placeholders),
                    get_example_csv_rows(template, use_example_as_example=False, submitted_fields=request.form)
                ]).as_csv_data
            },
            current_app.config['AWS_REGION']
        )
        session['upload_data'] = {
            "template_id": template_id,
            "original_file_name": file_name
        }
        return redirect(url_for(
            '.check_messages',
            upload_id=upload_id,
            service_id=service_id,
            template_type=template.template_type,
            from_test=True,
            help=2 if request.args.get('help') else 0
        ))

    return render_template(
        'views/send-test.html',
        template=template,
        recipient_column=first_column_heading[template.template_type],
        example=[get_example_csv_rows(template, use_example_as_example=False)],
        help=get_help_argument()
    )
def live_services_csv():
    results = service_api_client.get_live_services_data()["data"]

    column_names = OrderedDict([
        ('service_id', 'Service ID'),
        ('organisation_name', 'Organisation'),
        ('organisation_type', 'Organisation type'),
        ('service_name', 'Service name'),
        ('consent_to_research', 'Consent to research'),
        ('contact_name', 'Main contact'),
        ('contact_email', 'Contact email'),
        ('contact_mobile', 'Contact mobile'),
        ('live_date', 'Live date'),
        ('sms_volume_intent', 'SMS volume intent'),
        ('email_volume_intent', 'Email volume intent'),
        ('letter_volume_intent', 'Letter volume intent'),
        ('sms_totals', 'SMS sent this year'),
        ('email_totals', 'Emails sent this year'),
        ('letter_totals', 'Letters sent this year'),
        ('free_sms_fragment_limit', 'Free sms allowance'),
    ])

    # initialise with header row
    live_services_data = [[x for x in column_names.values()]]

    for row in results:
        if row['live_date']:
            row['live_date'] = datetime.strptime(
                row["live_date"], '%a, %d %b %Y %X %Z').strftime("%d-%m-%Y")

        live_services_data.append(
            [row[api_key] for api_key in column_names.keys()])

    return Spreadsheet.from_rows(live_services_data).as_csv_data, 200, {
        'Content-Type':
        'text/csv; charset=utf-8',
        'Content-Disposition':
        'inline; filename="{} live services report.csv"'.format(
            format_date_numeric(
                datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")), )
    }
def trial_report_csv():
    data = platform_stats_api_client.usage_for_trial_services()
    headers = [
        "service_id",
        "service_name",
        "creation_date",
        "created_by_name",
        "created_by_email",
        "notification_type",
        "notification_sum",
    ]

    return (
        Spreadsheet.from_rows([headers] + data).as_csv_data,
        200,
        {
            "Content-Type": "text/csv; charset=utf-8",
            "Content-Disposition": 'inline; filename="{} trial report.csv"'.format(
                format_date_numeric(datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
            ),
        },
    )
Beispiel #26
0
def platform_admin_quarterly_billing_csv():
    year_quarter = request.args.get('year_quarter')
    start_date, end_date = SUPPORTED_YEAR_QUARTERS[year_quarter]

    def present_row(billing_data):
        return [
                billing_data.get('service_id'),
                billing_data.get('service_name'),
                start_date,
                end_date,
                billing_data.get('sms_rate'),
                billing_data.get('total_cost'),
                billing_data.get("notifications_sent"),
                billing_data.get("billable_units"),
                billing_data.get("billable_units_adjusted"),
                billing_data.get("sms_free_rollover"),
                billing_data.get("chargeable_units"),
                billing_data.get("domestic_units"),
                billing_data.get("international_units"),
            ]

    data = platform_stats_api_client.get_billing_for_all_services({
        'start_date': start_date,
        'end_date': end_date
    })

    columns = [
        "Service ID", "Service name", "Start date", "End date",
        "SMS rate", "Total cost",
        "SMS Notifications sent", "Billable units", "Billable units adjusted(international)",
        "SMS free rollover from last quarter", "Chargeable units",
        "Domestic units", "International units",
    ]

    csv_data = [columns, *(present_row(d) for d in data)]
    return Spreadsheet.from_rows(csv_data).as_csv_data, 200, {
        'Content-Type': 'text/csv; charset=utf-8',
        'Content-Disposition': f'inline; filename="quarterly-billing-{year_quarter}.csv"'
    }
def performance_platform_xlsx():
    results = service_api_client.get_live_services_data()["data"]
    live_services_columns = ["service_id", "agency", "service_name", "_timestamp", "service", "count"]
    live_services_data = []
    live_services_data.append(live_services_columns)
    for row in results:
        live_services_data.append([
            row["service_id"],
            row["organisation_name"],
            row["service_name"],
            datetime.strptime(
                row["live_date"], '%a, %d %b %Y %X %Z'
            ).strftime("%Y-%m-%dT%H:%M:%S") + "Z" if row["live_date"] else None,
            "notification",
            1
        ])

    return Spreadsheet.from_rows(live_services_data).as_excel_file, 200, {
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'Content-Disposition': 'attachment; filename="{} performance platform report.xlsx"'.format(
            format_date_numeric(datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
        )
    }
Beispiel #28
0
def send_messages(service_id, template_id):
    template = Template(
        service_api_client.get_service_template(service_id, template_id)['data'],
        prefix=current_service['name']
    )

    form = CsvUploadForm()
    if form.validate_on_submit():
        try:
            upload_id = s3upload(
                service_id,
                Spreadsheet.from_file(form.file.data, filename=form.file.data.filename).as_dict,
                current_app.config['AWS_REGION']
            )
            session['upload_data'] = {
                "template_id": template_id,
                "original_file_name": form.file.data.filename
            }
            return redirect(url_for('.check_messages',
                                    service_id=service_id,
                                    upload_id=upload_id,
                                    template_type=template.template_type))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash('Couldn’t read {}. Try using a different file format.'.format(
                form.file.data.filename
            ))

    return render_template(
        'views/send.html',
        template=template,
        column_headings=list(ascii_uppercase[:len(template.placeholders) + 1]),
        example=[
            [first_column_heading[template.template_type]] + list(template.placeholders),
            get_example_csv_rows(template)
        ],
        form=form
    )
def notifications_sent_by_service():
    form = RequiredDateFilterForm()

    if form.validate_on_submit():
        start_date = form.start_date.data
        end_date = form.end_date.data

        headers = [
            "date_created",
            "service_id",
            "service_name",
            "notification_type",
            "count_sending",
            "count_delivered",
            "count_technical_failure",
            "count_temporary_failure",
            "count_permanent_failure",
            "count_sent",
        ]
        result = notification_api_client.get_notification_status_by_service(start_date, end_date)

        for row in result:
            row[0] = datetime.strptime(row[0], "%a, %d %b %Y %X %Z").strftime("%Y-%m-%d")

        return (
            Spreadsheet.from_rows([headers] + result).as_csv_data,
            200,
            {
                "Content-Type": "text/csv; charset=utf-8",
                "Content-Disposition": 'attachment; filename="{} to {} notification status per service report.csv"'.format(
                    start_date, end_date
                ),
            },
        )

    return render_template("views/platform-admin/notifications_by_service.html", form=form)
Beispiel #30
0
def send_messages(service_id, template_id):
    template = Template(service_api_client.get_service_template(
        service_id, template_id)['data'],
                        prefix=current_service['name'],
                        sms_sender=current_service['sms_sender'])

    form = CsvUploadForm()
    if form.validate_on_submit():
        try:
            upload_id = s3upload(
                service_id,
                Spreadsheet.from_file(
                    form.file.data, filename=form.file.data.filename).as_dict,
                current_app.config['AWS_REGION'])
            session['upload_data'] = {
                "template_id": template_id,
                "original_file_name": form.file.data.filename
            }
            return redirect(
                url_for('.check_messages',
                        service_id=service_id,
                        upload_id=upload_id,
                        template_type=template.template_type))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash(
                'Couldn’t read {}. Try using a different file format.'.format(
                    form.file.data.filename))

    return render_template(
        'views/send.html',
        template=template,
        column_headings=list(ascii_uppercase[:len(template.placeholders) + 1]),
        example=[[first_column_heading[template.template_type]] +
                 list(template.placeholders),
                 get_example_csv_rows(template)],
        form=form)
 def __call__(self, form, field):
     if not Spreadsheet.can_handle(field.data.filename):
         raise ValidationError("{} isn’t a spreadsheet that Notify can read".format(field.data.filename))
Beispiel #32
0
def send_messages(service_id, template_id):
    # if there's lots of data in the session, lets log it for debugging purposes
    # TODO: Remove this once we're confident we have session size under control
    if len(session.get('file_uploads', {}).keys()) > 2:
        current_app.logger.info(
            'session contains large file_uploads - json_len {}, keys: {}'.
            format(len(json.dumps(session['file_uploads'])),
                   session['file_uploads'].keys()))

    db_template = current_service.get_template_with_user_permission_or_403(
        template_id, current_user)

    email_reply_to = None
    sms_sender = None

    if db_template['template_type'] == 'email':
        email_reply_to = get_email_reply_to_address_from_session()
    elif db_template['template_type'] == 'sms':
        sms_sender = get_sms_sender_from_session()

    if email_or_sms_not_enabled(db_template['template_type'],
                                current_service.permissions):
        return redirect(
            url_for('.action_blocked',
                    service_id=service_id,
                    notification_type=db_template['template_type'],
                    return_to='view_template',
                    template_id=template_id))

    template = get_template(
        db_template,
        current_service,
        show_recipient=True,
        letter_preview_url=url_for(
            '.view_letter_template_preview',
            service_id=service_id,
            template_id=template_id,
            filetype='png',
            page_count=get_page_count_for_letter(db_template),
        ),
        email_reply_to=email_reply_to,
        sms_sender=sms_sender,
    )

    form = CsvUploadForm()
    if form.validate_on_submit():
        try:
            upload_id = s3upload(
                service_id,
                Spreadsheet.from_file(
                    form.file.data, filename=form.file.data.filename).as_dict,
                current_app.config['AWS_REGION'])
            return redirect(
                url_for(
                    '.check_messages',
                    service_id=service_id,
                    upload_id=upload_id,
                    template_id=template.id,
                    original_file_name=form.file.data.filename,
                ))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash(
                'Couldn’t read {}. Try using a different file format.'.format(
                    form.file.data.filename))
        except (XLDateError):
            flash((
                '{} contains numbers or dates that Notification can’t understand. '
                'Try formatting all columns as ‘text’ or export your file as CSV.'
            ).format(form.file.data.filename))

    column_headings = get_spreadsheet_column_headings_from_template(template)

    return render_template(
        'views/send.html',
        template=template,
        column_headings=list(ascii_uppercase[:len(column_headings)]),
        example=[column_headings,
                 get_example_csv_rows(template)],
        form=form)
Beispiel #33
0
def services_billing_csv():
    def present_row(billing_data):
        return [
            billing_data.get("service_id"),
            billing_data.get("service_name"),
            billing_data.get("breakdown_aet"),
            billing_data.get("breakdown_fy"),
            billing_data.get("breakdown_fy_year"),
            billing_data.get("breakdown_fy_quarter"),
            billing_data.get("notifications"),
            billing_data.get("notifications_sms"),
            billing_data.get("notifications_email"),
            billing_data.get("fragments_free_limit"),
            billing_data.get("fragments_domestic"),
            billing_data.get("fragments_international"),
            billing_data.get("cost"),
            billing_data.get("cost_chargeable"),
            billing_data.get("cost_cumulative"),
            billing_data.get("cost_chargeable_cumulative"),
            billing_data.get("units"),
            billing_data.get("units_cumulative"),
            billing_data.get("units_chargeable"),
            billing_data.get("units_chargeable_cumulative"),
            billing_data.get("units_free_available"),
            billing_data.get("units_free_remaining"),
            billing_data.get("units_free_used"),
            billing_data.get("unit_rate_domestic"),
            billing_data.get("unit_rate_international"),
        ]

    data = platform_stats_api_client.get_services_billing()

    columns = [
        "Service ID",
        "Service name",
        "AET period start",
        "FY period start",
        "FY year",
        "FY quarter",
        "Notifications sent",
        "SMS Notifications sent",
        "Email Notifications sent",
        "Service annual SMS fragment limit",
        "Domestic SMS fragments",
        "International SMS fragments",
        "Cost",
        "Chargeable cost",
        "Cost cumulative(year)",
        "Chargeable cost cumulative(year)",
        "Units",
        "Units cumulative(year)",
        "Chargeable units",
        "Chargeable units cumulative(year)",
        "Free units available",
        "Free units remaining",
        "Free units used",
        "Domestic unit rate",
        "International unit rate",
    ]

    csv_data = [columns, *(present_row(d) for d in data)]
    return Spreadsheet.from_rows(csv_data).as_csv_data, 200, {
        'Content-Type':
        'text/csv; charset=utf-8',
        'Content-Disposition':
        f'inline; filename="{datetime.now().date()}-services-billing.csv"'
    }
Beispiel #34
0
def send_messages(service_id, template_id):
    db_template = current_service.get_template_with_user_permission_or_403(
        template_id, current_user)

    email_reply_to = None
    sms_sender = None

    if db_template['template_type'] == 'email':
        email_reply_to = get_email_reply_to_address_from_session()
    elif db_template['template_type'] == 'sms':
        sms_sender = get_sms_sender_from_session()

    if db_template[
            'template_type'] not in current_service.available_template_types:
        return redirect(
            url_for('.action_blocked',
                    service_id=service_id,
                    notification_type=db_template['template_type'],
                    return_to='view_template',
                    template_id=template_id))

    template = get_template(
        db_template,
        current_service,
        show_recipient=True,
        letter_preview_url=url_for(
            'no_cookie.view_letter_template_preview',
            service_id=service_id,
            template_id=template_id,
            filetype='png',
            page_count=get_page_count_for_letter(db_template),
        ),
        email_reply_to=email_reply_to,
        sms_sender=sms_sender,
    )

    form = CsvUploadForm()
    if form.validate_on_submit():
        try:
            upload_id = s3upload(service_id,
                                 Spreadsheet.from_file_form(form).as_dict,
                                 current_app.config['AWS_REGION'])
            file_name_metadata = unicode_truncate(
                SanitiseASCII.encode(form.file.data.filename), 1600)
            set_metadata_on_csv_upload(service_id,
                                       upload_id,
                                       original_file_name=file_name_metadata)
            return redirect(
                url_for(
                    '.check_messages',
                    service_id=service_id,
                    upload_id=upload_id,
                    template_id=template.id,
                ))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash(
                'Could not read {}. Try using a different file format.'.format(
                    form.file.data.filename))
        except (XLDateError):
            flash((
                '{} contains numbers or dates that Notify cannot understand. '
                'Try formatting all columns as ‘text’ or export your file as CSV.'
            ).format(form.file.data.filename))

    column_headings = get_spreadsheet_column_headings_from_template(template)

    return render_template(
        'views/send.html',
        template=template,
        column_headings=list(ascii_uppercase[:len(column_headings)]),
        example=[column_headings,
                 get_example_csv_rows(template)],
        form=form,
        allowed_file_extensions=Spreadsheet.ALLOWED_FILE_EXTENSIONS)
def test_can_create_spreadsheet_from_large_excel_file():
    with open(str(Path.cwd() / 'tests' / 'spreadsheet_files' / 'excel 2007.xlsx'), 'rb') as xl:
        ret = Spreadsheet.from_file(xl, filename='xl.xlsx')
    assert ret.as_csv_data