From 227c20bd9ded56a119342236056c826d6c715696 Mon Sep 17 00:00:00 2001 From: FelipeGuzmanSierra <97761783+FelipeGuzmanSierra@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:38:15 -0500 Subject: [PATCH] Refactor pto formatter and add hours interval for long ptos --- lib/bas/domain/pto.rb | 49 +++++++++++++++++++++++++--- lib/bas/formatter/pto.rb | 41 +++++++++++------------ lib/bas/mapper/notion/pto_today.rb | 31 ++++++++++-------- lib/bas/mapper/postgres/pto_today.rb | 4 +-- spec/bas/formatter/pto_spec.rb | 17 +++++++--- 5 files changed, 95 insertions(+), 47 deletions(-) diff --git a/lib/bas/domain/pto.rb b/lib/bas/domain/pto.rb index 8bbafd4..b7beb8d 100644 --- a/lib/bas/domain/pto.rb +++ b/lib/bas/domain/pto.rb @@ -7,9 +7,9 @@ module Domain # the start date, and the end date of the time off period. # class Pto - attr_reader :individual_name, :start_date, :end_date + attr_reader :individual_name, :start_date_from, :start_date_to, :end_date_from, :end_date_to - ATTRIBUTES = %w[individual_name start_date end_date].freeze + ATTRIBUTES = %w[individual_name start_date_from start_date_to end_date_from end_date_to].freeze # Initializes a Domain::Pto instance with the specified individual name, start date, and end date. # @@ -21,8 +21,49 @@ class Pto # def initialize(individual_name, start_date, end_date) @individual_name = individual_name - @start_date = start_date - @end_date = end_date + + @start_date_from = start_date[:from] + @start_date_to = start_date[:to] + @end_date_from = end_date[:from] + @end_date_to = end_date[:to] + end + + def same_day? + start_date = extract_date(start_date_from) + end_date = extract_date(end_date_from) + + start_date == end_date + end + + def format_timezone(timezone) + @start_date_from = set_timezone(start_date_from, timezone) + @start_date_to = set_timezone(start_date_to, timezone) + @end_date_from = set_timezone(end_date_from, timezone) + @end_date_to = set_timezone(end_date_to, timezone) + end + + private + + def extract_date(date) + return if date.nil? + + date.strftime("%F") + end + + def build_date_time(date, timezone) + return if date.nil? + + date_time = date.include?("T") ? date : "#{date}T00:00:00.000#{timezone}" + + DateTime.parse(date_time).to_time + end + + def set_timezone(date, timezone) + return if date.nil? + + date_time = build_date_time(date, timezone) + + Time.at(date_time, in: timezone) end end end diff --git a/lib/bas/formatter/pto.rb b/lib/bas/formatter/pto.rb index 00b05ec..b006138 100644 --- a/lib/bas/formatter/pto.rb +++ b/lib/bas/formatter/pto.rb @@ -38,6 +38,8 @@ def initialize(config = {}) def format(ptos_list) raise Formatter::Exceptions::InvalidData unless ptos_list.all? { |pto| pto.is_a?(Domain::Pto) } + ptos_list.each { |pto| pto.format_timezone(@timezone) } + ptos_list.reduce("") do |payload, pto| built_template = build_template(Domain::Pto::ATTRIBUTES, pto) payload + format_message_by_case(built_template.gsub("\n", ""), pto) @@ -47,42 +49,37 @@ def format(ptos_list) private def format_message_by_case(built_template, pto) - date_start = format_timezone(pto.start_date).strftime("%F") - date_end = format_timezone(pto.end_date).strftime("%F") - - if date_start == date_end + if pto.same_day? interval = same_day_interval(pto) - day_message = today?(date_start) ? "today" : "the day #{date_start}" + day_message = today?(pto.start_date_from) ? "today" : "the day #{pto.start_date_from.strftime("%F")}" "#{built_template} #{day_message} #{interval}\n" else - "#{built_template} from #{date_start} to #{date_end}\n" + start_date_interval = day_interval(pto.start_date_from, pto.start_date_to) + end_date_interval = day_interval(pto.end_date_from, pto.end_date_to) + + "#{built_template} from #{start_date_interval} to #{end_date_interval}\n" end end - def same_day_interval(pto) - time_start = format_timezone(pto.start_date).strftime("%I:%M %P") - time_end = format_timezone(pto.end_date).strftime("%I:%M %P") - - time_start == time_end ? "all day" : "from #{time_start} to #{time_end}" - end + def day_interval(start_date, end_date) + return start_date.strftime("%F") if end_date.nil? - def format_timezone(date) - date_time = build_date(date) + time_start = start_date.strftime("%I:%M %P") + time_end = end_date.strftime("%I:%M %P") - Time.at(date_time, in: @timezone) + "#{start_date.strftime("%F")} (#{time_start} - #{time_end})" end - def today?(date) - time_now = Time.now.strftime("%F") + def same_day_interval(pto) + time_start = pto.start_date_from.strftime("%I:%M %P") + time_end = pto.end_date_from.strftime("%I:%M %P") - date == format_timezone(time_now).strftime("%F") + time_start == time_end ? "all day" : "from #{time_start} to #{time_end}" end - def build_date(date) - date_time = date.include?("T") ? date : "#{date}T00:00:00.000#{@timezone}" - - DateTime.parse(date_time).to_time + def today?(date) + date == Time.now(in: @timezone).strftime("%F") end end end diff --git a/lib/bas/mapper/notion/pto_today.rb b/lib/bas/mapper/notion/pto_today.rb index 8b79b83..9ee99e6 100644 --- a/lib/bas/mapper/notion/pto_today.rb +++ b/lib/bas/mapper/notion/pto_today.rb @@ -42,19 +42,11 @@ def normalize_response(response) response.map do |value| pto_fields = value["properties"].slice(*PTO_PARAMS) - pto_fields.each do |field, pto_value| - pto_fields[field] = extract_pto_value(field, pto_value) - end - - pto_fields - end - end - - def extract_pto_value(field, value) - case field - when "Person" then extract_person_field_value(value) - when "Desde?" then extract_date_field_value(value) - when "Hasta?" then extract_date_field_value(value) + { + "Person" => extract_person_field_value(pto_fields["Person"]), + "Desde?" => extract_date_field_value(pto_fields["Desde?"]), + "Hasta?" => extract_date_field_value(pto_fields["Hasta?"]) + } end end @@ -62,9 +54,20 @@ def extract_person_field_value(data) data["people"][0]["name"] end - def extract_date_field_value(data) + def extract_date_field_value(date) + { + from: extract_start_date(date), + to: extract_end_date(date) + } + end + + def extract_start_date(data) data["date"]["start"] end + + def extract_end_date(data) + data["date"]["end"] + end end end end diff --git a/lib/bas/mapper/postgres/pto_today.rb b/lib/bas/mapper/postgres/pto_today.rb index a932774..ce4aa99 100644 --- a/lib/bas/mapper/postgres/pto_today.rb +++ b/lib/bas/mapper/postgres/pto_today.rb @@ -27,8 +27,8 @@ def map(pg_response) ptos.map do |pto| name = pto["name"] - start_date = pto["start_date"] - end_date = pto["end_date"] + start_date = { from: pto["start_date"], to: nil } + end_date = { from: pto["end_date"], to: nil } Domain::Pto.new(name, start_date, end_date) end diff --git a/spec/bas/formatter/pto_spec.rb b/spec/bas/formatter/pto_spec.rb index 055c48b..5e9e43f 100644 --- a/spec/bas/formatter/pto_spec.rb +++ b/spec/bas/formatter/pto_spec.rb @@ -2,11 +2,16 @@ RSpec.describe Formatter::Pto do before do + day_from_interval = { from: "2024-01-11T19:00:00-05:00", to: "2024-01-11T23:00:00-05:00" } + day_to_interval = { from: "2024-01-17T12:00:00-05:00", to: "2024-01-17T16:00:00-05:00" } + @data = [ - Domain::Pto.new("Range PTO", "2024-01-11", "2024-01-13"), - Domain::Pto.new("Time PTO", "2024-03-13T08:00:00.000-05:00", "2024-03-13T12:00:00.000-05:00"), - Domain::Pto.new("Time PTO", "2024-03-13T18:00:00.000", "2024-03-13T19:00:00.000"), - Domain::Pto.new("Day PTO", "2024-01-11", "2024-01-11") + Domain::Pto.new("Range PTO", { from: "2024-01-11" }, { from: "2024-01-13" }), + Domain::Pto.new("Time PTO", { from: "2024-03-13T08:00:00.000-05:00" }, { from: "2024-03-13T12:00:00.000-05:00" }), + Domain::Pto.new("Time PTO", { from: "2024-03-13T18:00:00.000" }, { from: "2024-03-13T19:00:00.000" }), + Domain::Pto.new("Day PTO", { from: "2024-01-11" }, { from: "2024-01-11" }), + Domain::Pto.new("Day PTO", day_from_interval, { from: "2024-01-17" }), + Domain::Pto.new("Day PTO", { from: "2024-01-11" }, day_to_interval) ] end @@ -32,7 +37,9 @@ expectation = ":beach: Range PTO is on PTO from 2024-01-11 to 2024-01-13\n" \ ":beach: Time PTO is on PTO the day 2024-03-13 from 08:00 am to 12:00 pm\n" \ ":beach: Time PTO is on PTO the day 2024-03-13 from 01:00 pm to 02:00 pm\n" \ - ":beach: Day PTO is on PTO the day 2024-01-11 all day\n" + ":beach: Day PTO is on PTO the day 2024-01-11 all day\n" \ + ":beach: Day PTO is on PTO from 2024-01-11 (07:00 pm - 11:00 pm) to 2024-01-17\n" \ + ":beach: Day PTO is on PTO from 2024-01-11 to 2024-01-17 (12:00 pm - 04:00 pm)\n" expect(formatted_message).to be_an_instance_of(String) expect(formatted_message).to eq(expectation)