forest_liana 9.11.0 → 9.11.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 850c5fe6679c01ceeebc7cf3bd4035a1d69845c434be482d1aec4e1a1e7cb509
4
- data.tar.gz: d019665e403093766fa60323ed45df69c75e9ba6fb297fcdb4ce7099fee57ceb
3
+ metadata.gz: ef87edd50271f66059b83ec7b2b46ca943f65bba9e434ce559a41178922ffa93
4
+ data.tar.gz: 5f861a043a5674e29e985ded21a24e91c1e83dc83b43b152284739391fb1a9cb
5
5
  SHA512:
6
- metadata.gz: 5d3190446adab7cebf81af3881bfd959f040b3e106250d3cd562b74cffb002528bb0fe0e0e0b986fcf631e8b3bdaf01937f607f1c86fbb1f5b32b8c3d998f807
7
- data.tar.gz: 6a751f7b7e2ec02c3b09447d593bc390a05a1fb7ffe0c08cf3ab28fbfeae3dac5ea67039275e96d79f63ea1748b39b0133a98df36859b8ddd3f8d64651df2872
6
+ metadata.gz: 8b2eb6642cbdaf89e8ac091a0a7550728788ebc536e77d7a93e0d166cabaa7d1e25c5d4b911318d32cf92368d78fbab44be9836d0df1b23a50e86e2190089692
7
+ data.tar.gz: 22ee84aff57cb385a776de3485e880769dcaf25861fd5cbf1046cd6836ed9aaee877b5ae58f1335dfb15fb96206452e7972a6b1941c3b19c488448ee36666533
@@ -84,7 +84,8 @@ module ForestLiana
84
84
  field_name = condition['field']
85
85
 
86
86
  if @operator_date_parser.is_date_operator?(operator)
87
- condition = @operator_date_parser.get_date_filter(operator, value)
87
+ field_schema = SchemaUtils.find_column_schema_by_name(@resource.name, field_name)
88
+ condition = @operator_date_parser.get_date_filter(operator, value, field_schema)
88
89
  return "#{parse_field_name(field_name)} #{condition}"
89
90
  end
90
91
 
@@ -259,10 +260,12 @@ module ForestLiana
259
260
 
260
261
  def parse_previous_interval_condition(condition)
261
262
  raise_empty_condition_in_filter_error unless condition
263
+ field_schema = SchemaUtils.find_column_schema_by_name(@resource.name, condition['field'])
262
264
 
263
265
  parsed_condition = @operator_date_parser.get_date_filter_for_previous_interval(
264
266
  condition['operator'],
265
- condition['value']
267
+ condition['value'],
268
+ field_schema
266
269
  )
267
270
 
268
271
  "#{parse_field_name(condition['field'])} #{parsed_condition}"
@@ -14,7 +14,7 @@ module ForestLiana
14
14
  when 'day'
15
15
  '%d/%m/%Y'
16
16
  when 'week'
17
- 'W%V-%Y'
17
+ 'W%V-%G'
18
18
  when 'month'
19
19
  '%b %Y'
20
20
  when 'year'
@@ -70,7 +70,16 @@ module ForestLiana
70
70
  date - @timezone_offset.hours
71
71
  end
72
72
 
73
- def get_date_filter(operator, value)
73
+
74
+ def format_date(field_type, value)
75
+ if field_type == 'Dateonly'
76
+ return value.strftime('%Y-%m-%d')
77
+ end
78
+
79
+ value
80
+ end
81
+
82
+ def get_date_filter(operator, value, field_schema)
74
83
  return nil unless is_date_operator? operator
75
84
 
76
85
  filter = case operator
@@ -79,18 +88,18 @@ module ForestLiana
79
88
  when OPERATOR_PAST
80
89
  "<= '#{Time.now}'"
81
90
  when OPERATOR_TODAY
82
- "BETWEEN '#{to_client_timezone(Time.now.beginning_of_day)}' " +
83
- "AND '#{to_client_timezone(Time.now.end_of_day)}'"
91
+ "BETWEEN '#{format_date(field_schema[:type], to_client_timezone(Time.now.beginning_of_day))}' " +
92
+ "AND '#{format_date(field_schema[:type], to_client_timezone(Time.now.end_of_day))}'"
84
93
  when OPERATOR_PREVIOUS_X_DAYS
85
94
  ensure_integer_value(value)
86
95
  "BETWEEN '" +
87
- "#{to_client_timezone(Integer(value).day.ago.beginning_of_day)}'" +
88
- " AND '#{to_client_timezone(1.day.ago.end_of_day)}'"
96
+ "#{format_date(field_schema[:type], to_client_timezone(Integer(value).day.ago.beginning_of_day))}'" +
97
+ " AND '#{format_date(field_schema[:type], to_client_timezone(1.day.ago.end_of_day))}'"
89
98
  when OPERATOR_PREVIOUS_X_DAYS_TO_DATE
90
99
  ensure_integer_value(value)
91
100
  "BETWEEN '" +
92
- "#{to_client_timezone((Integer(value) - 1).day.ago.beginning_of_day)}'" +
93
- " AND '#{Time.now}'"
101
+ "#{format_date(field_schema[:type], to_client_timezone((Integer(value) - 1).day.ago.beginning_of_day))}'" +
102
+ " AND '#{format_date(field_schema[:type], Time.now)}'"
94
103
  when OPERATOR_BEFORE_X_HOURS_AGO
95
104
  ensure_integer_value(value)
96
105
  "< '#{(Integer(value)).hour.ago}'"
@@ -109,35 +118,35 @@ module ForestLiana
109
118
  to_date = PERIODS[operator][:to_date]
110
119
 
111
120
  if to_date
112
- from = to_client_timezone(Time.now.send("beginning_of_#{period_of_time}"))
113
- to = Time.now
121
+ from = format_date(field_schema[:type], to_client_timezone(Time.now.send("beginning_of_#{period_of_time}")))
122
+ to = format_date(field_schema[:type], Time.now)
114
123
  else
115
- from = to_client_timezone(duration.send(period).ago
116
- .send("beginning_of_#{period_of_time}"))
117
- to = to_client_timezone(duration.send(period).ago
118
- .send("end_of_#{period_of_time}"))
124
+ from = format_date(field_schema[:type], to_client_timezone(duration.send(period).ago
125
+ .send("beginning_of_#{period_of_time}")))
126
+ to = format_date(field_schema[:type], to_client_timezone(duration.send(period).ago
127
+ .send("end_of_#{period_of_time}")))
119
128
  end
120
129
 
121
130
  "BETWEEN '#{from}' AND '#{to}'"
122
131
  end
123
132
 
124
- def get_date_filter_for_previous_interval(operator, value)
133
+ def get_date_filter_for_previous_interval(operator, value, field_schema)
125
134
  return nil unless has_previous_interval? operator
126
135
 
127
136
  case operator
128
137
  when OPERATOR_TODAY
129
- return "BETWEEN '#{to_client_timezone(1.day.ago.beginning_of_day)}' AND " +
130
- "'#{to_client_timezone(1.day.ago.end_of_day)}'"
138
+ return "BETWEEN '#{format_date(field_schema[:type], to_client_timezone(1.day.ago.beginning_of_day))}' AND " +
139
+ "'#{format_date(field_schema[:type], to_client_timezone(1.day.ago.end_of_day))}'"
131
140
  when OPERATOR_PREVIOUS_X_DAYS
132
141
  ensure_integer_value(value)
133
142
  return "BETWEEN '" +
134
- "#{to_client_timezone((Integer(value) * 2).day.ago.beginning_of_day)}'" +
135
- " AND '#{to_client_timezone((Integer(value) + 1).day.ago.end_of_day)}'"
143
+ "#{format_date(field_schema[:type], to_client_timezone((Integer(value) * 2).day.ago.beginning_of_day))}'" +
144
+ " AND '#{format_date(field_schema[:type], to_client_timezone((Integer(value) + 1).day.ago.end_of_day))}'"
136
145
  when OPERATOR_PREVIOUS_X_DAYS_TO_DATE
137
146
  ensure_integer_value(value)
138
147
  return "BETWEEN '" +
139
- "#{to_client_timezone(((Integer(value) * 2) - 1).day.ago.beginning_of_day)}'" +
140
- " AND '#{to_client_timezone(Integer(value).day.ago)}'"
148
+ "#{format_date(field_schema[:type], to_client_timezone(((Integer(value) * 2) - 1).day.ago.beginning_of_day))}'" +
149
+ " AND '#{format_date(field_schema[:type], to_client_timezone(Integer(value).day.ago))}'"
141
150
  end
142
151
 
143
152
  duration = PERIODS[operator][:duration]
@@ -146,14 +155,14 @@ module ForestLiana
146
155
  to_date = PERIODS[operator][:to_date]
147
156
 
148
157
  if to_date
149
- from = to_client_timezone((duration)
150
- .send(period).ago.send("beginning_of_#{period_of_time}"))
151
- to = to_client_timezone((duration).send(period).ago)
158
+ from = format_date(field_schema[:type], to_client_timezone((duration)
159
+ .send(period).ago.send("beginning_of_#{period_of_time}")))
160
+ to = format_date(field_schema[:type], to_client_timezone((duration).send(period).ago))
152
161
  else
153
- from = to_client_timezone((duration * 2).send(period).ago
154
- .send("beginning_of_#{period_of_time}"))
155
- to = to_client_timezone((duration * 2).send(period).ago
156
- .send("end_of_#{period_of_time}"))
162
+ from = format_date(field_schema[:type], to_client_timezone((duration * 2).send(period).ago
163
+ .send("beginning_of_#{period_of_time}")))
164
+ to = format_date(field_schema[:type], to_client_timezone((duration * 2).send(period).ago
165
+ .send("end_of_#{period_of_time}")))
157
166
  end
