Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

加班補休額度申請 (#272) #296

Merged
merged 15 commits into from
Sep 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 0 additions & 54 deletions app/controllers/backend/overtime_controller.rb

This file was deleted.

98 changes: 98 additions & 0 deletions app/controllers/backend/overtimes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# frozen_string_literal: true
class Backend::OvertimesController < Backend::BaseController
before_action :set_query_object, except: :statistics

def index
@users = User.all
end

def verify;end

def update
if current_object.update(resource_params)
params[:approve] ? approve : reject
else
respond_to do |f|
f.html { render action: :verify }
f.json
end
end
end

def add_leave_time
@leave_time = LeaveTime.new
end

def create_leave_time
params[:leave_time][:user_id] = current_object.user.id
@leave_time = LeaveTime.new(resource_params)
if @leave_time.save(resource_params)
action_success(verify_backend_overtime_path(current_object))
else
render :add_leave_time
end
end

def add_compensatory_pay
@overtime_pay = OvertimePay.new
end

def create_compensatory_pay
params[:overtime_pay][:user_id] = current_object.user.id
params[:overtime_pay][:overtime_id] = params[:id]
@overtime_pay = OvertimePay.new(resource_params)
if @overtime_pay.save(resource_params)
action_success(verify_backend_overtime_path(current_object))
else
render :add_overtime_pay
end
end

def statistics
search_params = params.fetch(:q, {})&.permit(:year_eq, :month_eq)
@q = Overtime.where(compensatory_type: 'pay', status: :approved).ransack(search_params)
@summary = @q.result
end

private

def resource_params
case action_name
when 'create' then params.require(:overtime).permit(:user_id, :hours, :start_time, :end_time, :description)
when 'update' then params.require(:overtime).permit(:comment)
when 'create_leave_time' then params.require(:leave_time).permit(:user_id, :overtime_id, :leave_type, :quota, :effective_date, :expiration_date, :remark)
when 'create_compensatory_pay' then params.require(:overtime_pay).permit(:user_id, :overtime_id, :hour, :remark)
end
end

def set_query_object
@q = Overtime.ransack(search_params)
end

def search_params
@search_params = params.fetch(:q, {})&.permit(
:s, :status_eq, :end_time_lteq, :start_time_gteq, :compensatory_type_eq)
end

def collection_scope
@q.result.preload(:user)
end

def approve
if current_object.pending?
current_object.approve!(current_user)
action_success
else
action_fail t('warnings.not_verifiable'), :verify
end
end

def reject
if current_object.pending? or current_object.approved?
current_object.reject!(current_user)
action_success
else
action_fail t('warnings.not_verifiable'), :verify
end
end
end
34 changes: 0 additions & 34 deletions app/controllers/overtime_controller.rb

This file was deleted.

66 changes: 66 additions & 0 deletions app/controllers/overtimes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
class OvertimesController < BaseController
include Selectable

def index
@q = current_user.overtimes.order(created_at: :desc).ransack(search_params)
@current_collection = @q.result.page(params[:page])
@current_collection = Kaminari.paginate_array(@current_collection.first(5)).page(params[:page]) unless params[:q].present?
end

def new
@current_object = collection_scope.new
end

def create
@current_object = collection_scope.new(resource_params)
if @current_object.save
action_success
else
render action: :new
end
end

def update
if current_object.canceled?
action_fail t('warnings.not_cancellable'), :edit
else
current_object.assign_attributes(resource_params)
if !current_object.changed?
action_fail t('warnings.no_change'), :edit
elsif current_object.revise!
action_success
else
render action: :edit
end
end
end

def cancel
if current_object.may_cancel?
current_object.cancel!
@actions << :cancel
action_success
elsif current_object.approved?
action_fail t('warnings.already_happened'), :index
else
action_fail t('warnings.not_cancellable'), :index
end
end

private

def resource_params
params.require(:overtime).permit(
:start_time, :end_time, :description, :compensatory_type
)
end

def collection_scope
current_user.overtimes
end

def search_params
@search_params = params.fetch(:q, {})&.permit(
:status_eq, :end_time_lteq, :start_time_gteq, :compensatory_type_eq)
end
end
17 changes: 17 additions & 0 deletions app/helpers/backend/overtimes_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true
module Backend
module OvertimesHelper
def overtime_submit_disabled?
return unless current_object.pay?
!current_object.may_approve? || current_object.overtime_pay&.hour.nil?
end

def render_append_hours_options
if current_object.may_approve? && current_object.leave?
link_to t("title.backend/overtimes.append_quota"), add_leave_time_backend_overtime_path, class: 'btn btn-warning'
elsif current_object.may_approve? && current_object.pay?
link_to t("title.backend/overtimes.append_overtime_pay"), add_compensatory_pay_backend_overtime_path, class: 'btn btn-warning'
end
end
end
end
77 changes: 55 additions & 22 deletions app/models/overtime.rb
Original file line number Diff line number Diff line change
@@ -1,61 +1,94 @@
# frozen_string_literal: true
class Overtime < ApplicationRecord
include AASM
include SignatureConcern

enum status: Settings.overtimes.statuses
enum compensatory_type: Settings.overtimes.compensatory_types

belongs_to :user
validates :description, :start_time, :end_time, presence: true
belongs_to :manager, class_name: 'User', foreign_key: 'manager_id'

has_one :overtime_pay

validates :description, :start_time, :end_time, :compensatory_type, presence: true
validate :hours_should_be_positive_integer
validate :time_overlapped

before_validation :assign_hours
enum status: Settings.leave_applications.statuses

aasm column: :status, enum: true do
state :pending, initial: true
state :approved
state :rejected
state :canceled

event :approve, after_commit: :create_leave_time do
event :approve, before: proc { |manager| sign(manager) } do
transitions to: :approved, from: :pending
end

event :reject do
event :reject, before: proc { |manager| sign(manager) } do
transitions to: :rejected, from: %i(pending approved)
end

event :revise do
transitions to: :pending, from: %i(pending approved)
transitions to: :pending, from: %i(pending)
end

event :cancel do
transitions to: :canceled, from: :pending
transitions to: :canceled, from: :approved, unless: :happened?
transitions to: :canceled, from: %i(pending approved)
end
end
private

def happened?
Time.current > self.start_time
def leave_time_params
{
user_id: self.user_id,
leave_type: 'bonus',
quota: self.hours,
effective_date: self.start_time.to_date,
expiration_date: self.start_time.to_date.end_of_year
}
end

def auto_calculated_minutes
return @minutes = 0 unless start_time && end_time
@minutes = Daikichi::Config::Biz.within(start_time, end_time).in_minutes
ransacker :year do
Arel.sql('extract(year from created_at)')
end

ransacker :month do
Arel.sql('extract(month from created_at)')
end

private

def assign_hours
self.hours = self.send(:auto_calculated_minutes) / 60
return unless start_time && end_time
self.hours = ((end_time - start_time) / 3600).to_i
end

def hours_should_be_positive_integer
return if self.errors[:start_time].any? or self.errors[:end_time].any?
errors.add(:end_time, :not_integer) if (@minutes % 60).nonzero? || !self.hours.positive?
errors.add(:start_time, :should_be_earlier) unless self.end_time > self.start_time
return if errors.any?
errors.add(:end_time, :not_integer) unless ((end_time - start_time).to_i % 3600).zero?
errors.add(:start_time, :should_be_earlier) unless end_time > start_time
end

def time_overlapped
return if errors.any?
overlapped_records = Overtime.where('(start_time, end_time) OVERLAPS (?, ?)', start_time , end_time).where.not(id: self.id)
return unless overlapped_records.any?
time_overlapped_errors(overlapped_records)
end

def create_leave_time
if Date.today.month > 10
LeaveTime.create(leave_type: 'bonus', quota: hours, usable_hours: hours, used_hours: 0, locked_hours: 0, user_id: user_id, effective_date: Date.today, expiration_date: Date.today.end_of_year + 3.months, remark: "申請加班補休核准")
else
LeaveTime.create(leave_type: 'bonus', quota: hours, usable_hours: hours, used_hours: 0, locked_hours: 0, user_id: user_id, effective_date: Date.today, expiration_date: Date.today.end_of_year, remark: "申請加班補休核准")
def time_overlapped_errors(records)
url = Rails.application.routes.url_helpers
records.each do |record|
next if record.rejected? || record.canceled?
errors.add(:base,
I18n.t(
'activerecord.errors.models.overtime.attributes.base.time_range_overlapped',
start_time: record.start_time.to_formatted_s(:month_date),
end_time: record.end_time.to_formatted_s(:month_date),
link: url.overtime_path(id: record.id))
)
end
end
end
4 changes: 4 additions & 0 deletions app/models/overtime_pay.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class OvertimePay < ApplicationRecord
belongs_to :overtime
belongs_to :user
end