checkoff 0.51.0 → 0.53.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae2af0fc7d0e29eadef095ae0987a8be0deed073e5772991be91c6edf0bc06dd
4
- data.tar.gz: ae20ac97a3675df6e6438167f8bf40a0524a6cae0e89e186330e2c770c8172c7
3
+ metadata.gz: 70e5f767656e34b2431a2920a57ade34d64480f53d95855818bd607400ae9e60
4
+ data.tar.gz: 42b5dc27c71e1f0bb5772f00d8ae74947286f13e7bb319d9ae8ab2c8dbb06722
5
5
  SHA512:
6
- metadata.gz: 42d03ee1caf0c8c96ae6404575475a3a6ee7a71883434c4ec1085001b419f5556d2947a4b048a0452678a2805e653e098327858ecb43e257fc295e6cd47bf4e9
7
- data.tar.gz: f68d1acf02c47ab02ddf284469606d50589da4faad6a6c1536540d3a04e5812647200e661586461491d655fc65eed7aad3274c5dd92349af69ac90cb3837a3e3
6
+ metadata.gz: 8327942085367d3501b77563121dab0935696550a46036da89f4662d59d5dd7acc9fa49930db08f3901a1468b05c5ab63a2f813ab56415c9f627887b585d8386
7
+ data.tar.gz: 6046d32bfd28b7805771be9854843821d0d84c2da3e49eac3df3f44d839169b073117870a38e67659e4f3ca0356151bcbfc4eb2feabbb7a6ffc88efe7917673b
data/Gemfile.lock CHANGED
@@ -12,7 +12,7 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- checkoff (0.51.0)
15
+ checkoff (0.53.0)
16
16
  activesupport
17
17
  asana (> 0.10.0)
18
18
  cache_method
@@ -14,6 +14,45 @@ module Checkoff
14
14
  end
15
15
 
16
16
  # @return [Array(Hash<String, String>, Array<[Symbol, Array]>)] See https://developers.asana.com/docs/search-tasks-in-a-workspace
17
+ def handle_through_next
18
+ due_date_value = get_single_param('due_date.value').to_i
19
+
20
+ validate_unit_is_day!
21
+
22
+ # @sg-ignore
23
+ # @type [Date]
24
+ before = Date.today + due_date_value
25
+ # 'due_on.before' => '2023-01-01',
26
+ # 'due_on.after' => '2023-01-01',
27
+ # [{ 'due_on.before' => '2023-09-01' }, []]
28
+ [{ 'due_on.before' => before.to_s }, []]
29
+ end
30
+
31
+ # @return [Array(Hash<String, String>, Array<[Symbol, Array]>)] See https://developers.asana.com/docs/search-tasks-in-a-workspace
32
+ def handle_between
33
+ due_date_after = get_single_param('due_date.after')
34
+ raise 'Teach me how to handle due_date_before' if date_url_params.key? 'due_date.before'
35
+
36
+ validate_unit_not_provided!
37
+
38
+ # Example value: 1702857600000
39
+ after = Time.at(due_date_after.to_i / 1000).to_date
40
+ [{ 'due_on.after' => after.to_s }, []]
41
+ end
42
+
43
+ # @param param_key [String]
44
+ # @return [String]
45
+ def get_single_param(param_key)
46
+ raise "Expected #{param_key} to have at least one value" unless date_url_params.key? param_key
47
+
48
+ value = date_url_params.fetch(param_key)
49
+
50
+ raise "Expected #{param_key} to have one value" if value.length != 1
51
+
52
+ value[0]
53
+ end
54
+
55
+ # @return [Array(Hash<String, String>, Array<[Symbol, Array]>)]
17
56
  def convert
18
57
  return [{}, []] if date_url_params.empty?
19
58
 
@@ -21,38 +60,29 @@ module Checkoff
21
60
  # due_date.operator=through_next
22
61
  # due_date.value=0
23
62
  # due_date.unit=day
24
- validate_due_date_through_next!
63
+ due_date_operator = get_single_param('due_date.operator')
25
64
 
26
- value = date_url_params.fetch('due_date.value').fetch(0).to_i
65
+ return handle_through_next if due_date_operator == 'through_next'
27
66
 
28
- # @sg-ignore
29
- # @type [Date]
30
- before = Date.today + value
67
+ return handle_between if due_date_operator == 'between'
31
68
 
