bas 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./base"
4
+ require_relative "../version"
5
+ require_relative "../utils/postgres/request"
6
+
7
+ module Write
8
+ ##
9
+ # This class is an implementation of the Write::Base interface, specifically designed
10
+ # to update to a PostgresDB used as <b>common storage</b>.
11
+ #
12
+ class PostgresUpdate < Write::Base
13
+ PTO_PARAMS = "data, tag, archived, stage, status, version"
14
+
15
+ # Execute the Postgres utility to update data in the <b>common storage</b>
16
+ #
17
+ def execute
18
+ Utils::Postgres::Request.execute(params)
19
+ end
20
+
21
+ private
22
+
23
+ def params
24
+ {
25
+ connection: config[:connection],
26
+ query: build_query
27
+ }
28
+ end
29
+
30
+ def build_query
31
+ params, values = build_params
32
+ query = "UPDATE #{config[:db_table]} SET #{params} WHERE #{config[:conditions]}"
33
+
34
+ [query, values]
35
+ end
36
+
37
+ def build_params
38
+ params = ""
39
+ values = []
40
+
41
+ config[:params].each_with_index do |(param, value), idx|
42
+ params += "#{param}=$#{idx + 1}"
43
+ values << value
44
+ end
45
+
46
+ [params, values]
47
+ end
48
+ end
49
+ end
data/lib/bas.rb CHANGED
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "bas/version"
4
- require_relative "bas/use_cases/use_cases"
5
4
 
6
- module Bas # rubocop:disable Style/Documentation
7
- include UseCases
5
+ module Bas
8
6
  class Error < StandardError; end
9
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bas
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kommitters Open Source
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-19 00:00:00.000000000 Z
11
+ date: 2024-05-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A versatile business automation system offering key components for building
14
14
  various use cases. It provides an easy-to-use tool for implementing automation
@@ -31,73 +31,36 @@ files:
31
31
  - Rakefile
32
32
  - SECURITY.md
33
33
  - lib/bas.rb
34
- - lib/bas/domain/birthday.rb
35
- - lib/bas/domain/email.rb
36
- - lib/bas/domain/exceptions/function_not_implemented.rb
37
- - lib/bas/domain/issue.rb
38
- - lib/bas/domain/notification.rb
39
- - lib/bas/domain/pto.rb
40
- - lib/bas/domain/work_items_limit.rb
41
- - lib/bas/formatter/base.rb
42
- - lib/bas/formatter/birthday.rb
43
- - lib/bas/formatter/exceptions/invalid_data.rb
44
- - lib/bas/formatter/notification.rb
45
- - lib/bas/formatter/pto.rb
46
- - lib/bas/formatter/support_emails.rb
47
- - lib/bas/formatter/types/response.rb
48
- - lib/bas/formatter/work_items_limit.rb
49
- - lib/bas/process/base.rb
50
- - lib/bas/process/discord/exceptions/invalid_webhook_token.rb
51
- - lib/bas/process/discord/implementation.rb
52
- - lib/bas/process/discord/types/response.rb
53
- - lib/bas/process/openai/base.rb
54
- - lib/bas/process/openai/helper.rb
55
- - lib/bas/process/openai/types/response.rb
56
- - lib/bas/process/openai/use_case/humanize_pto.rb
57
- - lib/bas/process/slack/exceptions/invalid_webhook_token.rb
58
- - lib/bas/process/slack/implementation.rb
59
- - lib/bas/process/slack/types/response.rb
60
- - lib/bas/process/types/response.rb
34
+ - lib/bas/bot/base.rb
35
+ - lib/bas/bot/compare_wip_limit_count.rb
36
+ - lib/bas/bot/fetch_birthdays_from_notion.rb
37
+ - lib/bas/bot/fetch_domains_wip_counts_from_notion.rb
38
+ - lib/bas/bot/fetch_domains_wip_limit_from_notion.rb
39
+ - lib/bas/bot/fetch_emails_from_imap.rb
40
+ - lib/bas/bot/fetch_next_week_birthdays_from_notion.rb
41
+ - lib/bas/bot/fetch_next_week_ptos_from_notion.rb
42
+ - lib/bas/bot/fetch_ptos_from_notion.rb
43
+ - lib/bas/bot/format_birthdays.rb
44
+ - lib/bas/bot/format_emails.rb
45
+ - lib/bas/bot/format_wip_limit_exceeded.rb
46
+ - lib/bas/bot/garbage_collector.rb
47
+ - lib/bas/bot/humanize_pto.rb
48
+ - lib/bas/bot/notify_discord.rb
61
49
  - lib/bas/read/base.rb
