Class: Auth::System::Definition
- Inherits:
-
Object
- Object
- Auth::System::Definition
- Includes:
- Concerns::SystemConcern
- Defined in:
- app/models/auth/system/definition.rb
Instance Method Summary collapse
-
#add_cart_items(input_objects) ⇒ Object
@return true/false : depending on whether anything could be added to this definition or not.
- #after_query(query_result) ⇒ Object
-
#apply_location_specifications ⇒ Object
7th.
-
#apply_time_specifications ⇒ Object
let me first individually test this function.
-
#build_query(location_information, time_information) ⇒ Object
@return options : the hash of options for the query.
- #build_unit_from_output_hash_object_specifications ⇒ Object
-
#default_location_specification ⇒ Object
QUERY AND SUBSEQUENT FUNCTIONS.
- #dispatch_to_next_level ⇒ Object
-
#find_input_object_id_common_schedules ⇒ Object
7th.
-
#input_object_ids ⇒ Object
an array of arrays, each inner array contains a bunch of cart item ids.
-
#input_object_query_results(input_object_id_group) ⇒ Object
@param input_object_id_group : we consider one element at a time of the input_object_ids, which is an array of arrays.
-
#intersection_location_commonality ⇒ Object
whether the locations of incoming objects inside each object_id element are to be kept common?.
-
#intersection_results ⇒ Object
the results of the intersects, one for each element in the input object ids.
-
#lookup_speed(location_information) ⇒ Object
@param location_information : a location information hash, with a coordinates and a radius, key.
- #merge_into_existing_unit ⇒ Object
-
#merge_time_range ⇒ Object
the minimum time before and after the initial unit, in which we can merge incoming additional products.
-
#next_definition_location ⇒ Object
the dispatch id the definition id of the next_definition.
-
#output_objects ⇒ Object
what would be output for one input bunch.
-
#physical_requirements ⇒ Object
inside the minutes we will have only static first time use physical requirements.
- #query ⇒ Object
-
#query_options ⇒ Object
one for each input object id bunch.
-
#query_results ⇒ Object
one for each input object id bunch.
-
#validate_locations_within_radius(location_ids, coordinates, within_radius, location_categories) ⇒ Object
@param location_ids : the location ids which we want to check are within the radius for the provided coordinates.
Instance Method Details
#add_cart_items(input_objects) ⇒ Object
@return true/false : depending on whether anything could be added to this definition or not.
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'app/models/auth/system/definition.rb', line 54 def add_cart_items(input_objects) groups = {} input_objects.each do |input_object| if group_value = input_object.get_group_value(self.address) groups[group_value] = [] unless groups[group_value] groups[group_value] << input_object.id.to_s end end groups.values.each do |val| self.input_object_ids << val end !groups.empty? end |
#after_query(query_result) ⇒ Object
452 453 454 455 456 457 |
# File 'app/models/auth/system/definition.rb', line 452 def after_query(query_result) self.level.wrapper.process_query_results(query_result,entity_categories_needed_simultaneously_with_capacity.keys,query_id,consumables) end |
#apply_location_specifications ⇒ Object
7th
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'app/models/auth/system/definition.rb', line 242 def apply_location_specifications ## each intersection result refers to one "product" or "product_equivalent" coming in. self.intersection_results.each_with_index {|intersection_result,key| cart_item_ids = self.input_object_ids[key] cart_items = cart_item_ids.map{|c| c = Auth.configuration.cart_item_class.constantize.find(c)} if intersection_result[0][:locations] == ["*"] within_radius_type_location_specifications = 0 loc_sp = {:loc_id_type => [], :within_radius_type => []} cart_items.each do |citem| if specification = citem.get_specification(self.address) if location_information = specification.location if location_information[:within_radius] loc_sp[:within_radius_type] << location_information unless location_information[:within_radius].nil? raise "more than one within radius type of location" unless loc_sp[:within_radius_type].include? location_information else loc_sp[:loc_id_type] << location_information end end end end common_location_ids = nil if loc_sp[:loc_id_type].size > 0 #puts "the first loc_sp loc_id_type" #puts loc_sp[:loc_id_type][0].to_s common_location_ids = loc_sp[:loc_id_type].inject(loc_sp[:loc_id_type][0][:location_ids]){|result,el| result = result & el[:location_ids]} #puts "the common location ids are:" #puts common_location_ids raise "could not find common location ids" if common_location_ids.size == 0 end if loc_sp[:within_radius_type].size == 1 if common_location_ids coords = loc_sp[:within_radius_type][0][:origin_location] within_radius = loc_sp[:within_radius_type][0][:within_radius] permitted_location_categories = loc_sp[:within_radius_type][0][:location_categories] common_location_ids = validate_locations_within_radius(common_location_ids,coords,within_radius,permitted_location_categories) if common_location_ids.size > 0 ## these should be added to the location specifications. self.location_specifications << {:location_ids => common_location_ids} else raise "could not find common location ids" if common_location_ids.size == 0 end else ## in this case there is only a single within_radius_type of location specifications, and nothing else. ## so here it will carry all the location information only. self.location_specifications << loc_sp[:within_radius_type][0] end else if common_location_ids.nil? self.location_specifications << {} else self.location_specifications << {:location_ids => common_location_ids} end end else ## here it will depend on the location ids specified in the intersects. ## and how to apply these. end } end |
#apply_time_specifications ⇒ Object
let me first individually test this function.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'app/models/auth/system/definition.rb', line 195 def apply_time_specifications current_time = Time.now self.intersection_results.each_with_index {|intersection_result,key| cart_item_ids = self.input_object_ids[key] cart_items = cart_item_ids.map{|c| c = Auth.configuration.cart_item_class.constantize.find(c)} if intersection_result[0][:minute] == "*" start_time_ranges = [] cart_items.each do |citem| ## we have to see if the specifications contain this address or not. if specification = citem.get_specification(self.address) start_time_ranges << specification.start_time_range(current_time) end end raise "no start time range found" if start_time_ranges.empty? start_time_ranges.sort { |a, b| a[:start_time_range_beginning] <=> b[:start_time_range_beginning] } first_start_time_beginning = start_time_ranges[0][:start_time_range_beginning] first_start_time_end = start_time_ranges[0][:start_time_range_end] ## now check all the others start_time_ranges[1..-1].each do |srange| beg = srange[:start_time_range_beginning] raise "start time range cannot be synchronized" if beg >= first_start_time_end end ## the combined start_time becomes: ## the end time becomes the earliest of the end times. final_beginning_time = start_time_ranges[-1][:start_time_range_beginning] final_end_time = start_time_ranges.map{|c| c = c[:start_time_range_end]}.sort { |a, b| a <=> b }[0] time_specifications << {:start_time_range_beginning => final_beginning_time, :start_time_range_end => final_end_time} else end } end |
#build_query(location_information, time_information) ⇒ Object
@return options : the hash of options for the query.
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 |
# File 'app/models/auth/system/definition.rb', line 408 def build_query(location_information,time_information) = {} [:minute_ranges] = [time_information[:start_time_range_beginning], time_information[:start_time_range_end]] [:categories] = self.entity_categories_needed_simultaneously_with_capacity.keys ## these two may or may not be defined. [:location_ids] = location_information[:location_ids] [:location_categories] = location_information[:location_categories] if location_information[:within_radius] [:speed] = lookup_speed(location_information) [:coordinates] = location_information[:origin_location] elsif location_information[:location_ids] else raise "location information has neither within radius nor location ids." end [:query_id] = BSON::ObjectId.new.to_s self. << end |
#build_unit_from_output_hash_object_specifications ⇒ Object
467 468 469 470 |
# File 'app/models/auth/system/definition.rb', line 467 def build_unit_from_output_hash_object_specifications ## will call generate_barcodes and callouts on the unit ## will also call generate_new_instructions. end |
#default_location_specification ⇒ Object
QUERY AND SUBSEQUENT FUNCTIONS. decide how to assay the locations, whether to have multiple mini locations or have one location only. finish this as well today. today will do query and merge into existing unit, and add barcode. tomorrow will do video and photo instructions.
396 397 398 |
# File 'app/models/auth/system/definition.rb', line 396 def default_location_specification end |
#dispatch_to_next_level ⇒ Object
472 473 474 475 |
# File 'app/models/auth/system/definition.rb', line 472 def dispatch_to_next_level ## will check if this is the last incoming product bunch ## if yes, will dispatch all the products to the next level. end |
#find_input_object_id_common_schedules ⇒ Object
7th
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'app/models/auth/system/definition.rb', line 126 def find_input_object_id_common_schedules self.input_object_ids.each_with_index {|input_object_id_group,key| agg = input_object_query_results(input_object_id_group) query_results_array = [] agg.each do |res| query_results_array << res["query_results"] end combined_array = [] if query_results_array.empty? =begin if it is the first time, then the time information would normally look at the intersects for the query. so we just put a "*" in the intersects. the intersect results usually have [[{},{},{}],[{},{},{}]] so in this case, we will push an array, with one hash , where the minute will be * and the locations will be an array with one * [ [ { :minute => "*", :locations => ["*"] } ] ] =end combined_array = [ { :minute => "*", :locations => ["*"] } ] else ## so the input object ids are like that ## now what about the units. =begin query_results_array.first.each do |minute_hash| minute = minute_hash[:minute] locations = minute_hash[:locations] query_results_array[1..-1].each do |arr| if result = arr.bsearch{|x| x[:minute] >= minute} if result[:minute] == minute if intersection_location_commonality if (result[:locations] - locations).size > 0 combined_array << result end else combined_array << result end end end end end =end end intersection_results << combined_array } end |
#input_object_ids ⇒ Object
an array of arrays, each inner array contains a bunch of cart item ids.
33 |
# File 'app/models/auth/system/definition.rb', line 33 field :input_object_ids, type: Array, default: [] |
#input_object_query_results(input_object_id_group) ⇒ Object
@param input_object_id_group : we consider one element at a time of the input_object_ids, which is an array of arrays. So one array is passed in at a time, and that is called input_object_id_group @return : the result of the aggregation. It should have as many elements as the input_object_id_group and each element has only the query_results available on it.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'app/models/auth/system/definition.rb', line 70 def input_object_query_results(input_object_id_group) response = Auth::System::Wrapper.collection.aggregate([ { "$match" => { "levels.branches.definitions.units.output_cart_item_ids" => { "$in" => input_object_id_group } } }, { "$unwind" => { "path" => "$levels" } }, { "$unwind" => { "path" => "$levels.branches" } }, { "$unwind" => { "path" => "$levels.branches.definitions" } }, { "$unwind" => { "path" => "$levels.branches.definitions.units" } }, { "$match" => { "output_cart_item_ids" => { "$in" => self.input_object_ids } } }, { "$project" => { "query_results" => 1 } } ]) ## the query results contain what? ## just the minutes or is each element a hash? ## it should be a hash ## like minute : [locations...] response.each do |res| puts res["query_results"].to_s end response end |
#intersection_location_commonality ⇒ Object
whether the locations of incoming objects inside each object_id element are to be kept common?
45 |
# File 'app/models/auth/system/definition.rb', line 45 field :intersection_location_commonality, type: Boolean, default: false |
#intersection_results ⇒ Object
the results of the intersects, one for each element in the input object ids.
36 |
# File 'app/models/auth/system/definition.rb', line 36 field :intersection_results, type: Array, default: [] |
#lookup_speed(location_information) ⇒ Object
403 404 405 |
# File 'app/models/auth/system/definition.rb', line 403 def lookup_speed(location_information) 20 end |
#merge_into_existing_unit ⇒ Object
459 460 461 462 463 464 465 |
# File 'app/models/auth/system/definition.rb', line 459 def merge_into_existing_unit ## will check if merge is true ## if yes, then will check the existing units for merge_range ## if possible, will merge ## if not possible, will return false. ## this may make it necessary to end |
#merge_time_range ⇒ Object
the minimum time before and after the initial unit, in which we can merge incoming additional products. the numbers are in seconds by default it is 10 seconds before and after.
23 |
# File 'app/models/auth/system/definition.rb', line 23 field :merge_time_range, type: Array, default: [-10,10] |
#next_definition_location ⇒ Object
the dispatch id the definition id of the next_definition.
50 |
# File 'app/models/auth/system/definition.rb', line 50 field :next_definition_location, type: String |
#output_objects ⇒ Object
what would be output for one input bunch. key -> product id value -> quantity(float)
28 |
# File 'app/models/auth/system/definition.rb', line 28 field :output_objects, type: Hash, default: {} |
#physical_requirements ⇒ Object
inside the minutes we will have only static first time use physical requirements. like tubes , beakers, slides, whatever. how to coordinate for things created in a previous minute ?
16 |
# File 'app/models/auth/system/definition.rb', line 16 field :physical_requirements, type: Hash, default: {} |
#query ⇒ Object
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
# File 'app/models/auth/system/definition.rb', line 436 def query self.input_object_ids.each_with_index {|input_object_id_group,index| location_information = self.location_specifications[index] time_information = self.time_specifications[index] location_information = default_location_specification if location_information.blank? raise "no time information provided" if time_information.blank? = build_query(location_information,time_information) if [:within_radius] after_query(Auth.configuration.location_class.constantize.loc()) else after_query(Auth.configuration.location_class.constantize.find_entity()) end } end |
#query_options ⇒ Object
one for each input object id bunch.
39 |
# File 'app/models/auth/system/definition.rb', line 39 field :query_options, type: Array, default: [] |
#query_results ⇒ Object
one for each input object id bunch.
42 |
# File 'app/models/auth/system/definition.rb', line 42 field :query_results, type: Array, default: [] |
#validate_locations_within_radius(location_ids, coordinates, within_radius, location_categories) ⇒ Object
@param location_ids : the location ids which we want to check are within the radius for the provided coordinates. This is an array of strings. @param coordinates : the coordinates of the origin point. @param within_radius : the radius within the coordinates where to look if the location ids lie. @return location_ids_satisfying_conditions : the location ids which lie within the radius of the coordinates.
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'app/models/auth/system/definition.rb', line 330 def validate_locations_within_radius(location_ids,coordinates,within_radius,location_categories) aggregation_clause = [ { "$geoNear" => { "near" => { "type" => "Point", "coordinates" => [coordinates[:lng],coordinates[:lat]] }, "maxDistance" => within_radius, "spherical" => true, "distanceField" => "dist_calculated", "includeLocs" => "dist_location", "query" => { "$and" => [ { "_id" => { "$in" => location_ids } } ] } } }, { "$limit" => location_ids.size }, { "$project" => { "_id" => 1 } } ] if location_categories aggregation_clause[0]["$geoNear"]["query"]["$and"] << { "location_categories" => { "$in" => location_categories } } end response = Auth.configuration.location_class.constantize.collection.aggregate(aggregation_clause) = [] response.each do |res| << res["_id"] end return end |