@@ -7,7 +7,8 @@ def initialize(vaccination_record:)
77
88 def call
99 return if vaccination_record . sourced_from_service?
10- return if would_still_be_vaccinated?
10+ return if was_already_vaccinated?
11+ return if is_still_eligible_for_vaccination?
1112
1213 consents = patient . consents . includes ( :parent )
1314
@@ -58,15 +59,25 @@ def self.call(...) = new(...).call
5859
5960 attr_reader :vaccination_record
6061
61- delegate :patient , :programme_type , to : :vaccination_record
62+ delegate :patient , :programme_type , :programme , to : :vaccination_record
6263
6364 def academic_year = AcademicYear . current
6465
65- def other_vaccination_records
66- patient . vaccination_records . where . not ( id : vaccination_record . id )
66+ def previous_vaccination_records
67+ # We need to ensure there is a deterministic order of vaccination records on
68+ # a child so that the :already_vaccinated_notification is sent once and only
69+ # once per child. Using created_at alone is not sufficient as batching
70+ # allows for multiple vaccination records to be created with the same
71+ # created_at timestamp. We chose the ID as a tie-breaker since IDs are
72+ # unique and sequential.
73+ patient . vaccination_records . where (
74+ "(created_at < :created_at) OR (created_at = :created_at AND id < :id)" ,
75+ created_at : vaccination_record . created_at ,
76+ id : vaccination_record . id
77+ )
6778 end
6879
69- def would_still_be_vaccinated ?
80+ def was_already_vaccinated ?
7081 # We're not using the existing `Patient::ProgrammeStatus` instance here
7182 # because we want to know if the patient would still be vaccinated if we
7283 # took away the vaccination record in question, to know whether to send
@@ -79,11 +90,15 @@ def would_still_be_vaccinated?
7990 programme_type :,
8091 academic_year :,
8192 patient :,
82- vaccination_records : other_vaccination_records ,
93+ vaccination_records : previous_vaccination_records ,
8394 patient_locations : [ ] ,
8495 consents : [ ] ,
8596 triages : [ ] ,
8697 attendance_record : nil
8798 ) . status == :vaccinated
8899 end
100+
101+ def is_still_eligible_for_vaccination?
102+ !patient . programme_status ( programme , academic_year :) . vaccinated?
103+ end
89104end
0 commit comments