158
167
 
159
168
  "BETWEEN '#{from}' AND '#{to}'"
@@ -49,6 +49,23 @@ module ForestLiana
49
49
  model_found
50
50
  end
51
51
 
52
+ def self.find_column_schema_by_name(collection_name, field_name)
53
+ schema = ForestLiana.apimap.find { |collection| collection.name == collection_name }
54
+ if field_name.include?(':')
55
+ relation, field_name = field_name.split(':')
56
+ relation_schema = schema.fields.find do |field|
57
+ field[:field].to_s == relation
58
+ end
59
+ foreign_collection_name, = relation_schema[:reference].split('.')
60
+
61
+ return find_column_schema_by_name(foreign_collection_name, field_name)
62
+ else
63
+ return schema.fields.find do |field|
64
+ field[:field].to_s == field_name
65
+ end
66
+ end
67
+ end
68
+
52
69
  def self.tables_names
53
70
  ActiveRecord::Base.connection.tables
54
71
  end
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "9.11.0"
2
+ VERSION = "9.11.2"
3
3
  end
@@ -68,6 +68,25 @@ module ForestLiana
68
68
  expect(stat.value.find { |item| item[:label] == "W18-2021" }[:values][:value]).to eq(2)
69
69
  expect(stat.value.find { |item| item[:label] == "W19-2021" }[:values][:value]).to eq(2)
70
70
  end
71
+
72
+ it 'should return consistent data for a leap year with week transition' do
73
+ Owner.delete_all
74
+ Owner.create(name: 'Michel', hired_at: Date.parse('23-12-2024'));
75
+ Owner.create(name: 'Robert', hired_at: Date.parse('23-12-2024'));
76
+ Owner.create(name: 'José', hired_at: Date.parse('30-12-2024'));
77
+ Owner.create(name: 'Yves', hired_at: Date.parse('06-01-2025'));
78
+
79
+ stat = LineStatGetter.new(Owner, {
80
+ timezone: "Europe/Paris",
81
+ aggregator: "Count",
82
+ timeRange: "Week",
83
+ groupByFieldName: "hired_at",
84
+ }, user).perform
85
+
86
+ expect(stat.value.find { |item| item[:label] == "W52-2024" }[:values][:value]).to eq(2)
87
+ expect(stat.value.find { |item| item[:label] == "W01-2025" }[:values][:value]).to eq(1)
88
+ expect(stat.value.find { |item| item[:label] == "W02-2025" }[:values][:value]).to eq(1)
89
+ end
71
90
  end
72
91
  end
73
92
  end
@@ -3,12 +3,36 @@ module ForestLiana
3
3
  test 'OPERATOR_AFTER_X_HOURS_AGO and OPERATOR_BEFORE_X_HOURS_AGO should not take timezone into account' do
4
4
  # Setting a big timezone (GMT+10) on purpose, the timezone should not be applied on the result date
5
5
  operatorDateIntervalParser = OperatorDateIntervalParser.new('Australia/Sydney')
6
+ fake_field_schema = {
7
+ field: "foo",
8
+ type: "Dateonly",
9
+ is_filterable: true,
10
+ is_sortable: true,
11
+ is_read_only: false,
12
+ is_required: false,
13
+ is_virtual: false,
14
+ default_value: nil,
15
+ integration: nil,
16
+ reference: nil,
17
+ inverse_of: nil,
18
+ relationships: nil,
19
+ widget: nil,
20
+ validations: []
21
+ }
6
22
 
7
- result = operatorDateIntervalParser.get_date_filter(OperatorDateIntervalParser::OPERATOR_AFTER_X_HOURS_AGO, 2)
23
+ result = operatorDateIntervalParser.get_date_filter(
24
+ OperatorDateIntervalParser::OPERATOR_AFTER_X_HOURS_AGO,
25
+ 2,
26
+ fake_field_schema
27
+ )
8
28
  hourComputed = result.split('> ')[1].tr('\'', '').to_datetime.hour
9
29
  assert hourComputed == Time.now.utc.hour - 2
10
30
 
11
- result = operatorDateIntervalParser.get_date_filter(OperatorDateIntervalParser::OPERATOR_BEFORE_X_HOURS_AGO, 2)
31
+ result = operatorDateIntervalParser.get_date_filter(
32
+ OperatorDateIntervalParser::OPERATOR_BEFORE_X_HOURS_AGO,
33
+ 2,
34
+ fake_field_schema
35
+ )
12
36
  hourComputed = result.split('< ')[1].tr('\'', '').to_datetime.hour
13
37
  assert hourComputed == Time.now.utc.hour - 2
14
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_liana
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.11.0
4
+ version: 9.11.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Munda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-19 00:00:00.000000000 Z
11
+ date: 2025-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails