-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CRIMAPP-1357 caseworker can add MAAT decisions #726
base: main
Are you sure you want to change the base?
Changes from all commits
d512c73
9655f93
6309b4c
fb61b94
83aea31
d7e0762
d50651b
2fa67bb
aef7616
11c2da4
843085c
0f8ef19
0fb3f31
13d651b
2a286c8
9979b95
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,28 @@ | ||
module Deciding | ||
class DecisionNotFound < StandardError; end | ||
class AlreadyCreated < StandardError; end | ||
class ApplicationNotAssignedToUser < StandardError; end | ||
class DecisionNotFound < StandardError; end | ||
class MaatRecordNotChanged < StandardError; end | ||
|
||
class Event < RailsEventStore::Event | ||
class << self | ||
def build(decision, data = {}) | ||
args = { | ||
application_id: decision.application_id, | ||
decision_id: decision.decision_id | ||
} | ||
|
||
new(data: args.merge(data)) | ||
end | ||
end | ||
end | ||
|
||
class DraftCreated < RailsEventStore::Event; end | ||
class InterestsOfJusticeSet < RailsEventStore::Event; end | ||
class FundingDecisionSet < RailsEventStore::Event; end | ||
class CommentSet < RailsEventStore::Event; end | ||
class DraftCreatedFromMaat < RailsEventStore::Event; end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these should use Event, just don't call with build the creating events. |
||
class InterestsOfJusticeSet < Event; end | ||
class FundingDecisionSet < Event; end | ||
class SynchedWithMaat < Event; end | ||
class CommentSet < Event; end | ||
|
||
class << self | ||
def stream_name(decision_id) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
module Deciding | ||
class Command < Dry::Struct | ||
attribute :decision_id, Types::Uuid | ||
attribute :decision_id, Types::Uuid | Types::Integer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use the MAAT ID for the decision_id of MAAT decisions. This is used to create a unique event stream for the decision and ensure idempotency. (NB: we may start receiving notifications from MAAT relating to decisions.) |
||
|
||
def with_decision(&block) | ||
repository.with_aggregate( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,10 +2,11 @@ module Deciding | |
class CreateDraft < Command | ||
attribute :application_id, Types::Uuid | ||
attribute :user_id, Types::Uuid | ||
attribute :reference, Types::Integer | ||
|
||
def call | ||
with_decision do |decision| | ||
decision.create_draft(user_id:, application_id:) | ||
decision.create_draft(user_id:, application_id:, reference:) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Including reference in all deciding events simplifies linking to streams based on reference for submission history. |
||
end | ||
end | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module Deciding | ||
class CreateDraftFromMaat < Command | ||
attribute :application_id, Types::Uuid | ||
attribute :maat_decision, Maat::Decision | ||
attribute :user_id, Types::Uuid | ||
|
||
def call | ||
with_decision do |decision| | ||
decision.create_draft_from_maat( | ||
application_id:, maat_decision:, user_id: | ||
) | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module Deciding | ||
class UpdateFromMaatDecision < Command | ||
attribute :maat_decision, Maat::Decision | ||
attribute :user_id, Types::Uuid | ||
|
||
def call | ||
with_decision do |decision| | ||
decision.sync_with_maat(maat_decision:, user_id:) | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,37 +6,67 @@ def initialize(decision_id) | |
@decision_id = decision_id | ||
end | ||
|
||
attr_reader :application_id, :decision_id, :funding_decision, :comment, :state | ||
attr_reader :application_id, :decision_id, :funding_decision, :comment, | ||
:state, :reference, :maat_id, :checksum, :case_id | ||
|
||
# For decisions entered on CrimeReview by the caseworker | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TYPO |
||
def create_draft(user_id:, application_id:, reference:) | ||
raise AlreadyCreated unless @state.nil? | ||
|
||
def create_draft(user_id:, application_id:) | ||
apply DraftCreated.new( | ||
data: { decision_id:, application_id:, user_id: } | ||
data: { decision_id:, application_id:, user_id:, reference: } | ||
) | ||
end | ||
|
||
def set_interests_of_justice(user_id:, interests_of_justice:) | ||
apply InterestsOfJusticeSet.new( | ||
data: { decision_id:, application_id:, user_id:, interests_of_justice: } | ||
def create_draft_from_maat(application_id:, maat_decision:, user_id:) | ||
maat_decision = maat_decision.to_h | ||
raise AlreadyCreated unless @state.nil? | ||
|
||
apply DraftCreatedFromMaat.new( | ||
data: { decision_id:, application_id:, maat_decision:, user_id: } | ||
) | ||
end | ||
|
||
def sync_with_maat(maat_decision:, user_id:) | ||
raise MaatRecordNotChanged unless maat_decision&.checksum != checksum | ||
|
||
apply SynchedWithMaat.build(self, maat_decision:, user_id:) | ||
end | ||
|
||
def set_interests_of_justice(user_id:, interests_of_justice:) | ||
apply InterestsOfJusticeSet.build(self, user_id:, interests_of_justice:) | ||
end | ||
|
||
def set_funding_decision(user_id:, funding_decision:) | ||
apply FundingDecisionSet.new( | ||
data: { decision_id:, application_id:, user_id:, funding_decision: } | ||
) | ||
apply FundingDecisionSet.build(self, user_id:, funding_decision:) | ||
end | ||
|
||
def set_comment(user_id:, comment:) | ||
apply CommentSet.new( | ||
data: { decision_id:, application_id:, user_id:, comment: } | ||
) | ||
apply CommentSet.build(self, user_id:, comment:) | ||
end | ||
|
||
# When decision is drafted on Review by the caseworker (e.g. Non-means tested) | ||
on DraftCreated do |event| | ||
@application_id = event.data.fetch(:application_id) | ||
@reference = event.data.fetch(:reference, nil) | ||
@state = Types::DecisionState[:draft] | ||
end | ||
|
||
# When the decision is linked to a decision drafted on MAAT | ||
on DraftCreatedFromMaat do |event| | ||
@application_id = event.data.fetch(:application_id) | ||
|
||
update_from_maat(event.data.fetch(:maat_decision)) | ||
|
||
@state = Types::DecisionState[:draft] | ||
end | ||
|
||
on SynchedWithMaat do |event| | ||
return if event.data[:maat_decision].blank? | ||
|
||
update_from_maat(event.data.fetch(:maat_decision)) | ||
end | ||
|
||
on InterestsOfJusticeSet do |event| | ||
@interests_of_justice = event.data.fetch(:interests_of_justice) | ||
end | ||
|
@@ -49,8 +79,26 @@ def set_comment(user_id:, comment:) | |
@comment = event.data.fetch(:comment) | ||
end | ||
|
||
def update_from_maat(maat_attributes) | ||
decision = Maat::Decision.new(maat_attributes) | ||
|
||
@maat_id = decision.maat_id | ||
@reference = decision.reference | ||
@case_id = decision.case_id | ||
@interests_of_justice = decision.interests_of_justice | ||
@means = decision.means | ||
@funding_decision = decision.funding_decision | ||
@checksum = decision.checksum | ||
end | ||
|
||
def means | ||
return if @means.nil? | ||
|
||
Types::MeansDecision[@means] | ||
end | ||
|
||
def interests_of_justice | ||
return {} if @interests_of_justice.nil? | ||
return if @interests_of_justice.nil? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Review this |
||
|
||
Types::InterestsOfJusticeDecision[@interests_of_justice] | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
module Reviewing | ||
class AddMaatDecision < Command | ||
attribute :decision_id, Types::Uuid | Types::Integer | ||
|
||
def call | ||
with_review do |review| | ||
review.add_maat_decision(decision_id:) | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ class Review | |
def initialize(id) | ||
@id = id | ||
@decision_ids = [] | ||
@maat_ids = [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove maat_ids for now |
||
end | ||
|
||
attr_reader :id, :decision_ids, :state, :return_reason, :reviewed_at, :reviewer_id, :submitted_at, :superseded_by, | ||
|
@@ -52,10 +53,16 @@ def mark_as_ready(user_id:) | |
apply MarkedAsReady.build(self, user_id:) | ||
end | ||
|
||
def add_decision(user_id:, decision_id:) | ||
def add_decision(decision_id:, user_id: nil) | ||
apply DecisionAdded.build(self, user_id:, decision_id:) | ||
end | ||
|
||
def add_maat_decision(decision_id:) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are using this? |
||
raise DecisionAlreadyLinked if @decision_ids.include?(decision_id) | ||
|
||
apply MaatDecisionAdded.build(self, decision_id:) | ||
end | ||
|
||
on ApplicationReceived do |event| | ||
@state = Types::ReviewState[:open] | ||
@received_at = event.timestamp | ||
|
@@ -70,6 +77,10 @@ def add_decision(user_id:, decision_id:) | |
@decision_ids << event.data.fetch(:decision_id) | ||
end | ||
|
||
on MaatDecisionAdded do |event| | ||
@decision_ids << event.data.fetch(:decision_id) | ||
end | ||
|
||
on SentBack do |event| | ||
@state = Types::ReviewState[:sent_back] | ||
@return_reason = event.data.fetch(:reason, nil) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<%= govuk_summary_list(card: { title:, actions: }, rows: rows) do |list| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this used? |
||
list.with_row do |row| | ||
row.with_key { label_text(:funding_decision, scope: [:decision]) } | ||
row.with_value { decision_result(decision.funding_decision) } | ||
end | ||
|
||
list.with_row do |row| | ||
row.with_key { label_text(:comment, scope: [:decision]) } | ||
row.with_value { decision.comment } | ||
end | ||
end %> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<%= govuk_summary_list(card: { title:, actions: }) do |list| | ||
if linked_to_maat? | ||
list.with_row do |row| | ||
row.with_key { label_text(:maat_id) } | ||
row.with_value { decision.maat_id.to_s } | ||
end | ||
|
||
list.with_row do |row| | ||
row.with_key { label_text(:case_number) } | ||
row.with_value { decision.case_id } | ||
end | ||
end | ||
|
||
if interests_of_justice.present? | ||
list.with_row do |row| | ||
row.with_key { label_text(:ioj_result) } | ||
row.with_value { ioj_result } | ||
end | ||
list.with_row do |row| | ||
row.with_key { label_text(:ioj_details) } | ||
row.with_value { simple_format(interests_of_justice.details) } | ||
end | ||
list.with_row do |row| | ||
row.with_key { label_text(:ioj_assessed_by) } | ||
row.with_value { interests_of_justice.assessed_by } | ||
end | ||
list.with_row do |row| | ||
row.with_key { label_text(:ioj_assessed_on) } | ||
row.with_value { date(interests_of_justice.assessed_on) } | ||
end | ||
end | ||
|
||
if means.present? | ||
list.with_row do |row| | ||
row.with_key { label_text(:means_result) } | ||
row.with_value { ioj_result } | ||
end | ||
list.with_row do |row| | ||
row.with_key { label_text(:means_assessed_by) } | ||
row.with_value { means.assessed_by } | ||
end | ||
list.with_row do |row| | ||
row.with_key { label_text(:means_assessed_on) } | ||
row.with_value { date(means.assessed_on) } | ||
end | ||
end | ||
|
||
list.with_row do |row| | ||
row.with_key { label_text(:overall_result) } | ||
row.with_value { decision_result(decision.funding_decision) } | ||
end | ||
|
||
list.with_row do |row| | ||
row.with_key { label_text(:decision_comment) } | ||
row.with_value { decision.comment } | ||
end | ||
end %> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This constant is set on a per environment basis and is used to prevent unsupported applications being retrieved.