Skip to content

Commit 2ce96a8

Browse files
authored
Add store rates robustness (#34)
This removes the window and always uses the closest price but emails when the gap is over five days. It closes #31.
1 parent be37fc8 commit 2ce96a8

3 files changed

Lines changed: 83 additions & 18 deletions

File tree

lib/mix/tasks/store_rates.ex

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ defmodule Mix.Tasks.StoreRates do
66
alias PrisonRideshare.Repo
77
alias PrisonRideshareWeb.{GasPrice, Ride}
88
alias PrisonRideshare.CalculateRatesFromGasPrice
9-
10-
alias Timex.Duration
9+
alias PrisonRideshare.Email
1110

1211
import Ecto.Query
1312

@@ -28,17 +27,30 @@ defmodule Mix.Tasks.StoreRates do
2827
gas_prices = Repo.all(GasPrice, order_by: :inserted_at)
2928

3029
Enum.each(rides, fn ride ->
31-
window_before_ride_start = Timex.subtract(ride.start, Duration.from_days(1))
32-
33-
window_after_ride_start = Timex.add(ride.start, Duration.from_days(1))
30+
# Choose the nearest gas price by proximity to start time
3431

3532
closest_gas_price =
36-
Enum.find(gas_prices, fn gas_price ->
37-
Timex.after?(gas_price.inserted_at, window_before_ride_start) &&
38-
Timex.before?(gas_price.inserted_at, window_after_ride_start)
39-
end)
33+
case gas_prices do
34+
[] ->
35+
nil
36+
37+
_ ->
38+
Enum.min_by(gas_prices, fn gp ->
39+
abs(Timex.diff(gp.inserted_at, ride.start, :seconds))
40+
end)
41+
end
4042

4143
if closest_gas_price do
44+
# send a warning if the assigned gas price is 5 days or more from the ride start
45+
diff_seconds =
46+
Timex.diff(closest_gas_price.inserted_at, ride.start, :seconds)
47+
|> abs()
48+
49+
if diff_seconds >= 5 * 24 * 60 * 60 do
50+
Email.store_rates_gap_warning_report(ride, closest_gas_price)
51+
|> PrisonRideshare.Mailer.deliver_now()
52+
end
53+
4254
rate =
4355
if ride.institution.far,
4456
do: CalculateRatesFromGasPrice.far_rate(closest_gas_price),

lib/prison_rideshare_web/email.ex

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,34 @@ defmodule PrisonRideshare.Email do
6969
)
7070
end
7171

72+
def store_rates_gap_warning_report(ride, gas_price) do
73+
diff_seconds =
74+
Timex.diff(gas_price.inserted_at, ride.start, :seconds)
75+
|> abs()
76+
77+
gap_days = div(diff_seconds, 86_400)
78+
79+
body =
80+
[
81+
"Gas price assignment gap warning: the gas price assigned to a ride is #{gap_days} days apart from the ride start, is archival broken?",
82+
"",
83+
"Ride ID: #{ride.id}",
84+
"Visitor: #{ride.name}",
85+
"Ride start: #{ride.start}",
86+
"Assigned gas price timestamp: #{gas_price.inserted_at}",
87+
"Gap: #{gap_days} days"
88+
]
89+
|> Enum.join("\n")
90+
91+
new_email(
92+
to: ["barnone.coordinator+gap+warning@gmail.com", "bot@barnonewpg.org"],
93+
from: {"Bar None Bot", "bot@barnonewpg.org"},
94+
subject: "Gas price assignment gap warning",
95+
html_body: body,
96+
text_body: body
97+
)
98+
end
99+
72100
defp format_gas_price_failure_reason(:missing_value), do: "missing pageFunctionResult"
73101
defp format_gas_price_failure_reason(:invalid_number), do: "invalid number format"
74102
defp format_gas_price_failure_reason(:invalid_format), do: "invalid response format"

test/mix/tasks/store_rates_test.exs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
defmodule Mix.Tasks.StoreRatesTest do
22
use ExUnit.Case
33
use PrisonRideshareWeb.ConnCase
4+
use Bamboo.Test
45

56
alias PrisonRideshare.Repo
67

@@ -22,7 +23,7 @@ defmodule Mix.Tasks.StoreRatesTest do
2223
inserted_at: NaiveDateTime.from_erl!({{2018, 6, 24}, {16, 37, 0}})
2324
})
2425

