Commit Graph

732 Commits

Author SHA1 Message Date
Katie Smith
90d9135fcf Return cancelled letters for dashboard
Added cancelled letters to the number of failed letters in the statistics
that get used for the dashboard. At some point, we want to stop
including cancelled letters in the stats, but for now this keeps things
consistent with our current letter failure state, permanent-failure.
2018-12-03 17:51:09 +00:00
Pea Tyczynska
641cb6ec36 Add archived column to jobs table with default value of false 2018-11-28 14:38:59 +00:00
Katie Smith
ff06d120e8 Bump notifications-utils to 3.7.0
Bumped notifications-utils to 3.7.0. Version 3.7.0 includes the
`convert_utc_to_bst` and `convert_bst_to_utc` functions and the
`LETTER_PROCESSING_DEADLINE` constant, so these have been removed from
this repo and anywhere using these has now been updated to get these
from `notifications-utils`.

Also bumped pytest by a patch version to bring in a bug fix.
2018-11-26 12:53:39 +00:00
Leo Hemsted
d9aa220aa6 move folders and templates to other folders
new endpoints:
/services/<service_id>/move-to-folder
/services/<service_id>/move-to-folder/<target_template_folder_id>

* takes in a dict containing lists of `templates` and `folders` uuids.
* sets parent of templates and folders to the folder specified in the
  URL. Or None, if there was no id specified.
* if any template or folder has a differen service id, then the whole
  update fails
* if any folder is an ancestor of the target folder, then the whole
  update fails (as that would cause a cyclical folder structure).
* the whole function is wrapped in a single `transactional` decorator,
  so in case of error nothing will be saved.
2018-11-08 17:13:00 +00:00
Rebecca Law
1b0b16fa74 Update model and controller to handle parent_folder_id when creating a template.
If the parent_folder_id then check if the folder exists and is for the same service. If it is add the folder to the template model object, the relationship will be persisted when the template is saved. If the folder does not exist or is for a different service, then return a ResultNotFound error.
2018-11-07 16:17:09 +00:00
Rebecca Law
4849ecdf63 Update the template_schema to include a parent_folder_id.
When creating the Tempalte from_json, the folder is passed in. Since some validation should done, as in the folder exists and is for the same service, the folder is passed through to the Tempalte.from_json method.
When the template is persisted so is the relationship to folders.
TODO: If the folder is invalid a specific message should be returned.
2018-11-07 16:17:09 +00:00
Rebecca Law
39198ed67e Using jsonschema for create_template.
Updated jsonschema to Draft7, this allowed a conditional validation on subject, if template_type == 'email' or 'letter' then subject is required.
This version is backward compatible with Draft4.
When creating TempalteRedacted, I've built the dict depending on if the created_by or created_by_id exists.
2018-11-07 16:17:08 +00:00
Leo Hemsted
51a7a0add7 Merge pull request #2199 from alphagov/template-folder-crud
add template folder CRUD
2018-11-01 10:44:48 +00:00
Leo Hemsted
fbe34041d6 add template folder CRUD
* create template folder
* rename template folder
* get list of template folders for service (not nested/presented in any
  particular way)
* delete template folder

Also removed `lazy=dynamic` from the `template_folder.templates`
relationship. lazy=dynamic returns a query object (which you can then
filter further). We just want to return the entire fetched list, at
least for now.
2018-10-31 14:28:16 +00:00
Rebecca Law
a76c2a0695 Merge pull request #2192 from alphagov/exclude-failed-letters-from-billing
Update billing to ignore failed letters.
2018-10-30 09:44:57 +00:00
Rebecca Law
8832c6d82f Update billing to ignore failed letters. 2018-10-29 14:02:40 +00:00
Leo Hemsted
7d0fa279a3 eager join folders from the Template object to keep versioning working
The `@version_class` decorator looks at every dirty (modified) model in
the session to work out which new history models to create. However, if
there are dirty items in the session, sqlalchemy might flush to the
database, clearing the whole session.

We ran into problems with the archive service function, which is
versioned for api keys, templates and services. When constructing the
TemplateHistory objects, `history_meta.py::create_history` would call
getattr on `Template.folders`, which would make a database call to join
across to the TemplateFolder objects - this would then flush the dirty
Service object from the session before the ServiceHistory object was
created.

To get around this, we eager load the Template.folder object, joining
on to it automatically when the Template is fetched. That way, it
doesn't make a SELECT mid-way through the version decorator, and the
history is preserved.

Note: This relationship is only on Template, not TemplateHistory - so
we're not doing this join every single time we send a message.
2018-10-29 11:57:24 +00:00
Leo Hemsted
936c8489b3 add TemplateFolder model
a TemplateFolder has a service, a name, and a parent. Parent is a
nullable foreign key pointing to another TemplateFolder instance. We
don't do any checks here for cyclical or otherwise invalid folder
structures so keep your data clean, folks!

Unsurprisingly, a Template can be part of a TemplateFolder - there's a
mapping class (template_folder_map to avoid giving it a dumb name) -
this mapping table shouldn't be interacted with directly - rather, you
should use the `Template.folder` or `TemplateFolder.templates`
relationship.
2018-10-26 17:50:31 +01:00
Katie Smith
4c630ba2e2 Make name and filename fields of DVLAOrganisation non-nullable
If either of these fields are null, previewing a letter template won't
work.
2018-10-25 13:27:44 +01:00
Katie Smith
b2c4fc2787 Add edit_folders service permission
This is a temporary permission to allow some services to see and
edit folders before the feature is turned on for everyone.
2018-10-25 11:19:36 +01:00
Pea Tyczynska
e22e7245fe Use sanitised pdfs for sending and handle invalid pdfs, details below:
- pass new, sanitised pdf for sending
- move invalid pdfs to a newly created bucket
- set status fro notifications that failed pdf validation to a new status validation-failed
- adjust existing tests
2018-10-16 17:30:35 +01:00
Katie Smith
52095c9c8c Add filename to dvla_organisation table
Added a filename column to the dvla_organisation table and populated it
with the filenames that are currently hard-coded in template-preview.
The filenames for letter logos are going to be stored in the database,
instead of in template-preview.
2018-10-15 10:37:34 +01:00
Leo Hemsted
cffc697e7f letter estimated delivery now takes postage into account 2018-09-28 17:30:25 +01:00
Katie Smith
f41e0f05ec Make postage column part of ft_billing primary key
Now that the postage column is populated and there are no null values,
it can be added to the composite primary key of ft_billing.
2018-09-28 16:19:49 +01:00
Katie Smith
0936060f5d Add postage column to ft_billing
Added a new varchar column, postage, to ft_billing. This is nullable and
not part of the composite primary key for now, but this will change
later.
2018-09-28 13:52:10 +01:00
Katie Smith
335aeb386f Update FactBilling model to reflect current database state
The FactBilling model and the ft_billing database table have diverged
slightly - this makes some minor changes to the model columns so that
the model matches the table (which appears to be the correct version).

The ft_billing table is currently like this:

       Column       |            Type             | Modifiers | Storage  | Stats target | Description
--------------------+-----------------------------+-----------+----------+--------------+-------------
 bst_date           | date                        | not null  | plain    |              |
 template_id        | uuid                        | not null  | plain    |              |
 service_id         | uuid                        | not null  | plain    |              |
 notification_type  | text                        | not null  | extended |              |
 provider           | text                        | not null  | extended |              |
 rate_multiplier    | integer                     | not null  | plain    |              |
 international      | boolean                     | not null  | plain    |              |
 rate               | numeric                     | not null  | main     |              |
 billable_units     | integer                     |           | plain    |              |
 notifications_sent | integer                     |           | plain    |              |
 updated_at         | timestamp without time zone |           | plain    |              |
 created_at         | timestamp without time zone | not null  | plain    |              |
Indexes:
    "ft_billing_pkey" PRIMARY KEY, btree (bst_date, template_id, service_id, rate_multiplier, provider, notification_type, international, rate)
    "ix_ft_billing_bst_date" btree (bst_date)
    "ix_ft_billing_service_id" btree (service_id)
    "ix_ft_billing_template_id" btree (template_id)
2018-09-28 13:47:20 +01:00
Leo Hemsted
3739c573ea fix null check in constraint
There are two fun quirks of postgres/sql that we need to work around:
* any `x = y` where x or y is NULL returns NULL, rather than false.
* check constraints accept NULL or true values as good.

so, the check `postage in ('first', 'second')` returns `null` rather
than `false` when postage is null itself. This surprisingly passes the
check constraint. To get around this, we have to add an explicit not
null check as well.
2018-09-25 16:10:26 +01:00
Leo Hemsted
17612e5446 add postage constraint to notification history
A not valid constraint only checks against new rows, not existing rows.
We can call VALIDATE CONSTRAINT against this new constraint to check
the old rows (which we know are good, having run the command from
74961781). Adding a normal constraint acquires an ACCESS EXCLUSIVE
lock, but validate constraint only needs a SHARE UPDATE EXCLUSIVE lock.

see 9d4b8961 and 0a50993f for more information on marking constraints
as not valid.
2018-09-25 16:10:16 +01:00
Rebecca Law
a54645c5a3 Set the postage in the filename based on the postage set on the notification. 2018-09-25 11:04:58 +01:00
Leo Hemsted
8e19a0742f remove default postage from noti history
also add test for notification_history properly setting
2018-09-20 12:26:58 +01:00
Leo Hemsted
918e4b390f add postage to notification + noti_history
if it's a letter notification, postage must equal "first" or "second",
else it must equal null
2018-09-19 16:32:58 +01:00
Rebecca Law
5f73dfdbe9 Added constraints to services.postage: not nullable and can only containt "first" or "second" 2018-09-18 17:41:25 +01:00
Rebecca Law
1c0892888f Change the name of letter_class to postage, this will match the domain language used in the documentation.
Updated the tests to answer review comments.
2018-09-18 15:22:08 +01:00
Rebecca Law
79815b4f8a In order to support sending letters by first class we need a way to know how the service wants us to send the letter.
To start with this will be an attribute on the service, at the time the notification is created it will look at Service.letter_class to decide what class to use for the letter.

This PR adds Service.letter class as a nullable column.
Updated the create_service and update_service method to default the value to second.

Subsequent PRs will add the check constraint to ensure we only get first or second in the letter_class column and make that column nullable.
This can't be done all at once because it will cause an error if someone inserts or updates a service during the deploy.
2018-09-17 11:27:43 +01:00
Alexey Bezhan
c9ca720959 Change NotificationHistory.updated_at on update
Sets the updated_at to current time when the NotificationHistory
is modified (which happens occasionally for example to set status
to returned letter).
2018-09-13 14:09:09 +01:00
Alexey Bezhan
aacc00e3a7 Merge pull request #2075 from alphagov/process-returned-letters-list
Process returned letters list
2018-09-07 14:54:56 +01:00
Rebecca Law
8aacfb289d Add created_by_name to the Notification.serialize_for_csv.
The concern about performnace degrading has been thought through. We do not believe there will be an adverse effect since the high volume users do not send off messages.
2018-09-07 10:22:45 +01:00
Alexey Bezhan
3787e2954b Add a task to process returned letter lists
Adds an API endpoint `/letters/returned` that accepts a list of
notification references and creates a task to update their status.

Adds a new task that uses the list of references to update the status
of notifications to 'returned-letter'.

The update is currently done using a single query and logs the
number of changed records (including notification history records).
This could potentially be done within the `/letters/returned` endpoint,
but creating a job right away allows us to extend this more easily
in the future (e.g. logging missing notifications or adding callbacks).

The job is using the database tasks queue.
2018-09-06 16:39:17 +01:00
Alexey Bezhan
0dcf04def9 Add notification status for returned letters
We need to update letter notifications with a new status when DVLA
gives us a list of references for returned letters.

This adds the new status to the models and the DB.

DVLA call this 'returned mail', so I'm using it as the status name
since it seems less ambiguous than 'returned'.
2018-09-04 16:55:22 +01:00
Chris Hill-Scott
5d5047fb13 Add unique constraint to email branding domains
Does two things:

1. Revert "Revert "Add unique constraint to email branding domain""

This reverts commit af9cb30ef3.

2. Don’t allow empty string in email branding domain

Columns with multiple `null`s can have a uniqueness constraint. Columns
with multiple empty string values are not considered unique.

This commit:
- removes any duplicate empty string values
- casts empty strings to null string any time these columns are updated

---

Squashed into this single commits because these two things are not
atomic as individual commits.
2018-09-04 11:10:46 +01:00
Chris Hill-Scott
af9cb30ef3 Revert "Add unique constraint to email branding domain" 2018-09-04 10:55:49 +01:00
Chris Hill-Scott
f095fa1ddf Add unique constraint to email branding domain
Brandings with a domain set should be considered canonical. It doesn’t
make sense to have the same domain set on multiple different email
brands – you can’t tell which one to use.
2018-09-04 09:46:50 +01:00
Chris Hill-Scott
0c47d41977 Remove govuk from possible brands
‘GOV.UK’ doesn’t make sense as a type of brand. It only made sense as
a type of branding that a service had.

Since we’ve:
- deprecated the service branding column
- made sure it’s not used as a value in the email branding table

we can remove this value from the table of possible brand types.
2018-08-30 16:36:35 +01:00
Chris Hill-Scott
337496c5bc Deprecate service branding column
We want to drop this column. First we have to stop using it anywhere.

Needs to be made nullable so we can stop writing to it.
2018-08-30 16:05:37 +01:00
Rebecca Law
562facb49c Now that EmailBranding includes the brand type we do not need two separate colours. This PR removes the new colour columns. 2018-08-24 13:51:11 +01:00
Rebecca Law
3816010c72 Add brand_type to EmailBranding.
It makes more sense to put the brand_type with EmailBranding rather than in Service.
Next step is to add the new type to the form in admin app.
2018-08-23 13:53:05 +01:00
Rebecca Law
df2271a49f New columns for EmailBranding.
There is a requirement for the colour of the banner to be different to the single id colour. In order to accomodate that we are adding two new columns for that data.
These columns will be updated manually and not done with a data migration.

A new column called domain has been added. This will be used as a default domain, if the user that creates the service has a matching domain this email brand will be set for the service.

This PR only adds the new columns to the model and db.

https://www.pivotaltracker.com/story/show/159660295
2018-08-16 16:57:53 +01:00
Chris Hill-Scott
e0570c1773 Remove caseworking permission
What became ‘caseworking view’ is now available to all services.
2018-08-10 09:09:18 +01:00
Pea Tyczynska
c4bfd5479e Update EmailBranding model so it has separate name and text fields 2018-07-31 17:58:19 +01:00
Rebecca Law
19890412c9 Added a cancelled notification status so that we can cancel letters before they are sent. 2018-07-31 13:52:04 +01:00
Pea Tyczynska
4e49df2479 Delete MonthlyBilling model 2018-07-30 11:07:42 +01:00
Rebecca Law
a812060915 The unique constraint on SeviceCallbackApi was on service_id only.
Now that we have 2 types of api callbacks the constraint to be on service_id + callback_type.
2018-07-25 14:12:13 +01:00
Katie Smith
af5c4d2872 Include the notification sender name when serializing notifications
The `serialize` method of the Notification model now includes the
`created_by_name`. If a notification was sent as a one-off message this
value will now be the name of the person who sent the notification. If
a notification was sent through the API or by a CSV upload we don't
record the id of the sender, so `created_by_name` will be `None`.

This change affects the data that gets returned from these endpoints:
* /v2/notifications/<notification_id>
* /v2/notifications
2018-07-20 09:37:50 +01:00
Pea Tyczynska
183aa160c6 Add callback_type column to service_callback_api table
Also add service_callback_type table with allowed types
2018-07-17 16:54:00 +01:00
Rebecca Law
e2a1dfeb31 New dao and endpoints to create and update service data retention. 2018-07-11 17:02:49 +01:00