32
- validate_unit_is_day!
33
-
34
- # 'due_on.before' => '2023-01-01',
35
- # 'due_on.after' => '2023-01-01',
36
- # [{ 'due_on.before' => '2023-09-01' }, []]
37
- [{ 'due_on.before' => before.to_s }, []]
69
+ raise "Teach me how to handle date mode: #{due_date_operator.inspect}."
38
70
  end
39
71
 
40
72
  private
41
73
 
42
74
  # @return [void]
43
- def validate_unit_is_day!
44
- unit = date_url_params.fetch('due_date.unit').fetch(0)
75
+ def validate_unit_not_provided!
76
+ return unless date_url_params.key? 'due_date.unit'
45
77
 
46
- raise 'Teach me how to handle other time units' unless unit == 'day'
78
+ raise "Teach me how to handle other due_date.unit for these params: #{date_url_params.inspect}"
47
79
  end
48
80
 
49
81
  # @return [void]
50
- def validate_due_date_through_next!
51
- due_date_operators = date_url_params.fetch('due_date.operator')
52
-
53
- return if due_date_operators == ['through_next']
82
+ def validate_unit_is_day!
83
+ unit = date_url_params.fetch('due_date.unit').fetch(0)
54
84
 
55
- raise "Teach me how to handle date mode: #{due_date_operators}."
85
+ raise 'Teach me how to handle other time units' unless unit == 'day'
56
86
  end
57
87
 
58
88
  # @return [Hash<String, Array<String>>]
@@ -497,6 +497,47 @@ module Checkoff
497
497
  task_selector
498
498
  end
499
499
  end
500
+
501
+ # :estimate_exceeds_duration
502
+ class EstimateExceedsDurationFunctionEvaluator < FunctionEvaluator
503
+ FUNCTION_NAME = :estimate_exceeds_duration
504
+
505
+ def matches?
506
+ fn?(task_selector, FUNCTION_NAME)
507
+ end
508
+
509
+ # @param task [Asana::Resources::Task]
510
+ # @return [Float]
511
+ def calculate_allocated_hours(task)
512
+ due_on = nil
513
+ start_on = nil
514
+ start_on = Date.parse(task.start_on) unless task.start_on.nil?
515
+ due_on = Date.parse(task.due_on) unless task.due_on.nil?
516
+ allocated_hours = 8.0
517
+ # @sg-ignore
518
+ allocated_hours = (due_on - start_on + 1).to_i * 8.0 if start_on && due_on
519
+ allocated_hours
520
+ end
521
+
522
+ # @param task [Asana::Resources::Task]
523
+ # @return [Boolean]
524
+ def evaluate(task)
525
+ custom_field = pull_custom_field_by_name_or_raise(task, 'Estimated time')
526
+
527
+ # @sg-ignore
528
+ # @type [Integer, nil]
529
+ estimate_minutes = custom_field.fetch('number_value')
530
+
531
+ # no estimate set
532
+ return false if estimate_minutes.nil?
533
+
534
+ estimate_hours = estimate_minutes / 60.0
535
+
536
+ allocated_hours = calculate_allocated_hours(task)
537
+
538
+ estimate_hours > allocated_hours
539
+ end
540
+ end
500
541
  end
501
542
 
502
543
  # Evaluator task selectors against a task
@@ -527,6 +568,7 @@ module Checkoff
527
568
  Checkoff::TaskSelectorClasses::CustomFieldLessThanNDaysFromNowFunctionEvaluator,
528
569
  Checkoff::TaskSelectorClasses::CustomFieldGreaterThanOrEqualToNDaysFromNowFunctionEvaluator,
529
570
  Checkoff::TaskSelectorClasses::StringLiteralEvaluator,
571
+ Checkoff::TaskSelectorClasses::EstimateExceedsDurationFunctionEvaluator,
530
572
  ].freeze
531
573
 
532
574
  # @param task_selector [Array]
@@ -3,5 +3,5 @@
3
3
  # Command-line and gem client for Asana (unofficial)
4
4
  module Checkoff
5
5
  # Version of library
6
- VERSION = '0.51.0'
6
+ VERSION = '0.53.0'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checkoff
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.51.0
4
+ version: 0.53.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vince Broz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-03 00:00:00.000000000 Z
11
+ date: 2023-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport