From 20133aa438f23982ff99088f829f80b6b8d06ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Leli=C3=A8vre?= Date: Sun, 29 Dec 2024 14:45:43 +0100 Subject: [PATCH 1/4] Update requests_controller.rb --- app/controllers/api/v1/requests_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/api/v1/requests_controller.rb b/app/controllers/api/v1/requests_controller.rb index 1d93328..88408ef 100644 --- a/app/controllers/api/v1/requests_controller.rb +++ b/app/controllers/api/v1/requests_controller.rb @@ -50,6 +50,7 @@ def create end def update + @request.handler_id = current_user.id plant_attributes_from_params(@request) if @request.update(request_params) render json: @request.to_blueprint, status: :ok @@ -59,6 +60,7 @@ def update end def accept + @request.handler_id = current_user.id if @request.fire_state_event(:accept) render json: @request.to_blueprint else @@ -67,6 +69,7 @@ def accept end def refuse + @request.handler_id = current_user.id if @request.fire_state_event(:refuse) render json: @request.to_blueprint else @@ -75,6 +78,7 @@ def refuse end def cancel + @request.handler_id = current_user.id if @request.fire_state_event(:cancel) render json: @request.to_blueprint else @@ -83,6 +87,7 @@ def cancel end def complete + @request.handler_id = current_user.id if @request.fire_state_event(:complete) render json: @request.to_blueprint else From 276b484c31fa22a56bba70dabc67015caecc991d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Leli=C3=A8vre?= Date: Mon, 6 Jan 2025 11:43:20 +0100 Subject: [PATCH 2/4] Update seeds.rb --- db/seeds.rb | 390 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 261 insertions(+), 129 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index c8c52e1..4c4a572 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -6,7 +6,7 @@ DatabaseCleaner.clean Doorkeeper::Application.find_or_initialize_by( - name: 'ProGeSer' + name: 'Uniser' ).update!( uid: 'VkU79vCSfXw0rkYEOBbjMWflqsvBbznAr340OZ_3yAU', secret: 'Cqzm5WAbDs3Dq8URddDOXdHTFAUOtnqPsAZl-a7vbpQ', @@ -17,171 +17,303 @@ email: 'dev+grower@progeser.com', password: 'password', password_confirmation: 'password', - first_name: 'Grower', - last_name: 'ProGeSer' + first_name: 'Utilisateur', + last_name: 'Progeser' ) - # Pots - Pot.create!( - name: 'My square pot', - shape: :square, - dimensions: [7], - area: 49 + User.create!( + email: 'utilisateur@uniser.com', + password: 'superpassword', + password_confirmation: 'superpassword', + first_name: 'Utilisateur', + last_name: 'Uniser' ) - Pot.create!( - name: 'My rectangular pot', - shape: :rectangle, - dimensions: [8, 10], - area: 80 + User.create!( + email: 'bob.martin@uniser.com', + password: 'password_bob', + password_confirmation: 'password_bob', + first_name: 'Bob', + last_name: 'Martin' ) - Pot.create!( - name: 'My circular pot', - shape: :circle, - dimensions: [10], - area: 10 * Math::PI + # Pots + 10.times do |i| + shapes = %i[square rectangle circle] + shape = shapes.sample + dimensions = + case shape + when :square, :circle then [rand(5..20)] + when :rectangle then [rand(5..20), rand(5..20)] + end + area = + case shape + when :square then dimensions[0]**2 + when :rectangle then dimensions[0] * dimensions[1] + when :circle then (dimensions[0]**2) * Math::PI + end + + Pot.create!( + name: "Pot #{i + 1} - #{shape}", + shape: shape, + dimensions: dimensions, + area: area + ) + end + + # Bâtiments + building1 = Building.create!( + name: 'Bâtiment Principal', + description: 'Le bâtiment principal de la serre.' ) - Pot.create!( - name: 'My triangular pot', - shape: :triangle, - dimensions: [8, 10], - area: 40 + Building.create!( + name: 'Bâtiment Annexe', + description: 'Un bâtiment annexe de la serre.' ) - building1 = Building.create!( - name: 'Main Building', - description: 'The main building that houses the primary operations.' + Building.create!( + name: 'Extension', + description: 'Une extension de la serre.' ) Building.create!( - name: 'Secondary Building', - description: 'A secondary building for auxiliary functions and storage.' + name: 'Extérieur', + description: 'Un espace extérieur de la serre.' ) - # Greenhouses + # Serres greenhouse1 = building1.greenhouses.create!( - name: 'My big greenhouse', - width: 1000, - height: 2000 + name: 'Grande serre principale', + width: 2000, + height: 1000 ) greenhouse2 = building1.greenhouses.create!( - name: 'My small greenhouse', + name: 'Petite serre principale', + width: 1000, + height: 500 + ) + + building1.greenhouses.create!( + name: 'Serre de recherche', width: 500, height: 500 ) - # Benches - [greenhouse1, greenhouse2].each do |greenhouse| - Bench.create!( - greenhouse:, - name: "#{greenhouse.name} - bench 1", - dimensions: [200, 200], - positions: [200, 10] - ) + building1.greenhouses.create!( + name: 'Serre de production', + width: 500, + height: 300 + ) - Bench.create!( - greenhouse:, - name: "#{greenhouse.name} - bench 2", - dimensions: [500, 100], - positions: [200, 400] - ) + # Benchs pour greenhouse1 (Grande serre principale) + Bench.create!( + greenhouse: greenhouse1, + name: "Table 1 - #{greenhouse1.name}", + dimensions: [500, 200], + positions: [0, 0] + ) - Bench.create!( - greenhouse:, - name: "#{greenhouse.name} - bench 3", - dimensions: [50, 100], - positions: [400, 200] - ) - end + Bench.create!( + greenhouse: greenhouse1, + name: "Table 2 - #{greenhouse1.name}", + dimensions: [300, 150], + positions: [600, 0] + ) - # Plants - 3.times do + Bench.create!( + greenhouse: greenhouse1, + name: "Table 3 - #{greenhouse1.name}", + dimensions: [200, 200], + positions: [600, 300] + ) + + Bench.create!( + greenhouse: greenhouse1, + name: "Table 4 - #{greenhouse1.name}", + dimensions: [200, 200], + positions: [600, 550] + ) + + # Benchs pour greenhouse2 (Petite serre principale) + Bench.create!( + greenhouse: greenhouse2, + name: "Table 1 - #{greenhouse2.name}", + dimensions: [300, 300], + positions: [0, 0] + ) + + Bench.create!( + greenhouse: greenhouse2, + name: "Table 2 - #{greenhouse2.name}", + dimensions: [400, 200], + positions: [400, 0] + ) + + Bench.create!( + greenhouse: greenhouse2, + name: "Table 3 - #{greenhouse2.name}", + dimensions: [200, 200], + positions: [810, 200] + ) + + # Plantes + plant_names = %w[Fougère Orchidée Lavande Lys Géranium Hibiscus Violette Camélia Jasmin Magnolia] + + plant_names.each do |name| Plant.create!( - name: Faker::Food.vegetables + name: name ) end - # PlantStages - stage_names = %w[sprout seedling vegetative budding flowering ripening] + # Étapes des plantes + stage_names = %w[germe plantule végétative bourgeonnement floraison maturation] Plant.find_each do |plant| stage_names.each do |stage_name| plant.plant_stages.create!( name: stage_name, - duration: Faker::Number.between(from: 5, to: 30), - position: stage_names.find_index(stage_name) + 1 + duration: rand(5..30), + position: stage_names.index(stage_name) + 1 ) end end # Requests - # db/seeds.rb - - Request.create!( - requester_first_name: 'John', - requester_last_name: 'Doe', - requester_email: 'john.doe@example.com', - laboratory: 'My lab', - handler: User.first, - plant_stage: Plant.first.plant_stages.last, - name: 'My first request', - plant_name: Plant.first.name, - plant_stage_name: Plant.first.plant_stages.last.name, - comment: Faker::Movies::LordOfTheRings.quote, - due_date: Date.current + 3.months, - quantity: 50, - temperature: 'Chaud', - photoperiod: 8 - ) - - Request.create!( - requester_first_name: 'Alice', - requester_last_name: 'Smith', - requester_email: 'alice.smith@example.com', - laboratory: 'My other lab', - name: 'My new request', - plant_name: Plant.last.name, - plant_stage_name: Plant.last.plant_stages.last.name, - plant_stage: Plant.last.plant_stages.last, - comment: Faker::Movies::LordOfTheRings.quote, - due_date: Date.current + 2.months, - quantity: 200, - temperature: 'Froid', - photoperiod: 16 - ) - - # RequestDistributions - RequestDistribution.create!( - request: Request.first, - bench: Bench.first, - plant_stage: Request.first.plant_stage, - pot: Pot.first, - pot_quantity: 30, - positions_on_bench: [0, 0], - dimensions: [50, 50] - ) - - RequestDistribution.create!( - request: Request.first, - bench: Bench.first, - plant_stage: Request.first.plant_stage, - pot: Pot.second, - pot_quantity: 20, - positions_on_bench: [100, 50], - dimensions: [50, 20] - ) - - Request.first.update!(status: :accepted) - - RequestDistribution.create!( - request: Request.second, - bench: Bench.second, - plant_stage: Request.second.plant_stage, - pot: Pot.second, - pot_quantity: 20, - positions_on_bench: [0, 10], - dimensions: [20, 30] - ) + requests = [] + 5.times do |i| + plant = Plant.order('RANDOM()').first + plant_stage = plant.plant_stages.order('RANDOM()').first + requests << Request.create!( + requester_first_name: Faker::Name.first_name, + requester_last_name: Faker::Name.last_name, + requester_email: Faker::Internet.email, + laboratory: Faker::Science.scientist, + handler: User.first, + plant_stage: plant_stage, + name: "Requête #{i + 1}", + plant_name: plant.name, + plant_stage_name: plant_stage.name, + comment: Faker::Lorem.sentence, + due_date: Date.current + rand(1..6).months, + quantity: rand(10..100), + temperature: %w[Chaud Froid Extérieur].sample, + photoperiod: rand(6..18), + status: %i[pending refused completed].sample + ) + end + + def distribute_request(request) + return unless request_pending_or_accepted?(request) + + bench, pot = select_random_bench_and_pot + distribution_details = prepare_distribution_details(request, bench) + + handle_distribution( + request: request, + bench: bench, + pot: pot, + distribution_details: distribution_details + ) + end + + def request_pending_or_accepted?(request) + %w[pending accepted].include?(request.status) + end + + def select_random_bench_and_pot + [Bench.order('RANDOM()').first, Pot.order('RANDOM()').first] + end + + def prepare_distribution_details(request, bench) + dimensions = [rand(50..200), rand(50..200)] + position = find_position_for_request(bench, dimensions) + distributed_quantity = rand(1..request.quantity) + + { + dimensions: dimensions, + position: position, + quantity: distributed_quantity, + total_quantity: request.quantity + } + end + + def find_position_for_request(bench, dimensions) + occupied_positions = [] + find_available_position(bench, dimensions, occupied_positions) + end + + def handle_distribution(request:, bench:, pot:, distribution_details:) + if distribution_details[:position] + create_distribution_record( + request: request, + bench: bench, + pot: pot, + details: distribution_details + ) + end + + update_request_status(request, distribution_details[:quantity], distribution_details[:total_quantity]) + end + + def create_distribution_record(request:, bench:, pot:, details:) + create_request_distribution( + request: request, + bench: bench, + pot: pot, + plant_stage: request.plant_stage, + quantity: details[:quantity], + position: details[:position], + dimensions: details[:dimensions] + ) + end + + def find_available_position(bench, dimensions, occupied_positions) + max_attempts = 10 + + max_attempts.times do + position = [ + rand(0..(bench.dimensions[0] - dimensions[0])), + rand(0..(bench.dimensions[1] - dimensions[1])) + ] + + overlapping = occupied_positions.any? do |occupied| + overlap?(position, dimensions, occupied) + end + + return position unless overlapping + end + + nil + end + + def overlap?(position, dimensions, occupied) + ox, oy, ow, oh = occupied + px, py = position + pw, ph = dimensions + + !(px + pw <= ox || px >= ox + ow || py + ph <= oy || py >= oy + oh) + end + + def create_request_distribution(distribution_params) + RequestDistribution.create!( + request: distribution_params[:request], + bench: distribution_params[:bench], + plant_stage: distribution_params[:plant_stage], + pot: distribution_params[:pot], + pot_quantity: distribution_params[:quantity], + positions_on_bench: distribution_params[:position], + dimensions: distribution_params[:dimensions] + ) + end + + def update_request_status(request, distributed_quantity, total_quantity) + if distributed_quantity < total_quantity + request.update!(status: 'pending') + else + request.update!(status: 'accepted') + end + end + + requests.each { |request| distribute_request(request) } end From 47731b248d4c5725dd0b126d339628bc27fbbf2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Leli=C3=A8vre?= Date: Mon, 6 Jan 2025 11:45:12 +0100 Subject: [PATCH 3/4] Update seeds.rb --- db/seeds.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/seeds.rb b/db/seeds.rb index 4c4a572..c70949e 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -51,6 +51,8 @@ when :square then dimensions[0]**2 when :rectangle then dimensions[0] * dimensions[1] when :circle then (dimensions[0]**2) * Math::PI + else + raise "Unknown shape: #{shape}" end Pot.create!( From 27d6c1fc63244f8503b2af66b27df8ec6dc45d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Leli=C3=A8vre?= Date: Mon, 6 Jan 2025 11:45:45 +0100 Subject: [PATCH 4/4] Update seeds.rb --- db/seeds.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/seeds.rb b/db/seeds.rb index c70949e..682ac94 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -45,6 +45,8 @@ case shape when :square, :circle then [rand(5..20)] when :rectangle then [rand(5..20), rand(5..20)] + else + raise "Unknown shape: #{shape}" end area = case shape