harvest-ruby-v2 0.2.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.
@@ -0,0 +1,220 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pry'
4
+ require 'harvest/resources'
5
+
6
+ module Harvest
7
+ # Conversion for hash to Struct including nested items.
8
+ # TODO: Refactor for figuring out what Struct should be used
9
+ class NoValidStruct < ArgumentError
10
+ end
11
+
12
+ class ResourceFactory
13
+ def resource(klass, data)
14
+ data ||= {}
15
+ send(klass.to_sym, data)
16
+ end
17
+
18
+ def message_recipient(data)
19
+ data ||= {}
20
+ Struct::MessageRecipient.new(data)
21
+ end
22
+
23
+ def company(data)
24
+ data ||= {}
25
+ Struct::Company.new(data)
26
+ end
27
+
28
+ def estimate(data)
29
+ data ||= {}
30
+ convert_estimate_line_items(convert_client(Struct::Estimate.new(data)))
31
+ end
32
+
33
+ def estimate_line_item(data)
34
+ data ||= {}
35
+ Struct::EstimateLineItem.new(data)
36
+ end
37
+
38
+ def estimate_message(data)
39
+ data ||= {}
40
+ Struct::EstimateMessage.new(data)
41
+ end
42
+
43
+ def estimate_item_category(data)
44
+ data ||= {}
45
+ Struct::EstimateItemCategory.new(data)
46
+ end
47
+
48
+ def expense_category(data)
49
+ data ||= {}
50
+ Struct::ExpenseCategory.new(data)
51
+ end
52
+
53
+ def expense(data)
54
+ data ||= {}
55
+ Struct::Expense.new(data)
56
+ end
57
+
58
+ def invoice(data)
59
+ data ||= {}
60
+ Struct::Invoice.new(data)
61
+ end
62
+
63
+ def invoice_line_item(data)
64
+ data ||= {}
65
+ Struct::InvoiceLineItem.new(data)
66
+ end
67
+
68
+ def invoice_message(data)
69
+ data ||= {}
70
+ Struct::InvoiceMessage.new(data)
71
+ end
72
+
73
+ def invoice_payment(data)
74
+ data ||= {}
75
+ Struct::InvoicePayment.new(data)
76
+ end
77
+
78
+ def invoice_item_category(data)
79
+ data ||= {}
80
+ Struct::InvoiceItemCategory.new(data)
81
+ end
82
+
83
+ def project_assignment(data)
84
+ data ||= {}
85
+ unless data.nil?
86
+ convert_dates(
87
+ convert_project_client(
88
+ convert_task_assignments(
89
+ Struct::ProjectAssignment.new(data)
90
+ )
91
+ )
92
+ )
93
+ end
94
+ end
95
+
96
+ def project(data)
97
+ data ||= {}
98
+ convert_dates(Struct::Project.new(data)) unless data.nil?
99
+ end
100
+
101
+ def client(data)
102
+ data ||= {}
103
+ convert_dates(Struct::ResourceClient.new(data)) unless data.nil?
104
+ end
105
+
106
+ def task_assignment(data)
107
+ data ||= {}
108
+ convert_dates(convert_task(Struct::TaskAssignment.new(data))) unless data.nil?
109
+ end
110
+
111
+ def task(data)
112
+ data ||= {}
113
+ convert_dates(Struct::Task.new(data)) unless data.nil?
114
+ end
115
+
116
+ def user(data)
117
+ data ||= {}
118
+ convert_dates(Struct::User.new(data)) unless data.nil?
119
+ end
120
+
121
+ def user_assignment(data)
122
+ data ||= {}
123
+ convert_dates(Struct::UserAssignment.new(data)) unless data.nil?
124
+ end
125
+
126
+ def time_entry_external_reference(data)
127
+ data ||= {}
128
+ Struct::TimeEntryExternalReference.new(data)
129
+ end
130
+
131
+ def time_entry(data)
132
+ data ||= {}
133
+ convert_dates(
134
+ convert_project_client(
135
+ convert_task_assignment(
136
+ convert_task(
137
+ convert_user_assignment(
138
+ convert_user(
139
+ convert_external_reference(
140
+ Struct::TimeEntry.new(data)
141
+ )
142
+ )
143
+ )
144
+ )
145
+ )
146
+ )
147
+ )
148
+ end
149
+
150
+ private
151
+
152
+ def convert_estimate_line_items(data)
153
+ unless data.line_items.nil?
154
+ data.line_items = data.line_items.map { |ta| estimate_line_item(ta) }
155
+ end
156
+ data
157
+ end
158
+
159
+ def convert_external_reference(data)
160
+ data.external_reference = time_entry_external_reference(data.external_reference)
161
+ data
162
+ end
163
+
164
+ def convert_user(data)
165
+ data.user ||= {}
166
+ data.user = user(data.user) unless data.nil?
167
+ data
168
+ end
169
+
170
+ def convert_user_assignment(data)
171
+ data.user_assignment ||= {}
172
+ data.user_assignment = user_assignment(data.user_assignment) unless data.nil?
173
+ data
174
+ end
175
+
176
+ def convert_task_assignment(data)
177
+ data.task_assignment ||= {}
178
+
179
+ data.task_assignment = task_assignment(data.task_assignment) unless data.task_assignment.nil?
180
+ data
181
+ end
182
+
183
+ def convert_task_assignments(data)
184
+ unless data.task_assignments.nil?
185
+ data.task_assignments = data.task_assignments.map { |ta| task_assignment(ta) }
186
+ end
187
+ data
188
+ end
189
+
190
+ def convert_task(data)
191
+ data.task ||= {}
192
+ data.task = task(data.task) unless data.task.nil?
193
+ data
194
+ end
195
+
196
+ # @param data [Struct] passed a struct which contains an attribute client
197
+ def convert_client(data)
198
+ data.client = client(data.client)
199
+ data
200
+ end
201
+
202
+ def convert_project(data)
203
+ data.project = project(data.project)
204
+ data
205
+ end
206
+
207
+ def convert_project_client(data)
208
+ convert_project(convert_client(data))
209
+ end
210
+
211
+ def convert_dates(data)
212
+ %i[created_at updated_at sent_at accepted_at declined_at].each do |key|
213
+ if data.members.include?(key) && !data.method(key).call.nil?
214
+ data.method("#{key}=").call(DateTime.strptime(data.method(key).call))
215
+ end
216
+ end
217
+ data
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'harvest/resources/message'
4
+ require 'harvest/resources/company'
5
+ require 'harvest/resources/user'
6
+ require 'harvest/resources/task_assignment'
7
+ require 'harvest/resources/user_assignment'
8
+ require 'harvest/resources/timeentry'
9
+ require 'harvest/resources/estimates'
10
+ require 'harvest/resources/client'
11
+ require 'harvest/resources/expenses'
12
+ require 'harvest/resources/task'
13
+ require 'harvest/resources/project'
14
+ require 'harvest/resources/project_assignment'
15
+ require 'harvest/resources/invoices'
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Harvest
4
+ module Resources
5
+ # @param id [Integer]
6
+ # Unique ID for the client.
7
+ # @param name [String]
8
+ # A textual description of the client.
9
+ # @param is_active [Boolean]
10
+ # Whether the client is active or archived.
11
+ # @param address [String]
12
+ # The physical address for the client.
13
+ # @param statement_key [String]
14
+ # Used to build a URL to your client's invoice dashboard:
15
+ # @param currency [String]
16
+ # The currency code associated with this client.
17
+ # @param created_at [DateTime]
18
+ # Date and time the client was created.
19
+ # @param updated_at [DateTime]
20
+ # Date and time the client was last updated.
21
+ ResourceClient = Struct.new(
22
+ 'ResourceClient',
23
+ :id,
24
+ :name,
25
+ :is_active,
26
+ :address,
27
+ :statement_key,
28
+ :currency,
29
+ :created_at,
30
+ :updated_at,
31
+ keyword_init: true
32
+ )
33
+ end
34
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Harvest
4
+ module Resources
5
+ # @param base_uri [String]
6
+ # The Harvest URL for the company.
7
+ # @param full_domain [String]
8
+ # The Harvest domain for the company.
9
+ # @param name [String]
10
+ # The name of the company.
11
+ # @param is_active [Boolean]
12
+ # Whether the company is active or archived.
13
+ # @param week_start_day [String]
14
+ # The week day used as the start of the week. Returns one of: Saturday, Sunday, or Monday.
15
+ # @param wants_timestamp_timers [Boolean]
16
+ # Whether time is tracked via duration or start and end times.
17
+ # @param time_format [String]
18
+ # The format used to display time in Harvest. Returns either decimal or hours_minutes.
19
+ # @param plan_type [String]
20
+ # The type of plan the company is on. Examples: trial, free, or simple-v4
21
+ # @param clock [String]
22
+ # Used to represent whether the company is using a 12-hour or 24-hour clock.
23
+ # Returns either 12h or 24h.
24
+ # @param decimal_symbol [String]
25
+ # Symbol used when formatting decimals.
26
+ # @param thousands_separator [String]
27
+ # Separator used when formatting numbers.
28
+ # @param color_scheme [String]
29
+ # The color scheme being used in the Harvest web client.
30
+ # @param weekly_capacity [Integer]
31
+ # The weekly capacity in seconds.
32
+ # @param expense_feature [Boolean]
33
+ # Whether the expense module is enabled.
34
+ # @param invoice_feature [Boolean]
35
+ # Whether the invoice module is enabled.
36
+ # @param estimate_feature [Boolean]
37
+ # Whether the estimate module is enabled.
38
+ # @param approval_feature [Boolean]
39
+ # Whether the approval module is enabled.
40
+ Company = Struct.new(
41
+ 'Company',
42
+ :base_uri,
43
+ :full_domain,
44
+ :name,
45
+ :is_active,
46
+ :week_start_day,
47
+ :wants_timestamp_timers,
48
+ :time_format,
49
+ :plan_type,
50
+ :clock,
51
+ :decimal_symbol,
52
+ :thousands_separator,
53
+ :color_scheme,
54
+ :weekly_capacity,
55
+ :expense_feature,
56
+ :invoice_feature,
57
+ :estimate_feature,
58
+ :approval_feature,
59
+ keyword_init: true
60
+ )
61
+ end
62
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Harvest
4
+ module Resources
5
+ # @param id [Integer]
6
+ # Unique ID for the estimate.
7
+ # @param client [Struct]
8
+ # An object containing estimate's client id and name.
9
+ # @param line_items [List]
10
+ # Array of estimate line items.
11
+ # @param creator [Struct]
12
+ # An object containing the id and name of the person that created the estimate.
13
+ # @param client_key [String]
14
+ # Used to build a URL to the public web invoice for your client:
15
+ # @param number [String]
16
+ # If no value is set, the number will be automatically generated.
17
+ # @param purchase_order [String]
18
+ # The purchase order number.
19
+ # @param amount [decimal]
20
+ # The total amount for the estimate, including any discounts and taxes.
21
+ # @param tax [decimal]
22
+ # This percentage is applied to the subtotal, including line items and
23
+ # discounts.
24
+ # @param tax_amount [decimal]
25
+ # The first amount of tax included, calculated from tax. If no tax is
26
+ # defined, this value will be null.
27
+ # @param tax2 [decimal]
28
+ # This percentage is applied to the subtotal, including line items and
29
+ # discounts.
30
+ # @param tax2_amount [decimal]
31
+ # The amount calculated from tax2.
32
+ # @param discount [decimal]
33
+ # This percentage is subtracted from the subtotal.
34
+ # @param discount_amount [decimal]
35
+ # The amount calcuated from discount.
36
+ # @param subject [String]
37
+ # The estimate subject.
38
+ # @param notes [String]
39
+ # Any additional notes included on the estimate.
40
+ # @param currency [String]
41
+ # The currency code associated with this estimate.
42
+ # @param state [String]
43
+ # The current state of the estimate: draft, sent, accepted, or declined.
44
+ # @param issue_date [Date]
45
+ # Date the estimate was issued.
46
+ # @param sent_at [DateTime]
47
+ # Date and time the estimate was sent.
48
+ # @param accepted_at [DateTime]
49
+ # Date and time the estimate was accepted.
50
+ # @param declined_at [DateTime]
51
+ # Date and time the estimate was declined.
52
+ # @param created_at [DateTime]
53
+ # Date and time the estimate was created.
54
+ # @param updated_at [DateTime]
55
+ # Date and time the estimate was last updated.
56
+ Estimate = Struct.new(
57
+ 'Estimate',
58
+ :id,
59
+ :client,
60
+ :line_items,
61
+ :creator,
62
+ :client_key,
63
+ :number,
64
+ :purchase_order,
65
+ :amount,
66
+ :tax,
67
+ :tax_amount,
68
+ :tax2,
69
+ :tax2_amount,
70
+ :discount,
71
+ :discount_amount,
72
+ :subject,
73
+ :notes,
74
+ :currency,
75
+ :state,
76
+ :issue_date,
77
+ :sent_at,
78
+ :accepted_at,
79
+ :declined_at,
80
+ :created_at,
81
+ :updated_at,
82
+ keyword_init: true
83
+ )
84
+
85
+ # @param id [Integer]
86
+ # Unique ID for the line item.
87
+ # @param kind [String]
88
+ # The name of an estimate item category.
89
+ # @param description [String]
90
+ # Text description of the line item.
91
+ # @param quantity [Integer]
92
+ # The unit quantity of the item.
93
+ # @param unit_price [decimal]
94
+ # The individual price per unit.
95
+ # @param amount [decimal]
96
+ # The line item subtotal (quantity * unit_price).
97
+ # @param taxed [Boolean]
98
+ # Whether the estimate's tax percentage applies to this line item.
99
+ # @param taxed2 [Boolean]
100
+ # Whether the estimate's tax2 percentage applies to this line item.
101
+ EstimateLineItem = Struct.new(
102
+ 'EstimateLineItem',
103
+ :id,
104
+ :kind,
105
+ :description,
106
+ :quantity,
107
+ :unit_price,
108
+ :amount,
109
+ :taxed,
110
+ :taxed2,
111
+ keyword_init: true
112
+ )
113
+
114
+ # @param id [Integer]
115
+ # Unique ID for the message.
116
+ # @param sent_by [String]
117
+ # Name of the user that created the message.
118
+ # @param sent_by_email [String]
119
+ # Email of the user that created the message.
120
+ # @param sent_from [String]
121
+ # Name of the user that the message was sent from.
122
+ # @param sent_from_email [String]
123
+ # Email of the user that message was sent from.
124
+ # @param recipients [List]
125
+ # Array of estimate message recipients.
126
+ # @param subject [String]
127
+ # The message subject.
128
+ # @param body [String]
129
+ # The message body.
130
+ # @param send_me_a_copy [Boolean]
131
+ # Whether to email a copy of the message to the current user.
132
+ # @param event_type [String]
133
+ # The type of estimate event that occurred with the message: send, accept,
134
+ # decline, re-open, view, or invoice.
135
+ # @param created_at [DateTime]
136
+ # Date and time the message was created.
137
+ # @param updated_at [DateTime]
138
+ # Date and time the message was last updated.
139
+ EstimateMessage = Struct.new(
140
+ 'EstimateMessage',
141
+ :id,
142
+ :sent_by,
143
+ :sent_by_email,
144
+ :sent_from,
145
+ :sent_from_email,
146
+ :recipients,
147
+ :subject,
148
+ :body,
149
+ :send_me_a_copy,
150
+ :event_type,
151
+ :created_at,
152
+ :updated_at,
153
+ keyword_init: true
154
+ )
155
+
156
+ # @param id [Integer]
157
+ # Unique ID for the estimate item category.
158
+ # @param name [String]
159
+ # The name of the estimate item category.
160
+ # @param created_at [DateTime]
161
+ # Date and time the estimate item category was created.
162
+ # @param updated_at [DateTime]
163
+ # Date and time the estimate item category was last updated.
164
+ EstimateItemCategory = Struct.new(
165
+ 'EstimateItemCategory',
166
+ :id,
167
+ :name,
168
+ :created_at,
169
+ :updated_at,
170
+ keyword_init: true
171
+ )
172
+ end
173
+ end