62
- - lib/bas/read/github/base.rb
63
- - lib/bas/read/github/types/response.rb
64
- - lib/bas/read/github/use_case/repo_issues.rb
65
- - lib/bas/read/imap/base.rb
66
- - lib/bas/read/imap/types/response.rb
67
- - lib/bas/read/imap/use_case/support_emails.rb
68
- - lib/bas/read/notion/base.rb
69
- - lib/bas/read/notion/exceptions/invalid_api_key.rb
70
- - lib/bas/read/notion/exceptions/invalid_database_id.rb
71
- - lib/bas/read/notion/helper.rb
72
- - lib/bas/read/notion/types/response.rb
73
- - lib/bas/read/notion/use_case/birthday_next_week.rb
74
- - lib/bas/read/notion/use_case/birthday_today.rb
75
- - lib/bas/read/notion/use_case/notification.rb
76
- - lib/bas/read/notion/use_case/pto_next_week.rb
77
- - lib/bas/read/notion/use_case/pto_today.rb
78
- - lib/bas/read/notion/use_case/work_items_limit.rb
79
- - lib/bas/read/postgres/base.rb
80
- - lib/bas/read/postgres/helper.rb
81
- - lib/bas/read/postgres/types/response.rb
82
- - lib/bas/read/postgres/use_case/pto_today.rb
83
- - lib/bas/serialize/base.rb
84
- - lib/bas/serialize/github/issues.rb
85
- - lib/bas/serialize/imap/support_emails.rb
86
- - lib/bas/serialize/notion/birthday_today.rb
87
- - lib/bas/serialize/notion/notification.rb
88
- - lib/bas/serialize/notion/pto_today.rb
89
- - lib/bas/serialize/notion/work_items_limit.rb
90
- - lib/bas/serialize/postgres/pto_today.rb
91
- - lib/bas/use_cases/types/config.rb
92
- - lib/bas/use_cases/use_case.rb
93
- - lib/bas/use_cases/use_cases.rb
50
+ - lib/bas/read/default.rb
51
+ - lib/bas/read/postgres.rb
52
+ - lib/bas/read/types/response.rb
53
+ - lib/bas/utils/discord/integration.rb
54
+ - lib/bas/utils/exceptions/function_not_implemented.rb
55
+ - lib/bas/utils/exceptions/invalid_process_response.rb
56
+ - lib/bas/utils/imap/request.rb
57
+ - lib/bas/utils/notion/request.rb
58
+ - lib/bas/utils/openai/run_assistant.rb
59
+ - lib/bas/utils/postgres/request.rb
94
60
  - lib/bas/version.rb
95
61
  - lib/bas/write/base.rb
96
- - lib/bas/write/logs/base.rb
97
- - lib/bas/write/logs/use_case/console_log.rb
98
- - lib/bas/write/notion/base.rb
99
- - lib/bas/write/notion/use_case/empty_notification.rb
100
- - lib/bas/write/notion/use_case/notification.rb
62
+ - lib/bas/write/postgres.rb
63
+ - lib/bas/write/postgres_update.rb
101
64
  - renovate.json
102
65
  - sig/business_automation_system.rbs
103
66
  homepage: https://github.com/kommitters/bas
@@ -121,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
84
  - !ruby/object:Gem::Version
122
85
  version: '0'
123
86
  requirements: []
124
- rubygems_version: 3.5.3
87
+ rubygems_version: 3.5.9
125
88
  signing_key:
126
89
  specification_version: 4
