From ed0237ce27d565fcc67bced420c71f4c1aa3e014 Mon Sep 17 00:00:00 2001 From: apoorv1316 Date: Mon, 29 Apr 2024 12:48:41 +0530 Subject: [PATCH 1/3] crud custom leaves --- .../v1/custom_leaves_controller.rb | 29 ++++++++++++ app/models/custom_leave.rb | 35 +++++++++++++++ app/models/custom_leave_user.rb | 26 +++++++++++ app/models/leave.rb | 1 + app/models/user.rb | 2 + app/services/custom_leaves_service.rb | 45 +++++++++++++++++++ config/routes/internal_api.rb | 2 +- .../20240426050940_create_custom_leaves.rb | 14 ++++++ ...0240426053100_create_custom_leave_users.rb | 12 +++++ db/schema.rb | 24 +++++++++- 10 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 app/controllers/internal_api/v1/custom_leaves_controller.rb create mode 100644 app/models/custom_leave.rb create mode 100644 app/models/custom_leave_user.rb create mode 100644 app/services/custom_leaves_service.rb create mode 100644 db/migrate/20240426050940_create_custom_leaves.rb create mode 100644 db/migrate/20240426053100_create_custom_leave_users.rb diff --git a/app/controllers/internal_api/v1/custom_leaves_controller.rb b/app/controllers/internal_api/v1/custom_leaves_controller.rb new file mode 100644 index 0000000000..3533604be8 --- /dev/null +++ b/app/controllers/internal_api/v1/custom_leaves_controller.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class InternalApi::V1::CustomLeavesController < InternalApi::V1::ApplicationController + before_action :leave, only: [:update] + + def update + authorize current_user, policy_class: LeaveWithLeaveTypesPolicy + CustomLeavesService.new(leave, update_params).process + render json: { notice: "Leaves updated successfully" }, status: :ok + end + + private + + def leave + @_leave ||= current_company.leaves.find_or_create_by(year: params[:year]) + end + + def update_params + params.require(:custom_leaves).permit( + add_custom_leaves: [:name, :color, :icon, :allocation_value, + :allocation_period, user_ids: [], + ], + update_custom_leaves: [:id, :name, :color, :icon, :allocation_value, + :allocation_period, user_ids: [], + ], + remove_custom_leaves: [] + ) + end +end diff --git a/app/models/custom_leave.rb b/app/models/custom_leave.rb new file mode 100644 index 0000000000..ded0814e4b --- /dev/null +++ b/app/models/custom_leave.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: custom_leaves +# +# id :bigint not null, primary key +# allocation_period :integer not null +# allocation_value :integer not null +# name :string not null +# created_at :datetime not null +# updated_at :datetime not null +# leave_id :bigint not null +# +# Indexes +# +# index_custom_leaves_on_leave_id (leave_id) +# +# Foreign Keys +# +# fk_rails_... (leave_id => leaves.id) +# +class CustomLeave < ApplicationRecord + belongs_to :leave + has_many :custom_leave_users, dependent: :destroy + has_many :users, through: :custom_leave_users + + enum allocation_period: { + days: 0, + weeks: 1, + months: 2 + } + + validates :name, :allocation_value, :allocation_period, presence: true +end diff --git a/app/models/custom_leave_user.rb b/app/models/custom_leave_user.rb new file mode 100644 index 0000000000..7c4fe8f4b9 --- /dev/null +++ b/app/models/custom_leave_user.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: custom_leave_users +# +# id :bigint not null, primary key +# created_at :datetime not null +# updated_at :datetime not null +# custom_leave_id :bigint not null +# user_id :bigint not null +# +# Indexes +# +# index_custom_leave_users_on_custom_leave_id (custom_leave_id) +# index_custom_leave_users_on_user_id (user_id) +# +# Foreign Keys +# +# fk_rails_... (custom_leave_id => custom_leaves.id) +# fk_rails_... (user_id => users.id) +# +class CustomLeaveUser < ApplicationRecord + belongs_to :custom_leave + belongs_to :user +end diff --git a/app/models/leave.rb b/app/models/leave.rb index f90b328288..0b5b5cde51 100644 --- a/app/models/leave.rb +++ b/app/models/leave.rb @@ -29,6 +29,7 @@ class Leave < ApplicationRecord belongs_to :company has_many :leave_types, class_name: "LeaveType", dependent: :destroy + has_many :custom_leaves, class_name: "CustomLeave", dependent: :destroy validates :year, presence: true, numericality: { greater_than_or_equal_to: 1000, less_than_or_equal_to: 9999 } diff --git a/app/models/user.rb b/app/models/user.rb index 8ff3fe20e8..002a7c6f7f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -72,6 +72,8 @@ def initialize(msg = "Spam User Login") has_many :clients, through: :projects has_many :client_members, dependent: :destroy has_many :timeoff_entries, dependent: :destroy + has_many :custom_leave_users + has_many :custom_leaves, through: :custom_leave_users, source: :custom_leave rolify strict: true diff --git a/app/services/custom_leaves_service.rb b/app/services/custom_leaves_service.rb new file mode 100644 index 0000000000..fb9d6a39db --- /dev/null +++ b/app/services/custom_leaves_service.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class CustomLeavesService + attr_reader :leave, :params + + def initialize(leave, params) + @leave = leave + @params = params + end + + def process + ActiveRecord::Base.transaction do + add_custom_leaves + update_custom_leaves + remove_custom_leaves + end + end + + private + + def add_custom_leaves + return if params[:add_custom_leaves].blank? + + params[:add_custom_leaves].each do |custom_leave| + leave.custom_leaves.create!(custom_leave) + end + end + + def update_custom_leaves + return if params[:update_custom_leaves].blank? + + params[:update_custom_leaves].each do |update_custom_leave| + custom_leave = leave.custom_leaves.find(update_custom_leave[:id]) + next unless custom_leave + + custom_leave.update!(update_custom_leave) + end + end + + def remove_custom_leaves + return if params[:remove_custom_leaves].blank? + + leave.custom_leaves.where(id: params[:remove_custom_leaves]).destroy_all + end +end diff --git a/config/routes/internal_api.rb b/config/routes/internal_api.rb index 169dfcf185..ed64750fec 100644 --- a/config/routes/internal_api.rb +++ b/config/routes/internal_api.rb @@ -155,7 +155,7 @@ resources :timeoff_entries, except: [:new, :edit] patch "leave_with_leave_type/:year", to: "leave_with_leave_types#update", as: :update_leave_with_leave_types - + patch "custom_leaves/:year", to: "custom_leaves#update" match "*path", to: "application#not_found", via: :all, constraints: lambda { |req| req.path.exclude?("rails/active_storage") && req.path.include?("internal_api") } diff --git a/db/migrate/20240426050940_create_custom_leaves.rb b/db/migrate/20240426050940_create_custom_leaves.rb new file mode 100644 index 0000000000..eb4896589b --- /dev/null +++ b/db/migrate/20240426050940_create_custom_leaves.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CreateCustomLeaves < ActiveRecord::Migration[7.1] + def change + create_table :custom_leaves do |t| + t.string :name, null: false + t.integer :allocation_value, null: false + t.integer :allocation_period, null: false + t.references :leave, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20240426053100_create_custom_leave_users.rb b/db/migrate/20240426053100_create_custom_leave_users.rb new file mode 100644 index 0000000000..c1b57d774e --- /dev/null +++ b/db/migrate/20240426053100_create_custom_leave_users.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class CreateCustomLeaveUsers < ActiveRecord::Migration[7.1] + def change + create_table :custom_leave_users do |t| + t.references :custom_leave, null: false, foreign_key: true + t.references :user, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 813770e521..cfba1f1713 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_04_11_174949) do +ActiveRecord::Schema[7.1].define(version: 2024_04_26_053100) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -145,6 +145,25 @@ t.boolean "calendar_enabled", default: true end + create_table "custom_leave_users", force: :cascade do |t| + t.bigint "custom_leave_id", null: false + t.bigint "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["custom_leave_id"], name: "index_custom_leave_users_on_custom_leave_id" + t.index ["user_id"], name: "index_custom_leave_users_on_user_id" + end + + create_table "custom_leaves", force: :cascade do |t| + t.string "name", null: false + t.integer "allocation_value", null: false + t.integer "allocation_period", null: false + t.bigint "leave_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["leave_id"], name: "index_custom_leaves_on_leave_id" + end + create_table "data_migrations", primary_key: "version", id: :string, force: :cascade do |t| end @@ -536,6 +555,9 @@ add_foreign_key "client_members", "companies" add_foreign_key "client_members", "users" add_foreign_key "clients", "companies" + add_foreign_key "custom_leave_users", "custom_leaves", column: "custom_leave_id" + add_foreign_key "custom_leave_users", "users" + add_foreign_key "custom_leaves", "leaves", column: "leave_id" add_foreign_key "devices", "companies" add_foreign_key "devices", "users" add_foreign_key "employments", "companies" From 2a55f36628bce133305a849d7d9c739e45e13d02 Mon Sep 17 00:00:00 2001 From: apoorv1316 Date: Thu, 2 May 2024 12:51:00 +0530 Subject: [PATCH 2/3] send custom leaves in index action --- app/controllers/internal_api/v1/leaves_controller.rb | 2 +- app/models/custom_leave.rb | 1 + app/views/internal_api/v1/leaves/index.json.jbuilder | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/controllers/internal_api/v1/leaves_controller.rb b/app/controllers/internal_api/v1/leaves_controller.rb index 6f05f405a7..23fe06f942 100644 --- a/app/controllers/internal_api/v1/leaves_controller.rb +++ b/app/controllers/internal_api/v1/leaves_controller.rb @@ -5,7 +5,7 @@ class InternalApi::V1::LeavesController < InternalApi::V1::ApplicationController def index authorize Leave - leaves = current_company.leaves.includes([:leave_types]) + leaves = current_company.leaves.includes([:leave_types, :custom_leaves]) render :index, locals: { leaves: } diff --git a/app/models/custom_leave.rb b/app/models/custom_leave.rb index ded0814e4b..3c49427c7f 100644 --- a/app/models/custom_leave.rb +++ b/app/models/custom_leave.rb @@ -32,4 +32,5 @@ class CustomLeave < ApplicationRecord } validates :name, :allocation_value, :allocation_period, presence: true + validates :allocation_value, numericality: { greater_than_or_equal_to: 1 } end diff --git a/app/views/internal_api/v1/leaves/index.json.jbuilder b/app/views/internal_api/v1/leaves/index.json.jbuilder index e5207525a5..b80d6b913f 100644 --- a/app/views/internal_api/v1/leaves/index.json.jbuilder +++ b/app/views/internal_api/v1/leaves/index.json.jbuilder @@ -13,4 +13,14 @@ json.leaves leaves do |leave| json.allocation_frequency leave_type.allocation_frequency json.carry_forward_days leave_type.carry_forward_days end + json.custom_leaves leave.custom_leaves do |custom_leave| + json.id custom_leave.id + json.name custom_leave.name + json.allocation_value custom_leave.allocation_value + json.allocation_period custom_leave.allocation_period + json.users custom_leave.users do |user| + json.id user.id + json.full_name user.full_name + end + end end From 7f8d15e9bca0845dd37bac59952dd8dc78727e3b Mon Sep 17 00:00:00 2001 From: apoorv1316 Date: Tue, 14 May 2024 11:49:39 +0530 Subject: [PATCH 3/3] review comments --- app/controllers/internal_api/v1/custom_leaves_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/internal_api/v1/custom_leaves_controller.rb b/app/controllers/internal_api/v1/custom_leaves_controller.rb index 3533604be8..1a6ca7b8ad 100644 --- a/app/controllers/internal_api/v1/custom_leaves_controller.rb +++ b/app/controllers/internal_api/v1/custom_leaves_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class InternalApi::V1::CustomLeavesController < InternalApi::V1::ApplicationController - before_action :leave, only: [:update] + before_action :set_leave, only: [:update] def update authorize current_user, policy_class: LeaveWithLeaveTypesPolicy @@ -11,7 +11,7 @@ def update private - def leave + def set_leave @_leave ||= current_company.leaves.find_or_create_by(year: params[:year]) end