wordjelly-auth 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/auth/clients_controller.rb +8 -0
- data/app/controllers/auth/profiles_controller.rb +2 -1
- data/app/helpers/auth/clients_helper.rb +2 -0
- data/app/models/auth/concerns/shopping/product_concern.rb +38 -23
- data/app/models/auth/work/cycle.rb +131 -58
- data/app/models/auth/work/minute.rb +124 -0
- data/app/views/auth/clients/_form.html.erb +1 -1
- data/app/views/auth/clients/edit.html.erb +1 -1
- data/app/views/auth/clients/show.html.erb +6 -2
- data/app/views/layouts/auth/navbar/_personalization.html.erb +1 -1
- data/lib/auth/engine.rb +14 -0
- data/lib/auth/rails/routes.rb +2 -1
- data/lib/auth/version.rb +1 -1
- data/spec/dummy/app/assets/time_hashes.json +1 -1
- data/spec/dummy/config/initializers/preinitializer.rb +6 -5
- data/spec/dummy/log/development.log +2514 -0
- data/spec/dummy/log/test.log +308 -0
- data/spec/models/auth/shopping/product_spec.rb +3 -5
- data/spec/models/auth/work/cycle_spec.rb +11 -0
- data/spec/models/auth/work/minute_spec.rb +10 -0
- data/spec/support/work_support.rb +13 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19a46d7a74a79c55717dd9c3eb1e9a9bfa2f59b0
|
4
|
+
data.tar.gz: 43690d96180781c8c12bfb818bf5c7a61e8fb59e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf2eb9ea412904b566efaad965adfcb8fe32409ea337187b6ec5985d57c99e9a93d6f8be165f128bc0a6e034b3ae2b948929acc08dcbe0ed154b9fedbb65d061
|
7
|
+
data.tar.gz: 3f428c140567a30d25e20722caed25b7e09b18b24d2f875cebef0acf204705a8b782093b483b6c0a9f4781df46f4e6b19f92ed5895cf312cdcd37c462e2366d5
|
@@ -24,6 +24,11 @@ module Auth
|
|
24
24
|
respond_with @client
|
25
25
|
end
|
26
26
|
|
27
|
+
## how are we going to get the client id exactly?
|
28
|
+
## that's the basic problem
|
29
|
+
## thereafter we can do the rest.
|
30
|
+
|
31
|
+
|
27
32
|
# GET /clients/new
|
28
33
|
def new
|
29
34
|
#@client = Client.new
|
@@ -86,6 +91,9 @@ module Auth
|
|
86
91
|
|
87
92
|
## if the resource_signed_in is an admin, just return
|
88
93
|
## otherwise if the user's id is not the same as the id passed in, then throw a not_found.
|
94
|
+
## this means that only if the guy is an admin , then this can work.
|
95
|
+
## otherwise it cannot work
|
96
|
+
## i think this has to be done from the web app.
|
89
97
|
def verify_client_belongs_to_user
|
90
98
|
return if @resource_for_web_app.is_admin?
|
91
99
|
not_found("client does not belong to user") if @resource_for_web_app.id.to_s != params[:id]
|
@@ -11,12 +11,13 @@ class Auth::ProfilesController < Auth::ApplicationController
|
|
11
11
|
before_action :initialize_vars, TCONDITIONS
|
12
12
|
before_action :is_admin_user, :only => [:set_proxy_user]
|
13
13
|
|
14
|
-
|
15
14
|
def initialize_vars
|
15
|
+
puts "---------------------------------------------------"
|
16
16
|
@resource_params = {}
|
17
17
|
@profile_resource = nil
|
18
18
|
@all_params = permitted_params.deep_symbolize_keys
|
19
19
|
|
20
|
+
|
20
21
|
if collection = @all_params[:resource]
|
21
22
|
|
22
23
|
if Auth.configuration.auth_resources[collection.singularize.capitalize]
|
@@ -117,6 +117,23 @@ module Auth::Concerns::Shopping::ProductConcern
|
|
117
117
|
|
118
118
|
module ClassMethods
|
119
119
|
|
120
|
+
## so we have completed the rolling n minutes.
|
121
|
+
def add_to_previous_rolling_n_minutes(minutes,origin_epoch,cycle_to_add)
|
122
|
+
|
123
|
+
## get all the minutes less than that.
|
124
|
+
rolling_n_minutes_less_than_that = minutes.keys.select{|c| c < origin_epoch}
|
125
|
+
|
126
|
+
end_min = rolling_n_minutes_less_than_that.size < Auth.configuration.rolling_minutes ? rolling_n_minutes_less_than_that.size : Auth.configuration.rolling_minutes
|
127
|
+
|
128
|
+
end_min = end_min - 1
|
129
|
+
|
130
|
+
end_min = end_min > 0 ? end_min : 0
|
131
|
+
rolling_n_minutes_less_than_that[0..end_min].each do |epoch|
|
132
|
+
minutes[epoch].cycles << cycle_to_add
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
120
137
|
## minutes : {epoch => minute object}
|
121
138
|
def schedule_cycles(minutes,location_id,conditions = {})
|
122
139
|
|
@@ -124,44 +141,42 @@ module Auth::Concerns::Shopping::ProductConcern
|
|
124
141
|
|
125
142
|
products = Auth.configuration.product_class.constantize.where(conditions) if !conditions.blank?
|
126
143
|
|
127
|
-
|
128
|
-
|
129
|
-
#puts "doing minute: #{minute}"
|
144
|
+
minutes.keys.each do |epoch|
|
145
|
+
|
130
146
|
products.each do |product|
|
131
|
-
|
147
|
+
|
132
148
|
all_cycles_valid = true
|
133
149
|
product.cycles.each do |cycle|
|
134
|
-
|
135
|
-
all_cycles_valid = cycle.requirements_satisfied(
|
136
|
-
|
150
|
+
|
151
|
+
all_cycles_valid = cycle.requirements_satisfied(epoch + cycle.time_since_prev_cycle.minutes*60,location_id)
|
152
|
+
|
137
153
|
end
|
154
|
+
|
155
|
+
## just because the cycles are valid, it means we have workers, but how many?
|
156
|
+
## that also has to be returned by the cycle validity statements
|
157
|
+
|
138
158
|
if all_cycles_valid == true
|
159
|
+
cycle_chain = []
|
139
160
|
product.cycles.each do |cycle|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
161
|
+
epoch_at_which_to_add = epoch + cycle.time_since_prev_cycle.minutes*60
|
162
|
+
cycle_to_add = cycle.dup
|
163
|
+
cycle_to_add.origin_epoch = epoch_at_which_to_add
|
164
|
+
cycle_to_add.cycle_chain = cycle_chain
|
165
|
+
if minutes[epoch_at_which_to_add]
|
166
|
+
|
167
|
+
add_to_previous_rolling_n_minutes(minutes,epoch_at_which_to_add,cycle_to_add)
|
144
168
|
|
145
|
-
minutes[
|
146
|
-
|
147
|
-
#puts "these are the cycles---------"
|
148
|
-
#puts minutes[minute_at_which_to_add].cycles.to_s
|
169
|
+
minutes[epoch_at_which_to_add].cycles << cycle_to_add
|
149
170
|
|
171
|
+
cycle_chain << cycle_to_add.id.to_s
|
150
172
|
else
|
151
|
-
raise "necessary minute not in range."
|
173
|
+
#raise "necessary minute not in range."
|
152
174
|
end
|
153
175
|
end
|
154
176
|
end
|
155
177
|
end
|
156
178
|
end
|
157
|
-
|
158
|
-
#puts minutes.to_s
|
159
|
-
|
160
179
|
minutes
|
161
|
-
|
162
180
|
end
|
163
|
-
|
164
181
|
end
|
165
|
-
|
166
182
|
end
|
167
|
-
|
@@ -2,6 +2,11 @@ class Auth::Work::Cycle
|
|
2
2
|
|
3
3
|
include Mongoid::Document
|
4
4
|
|
5
|
+
## for aggs.
|
6
|
+
attr_accessor :cycle_index
|
7
|
+
|
8
|
+
field :origin_epoch
|
9
|
+
|
5
10
|
embedded_in :minutes, :class_name => "Auth::Work::Minute", :polymorphic => true
|
6
11
|
|
7
12
|
embedded_in :products, :class_name => Auth.configuration.product_class, :polymorphic => true
|
@@ -9,11 +14,24 @@ class Auth::Work::Cycle
|
|
9
14
|
embeds_many :templates, :class_name => "Auth::Work::Template"
|
10
15
|
|
11
16
|
## each cycle will have a limit
|
12
|
-
field :capacity, type: Integer
|
17
|
+
field :capacity, type: Integer, default: 0
|
18
|
+
|
19
|
+
## there will have to be another field, saying workers who can do it, and entities who can do it.
|
20
|
+
field :workers_available, type: Array
|
21
|
+
|
13
22
|
|
14
23
|
## it will have a list of workers to whom it is assigned
|
15
24
|
field :workers_assigned, type: Array
|
25
|
+
|
16
26
|
|
27
|
+
## the available entities, these are set at the time of creating the minutes.
|
28
|
+
field :entities_available, type: Array
|
29
|
+
|
30
|
+
|
31
|
+
## the entities assigned, finally.
|
32
|
+
field :entities_assigned, type: Array
|
33
|
+
|
34
|
+
|
17
35
|
## it has to have a priority score
|
18
36
|
field :priority, type: Float
|
19
37
|
|
@@ -36,9 +54,11 @@ class Auth::Work::Cycle
|
|
36
54
|
=end
|
37
55
|
field :requirements, type: Hash
|
38
56
|
|
39
|
-
|
40
57
|
field :cycle_code, type: String
|
41
58
|
|
59
|
+
## the ids of the related cycles.
|
60
|
+
field :cycle_chain, type: Array
|
61
|
+
|
42
62
|
before_save do |document|
|
43
63
|
document.cycle_code = BSON::ObjectId.new.to_s unless document.cycle_code
|
44
64
|
end
|
@@ -70,81 +90,134 @@ class Auth::Work::Cycle
|
|
70
90
|
end
|
71
91
|
|
72
92
|
def requirements_satisfied(epoch,location_id)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
92
|
-
},
|
93
|
-
{
|
94
|
-
"end_time" => {
|
95
|
-
"$gte" => time_for_query
|
96
|
-
}
|
93
|
+
|
94
|
+
#puts "came to requirements satisfied"
|
95
|
+
Auth.configuration.location_class.constantize.all.each do |l|
|
96
|
+
puts l.attributes.to_s
|
97
|
+
end
|
98
|
+
location = Auth.configuration.location_class.constantize.find(location_id)
|
99
|
+
|
100
|
+
#puts "location found :#{location}"
|
101
|
+
#puts "epoch : #{epoch}, and location id: #{location_id}"
|
102
|
+
time_for_query = Time.at(epoch)
|
103
|
+
applicable_schedules = Auth::Work::Schedule.collection.find({
|
104
|
+
"$and" => [
|
105
|
+
{
|
106
|
+
"location_id" => location_id
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"start_time" => {
|
110
|
+
"$lte" => time_for_query
|
97
111
|
}
|
98
|
-
|
99
|
-
|
100
|
-
|
112
|
+
},
|
113
|
+
{
|
114
|
+
"end_time" => {
|
115
|
+
"$gte" => time_for_query
|
116
|
+
}
|
117
|
+
}
|
118
|
+
]
|
119
|
+
})
|
120
|
+
|
101
121
|
|
102
122
|
|
103
|
-
|
104
|
-
|
123
|
+
#puts "applicable schedules:"
|
124
|
+
#puts applicable_schedules.to_s
|
105
125
|
|
106
|
-
|
126
|
+
applicable_schedules = applicable_schedules.to_a
|
107
127
|
|
108
|
-
|
109
|
-
|
110
|
-
|
128
|
+
return false if (applicable_schedules.blank? || applicable_schedules.size == 0)
|
129
|
+
|
130
|
+
#puts "there are applicable schedules"
|
111
131
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
132
|
+
req = self.requirements.deep_dup
|
133
|
+
#puts "req are:"
|
134
|
+
#puts req.to_s
|
135
|
+
|
136
|
+
applicable_schedules.map!{|c| c = Mongoid::Factory.from_db(Auth::Work::Schedule,c)}
|
117
137
|
|
118
|
-
|
119
|
-
|
120
|
-
schedule_for_object = schedule.for_object_class.constantize.find(schedule.for_object_id)
|
121
|
-
|
122
|
-
#puts "schedule for object is: #{schedule_for_object}"
|
138
|
+
## here basically suppose you have n applicable schedules.
|
139
|
+
## you need to combine them into cycle categories and see how many combinations you get out of it.
|
123
140
|
|
124
|
-
|
141
|
+
available_resources = {}
|
125
142
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
143
|
+
applicable_schedules.each do |schedule|
|
144
|
+
|
145
|
+
schedule_for_object = schedule.for_object_class.constantize.find(schedule.for_object_id)
|
146
|
+
|
147
|
+
schedule_for_object.cycle_types.keys.each do |type|
|
148
|
+
#req[type] = req[type] - 1 if req[type]
|
149
|
+
available_resources[type] = 0 unless available_resources[type]
|
150
|
+
available_resources[type]+=1
|
151
|
+
end
|
131
152
|
|
153
|
+
end
|
154
|
+
|
155
|
+
## now we have certain type counts necessary for this cycle.
|
156
|
+
## now how to return the available capacity.
|
157
|
+
#k = req.values.uniq
|
158
|
+
#return true if ((k[0] == 0) && (k.size == 1))
|
159
|
+
#return false
|
160
|
+
|
161
|
+
## so how to split into multiples ?
|
162
|
+
## just do it sequentially.
|
163
|
+
failed = false
|
164
|
+
while failed == false
|
165
|
+
self.requirements.keys.each do |req|
|
166
|
+
failed = true unless available_resources[req]
|
167
|
+
break unless available_resources[req]
|
168
|
+
failed = true if available_resources[req] < self.requirements[req]
|
169
|
+
break if available_resources[req] < self.requirements[req]
|
170
|
+
available_resources[req] -= self.requirements[req]
|
132
171
|
end
|
133
|
-
|
134
|
-
|
172
|
+
self.capacity+=1 if failed == false
|
173
|
+
end
|
174
|
+
|
175
|
+
## now this becomes the cycle capacity.
|
176
|
+
## but only for the origin minute.
|
177
|
+
|
178
|
+
return self.capacity > 0
|
135
179
|
|
180
|
+
end
|
136
181
|
|
137
|
-
return true if ((k[0] == 0) && (k.size == 1))
|
138
|
-
return false
|
139
182
|
|
140
|
-
|
183
|
+
###########################################################
|
184
|
+
##
|
185
|
+
##
|
186
|
+
## BOOKINGS.
|
187
|
+
##
|
188
|
+
##
|
189
|
+
###########################################################
|
190
|
+
|
191
|
+
|
141
192
|
|
142
|
-
|
193
|
+
def after_book
|
194
|
+
Auth::Work::Minute.get_affected_minutes(self.start_time,self.end_time,self.workers_assigned,self.entities_assigned).each do |minute|
|
143
195
|
|
144
|
-
|
196
|
+
## each cycle has its index as cycle_index
|
197
|
+
## this is used to update the cycles.
|
198
|
+
|
199
|
+
end
|
200
|
+
end
|
145
201
|
|
202
|
+
def book
|
203
|
+
after_book
|
146
204
|
end
|
147
205
|
|
206
|
+
|
207
|
+
## so the search criteria is
|
208
|
+
## where entity_ids == [n1,n2,n3], or worker_ids= [y1,y2,y3]
|
209
|
+
## range is such that
|
210
|
+
## if (end time or start time) of any cycle is (from this minute -> time of end of this cycle)
|
211
|
+
## or if start time <= this minute, and end time is >= minute of end of this cycle.
|
212
|
+
## for any of those cycles -> if priority is applicable, then block, and block all related chains.
|
213
|
+
## how to block the related chains ?
|
214
|
+
## a cycle has to store all its related chain ids, and also its 30 minute references.
|
215
|
+
## so that's it.
|
216
|
+
## this is something to execute tomorrow.
|
217
|
+
|
218
|
+
## so plan for today
|
219
|
+
##
|
220
|
+
|
148
221
|
end
|
149
222
|
|
150
223
|
|
@@ -3,4 +3,128 @@ class Auth::Work::Minute
|
|
3
3
|
embeds_many :cycles, :class_name => "Auth::Work::Cycle", :as => :minute_cycles
|
4
4
|
field :time, type: Time
|
5
5
|
field :geom, type: Array
|
6
|
+
|
7
|
+
## returns all minutes which have affected cycles , only containing the affected cycles.
|
8
|
+
def self.get_affected_minutes(cycle_start_time,cycle_end_time,cycle_workers_assigned,cycle_entities_assigned)
|
9
|
+
response = Auth::Work::Minute.collection.aggregate([
|
10
|
+
{
|
11
|
+
"$match" => {
|
12
|
+
"cycles" => {
|
13
|
+
"$elemMatch" => {
|
14
|
+
"$and" => [
|
15
|
+
{
|
16
|
+
"$or" => [
|
17
|
+
{
|
18
|
+
"start_time" => {
|
19
|
+
"$gte" => cycle_start_time,
|
20
|
+
"$lte" => cycle_end_time
|
21
|
+
}
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"end_time" => {
|
25
|
+
"$gte" => cycle_start_time,
|
26
|
+
"$lte" => cycle_end_time
|
27
|
+
}
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"$and" => [
|
31
|
+
{
|
32
|
+
"start_time" => {
|
33
|
+
"$lte" => cycle_start_time
|
34
|
+
}
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"end_time" => {
|
38
|
+
"$gte" => cycle_end_time
|
39
|
+
}
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
43
|
+
]
|
44
|
+
},
|
45
|
+
{
|
46
|
+
"$or" => [
|
47
|
+
{
|
48
|
+
"workers_available" => {
|
49
|
+
"$in" => cycle_workers_assigned
|
50
|
+
}
|
51
|
+
},
|
52
|
+
{
|
53
|
+
"entities_available" => {
|
54
|
+
"$in" => cycle_entities_assigned
|
55
|
+
}
|
56
|
+
}
|
57
|
+
]
|
58
|
+
}
|
59
|
+
]
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"$unwind" => "cycles",
|
66
|
+
"includeArrayIndex" => "cycle_index"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"$match" => {
|
70
|
+
"$and" => [
|
71
|
+
{
|
72
|
+
"$or" => [
|
73
|
+
{
|
74
|
+
"cycles.start_time" => {
|
75
|
+
"$gte" => cycle_start_time,
|
76
|
+
"$lte" => cycle_end_time
|
77
|
+
}
|
78
|
+
},
|
79
|
+
{
|
80
|
+
"cycles.end_time" => {
|
81
|
+
"$gte" => cycle_start_time,
|
82
|
+
"$lte" => cycle_end_time
|
83
|
+
}
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"$and" => [
|
87
|
+
{
|
88
|
+
"cycles.start_time" => {
|
89
|
+
"$lte" => cycle_start_time
|
90
|
+
}
|
91
|
+
},
|
92
|
+
{
|
93
|
+
"cycles.end_time" => {
|
94
|
+
"$gte" => cycle_end_time
|
95
|
+
}
|
96
|
+
}
|
97
|
+
]
|
98
|
+
}
|
99
|
+
]
|
100
|
+
},
|
101
|
+
{
|
102
|
+
"$or" => [
|
103
|
+
{
|
104
|
+
"cycles.workers_available" => {
|
105
|
+
"$in" => cycle_workers_assigned
|
106
|
+
}
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"cycles.entities_available" => {
|
110
|
+
"$in" => cycle_entities_assigned
|
111
|
+
}
|
112
|
+
}
|
113
|
+
]
|
114
|
+
}
|
115
|
+
]
|
116
|
+
}
|
117
|
+
},
|
118
|
+
{
|
119
|
+
"$group" => {
|
120
|
+
"_id" => "$_id",
|
121
|
+
"cycles" => {
|
122
|
+
"$push" => "$cycles"
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
])
|
127
|
+
response
|
128
|
+
end
|
129
|
+
|
6
130
|
end
|