bas 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -0
  3. data/README.md +68 -147
  4. data/lib/bas/bot/base.rb +74 -0
  5. data/lib/bas/bot/compare_wip_limit_count.rb +92 -0
  6. data/lib/bas/bot/fetch_birthdays_from_notion.rb +128 -0
  7. data/lib/bas/bot/fetch_domains_wip_counts_from_notion.rb +121 -0
  8. data/lib/bas/bot/fetch_domains_wip_limit_from_notion.rb +134 -0
  9. data/lib/bas/bot/fetch_emails_from_imap.rb +99 -0
  10. data/lib/bas/bot/fetch_next_week_birthdays_from_notion.rb +142 -0
  11. data/lib/bas/bot/fetch_next_week_ptos_from_notion.rb +162 -0
  12. data/lib/bas/bot/fetch_ptos_from_notion.rb +138 -0
  13. data/lib/bas/bot/format_birthdays.rb +97 -0
  14. data/lib/bas/bot/format_emails.rb +124 -0
  15. data/lib/bas/bot/format_wip_limit_exceeded.rb +97 -0
  16. data/lib/bas/bot/garbage_collector.rb +85 -0
  17. data/lib/bas/bot/humanize_pto.rb +119 -0
  18. data/lib/bas/bot/notify_discord.rb +96 -0
  19. data/lib/bas/read/base.rb +10 -23
  20. data/lib/bas/read/default.rb +16 -0
  21. data/lib/bas/read/postgres.rb +44 -0
  22. data/lib/bas/read/types/response.rb +18 -0
  23. data/lib/bas/utils/discord/integration.rb +43 -0
  24. data/lib/bas/utils/exceptions/function_not_implemented.rb +16 -0
  25. data/lib/bas/utils/exceptions/invalid_process_response.rb +16 -0
  26. data/lib/bas/utils/imap/request.rb +76 -0
  27. data/lib/bas/utils/notion/request.rb +45 -0
  28. data/lib/bas/utils/openai/run_assistant.rb +99 -0
  29. data/lib/bas/utils/postgres/request.rb +50 -0
  30. data/lib/bas/version.rb +1 -1
  31. data/lib/bas/write/base.rb +12 -17
  32. data/lib/bas/write/postgres.rb +45 -0
  33. data/lib/bas/write/postgres_update.rb +49 -0
  34. data/lib/bas.rb +1 -3
  35. metadata +30 -67
  36. data/lib/bas/domain/birthday.rb +0 -25
  37. data/lib/bas/domain/email.rb +0 -34
  38. data/lib/bas/domain/exceptions/function_not_implemented.rb +0 -18
  39. data/lib/bas/domain/issue.rb +0 -22
  40. data/lib/bas/domain/notification.rb +0 -23
  41. data/lib/bas/domain/pto.rb +0 -69
  42. data/lib/bas/domain/work_items_limit.rb +0 -25
  43. data/lib/bas/formatter/base.rb +0 -53
  44. data/lib/bas/formatter/birthday.rb +0 -38
  45. data/lib/bas/formatter/exceptions/invalid_data.rb +0 -15
  46. data/lib/bas/formatter/notification.rb +0 -34
  47. data/lib/bas/formatter/pto.rb +0 -89
  48. data/lib/bas/formatter/support_emails.rb +0 -73
  49. data/lib/bas/formatter/types/response.rb +0 -16
  50. data/lib/bas/formatter/work_items_limit.rb +0 -68
  51. data/lib/bas/process/base.rb +0 -39
  52. data/lib/bas/process/discord/exceptions/invalid_webhook_token.rb +0 -16
  53. data/lib/bas/process/discord/implementation.rb +0 -71
  54. data/lib/bas/process/discord/types/response.rb +0 -22
  55. data/lib/bas/process/openai/base.rb +0 -72
  56. data/lib/bas/process/openai/helper.rb +0 -19
  57. data/lib/bas/process/openai/types/response.rb +0 -27
  58. data/lib/bas/process/openai/use_case/humanize_pto.rb +0 -53
  59. data/lib/bas/process/slack/exceptions/invalid_webhook_token.rb +0 -16
  60. data/lib/bas/process/slack/implementation.rb +0 -70
  61. data/lib/bas/process/slack/types/response.rb +0 -21
  62. data/lib/bas/process/types/response.rb +0 -16
  63. data/lib/bas/read/github/base.rb +0 -57
  64. data/lib/bas/read/github/types/response.rb +0 -27
  65. data/lib/bas/read/github/use_case/repo_issues.rb +0 -17
  66. data/lib/bas/read/imap/base.rb +0 -70
  67. data/lib/bas/read/imap/types/response.rb +0 -27
  68. data/lib/bas/read/imap/use_case/support_emails.rb +0 -26
  69. data/lib/bas/read/notion/base.rb +0 -52
  70. data/lib/bas/read/notion/exceptions/invalid_api_key.rb +0 -15
  71. data/lib/bas/read/notion/exceptions/invalid_database_id.rb +0 -15
  72. data/lib/bas/read/notion/helper.rb +0 -21
  73. data/lib/bas/read/notion/types/response.rb +0 -26
  74. data/lib/bas/read/notion/use_case/birthday_next_week.rb +0 -41
  75. data/lib/bas/read/notion/use_case/birthday_today.rb +0 -29
  76. data/lib/bas/read/notion/use_case/notification.rb +0 -28
  77. data/lib/bas/read/notion/use_case/pto_next_week.rb +0 -71
  78. data/lib/bas/read/notion/use_case/pto_today.rb +0 -30
  79. data/lib/bas/read/notion/use_case/work_items_limit.rb +0 -37
  80. data/lib/bas/read/postgres/base.rb +0 -46
  81. data/lib/bas/read/postgres/helper.rb +0 -16
  82. data/lib/bas/read/postgres/types/response.rb +0 -42
  83. data/lib/bas/read/postgres/use_case/pto_today.rb +0 -32
  84. data/lib/bas/serialize/base.rb +0 -30
  85. data/lib/bas/serialize/github/issues.rb +0 -57
  86. data/lib/bas/serialize/imap/support_emails.rb +0 -56
  87. data/lib/bas/serialize/notion/birthday_today.rb +0 -68
  88. data/lib/bas/serialize/notion/notification.rb +0 -56
  89. data/lib/bas/serialize/notion/pto_today.rb +0 -75
  90. data/lib/bas/serialize/notion/work_items_limit.rb +0 -65
  91. data/lib/bas/serialize/postgres/pto_today.rb +0 -47
  92. data/lib/bas/use_cases/types/config.rb +0 -20
  93. data/lib/bas/use_cases/use_case.rb +0 -42
  94. data/lib/bas/use_cases/use_cases.rb +0 -465
  95. data/lib/bas/write/logs/base.rb +0 -33
  96. data/lib/bas/write/logs/use_case/console_log.rb +0 -22
  97. data/lib/bas/write/notion/base.rb +0 -36
  98. data/lib/bas/write/notion/use_case/empty_notification.rb +0 -38
  99. data/lib/bas/write/notion/use_case/notification.rb +0 -38
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Read
4
- module Github
5
- module Types
6
- ##
7
- # Represents a response received from the Octokit Github client. It encapsulates essential
8
- # information about the response, providing a structured way to handle and analyze
9
- # its responses.
10
- class Response
11
- attr_reader :status_code, :message, :results
12
-
13
- def initialize(response)
14
- if response.empty?
15
- @status_code = 404
16
- @message = "no result were found"
17
- @results = []
18
- else
19
- @status_code = 200
20
- @message = "success"
21
- @results = response
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Github
7
- ##
8
- # This class is an implementation of the Read::Github::Base interface, specifically designed
9
- # for reading issues from a Github repository.
10
- #
11
- class RepoIssues < Github::Base
12
- def execute
13
- read("list_issues", config[:repo])
14
- end
15
- end
16
- end
17
- end
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "net/imap"
4
- require "gmail_xoauth"
5
-
6
- require_relative "../base"
7
- require_relative "./types/response"
8
-
9
- module Read
10
- module Imap
11
- ##
12
- # This class is an implementation of the Read::Base interface, specifically designed
13
- # for reading data from an IMAP server.
14
- #
15
- class Base < Read::Base
16
- protected
17
-
18
- # Implements the reading logic for emails data from an IMAP server.
19
- # It connects to an IMAP server inbox, request emails base on a filter,
20
- # and returns a validated response.
21
- #
22
- def read(email_domain, email_port, token_uri, query)
23
- access_token = refresh_token(token_uri)
24
-
25
- imap_fetch(email_domain, email_port, query, access_token)
26
-
27
- Read::Imap::Types::Response.new(@emails)
28
- end
29
-
30
- private
31
-
32
- def imap_fetch(email_domain, email_port, query, access_token)
33
- imap = Net::IMAP.new(email_domain, port: email_port, ssl: true)
34
-
35
- imap.authenticate("XOAUTH2", config[:user], access_token)
36
-
37
- imap.examine(config[:inbox])
38
-
39
- @emails = fetch_emails(imap, query)
40
-
41
- imap.logout
42
- imap.disconnect
43
- end
44
-
45
- def fetch_emails(imap, query)
46
- imap.search(query).map do |message_id|
47
- imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
48
- end
49
- end
50
-
51
- def refresh_token(token_uri)
52
- uri = URI.parse(token_uri)
53
-
54
- response = Net::HTTP.post_form(uri, params)
55
- token_data = JSON.parse(response.body)
56
-
57
- token_data["access_token"]
58
- end
59
-
60
- def params
61
- {
62
- "grant_type" => "refresh_token",
63
- "refresh_token" => config[:refresh_token],
64
- "client_id" => config[:client_id],
65
- "client_secret" => config[:client_secret]
66
- }
67
- end
68
- end
69
- end
70
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Read
4
- module Imap
5
- module Types
6
- ##
7
- # Represents a response received from the Imap client. It encapsulates essential
8
- # information about the response, providing a structured way to handle and analyze
9
- # its responses.
10
- class Response
11
- attr_reader :status_code, :message, :results
12
-
13
- def initialize(response)
14
- if response.empty?
15
- @status_code = 404
16
- @message = "no result were found"
17
- @results = []
18
- else
19
- @status_code = 200
20
- @message = "success"
21
- @results = response
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Imap
7
- ##
8
- # This class is an implementation of the Read::Imap::Base interface, specifically designed
9
- # for reading support email from a Google Gmail account.
10
- #
11
- class SupportEmails < Imap::Base
12
- TOKEN_URI = "https://oauth2.googleapis.com/token"
13
- EMAIL_DOMAIN = "imap.gmail.com"
14
- EMAIL_PORT = 993
15
-
16
- # Implements the data reading filter for support emails from Google Gmail.
17
- #
18
- def execute
19
- yesterday = (Time.now - (60 * 60 * 24)).strftime("%d-%b-%Y")
20
- query = ["TO", config[:search_email], "SINCE", yesterday]
21
-
22
- read(EMAIL_DOMAIN, EMAIL_PORT, TOKEN_URI, query)
23
- end
24
- end
25
- end
26
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "httparty"
4
-
5
- require_relative "../base"
6
- require_relative "./exceptions/invalid_api_key"
7
- require_relative "./exceptions/invalid_database_id"
8
- require_relative "./types/response"
9
- require_relative "./helper"
10
-
11
- module Read
12
- module Notion
13
- ##
14
- # This class is an implementation of the Read::Base interface, specifically designed
15
- # for reading data from Notion.
16
- #
17
- class Base < Read::Base
18
- NOTION_BASE_URL = "https://api.notion.com"
19
-
20
- protected
21
-
22
- # Implements the read logic for data from Notion. It sends a POST
23
- # request to the Notion API to query the specified database and returns a validated response.
24
- #
25
- # <br>
26
- # <b>raises</b> <tt>Exceptions::Notion::InvalidApiKey</tt> if the API key provided is incorrect or invalid.
27
- #
28
- # <b>raises</b> <tt>Exceptions::Notion::InvalidDatabaseId</tt> if the Database id provided is incorrect
29
- # or invalid.
30
- #
31
- def read(filter)
32
- url = "#{NOTION_BASE_URL}/v1/databases/#{config[:database_id]}/query"
33
-
34
- httparty_response = HTTParty.post(url, { body: filter.to_json, headers: })
35
-
36
- notion_response = Read::Notion::Types::Response.new(httparty_response)
37
-
38
- Read::Notion::Helper.validate_response(notion_response)
39
- end
40
-
41
- private
42
-
43
- def headers
44
- {
45
- "Authorization" => "Bearer #{config[:secret]}",
46
- "Content-Type" => "application/json",
47
- "Notion-Version" => "2022-06-28"
48
- }
49
- end
50
- end
51
- end
52
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Exceptions
4
- module Notion
5
- ##
6
- # Provides a domain-specific representation for errors that occurs when an invalid API key is provided
7
- # for a Notion-related operation.
8
- #
9
- class InvalidApiKey < StandardError
10
- def initialize(message = "The provided API token is invalid.")
11
- super(message)
12
- end
13
- end
14
- end
15
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Exceptions
4
- module Notion
5
- ##
6
- # Provides a domain-specific representation for errors that occurs when an invalid database id is provided
7
- # for a Notion-related operation.
8
- #
9
- class InvalidDatabaseId < StandardError
10
- def initialize(message = "The provided id doesn't match any database.")
11
- super(message)
12
- end
13
- end
14
- end
15
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Read
4
- module Notion
5
- ##
6
- # Provides common fuctionalities along the Read::Notion domain.
7
- #
8
- module Helper
9
- def self.validate_response(response)
10
- case response.status_code
11
- when 401
12
- raise Exceptions::Notion::InvalidApiKey, response.message
13
- when 404
14
- raise Exceptions::Notion::InvalidDatabaseId, response.message
15
- else
16
- response
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Read
4
- module Notion
5
- module Types
6
- ##
7
- # Represents a response received from the Notion API. It encapsulates essential information about the response,
8
- # providing a structured way to handle and analyze its responses.
9
- class Response
10
- attr_reader :status_code, :message, :results
11
-
12
- def initialize(response)
13
- if response["results"].nil?
14
- @status_code = response["status"]
15
- @message = response["message"]
16
- @results = []
17
- else
18
- @status_code = 200
19
- @message = "success"
20
- @results = response["results"]
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Notion
7
- ##
8
- # This class is an implementation of the Read::Notion::Base interface, specifically designed
9
- # for reading next week birthdays data from Notion.
10
- #
11
- class BirthdayNextWeek < Notion::Base
12
- DAYS_BEFORE_NOTIFY = 8
13
-
14
- # Implements the data reading filter for next week Birthdays data from Notion.
15
- #
16
- def execute
17
- filter = {
18
- filter: {
19
- or: [
20
- { property: "BD_this_year", date: { equals: eight_days_from_now } }
21
- ]
22
- }
23
- }
24
-
25
- read(filter)
26
- end
27
-
28
- private
29
-
30
- def eight_days_from_now
31
- date = Time.now.utc + days_in_second(DAYS_BEFORE_NOTIFY)
32
-
33
- date.utc.strftime("%F").to_s
34
- end
35
-
36
- def days_in_second(days)
37
- days * 24 * 60 * 60
38
- end
39
- end
40
- end
41
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Notion
7
- ##
8
- # This class is an implementation of the Read::Notion::Base interface, specifically designed
9
- # for reading birthday data from Notion.
10
- #
11
- class BirthdayToday < Notion::Base
12
- # Implements the reading filter for todays Birthdays data from Notion.
13
- #
14
- def execute
15
- today = Time.now.utc.strftime("%F").to_s
16
-
17
- filter = {
18
- filter: {
19
- or: [
20
- { property: "BD_this_year", date: { equals: today } }
21
- ]
22
- }
23
- }
24
-
25
- read(filter)
26
- end
27
- end
28
- end
29
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Notion
7
- ##
8
- # This class is an implementation of the Read::Notion::Base interface, specifically designed
9
- # for reading Notification data from Notion.
10
- #
11
- class Notification < Notion::Base
12
- # Implements the reading filter for notification data from Notion.
13
- #
14
- def execute
15
- filter = {
16
- filter: {
17
- property: "Use Case",
18
- title: {
19
- equals: config[:use_case_title]
20
- }
21
- }
22
- }
23
-
24
- read(filter)
25
- end
26
- end
27
- end
28
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Notion
7
- ##
8
- # This class is an implementation of the Read::Notion::Base interface, specifically designed
9
- # for reading next week Paid Time Off (PTO) data from Notion.
10
- #
11
- class PtoNextWeek < Notion::Base
12
- # Implements the reading filter for next week PTO's data from Notion.
13
- #
14
- def execute
15
- filter = build_filter
16
-
17
- read(filter)
18
- end
19
-
20
- private
21
-
22
- def next_week_dates
23
- monday = next_week_monday
24
- sunday = monday + 6
25
-
26
- [monday, sunday]
27
- end
28
-
29
- def next_week_monday
30
- today = Date.today
31
- week_day = today.wday
32
-
33
- days = week_day.zero? ? 1 : 8 - week_day
34
-
35
- today + days
36
- end
37
-
38
- def build_filter
39
- monday, sunday = next_week_dates
40
-
41
- {
42
- filter: {
43
- or: [
44
- belong_next_week("Desde?", monday, sunday),
45
- belong_next_week("Hasta?", monday, sunday),
46
- cover_next_week(monday, sunday)
47
- ]
48
- }
49
- }
50
- end
51
-
52
- def belong_next_week(property, after_day, before_day)
53
- {
54
- and: [
55
- { property:, date: { on_or_after: after_day } },
56
- { property:, date: { on_or_before: before_day } }
57
- ]
58
- }
59
- end
60
-
61
- def cover_next_week(monday, sunday)
62
- {
63
- and: [
64
- { property: "Hasta?", date: { on_or_after: sunday } },
65
- { property: "Desde?", date: { on_or_before: monday } }
66
- ]
67
- }
68
- end
69
- end
70
- end
71
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Notion
7
- ##
8
- # This class is an implementation of the Read::Notion::Base interface, specifically designed
9
- # for reading Paid Time Off (PTO) data from Notion.
10
- #
11
- class PtoToday < Notion::Base
12
- # Implements the reading filter for todays PTO's data from Notion.
13
- #
14
- def execute
15
- today = Time.now.utc.strftime("%F").to_s
16
-
17
- filter = {
18
- filter: {
19
- "and": [
20
- { property: "Desde?", date: { on_or_before: today } },
21
- { property: "Hasta?", date: { on_or_after: today } }
22
- ]
23
- }
24
- }
25
-
26
- read(filter)
27
- end
28
- end
29
- end
30
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Notion
7
- ##
8
- # This class is an implementation of the Read::Notion::Base interface, specifically designed
9
- # for counting "in progress" work items from work item database in Notion.
10
- #
11
- class WorkItemsLimit < Notion::Base
12
- # Implements the data reading count of "in progress" work items from Notion.
13
- #
14
- def execute
15
- filter = {
16
- filter: {
17
- "and": [
18
- { property: "OK", formula: { string: { contains: "✅" } } },
19
- { "or": status_conditions }
20
- ]
21
- }
22
- }
23
-
24
- read(filter)
25
- end
26
-
27
- private
28
-
29
- def status_conditions
30
- [
31
- { property: "Status", status: { equals: "In Progress" } },
32
- { property: "Status", status: { equals: "On Hold" } }
33
- ]
34
- end
35
- end
36
- end
37
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "pg"
4
-
5
- require_relative "../base"
6
- require_relative "./types/response"
7
- require_relative "./helper"
8
-
9
- module Read
10
- module Postgres
11
- ##
12
- # This class is an implementation of the Read::Base interface, specifically designed
13
- # for reading data from Postgres.
14
- #
15
- class Base < Read::Base
16
- protected
17
-
18
- # Implements the read logic from a Postgres database. It use the PG gem
19
- # to request data from a local or external database and returns a validated response.
20
- #
21
- # Gem: pg (https://rubygems.org/gems/pg)
22
- #
23
- def read(query)
24
- pg_connection = PG::Connection.new(config[:connection])
25
-
26
- pg_result = execute_query(pg_connection, query)
27
-
28
- postgres_response = Read::Postgres::Types::Response.new(pg_result)
29
-
30
- Read::Postgres::Helper.validate_response(postgres_response)
31
- end
32
-
33
- private
34
-
35
- def execute_query(pg_connection, query)
36
- if query.is_a? String
37
- pg_connection.exec(query)
38
- else
39
- sentence, params = query
40
-
41
- pg_connection.exec_params(sentence, params)
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Read
4
- module Postgres
5
- ##
6
- # Provides common fuctionalities along the Read::Postgres domain.
7
- #
8
- module Helper
9
- def self.validate_response(response)
10
- response.response.check_result
11
-
12
- response
13
- end
14
- end
15
- end
16
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Read
4
- module Postgres
5
- module Types
6
- ##
7
- # Represents a response received from the Postgres API. It encapsulates essential information about the response,
8
- # providing a structured way to handle and analyze its responses.
9
- class Response
10
- attr_reader :status, :message, :response, :fields, :records
11
-
12
- SUCCESS_STATUS = "PGRES_TUPLES_OK"
13
-
14
- def initialize(response)
15
- if response.res_status == SUCCESS_STATUS
16
- success_response(response)
17
- else
18
- failure_response(response)
19
- end
20
- end
21
-
22
- private
23
-
24
- def success_response(response)
25
- @status = response.res_status
26
- @message = "success"
27
- @response = response
28
- @fields = response.fields
29
- @records = response.values
30
- end
31
-
32
- def failure_response(response)
33
- @status = response.res_status
34
- @message = response.result_error_message
35
- @response = response
36
- @fields = nil
37
- @records = nil
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../base"
4
-
5
- module Read
6
- module Postgres
7
- ##
8
- # This class is an implementation of the Read::Postgres::Base interface, specifically designed
9
- # for reading Paid Time Off (PTO) data from a Postgres Database.
10
- #
11
- class PtoToday < Base
12
- # Implements the data reading query for todays PTO data from a Postgres database.
13
- #
14
- def execute
15
- read(build_query)
16
- end
17
-
18
- private
19
-
20
- def build_query
21
- today = Time.now.utc.strftime("%F").to_s
22
-
23
- start_time = "#{today}T00:00:00"
24
- end_time = "#{today}T23:59:59"
25
-
26
- where = "(start_date <= $1 AND end_date >= $1) OR (start_date>= $2 AND end_date <= $3)"
27
-
28
- ["SELECT * FROM pto WHERE #{where}", [today, start_time, end_time]]
29
- end
30
- end
31
- end
32
- end