127
90
  summary: BAS - Business automation system
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Domain
4
- ##
5
- # The Domain::Birthday class provides a domain-specific representation of a Birthday object.
6
- # It encapsulates the individual's name and their birthdate, offering a structured way to
7
- # handle and manipulate birthday information.
8
- class Birthday
9
- attr_reader :individual_name, :birth_date
10
-
11
- ATTRIBUTES = %w[individual_name birth_date].freeze
12
-
13
- # Initializes a Domain::Birthday instance with the specified individual name, and date of birth.
14
- #
15
- # <br>
16
- # <b>Params:</b>
17
- # * <tt>String</tt> individual_name Name of the individual
18
- # * <tt>Date</tt> birth_date Birthdate from the individual
19
- #
20
- def initialize(individual_name, date)
21
- @individual_name = individual_name
22
- @birth_date = date
23
- end
24
- end
25
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Domain
4
- ##
5
- # The Domain::Email class provides a domain-specific representation of an Email object.
6
- # It encapsulates information about an email, including the subject, the sender, and the date.
7
- #
8
- class Email
9
- attr_reader :subject, :sender
10
- attr_accessor :date
11
-
12
- ATTRIBUTES = %w[subject sender date].freeze
13
-
14
- # Initializes a Domain::Email instance with the specified subject, sender, and date.
15
- #
16
- # <br>
17
- # <b>Params:</b>
18
- # * <tt>String</tt> email subject.
19
- # * <tt>String</tt> Email of the sender.
20
- # * <tt>String</tt> Reception date
21
- #
22
- def initialize(subject, sender, date)
23
- @subject = subject
24
- @sender = sender
25
- @date = parse_to_datetime(date)
26
- end
27
-
28
- private
29
-
30
- def parse_to_datetime(date)
31
- DateTime.parse(date).to_time
32
- end
33
- end
34
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Domain
4
- module Exceptions
5
- ##
6
- # Provides a domain-specific representation for errors that occur when a function has not been implemented yet.
7
- # It inherits from StandardError # and allows developers to raise a specific exception when a required function
8
- # remains unimplemented in a subclass.
9
- #
10
- class FunctionNotImplemented < StandardError
11
- # Initializes the exception with an optional custom error message.
12
- #
13
- def initialize(message = "The function haven't been implemented yet.")
14
- super(message)
15
- end
16
- end
17
- end
18
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Domain
4
- ##
5
- # The Domain::Issue class provides a domain-specific representation of a Github issue object.
6
- # It encapsulates information about a repository issue, including the title, state, assignees,
7
- # description, and the repository url.
8
- #
9
- class Issue
10
- attr_reader :title, :state, :assignees, :description, :url
11
-
12
- ATTRIBUTES = %w[title state assignees description url].freeze
13
-
14
- def initialize(title, state, assignees, body, url)
15
- @title = title
16
- @state = state
17
- @assignees = assignees
18
- @description = body
19
- @url = url
20
- end
21
- end
22
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Domain
4
- ##
5
- # The Domain::Notification class provides a domain-specific representation of a Notification object.
6
- # It encapsulates the notification text.
7
- #
8
- class Notification
9
- attr_reader :notification
10
-
11
- ATTRIBUTES = %w[notification].freeze
12
-
13
- # Initializes a Domain::Notification instance with the specified notification text.
14
- #
15
- # <br>
16
- # <b>Params:</b>
17
- # * <tt>String</tt> notification
18
- #
19
- def initialize(notification)
20
- @notification = notification
21
- end
22
- end
23
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Domain
4
- ##
5
- # The Domain::Pto class provides a domain-specific representation of a Paid Time Off (PTO) object.
6
- # It encapsulates information about an individual's time off, including the individual's name,
7
- # the start date, and the end date of the time off period.
8
- #
9
- class Pto
10
- attr_reader :individual_name, :start_date_from, :start_date_to, :end_date_from, :end_date_to
11
-
12
- ATTRIBUTES = %w[individual_name start_date_from start_date_to end_date_from end_date_to].freeze
13
-
14
- # Initializes a Domain::Pto instance with the specified individual name, start date, and end date.
15
- #
16
- # <br>
17
- # <b>Params:</b>
18
- # * <tt>String</tt> individual_name Name of the individual.
19
- # * <tt>DateTime</tt> start_date Start day of the PTO.
20
- # * <tt>String</tt> end_date End date of the PTO.
21
- #
22
- def initialize(individual_name, start_date, end_date)
23
- @individual_name = individual_name
24
-
25
- @start_date_from = start_date[:from]
26
- @start_date_to = start_date[:to]
27
- @end_date_from = end_date[:from]
28
- @end_date_to = end_date[:to]
29
- end
30
-
31
- def same_day?
32
- start_date = extract_date(start_date_from)
33
- end_date = extract_date(end_date_from)
34
-
35
- start_date == end_date
36
- end
37
-
38
- def format_timezone(timezone)
39
- @start_date_from = set_timezone(start_date_from, timezone)
40
- @start_date_to = set_timezone(start_date_to, timezone)
41
- @end_date_from = set_timezone(end_date_from, timezone)
42
- @end_date_to = set_timezone(end_date_to, timezone)
43
- end
44
-
45
- private
46
-
47
- def extract_date(date)
48
- return if date.nil?
49
-
50
- date.strftime("%F")
51
- end
52
-
53
- def build_date_time(date, timezone)
54
- return if date.nil?
55
-
56
- date_time = date.include?("T") ? date : "#{date}T00:00:00.000#{timezone}"
57
-
58
- DateTime.parse(date_time).to_time
59
- end
60
-
61
- def set_timezone(date, timezone)
62
- return if date.nil?
63
-
64
- date_time = build_date_time(date, timezone)
65
-
66
- Time.at(date_time, in: timezone)
67
- end
68
- end
69
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Domain
4
- ##
5
- # The Domain::WorkItemsLimit class provides a domain-specific representation of a Work Item object.
6
- # It encapsulates information about a work items limit, including the domain and total.
7
- #
8
- class WorkItemsLimit
9
- attr_reader :domain, :total
10
-
11
- ATTRIBUTES = %w[domain total].freeze
12
-
13
- # Initializes a Domain::WorkItemsLimit instance with the specified domain and total.
14
- #
15
- # <br>
16
- # <b>Params:</b>
17
- # * <tt>String</tt> 'domain' responsible domain of the work items.
18
- # * <tt>String</tt> 'total' total 'in progress' work items.
19
- #
20
- def initialize(domain, total)
21
- @domain = domain
22
- @total = total
23
- end
24
- end
25
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../domain/exceptions/function_not_implemented"
4
- require "erb"
5
-
6
- module Formatter
7
- ##
8
- # The Formatter::Base module serves as the foundation for implementing specific data presentation logic
9
- # within the Formatter module. Defines essential methods, that provide a blueprint for creating custom
10
- # formatters tailored to different use cases.
11
- #
12
- class Base
13
- attr_reader :template
14
-
15
- # Initializes the fetcher with essential configuration parameters.
16
- #
17
- def initialize(config = {})
18
- @config = config
19
- @template = config[:template]
20
- end
21
-
22
- # This method is designed to provide a specified format for data from any implementation of
23
- # the Serialize::Base interface.
24
- # Must be overridden by subclasses, with specific logic based on the use case.
25
- #
26
- # <br>
27
- # <b>Params:</b>
28
- # * <tt>List<Domain::></tt> domain_data: List of specific domain objects depending on the use case.
29
- #
30
- # <br>
31
- # <b>raises</b> <tt>Domain::Exceptions::FunctionNotImplemented</tt> when missing implementation.
32
- #
33
- # <b>returns</b> <tt>String</tt> Formatted payload suitable for a Process::Base implementation.
34
- #
35
- def format(_domain_data)
36
- raise Domain::Exceptions::FunctionNotImplemented
37
- end
38
-
39
- protected
40
-
41
- def build_template(attributes, instance)
42
- formated_template = format_template(attributes, instance)
43
-
44
- "#{ERB.new(formated_template).result(binding)}\n"
45
- end
46
-
47
- def format_template(attributes, _instance)
48
- attributes.reduce(template) do |formated_template, attribute|
49
- formated_template.gsub(attribute, "<%= instance.#{attribute} %>")
50
- end
51
- end
52
- end
53
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../domain/birthday"
4
- require_relative "./exceptions/invalid_data"
5
- require_relative "./base"
6
- require_relative "./types/response"
7
-
8
- module Formatter
9
- ##
10
- # This class implements methods from the Formatter::Base module, tailored to format the
11
- # Domain::Birthday structure for a Process.
12
- class Birthday < Base
13
- # Implements the logic for building a formatted payload with the given template for birthdays.
14
- #
15
- # <br>
16
- # <b>Params:</b>
17
- # * <tt>List<Domain::Birthday></tt> birthdays_list: list of serialized birthdays.
18
- #
19
- # <br>
20
- # <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
21
- #
22
- # <br>
23
- # <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
24
- # the formatted payload suitable for a Process.
25
- #
26
- def format(birthdays_list)
27
- raise Formatter::Exceptions::InvalidData unless birthdays_list.all? do |brithday|
28
- brithday.is_a?(Domain::Birthday)
29
- end
30
-
31
- response = birthdays_list.reduce("") do |payload, birthday|
32
- payload + build_template(Domain::Birthday::ATTRIBUTES, birthday)
33
- end
34
-
35
- Formatter::Types::Response.new(response)
36
- end
37
- end
38
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Formatter
4
- module Exceptions
5
- ##
6
- # Provides a domain-specific representation for errors that occurs when trying to process invalid
7
- # data on a Fetcher::Base implementation
8
- #
9
- class InvalidData < StandardError
10
- def initialize(message = "")
11
- super(message)
12
- end
13
- end
14
- end
15
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "../domain/notification"
4
- require_relative "./exceptions/invalid_data"
5
- require_relative "./base"
6
- require_relative "./types/response"
7
-
8
- module Formatter
9
- ##
10
- # This class implements methods from the Formatter::Base module, tailored to format the
11
- # Domain::Notification structure for a Process.
12
- class Notification < Base
13
- # Implements the logic for building a formatted notification message
14
- #
15
- # <br>
16
- # <b>Params:</b>
17
- # * <tt>List<Domain::Notification></tt> notifications_list: list of serialized notifications.
18
- #
19
- # <br>
20
- # <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
21
- #
22
- # <br>
23
- # <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
24
- # the formatted payload suitable for a Process.
25
- #
26
- def format(notifications_list)
27
- raise Formatter::Exceptions::InvalidData unless notifications_list.all? do |notification|
28
- notification.is_a?(Domain::Notification)
29
- end
30
-
31
- Formatter::Types::Response.new(notifications_list[0].notification)
32
- end
33
- end
34
- end
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "date"
4
-
5
- require_relative "../domain/pto"
6
- require_relative "./exceptions/invalid_data"
7
- require_relative "./base"
8
- require_relative "./types/response"
9
-
10
- module Formatter
11
- ##
12
- # This class implements methods from the Formatter::Base module, tailored to format the
13
- # Domain::Pto structure for a Process.
14
- class Pto < Base
15
- DEFAULT_TIME_ZONE = "+00:00"
16
-
17
- # Initializes the Slack formatter with essential configuration parameters.
18
- #
19
- # <b>timezone</b> : expect an string with the time difference relative to the UTC. Example: "-05:00"
20
- def initialize(config = {})
21
- super(config)
22
-
23
- @timezone = config[:timezone] || DEFAULT_TIME_ZONE
24
- end
25
-
26
- # Implements the logic for building a formatted payload with the given template for PTO's.
27
- #
28
- # <br>
29
- # <b>Params:</b>
30
- # * <tt>List<Domain::Pto></tt> pto_list: List of serialized PTO's.
31
- #
32
- # <br>
33
- # <b>raises</b> <tt>Formatter::Exceptions::InvalidData</tt> when invalid data is provided.
34
- #
35
- # <br>
36
- # <b>returns</b> <tt>Formatter::Types::Response</tt> formatter response: standard output for
37
- # the formatted payload suitable for a Process.
38
- #
39
-
40
- def format(ptos_list)
41
- raise Formatter::Exceptions::InvalidData unless ptos_list.all? { |pto| pto.is_a?(Domain::Pto) }
42
-
43
- ptos_list.each { |pto| pto.format_timezone(@timezone) }
44
-
45
- response = ptos_list.reduce("") do |payload, pto|
46
- built_template = build_template(Domain::Pto::ATTRIBUTES, pto)
47
- payload + format_message_by_case(built_template.gsub("\n", ""), pto)
48
- end
49
-
50
- Formatter::Types::Response.new(response)
51
- end
52
-
53
- private
54
-
55
- def format_message_by_case(built_template, pto)
56
- if pto.same_day?
57
- interval = same_day_interval(pto)
58
- day_message = today?(pto.start_date_from) ? "today" : "the day #{pto.start_date_from.strftime("%F")}"
59
-
60
- "#{built_template} #{day_message} #{interval}\n"
61
- else
62
- start_date_interval = day_interval(pto.start_date_from, pto.start_date_to)
63
- end_date_interval = day_interval(pto.end_date_from, pto.end_date_to)
64
-
65
- "#{built_template} from #{start_date_interval} to #{end_date_interval}\n"
66
- end
67
- end
68
-
69
- def day_interval(start_date, end_date)
70
- return start_date.strftime("%F") if end_date.nil?
71
-
72
- time_start = start_date.strftime("%I:%M %P")
73
- time_end = end_date.strftime("%I:%M %P")
74
-
75
- "#{start_date.strftime("%F")} (#{time_start} - #{time_end})"
76
- end
77
-
78
- def same_day_interval(pto)
79
- time_start = pto.start_date_from.strftime("%I:%M %P")
80
- time_end = pto.end_date_from.strftime("%I:%M %P")
81
-
82
- time_start == time_end ? "all day" : "from #{time_start} to #{time_end}"
83
- end
84
-
85
- def today?(date)
86
- date == Time.now(in: @timezone).strftime("%F")
87
- end
88
- end
89
- end