moco-ruby 0.1.2 → 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.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -3
- data/CHANGELOG.md +104 -5
- data/Gemfile +3 -1
- data/Gemfile.lock +72 -23
- data/README.md +225 -55
- data/examples/v2_api_example.rb +73 -0
- data/lib/moco/client.rb +47 -0
- data/lib/moco/collection_proxy.rb +200 -0
- data/lib/moco/connection.rb +68 -0
- data/lib/moco/entities/activity.rb +101 -0
- data/lib/moco/entities/base_entity.rb +312 -0
- data/lib/moco/entities/company.rb +28 -0
- data/lib/moco/entities/deal.rb +24 -0
- data/lib/moco/entities/expense.rb +37 -0
- data/lib/moco/entities/holiday.rb +25 -0
- data/lib/moco/entities/invoice.rb +53 -0
- data/lib/moco/entities/planning_entry.rb +26 -0
- data/lib/moco/entities/presence.rb +30 -0
- data/lib/moco/entities/project.rb +48 -0
- data/lib/moco/entities/schedule.rb +26 -0
- data/lib/moco/entities/task.rb +20 -0
- data/lib/moco/entities/user.rb +33 -0
- data/lib/moco/entities/web_hook.rb +27 -0
- data/lib/moco/entities.rb +11 -4
- data/lib/moco/entity_collection.rb +59 -0
- data/lib/moco/helpers.rb +1 -0
- data/lib/moco/nested_collection_proxy.rb +43 -0
- data/lib/moco/sync.rb +337 -62
- data/lib/moco/version.rb +1 -1
- data/lib/moco.rb +28 -2
- data/moco.gemspec +36 -0
- data/mocurl.rb +51 -34
- data/sync_activity.rb +12 -6
- metadata +42 -8
- data/lib/moco/api.rb +0 -194
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MOCO
|
4
|
+
# Represents a MOCO webhook
|
5
|
+
# Provides methods for webhook-specific operations
|
6
|
+
class WebHook < BaseEntity
|
7
|
+
# Override entity_path to match API path
|
8
|
+
def self.entity_path
|
9
|
+
"account/web_hooks"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Instance methods for webhook-specific operations
|
13
|
+
def enable
|
14
|
+
client.put("account/web_hooks/#{id}/enable")
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def disable
|
19
|
+
client.put("account/web_hooks/#{id}/disable")
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
"#{target} - #{url}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/moco/entities.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative "helpers"
|
|
4
4
|
|
5
5
|
module MOCO
|
6
6
|
# Base entity class others inherit from, providing comparison, to_h, to_json
|
7
|
+
# @deprecated Use MOCO::BaseEntity from entities/base_entity.rb instead
|
7
8
|
class BaseEntity
|
8
9
|
def eql?(other)
|
9
10
|
return false unless other.is_a? self.class
|
@@ -28,7 +29,6 @@ module MOCO
|
|
28
29
|
hash
|
29
30
|
end
|
30
31
|
|
31
|
-
# rubocop:disable Metrics/MethodLength
|
32
32
|
def to_json(*arg)
|
33
33
|
to_h do |k, v|
|
34
34
|
if v.is_a? Hash
|
@@ -43,9 +43,9 @@ module MOCO
|
|
43
43
|
end.to_h.to_json(arg)
|
44
44
|
end
|
45
45
|
end
|
46
|
-
# rubocop:enable Metrics/MethodLength
|
47
46
|
|
48
47
|
# https://hundertzehn.github.io/mocoapp-api-docs/sections/projects.html
|
48
|
+
# @deprecated Use MOCO::Project from entities/project.rb instead
|
49
49
|
class Project < BaseEntity
|
50
50
|
attr_accessor :id, :active, :name, :customer, :tasks
|
51
51
|
|
@@ -55,6 +55,7 @@ module MOCO
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# https://hundertzehn.github.io/mocoapp-api-docs/sections/project_tasks.html
|
58
|
+
# @deprecated Use MOCO::Task from entities/task.rb instead
|
58
59
|
class Task < BaseEntity
|
59
60
|
attr_accessor :id, :active, :name, :project_id, :billable
|
60
61
|
|
@@ -64,22 +65,28 @@ module MOCO
|
|
64
65
|
end
|
65
66
|
|
66
67
|
# https://hundertzehn.github.io/mocoapp-api-docs/sections/activities.html
|
68
|
+
# @deprecated Use MOCO::Activity from entities/activity.rb instead
|
67
69
|
class Activity < BaseEntity
|
68
70
|
attr_accessor :id, :active, :date, :description, :project, :task, :seconds, :hours, :billable, :billed, :user,
|
69
71
|
:customer, :tag
|
70
72
|
|
71
73
|
def to_s
|
72
|
-
|
73
|
-
|
74
|
+
description_part = description.empty? ? "" : " (#{description})"
|
75
|
+
status_part = "(#{%i[billable billed].map { |x| (send(x) ? "" : "not ") + x.to_s }.join(", ")})"
|
76
|
+
|
77
|
+
"#{date} - #{Helpers.decimal_hours_to_civil(hours)}h (#{seconds}s) - " \
|
78
|
+
"#{project&.name} - #{task&.name}#{description_part} #{status_part}"
|
74
79
|
end
|
75
80
|
end
|
76
81
|
|
77
82
|
# https://hundertzehn.github.io/mocoapp-api-docs/sections/companies.html
|
83
|
+
# @deprecated Use MOCO::Company from entities/company.rb instead
|
78
84
|
class Customer < BaseEntity
|
79
85
|
attr_accessor :id, :name
|
80
86
|
end
|
81
87
|
|
82
88
|
# https://hundertzehn.github.io/mocoapp-api-docs/sections/users.html
|
89
|
+
# @deprecated Use MOCO::User from entities/user.rb instead
|
83
90
|
class User < BaseEntity
|
84
91
|
attr_accessor :id, :firstname, :lastname
|
85
92
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "collection_proxy"
|
4
|
+
|
5
|
+
module MOCO
|
6
|
+
# Provides high-level collection operations for MOCO entities
|
7
|
+
class EntityCollection
|
8
|
+
include Enumerable
|
9
|
+
attr_reader :client, :path, :entity_class_name
|
10
|
+
|
11
|
+
def initialize(client, path, entity_class_name)
|
12
|
+
@client = client
|
13
|
+
@path = path
|
14
|
+
@entity_class_name = entity_class_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def all
|
18
|
+
collection.all
|
19
|
+
end
|
20
|
+
|
21
|
+
def find(id)
|
22
|
+
collection.find(id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def where(filters = {})
|
26
|
+
collection.where(filters)
|
27
|
+
end
|
28
|
+
|
29
|
+
def create(attributes)
|
30
|
+
collection.create(attributes)
|
31
|
+
end
|
32
|
+
|
33
|
+
def each(&)
|
34
|
+
collection.each(&)
|
35
|
+
end
|
36
|
+
|
37
|
+
def first
|
38
|
+
all.first
|
39
|
+
end
|
40
|
+
|
41
|
+
def count
|
42
|
+
all.count
|
43
|
+
end
|
44
|
+
|
45
|
+
def update(id, attributes)
|
46
|
+
collection.update(id, attributes)
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete(id)
|
50
|
+
collection.delete(id)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def collection
|
56
|
+
@collection ||= CollectionProxy.new(client, path, entity_class_name)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/moco/helpers.rb
CHANGED
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MOCO
|
4
|
+
# Provides ActiveRecord-style query interface for nested MOCO entities
|
5
|
+
# For example, project.tasks is a nested collection of tasks under a project
|
6
|
+
class NestedCollectionProxy < CollectionProxy
|
7
|
+
attr_reader :parent, :records
|
8
|
+
|
9
|
+
def initialize(client, parent, path_or_entity_name, entity_class_name)
|
10
|
+
@parent = parent
|
11
|
+
super(client, path_or_entity_name, entity_class_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Override determine_base_path to include the parent's path
|
15
|
+
# For nested resources, we ignore any custom entity_path and just use simple pluralization
|
16
|
+
def determine_base_path(path_or_entity_name)
|
17
|
+
parent_type = ActiveSupport::Inflector.underscore(parent.class.name.split("::").last)
|
18
|
+
# Use simple tableized name, not entity_path (which might include 'projects/' prefix)
|
19
|
+
nested_path = ActiveSupport::Inflector.tableize(path_or_entity_name.to_s)
|
20
|
+
"#{parent_type.pluralize}/#{parent.id}/#{nested_path}"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create a new entity in this nested collection
|
24
|
+
def create(attributes)
|
25
|
+
klass = entity_class
|
26
|
+
return nil unless klass && klass <= MOCO::BaseEntity
|
27
|
+
|
28
|
+
klass.new(client, client.post(@base_path, attributes))
|
29
|
+
end
|
30
|
+
|
31
|
+
# Delete all entities in this nested collection
|
32
|
+
def destroy_all
|
33
|
+
client.delete("#{@base_path}/destroy_all")
|
34
|
+
true
|
35
|
+
rescue StandardError => e
|
36
|
+
warn "Warning: Failed to destroy all entities in #{@base_path}: #{e.message}"
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
# Make these methods public so they can be accessed by Project#tasks
|
41
|
+
public :load_records, :loaded?
|
42
|
+
end
|
43
|
+
end
|