25-
other_price =
26+
ancient_price =
2627
Repo.insert!(%GasPrice{
2728
price: 5,
2829
inserted_at: NaiveDateTime.from_erl!({{2017, 1, 1}, {0, 0, 0}})
@@ -40,6 +41,16 @@ defmodule Mix.Tasks.StoreRatesTest do
4041
far: true
4142
})
4243

44+
_ancient_ride =
45+
Repo.insert!(%Ride{
46+
start: NaiveDateTime.from_erl!({{2017, 2, 2}, {11, 0, 0}}),
47+
institution: close_institution,
48+
end: NaiveDateTime.from_erl!({{2017, 2, 2}, {12, 0, 0}}),
49+
address: "address",
50+
contact: "contact",
51+
name: "name"
52+
})
53+
4354
_old_ride =
4455
Repo.insert!(%Ride{
4556
start: NaiveDateTime.from_erl!({{2018, 5, 23}, {11, 0, 0}}),
@@ -95,7 +106,7 @@ defmodule Mix.Tasks.StoreRatesTest do
95106
Repo.insert!(%Ride{
96107
start: NaiveDateTime.from_erl!({{2018, 6, 28}, {11, 0, 0}}),
97108
institution: far_institution,
98-
gas_price: other_price,
109+
gas_price: ancient_price,
99110
end: NaiveDateTime.from_erl!({{2018, 6, 28}, {12, 0, 0}}),
100111
address: "address",
101112
contact: "contact",
@@ -116,6 +127,7 @@ defmodule Mix.Tasks.StoreRatesTest do
116127
Mix.Tasks.StoreRates.run([])
117128

118129
[
130+
ancient,
119131
old,
120132
yesterday,
121133
zero_rate_ride,
@@ -129,7 +141,10 @@ defmodule Mix.Tasks.StoreRatesTest do
129141
|> preload(:gas_price)
130142
|> Repo.all()
131143

132-
refute old.gas_price
144+
assert ancient.gas_price.id == ancient_price.id
145+
146+
assert old.gas_price.id == yesterday_price.id
147+
assert old.rate == ~M[23]
133148

134149
assert yesterday.gas_price.id == yesterday_price.id
135150
assert yesterday.rate == ~M[23]
@@ -140,14 +155,24 @@ defmodule Mix.Tasks.StoreRatesTest do
140155
assert today.gas_price.id == today_price.id
141156
assert today.rate == ~M[20]
142157

143-
refute tomorrow.gas_price
158+
assert tomorrow.gas_price.id == today_price.id
159+
assert tomorrow.rate == ~M[20]
144160

145-
assert already_set_gas_price.gas_price.id == other_price.id
161+
assert already_set_gas_price.gas_price.id == ancient_price.id
146162
refute already_set_rate.gas_price
147163

148-
[yesterday_version, _zero_version, _today_version] = Repo.all(PaperTrail.Version)
149-
assert yesterday_version.event == "update"
150-
assert yesterday_version.origin == "StoreRates"
151-
assert yesterday_version.item_id == yesterday.id
164+
ancient_version = hd(Repo.all(PaperTrail.Version))
165+
166+
assert ancient_version.event == "update"
167+
assert ancient_version.origin == "StoreRates"
168+
assert ancient_version.item_id == ancient.id
169+
170+
assert_delivered_email(
171+
PrisonRideshare.Email.store_rates_gap_warning_report(ancient, ancient_price)
172+
)
173+
174+
assert_delivered_email(
175+
PrisonRideshare.Email.store_rates_gap_warning_report(old, yesterday_price)
176+
)
152177
end
153178
end

0 commit comments

Comments
 (0)