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
@@ -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