From 405125df6c87a46f66b164d3d54f72d0386be86f Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 31 Jan 2024 02:19:24 -0600 Subject: [PATCH] Linked Vendors to Participants via Service Contracts --- app/controllers/participants_controller.rb | 32 ++++++- .../service_contracts_controller.rb | 43 ++++++++++ app/controllers/vendors_controller.rb | 12 +++ app/helpers/service_contracts_helper.rb | 2 + app/models/participant.rb | 2 + app/models/service_contract.rb | 4 + app/models/vendor.rb | 3 +- app/views/participants/show.html.erb | 83 +++++++++++++++++++ app/views/service_contracts/edit.html.erb | 39 +++++++++ config/routes.rb | 10 ++- ...20240131072940_create_service_contracts.rb | 12 +++ db/schema.rb | 15 +++- .../service_contracts_controller_test.rb | 7 ++ test/fixtures/service_contracts.yml | 13 +++ test/models/service_contract_test.rb | 7 ++ 15 files changed, 278 insertions(+), 6 deletions(-) create mode 100644 app/controllers/service_contracts_controller.rb create mode 100644 app/helpers/service_contracts_helper.rb create mode 100644 app/models/service_contract.rb create mode 100644 app/views/service_contracts/edit.html.erb create mode 100644 db/migrate/20240131072940_create_service_contracts.rb create mode 100644 test/controllers/service_contracts_controller_test.rb create mode 100644 test/fixtures/service_contracts.yml create mode 100644 test/models/service_contract_test.rb diff --git a/app/controllers/participants_controller.rb b/app/controllers/participants_controller.rb index d9ae4cd..63fc809 100644 --- a/app/controllers/participants_controller.rb +++ b/app/controllers/participants_controller.rb @@ -7,13 +7,15 @@ class ParticipantsController < ApplicationController def show - @participant = Participant.includes(:employments).find(params[:id]) + @participant = Participant.includes(:employments, :service_contracts).find(params[:id]) @workers = @participant.workers # Fetch associated workers - @employment = Employment.new # Initialize a new Employment object - @participant = Participant.includes(employments: :worker).find(params[:id]) @employments = @participant.employments.includes(:worker).order('workers.last_name') + @service_contracts = @participant.service_contracts.includes(:vendor) # Fetch associated service contracts + @employment = Employment.new # Initialize a new Employment object + @service_contract = ServiceContract.new # Initialize a new Service Contract object end + def new @participant = Participant.new @@ -74,6 +76,25 @@ class ParticipantsController < ApplicationController render 'show' end end + + def link_vendor + @participant = Participant.find(params[:id]) + @service_contract = @participant.service_contracts.new(service_contract_params) + + if @service_contract.save + redirect_to @participant, notice: 'Vendor was successfully linked.' + else + flash[:alert] = @service_contract.errors.full_messages.to_sentence + render 'show' + end + end + + private + + def service_contract_params + # Define your service contract parameters here + end + private @@ -122,5 +143,10 @@ class ParticipantsController < ApplicationController def employment_params params.require(:employment).permit(:worker_id, :start_date, :end_date) end + + def service_contract_params + params.require(:service_contract).permit(:vendor_id, :start_date, :end_date) + end + end diff --git a/app/controllers/service_contracts_controller.rb b/app/controllers/service_contracts_controller.rb new file mode 100644 index 0000000..725cc4f --- /dev/null +++ b/app/controllers/service_contracts_controller.rb @@ -0,0 +1,43 @@ +class ServiceContractsController < ApplicationController + before_action :set_service_contract, only: [:edit, :update, :destroy] + + def new + @service_contract = ServiceContract.new + end + + def create + @service_contract = ServiceContract.new(service_contract_params) + if @service_contract.save + redirect_to participant_path(@service_contract.participant), notice: 'Service contract was successfully created.' + else + render :new + end + end + + def edit + end + + def update + if @service_contract.update(service_contract_params) + redirect_to participant_path(@service_contract.participant), notice: 'Service contract was successfully updated.' + else + render :edit + end + end + + def destroy + @service_contract.destroy + redirect_to participant_path(@service_contract.participant), notice: 'Service contract was successfully destroyed.' + end + + private + + def set_service_contract + @service_contract = ServiceContract.find(params[:id]) + end + + def service_contract_params + params.require(:service_contract).permit(:start_date, :end_date, :participant_id, :vendor_id) + end + end + \ No newline at end of file diff --git a/app/controllers/vendors_controller.rb b/app/controllers/vendors_controller.rb index 8017e57..eaf9d82 100644 --- a/app/controllers/vendors_controller.rb +++ b/app/controllers/vendors_controller.rb @@ -38,6 +38,18 @@ class VendorsController < ApplicationController @vendor.destroy redirect_to vendors_path end + + def search + if params[:term].present? + @vendors = Vendor.where("name LIKE ?", "%#{params[:term]}%") + else + @vendors = Vendor.none + end + + # Respond with a JSON array of vendor names and IDs + render json: @vendors.map { |vendor| { label: vendor.name, value: vendor.id } } + end + private def vendor_params diff --git a/app/helpers/service_contracts_helper.rb b/app/helpers/service_contracts_helper.rb new file mode 100644 index 0000000..1c4bcd1 --- /dev/null +++ b/app/helpers/service_contracts_helper.rb @@ -0,0 +1,2 @@ +module ServiceContractsHelper +end diff --git a/app/models/participant.rb b/app/models/participant.rb index 3131413..a24835a 100644 --- a/app/models/participant.rb +++ b/app/models/participant.rb @@ -3,6 +3,8 @@ class Participant < ApplicationRecord belongs_to :employer, optional: true has_many :employments has_many :workers, through: :employments + has_many :service_contracts + has_many :vendors, through: :service_contracts # Validations validates :first_name, presence: true diff --git a/app/models/service_contract.rb b/app/models/service_contract.rb new file mode 100644 index 0000000..3a36333 --- /dev/null +++ b/app/models/service_contract.rb @@ -0,0 +1,4 @@ +class ServiceContract < ApplicationRecord + belongs_to :participant + belongs_to :vendor +end diff --git a/app/models/vendor.rb b/app/models/vendor.rb index 4248275..381a29c 100644 --- a/app/models/vendor.rb +++ b/app/models/vendor.rb @@ -1,5 +1,6 @@ class Vendor < ApplicationRecord # Many-to-many relationships - has_and_belongs_to_many :participants has_and_belongs_to_many :employers + has_many :service_contracts + has_many :participants, through: :service_contracts end diff --git a/app/views/participants/show.html.erb b/app/views/participants/show.html.erb index ad2cbee..eec09f9 100644 --- a/app/views/participants/show.html.erb +++ b/app/views/participants/show.html.erb @@ -150,3 +150,86 @@ $(document).ready(function() { }); + +

Linked Vendors

+<% if @service_contracts.present? %> + + + + + + + + + + + <% @service_contracts.each do |contract| %> + + + + + + + <% end %> + +
Vendor NameStart DateEnd DateActions
<%= contract.vendor&.name || 'No Vendor Assigned' %><%= contract.start_date.strftime('%B %d, %Y') if contract.start_date.present? %><%= contract.end_date.strftime('%B %d, %Y') if contract.end_date.present? %> + <%= link_to vendor_path(contract.vendor), class: 'btn btn-sm btn-secondary' do %> + + <% end %> + <%= link_to edit_service_contract_path(contract), class: 'btn btn-sm btn-info' do %> + + <% end %> +
+<% else %> +

No service contracts available.

+<% end %> + +
+ +<%= form_with(model: [@participant, @service_contract], url: link_vendor_participant_path(@participant), method: :post, class: 'row g-3') do |form| %> +
+ <%= form.label :vendor_name, "Add New Vendor", class: 'form-label' %> + <%= text_field_tag :vendor_name, nil, id: 'vendor-autocomplete', class: 'form-control', placeholder: 'Start typing vendor name...' %> + <%= hidden_field_tag 'service_contract[vendor_id]', nil, id: 'selected-vendor-id' %> +
+ +
+ <%= form.label :start_date, class: 'form-label' %> + <%= form.date_field :start_date, class: 'form-control' %> +
+ +
+ <%= form.label :end_date, class: 'form-label' %> + <%= form.date_field :end_date, class: 'form-control' %> +
+ +
+ <%= form.submit "Link Vendor", class: 'btn btn-dark' %> +
+<% end %> + +<%# JavaScript for Vendor Autocomplete %> + + + diff --git a/app/views/service_contracts/edit.html.erb b/app/views/service_contracts/edit.html.erb new file mode 100644 index 0000000..8009377 --- /dev/null +++ b/app/views/service_contracts/edit.html.erb @@ -0,0 +1,39 @@ +
+
+
+

