Last active
January 15, 2021 19:03
-
-
Save baldwindavid/78dd8ca6af95cb81da66449d4e42a78a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unit_statuses = | |
# There is a Unit schema that is tied to a "units" table | |
from(unit in Unit, | |
# grab a lease tied to a unit (office space) | |
# Leases have start and end dates so the lease must be during the week | |
# of the given `date`. This will scope leases to that requirement. | |
left_join: lease in ^Leasing.filter_active_leases_during_week(Lease, date), | |
on: lease.unit_id == unit.id, | |
# join the unit type (Salon, Office, Focus, etc) | |
join: unit_type in assoc(unit, :unit_type), | |
# select only these two pieces of data | |
# The lease.id will either be an ID or nil | |
select: %{unit_type_name: unit_type.name, lease_id: lease.id} | |
) | |
# Only query for units for the given property | |
|> Inventory.filter_units_by_property(property) | |
# Up until this point the query is just being built; the database hasn't | |
# been queried yet. Repo.all() will query the database and return a List | |
# in the form... | |
# [ | |
# %{unit_type_name: "Salon", lease_id: xxx}, | |
# %{unit_type_name: "Salon", lease_id: nil}, | |
# %{unit_type_name: "Focus", lease_id: xxx}, ... | |
|> Repo.all() | |
# Group the data by unit type name returning... | |
# %{ | |
# "Salon" => [%{unit_type_name: "Salon", lease_id: xxx},...], | |
# "Focus" => [...], ... | |
# } | |
|> Enum.group_by(& &1.unit_type_name) | |
# Iterate through each of those maps and gather each with into a new | |
# list with maps containing calculated values for each unit type... | |
# | |
# [ | |
# %{ | |
# unit_type_name: "Salon", | |
# total_count: 25, | |
# occupied_count: 20, | |
# vacant_count: 5, | |
# percent_occupied: 80% | |
# } | |
# ... | |
# ] | |
# | |
# Note that fn {unit_type_name, unit_statuses} -> works here because | |
# you're dealing with key value pairs which can be patterned match in the | |
# form of a tuple {key, value} | |
|> Enum.map(fn {unit_type_name, unit_statuses} -> | |
# Enum.count just counts a collection | |
total_count = Enum.count(unit_statuses) | |
# Enum.count optionally takes a function to filter out only matching | |
# values. & &1.lease_id is a shorthand for an anonymous function. This is the same | |
# as... Enum.count(unit_statuses, fn status -> status.lease_id end) | |
occupied_count = Enum.count(unit_statuses, & &1.lease_id) | |
# The same shorthand is used here except with a named function `is_nil` | |
# and passing it the argument of &1.lease_id. Supposing I wanted to call | |
# `is_nil` with a value rather than a struct, it could be called as | |
# `&is_nil/1` and the value would just automatically passed as the | |
# argument. | |
vacant_count = Enum.count(unit_statuses, &is_nil(&1.lease_id)) | |
percent_occupied = | |
Number.Percentage.number_to_percentage(occupied_count / total_count * 100, precision: 0) | |
# Just returning a dumb map | |
# The result of all this will be a list of these maps. | |
%{ | |
unit_type_name: unit_type_name, | |
total_count: total_count, | |
occupied_count: occupied_count, | |
vacant_count: vacant_count, | |
percent_occupied: percent_occupied | |
} | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment