bas 0.3.1 → 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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +9 -0
  5. data/README.md +68 -147
  6. data/lib/bas/bot/base.rb +74 -0
  7. data/lib/bas/bot/compare_wip_limit_count.rb +92 -0
  8. data/lib/bas/bot/fetch_birthdays_from_notion.rb +128 -0
  9. data/lib/bas/bot/fetch_domains_wip_counts_from_notion.rb +121 -0
  10. data/lib/bas/bot/fetch_domains_wip_limit_from_notion.rb +134 -0
  11. data/lib/bas/bot/fetch_emails_from_imap.rb +99 -0
  12. data/lib/bas/bot/fetch_next_week_birthdays_from_notion.rb +142 -0
  13. data/lib/bas/bot/fetch_next_week_ptos_from_notion.rb +162 -0
  14. data/lib/bas/bot/fetch_ptos_from_notion.rb +138 -0
  15. data/lib/bas/bot/format_birthdays.rb +97 -0
  16. data/lib/bas/bot/format_emails.rb +124 -0
  17. data/lib/bas/bot/format_wip_limit_exceeded.rb +97 -0
  18. data/lib/bas/bot/garbage_collector.rb +85 -0
  19. data/lib/bas/bot/humanize_pto.rb +119 -0
  20. data/lib/bas/bot/notify_discord.rb +96 -0
  21. data/lib/bas/read/base.rb +10 -23
  22. data/lib/bas/read/default.rb +16 -0
  23. data/lib/bas/read/postgres.rb +44 -0
  24. data/lib/bas/read/types/response.rb +18 -0
  25. data/lib/bas/utils/discord/integration.rb +43 -0
  26. data/lib/bas/utils/exceptions/function_not_implemented.rb +16 -0
  27. data/lib/bas/utils/exceptions/invalid_process_response.rb +16 -0
  28. data/lib/bas/utils/imap/request.rb +76 -0
  29. data/lib/bas/utils/notion/request.rb +45 -0
  30. data/lib/bas/utils/openai/run_assistant.rb +99 -0
  31. data/lib/bas/utils/postgres/request.rb +50 -0
  32. data/lib/bas/version.rb +1 -1
  33. data/lib/bas/write/base.rb +12 -17
  34. data/lib/bas/write/postgres.rb +45 -0
  35. data/lib/bas/write/postgres_update.rb +49 -0
  36. data/lib/bas.rb +1 -3
  37. metadata +31 -57
  38. data/lib/bas/domain/birthday.rb +0 -25
  39. data/lib/bas/domain/email.rb +0 -34
  40. data/lib/bas/domain/exceptions/function_not_implemented.rb +0 -18
  41. data/lib/bas/domain/issue.rb +0 -22
  42. data/lib/bas/domain/pto.rb +0 -69
  43. data/lib/bas/domain/work_items_limit.rb +0 -25
  44. data/lib/bas/formatter/base.rb +0 -53
  45. data/lib/bas/formatter/birthday.rb +0 -38
  46. data/lib/bas/formatter/exceptions/invalid_data.rb +0 -15
  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/slack/exceptions/invalid_webhook_token.rb +0 -16
  56. data/lib/bas/process/slack/implementation.rb +0 -70
  57. data/lib/bas/process/slack/types/response.rb +0 -21
  58. data/lib/bas/process/types/response.rb +0 -16
  59. data/lib/bas/read/github/base.rb +0 -57
  60. data/lib/bas/read/github/types/response.rb +0 -27
  61. data/lib/bas/read/github/use_case/repo_issues.rb +0 -17
  62. data/lib/bas/read/imap/base.rb +0 -70
  63. data/lib/bas/read/imap/types/response.rb +0 -27
  64. data/lib/bas/read/imap/use_case/support_emails.rb +0 -26
  65. data/lib/bas/read/notion/base.rb +0 -52
  66. data/lib/bas/read/notion/exceptions/invalid_api_key.rb +0 -15
  67. data/lib/bas/read/notion/exceptions/invalid_database_id.rb +0 -15
  68. data/lib/bas/read/notion/helper.rb +0 -21
  69. data/lib/bas/read/notion/types/response.rb +0 -26
  70. data/lib/bas/read/notion/use_case/birthday_next_week.rb +0 -41
  71. data/lib/bas/read/notion/use_case/birthday_today.rb +0 -29
  72. data/lib/bas/read/notion/use_case/pto_next_week.rb +0 -71
  73. data/lib/bas/read/notion/use_case/pto_today.rb +0 -30
  74. data/lib/bas/read/notion/use_case/work_items_limit.rb +0 -37
  75. data/lib/bas/read/postgres/base.rb +0 -46
  76. data/lib/bas/read/postgres/helper.rb +0 -16
  77. data/lib/bas/read/postgres/types/response.rb +0 -42
  78. data/lib/bas/read/postgres/use_case/pto_today.rb +0 -32
  79. data/lib/bas/serialize/base.rb +0 -30
  80. data/lib/bas/serialize/github/issues.rb +0 -57
  81. data/lib/bas/serialize/imap/support_emails.rb +0 -56
  82. data/lib/bas/serialize/notion/birthday_today.rb +0 -68
  83. data/lib/bas/serialize/notion/pto_today.rb +0 -75
  84. data/lib/bas/serialize/notion/work_items_limit.rb +0 -65
  85. data/lib/bas/serialize/postgres/pto_today.rb +0 -47
  86. data/lib/bas/use_cases/types/config.rb +0 -20
  87. data/lib/bas/use_cases/use_case.rb +0 -42
  88. data/lib/bas/use_cases/use_cases.rb +0 -389
  89. data/lib/bas/write/logs/base.rb +0 -33
  90. data/lib/bas/write/logs/use_case/console_log.rb +0 -22
@@ -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 it's 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,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: property, date: { on_or_after: after_day } },
56
- { property: 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 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 it's 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
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../domain/exceptions/function_not_implemented"
4
-
5
- module Serialize
6
- ##
7
- # The Serialize::Base module serves as the foundation for implementing specific data shaping logic within the
8
- # Serialize module. Defines essential methods, that provide a blueprint for organizing or shaping data in a manner
9
- # suitable for downstream formatting processes.
10
- #
11
- module Base
12
- # An method meant to prepare or organize the data coming from an implementation of the Read::Base interface.
13
- # Must be overridden by subclasses, with specific logic based on the use case.
14
- #
15
- # <br>
16
- # <b>Params:</b>
17
- # * <tt>Read::Notion::Types::Response</tt> response: Response produced by a reader.
18
- #
19
- # <br>
20
- #
21
- # <b>raises</b> <tt>Domain::Exceptions::FunctionNotImplemented</tt> when missing implementation.
22
- # <br>
23
- #
24
- # <b>returns</b> <tt>List<Domain::></tt> Serialize list of data, ready to be formatted.
25
- #
26
- def execute(_response)
27
- raise Domain::Exceptions::FunctionNotImplemented
28
- end
29
- end
30
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../domain/issue"
4
- require_relative "../base"
5
-
6
- module Serialize
7
- module Github
8
- ##
9
- # This class implements the methods of the Serialize::Base module, specifically designed for
10
- # preparing or shaping Github issues data coming from a Read::Base implementation.
11
- class Issues
12
- include Base
13
-
14
- # Implements the logic for shaping the results from a reader response.
15
- #
16
- # <br>
17
- # <b>Params:</b>
18
- # * <tt>Read::Github::Types::Response</tt> github_response: Array of github issues data.
19
- #
20
- # <br>
21
- # <b>return</b> <tt>List<Domain::Issue></tt> serialized github issues to be used by a
22
- # Formatter::Base implementation.
23
- #
24
- def execute(github_response)
25
- return [] if github_response.results.empty?
26
-
27
- normalized_github_data = normalize_response(github_response.results)
28
-
29
- normalized_github_data.map do |issue|
30
- Domain::Issue.new(
31
- issue["title"], issue["state"], issue["assignees"], issue["body"], issue["url"]
32
- )
33
- end
34
- end
35
-
36
- private
37
-
38
- def normalize_response(results)
39
- return [] if results.nil?
40
-
41
- results.map do |value|
42
- {
43
- "title" => value[:title],
44
- "state" => value[:state],
45
- "assignees" => extract_assignees(value[:assignees]),
46
- "body" => value[:body],
47
- "url" => value[:url]
48
- }
49
- end
50
- end
51
-
52
- def extract_assignees(assignees)
53
- assignees.map { |assignee| assignee[:login] }
54
- end
55
- end
56
- end
57
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../domain/email"
4
- require_relative "../base"
5
-
6
- module Serialize
7
- module Imap
8
- ##
9
- # This class implements the methods of the Serialize::Base module, specifically designed for
10
- # preparing or shaping support emails data coming from a Read::Base implementation.
11
- class SupportEmails
12
- include Base
13
-
14
- # Implements the logic for shaping the results from a reader response.
15
- #
16
- # <br>
17
- # <b>Params:</b>
18
- # * <tt>Read::Imap::Types::Response</tt> imap_response: Array of imap emails data.
19
- #
20
- # <br>
21
- # <b>return</b> <tt>List<Domain::Email></tt> support_emails_list, serialized support emails to be used by a
22
- # Formatter::Base implementation.
23
- #
24
- def execute(imap_response)
25
- return [] if imap_response.results.empty?
26
-
27
- normalized_email_data = normalize_response(imap_response.results)
28
-
29
- normalized_email_data.map do |email|
30
- Domain::Email.new(email["subject"], email["sender"], email["date"])
31
- end
32
- end
33
-
34
- private
35
-
36
- def normalize_response(results)
37
- return [] if results.nil?
38
-
39
- results.map do |value|
40
- {
41
- "sender" => extract_sender(value),
42
- "date" => value.date,
43
- "subject" => value.subject
44
- }
45
- end
46
- end
47
-
48
- def extract_sender(value)
49
- mailbox = value.sender[0]["mailbox"]
50
- host = value.sender[0]["host"]
51
-
52
- "#{mailbox}@#{host}"
53
- end
54
- end
55
- end
56
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../domain/birthday"
4
- require_relative "../base"
5
-
6
- module Serialize
7
- module Notion
8
- ##
9
- # This class implements the methods of the Serialize::Base module, specifically designed for preparing or
10
- # shaping birthdays data coming from a Read::Base implementation.
11
- class BirthdayToday
12
- include Base
13
-
14
- BIRTHDAY_PARAMS = ["Complete Name", "BD_this_year"].freeze
15
-
16
- # Implements the logic for shaping the results from a reader response.
17
- #
18
- # <br>
19
- # <b>Params:</b>
20
- # * <tt>Read::Notion::Types::Response</tt> notion_response: Notion response object.
21
- #
22
- # <br>
23
- # <b>return</b> <tt>List<Domain::Birthday></tt> birthdays_list, serialized birthdays to be used by a
24
- # Formatter::Base implementation.
25
- #
26
- def execute(notion_response)
27
- return [] if notion_response.results.empty?
28
-
29
- normalized_notion_data = normalize_response(notion_response.results)
30
-
31
- normalized_notion_data.map do |birthday|
32
- Domain::Birthday.new(birthday["Complete Name"], birthday["BD_this_year"])
33
- end
34
- end
35
-
36
- private
37
-
38
- def normalize_response(results)
39
- return [] if results.nil?
40
-
41
- results.map do |value|
42
- birthday_fields = value["properties"].slice(*BIRTHDAY_PARAMS)
43
-
44
- birthday_fields.each do |field, birthday_value|
45
- birthday_fields[field] = extract_birthday_value(field, birthday_value)
46
- end
47
-
48
- birthday_fields
49
- end
50
- end
51
-
52
- def extract_birthday_value(field, value)
53
- case field
54
- when "Complete Name" then extract_rich_text_field_value(value)
55
- when "BD_this_year" then extract_date_field_value(value)
56
- end
57
- end
58
-
59
- def extract_rich_text_field_value(data)
60
- data["rich_text"][0]["plain_text"]
61
- end
62
-
63
- def extract_date_field_value(data)
64
- data["formula"]["date"]["start"]
65
- end
66
- end
67
- end
68
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../../domain/pto"
4
- require_relative "../base"
5
-
6
- module Serialize
7
- module Notion
8
- ##
9
- # This class implements the methods of the Serialize::Base module, specifically designed for preparing or
10
- # shaping PTO's data coming from a Read::Base implementation.
11
- #
12
- class PtoToday
13
- include Base
14
-
15
- PTO_PARAMS = ["Description", "Desde?", "Hasta?"].freeze
16
-
17
- # Implements the logic for shaping the results from a reader response.
18
- #
19
- # <br>
20
- # <b>Params:</b>
21
- # * <tt>Read::Notion::Types::Response</tt> notion_response: Notion response object.
22
- #
23
- # <br>
24
- # <b>returns</b> <tt>List<Domain::Pto></tt> ptos_list, serialized PTO's to be used by a Formatter::Base
25
- # implementation.
26
- #
27
- def execute(notion_response)
28
- return [] if notion_response.results.empty?
29
-
30
- normalized_notion_data = normalize_response(notion_response.results)
31
-
32
- normalized_notion_data.map do |pto|
33
- Domain::Pto.new(pto["Description"], pto["Desde?"], pto["Hasta?"])
34
- end
35
- end
36
-
37
- private
38
-
39
- def normalize_response(response)
40
- return [] if response.nil?
41
-
42
- response.map do |value|
43
- pto_fields = value["properties"].slice(*PTO_PARAMS)
44
-
45
- {
46
- "Description" => extract_description_field_value(pto_fields["Description"]),
47
- "Desde?" => extract_date_field_value(pto_fields["Desde?"]),
48
- "Hasta?" => extract_date_field_value(pto_fields["Hasta?"])
49
- }
50
- end
51
- end
52
-
53
- def extract_description_field_value(data)
54
- names = data["title"].map { |name| name["plain_text"] }
55
-
56
- names.join(" ")
57
- end
58
-
59
- def extract_date_field_value(date)
60
- {
61
- from: extract_start_date(date),
62
- to: extract_end_date(date)
63
- }
64
- end
65
-
66
- def extract_start_date(data)
67
- data["date"]["start"]
68
- end
69
-
70
- def extract_end_date(data)
71
- data["date"]["end"]
72
- end
73
- end
74
- end
75
- end