Edit Service Contract

+ + <%= form_with(model: @service_contract, url: service_contract_path(@service_contract), method: :patch, local: true, html: { class: 'needs-validation', novalidate: true }) do |form| %> + <% if @service_contract.errors.any? %> + + <% end %> + +
+ <%= form.label :start_date, class: 'form-label' %> + <%= form.date_field :start_date, class: 'form-control' %> +
+ +
+ <%= form.label :end_date, class: 'form-label' %> + <%= form.date_field :end_date, class: 'form-control' %> +
+ +
+ <%= form.submit "Update Service Contract", class: 'btn btn-dark' %> +
+ <% end %> + +
+ <%= link_to 'Back to Participant', participant_path(@service_contract.participant), class: 'btn btn-secondary' %> + <%= link_to 'Delete Service Contract', service_contract_path(@service_contract), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger' %> +
+
+
+
diff --git a/config/routes.rb b/config/routes.rb index 202f74a..a673fd4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,6 +12,7 @@ Rails.application.routes.draw do resources :participants do member do post 'link_worker' + post 'link_vendor' end end @@ -19,8 +20,15 @@ Rails.application.routes.draw do get 'search', on: :collection end - resources :vendors + resources :vendors do + collection do + get 'search' + end + end + resources :employments, only: [:edit, :update, :destroy] + resources :service_contracts + resources :employers do get 'search', on: :collection end diff --git a/db/migrate/20240131072940_create_service_contracts.rb b/db/migrate/20240131072940_create_service_contracts.rb new file mode 100644 index 0000000..23bd353 --- /dev/null +++ b/db/migrate/20240131072940_create_service_contracts.rb @@ -0,0 +1,12 @@ +class CreateServiceContracts < ActiveRecord::Migration[7.1] + def change + create_table :service_contracts do |t| + t.references :participant, null: false, foreign_key: true + t.references :vendor, null: false, foreign_key: true + t.date :start_date + t.date :end_date + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index b27529d..0c02f26 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_01_30_051346) do +ActiveRecord::Schema[7.1].define(version: 2024_01_31_072940) do create_table "employers", force: :cascade do |t| t.string "first_name" t.string "phone" @@ -86,6 +86,17 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_30_051346) do t.datetime "updated_at", null: false end + create_table "service_contracts", force: :cascade do |t| + t.integer "participant_id", null: false + t.integer "vendor_id", null: false + t.date "start_date" + t.date "end_date" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["participant_id"], name: "index_service_contracts_on_participant_id" + t.index ["vendor_id"], name: "index_service_contracts_on_vendor_id" + end + create_table "users", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false @@ -137,4 +148,6 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_30_051346) do add_foreign_key "employments", "workers" add_foreign_key "participants", "employers" add_foreign_key "participants", "workers" + add_foreign_key "service_contracts", "participants" + add_foreign_key "service_contracts", "vendors" end diff --git a/test/controllers/service_contracts_controller_test.rb b/test/controllers/service_contracts_controller_test.rb new file mode 100644 index 0000000..2736618 --- /dev/null +++ b/test/controllers/service_contracts_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ServiceContractsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/service_contracts.yml b/test/fixtures/service_contracts.yml new file mode 100644 index 0000000..cec08b3 --- /dev/null +++ b/test/fixtures/service_contracts.yml @@ -0,0 +1,13 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + participant: one + vendor: one + start_date: 2024-01-31 + end_date: 2024-01-31 + +two: + participant: two + vendor: two + start_date: 2024-01-31 + end_date: 2024-01-31 diff --git a/test/models/service_contract_test.rb b/test/models/service_contract_test.rb new file mode 100644 index 0000000..aa25ac4 --- /dev/null +++ b/test/models/service_contract_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ServiceContractTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end