#ruby-on-rails
#ruby-on-rails
Вопрос:
Например, сотруднику разрешено 15 отпусков в год. Моя функция вычисляет общее количество листьев allover. Но я хочу рассчитать дату присоединения с момента завершения года, а по завершении года с даты присоединения разрешенные отпуска обновляются до 15.он метод, который вычисляет общее количество отпусков сотрудника.
class Employee < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
acts_as_paranoid
devise :database_authenticatable,
:recoverable, :rememberable, :validatable
validates :email, presence: true,
format: { with: /A[w -.] @[a-zd-] (.[a-zd-] )*.[a-z] z/i,
message: "is not valid"
}
validates :first_name, :last_name, :address, :city, :country, presence: true, format: { with: /[a-z] /i ,
message: "only allows letters" }
validates :joining_date, :bank_name, :bank_title, presence: true
validates :current_salary, :allowed_leaves, numericality: true, presence: true
validates :bank_account_id, uniqueness:true, numericality: true, presence: true, length: { minimum: 16, maximum: 16}
has_many :increments, dependent: :destroy
has_many :salaries, dependent: :destroy
has_many :leaves, dependent: :destroy
has_many :designations, dependent: :destroy
has_many :employee_projects, dependent: :destroy
has_many :projects, through: :employee_projects
has_many :timelogs, dependent: :destroy
has_many :medical_applications, dependent: :destroy
before_update :update_leaves, :if => :allowed_leaves_changed?
def display_name
[first_name, last_name].join(' ')
end
def self.send_and_create_salary_slips
send_salary_slips
end
def update_leaves
taken_leaves = self.leaves.where(status: "Approved").count
allowed_leaves = self.allowed_leaves
total_leaves = (allowed_leaves-taken_leaves)
self.update_column(:availed_leaves, total_leaves)
end
def create_salary_slip
salary = self.salaries.new
salary.gross_salary = self.current_salary
salary.basic_salary = self.current_salary
salary.month = Date.today.month
salary.year = Date.today.year
salary.status = "pending"
salary.save!
end
def self.send_salary_slips
self.all.each do |employee|
salary_slip = employee.salaries.last
EmployeeMailer.send_salary_slip(salary_slip, employee).deliver if salary_slip.present?
employee.create_salary_slip
end
end
end
Модель leave — это hear
class Leave < ApplicationRecord
PENDING = "Pending"
Approved = "Approved"
REJECTED = "Rejected"
belongs_to :employee
before_save :save_status
after_update :calculate_availed_leave
validates :leave_date, :leave_description, presence: true
def allowed?
self.employee.availed_leaves > 0
end
def display_status
{
PENDING => "Pending",
Approved => "Approved",
REJECTED => "Rejected",
}[status.to_s]
end
def Approved?
status == Approved
end
def REJECTED?
status == REJECTED
end
private
def save_status
self.status ||= "Pending" # note self.status = 'P' if self.status.nil? might be safer (per @frontendbeauty)
end
def calculate_availed_leave
date = self.employee.joining_date 1.year
apply_date = self.leave_date
if apply_date < date
taken_leaves = self.employee.leaves.where(status: "Approved").count
availed_leaves = self.employee.allowed_leaves - taken_leaves
self.employee.update(availed_leaves: availed_leaves)
elsif apply_date < new_date
allowed_leaves = self.employee.allowed_leaves
self.employee.update(availed_leaves: allowed_leaves)
end
end
end
Комментарии:
1. Пропорционально ли количество разрешенных листьев? То есть, в его 4-месячную годовщину ему разрешено занимать 5 дней? Или ему разрешено взять отпуск только на 15 дней после годовщины? На дату его присоединения 1.год 1.день у него будет 30 дней или только 15?
2. Сотруднику разрешается брать отпуск только на 15 дней после его юбилейной даты
3. @SteveTurczyn Я рассчитываю отпуск с даты присоединения до завершения года. по завершении года увольнения сотрудников начинаются снова с 15. Если сотрудник подал заявку на 15 отпусков в год, то ему не разрешается подавать заявку на отпуска
4. Может ли он перенести? То есть, если в прошлом году он взял только 12, на его годовщину ему нужно взять 15 или 18?
5. @SteveTurczyn Нет, каждый год ему нужно брать 15
Ответ №1:
Спасибо за публикацию дополнительной информации. Теперь я вижу, что этот метод заключается в after_update
обновлении общего и доступного отпуска в employees
таблице.
Неясно, как долго вы будете хранить записи об отпусках в системе, но если у вас нет конкретных планов по очистке записей, вам нужно убедиться, что вы не обновляете доступные даты сотрудника при повторном сохранении записи об отпуске, скажем, трехлетней давности.
Я также отмечаю, что вы сохраняете оставшийся доступный отпуск в записи о сотруднике, а это значит, что есть вероятность, что он может стать неправильным. Я думаю, что лучше вычислять по мере необходимости.
Итак, я бы добавил следующие методы в запись о сотруднике.
class Employee < ActiveRecord
def allocated_leave_days(date=nil)
date ||= Date.today
date > joining_date 1.year ? 15 : 0
end
def year_to_examine(date=nil)
date ||= Date.today
end_date = joining_date
end_date = end_date 1.year while end_date < date
start_date = [joining_date, end_date - 1.year].max
(start_date..end_date)
end
def taken_leave_days(date=nil)
date ||= Date.today
leaves.where(status: 'Approved', leave_date: year_to_examine(date)).count
end
def remaining_leave_days(date=nil)
date ||= Date.today
[allocated_leave_days(date) - taken_leave_days(date), 0].max
end
end
Итак, теперь, если вы хотите узнать права сотрудника сегодня, вы должны сделать my_employee.allocated_leave_days
или (для некоторой даты в будущем или прошлом) my_employee.allocated_leave_days(my_test_date)
Если вы хотите узнать, сколько дней у него осталось, вы бы сделали my_employee.remaining_leave_days
или (для некоторой даты в будущем году) my_employee.remaining_leave_days(my_test_date)
Комментарии:
1. сэр, отпуск сотрудника за текущий год завершен в этом году, когда я выбираю дату после года из joining_date, он все еще не подает заявку на отпуск
2. Какой из методов не работает? Я не совсем понимаю, о чем вы говорите.
3. @ SteveTurczyn по завершении года увольнения сотрудников начинаются снова с 15. Но вышеупомянутый метод снова не начинается с 15. когда увольнение сотрудника завершено, разрешенный отпуск начинается снова с 15
4. Вам нужно указать, что вы подразумеваете под «вышеуказанным методом»… Я дал вам четыре метода. Если интересующая вас дата больше, чем join_date 1.year, то
allocated_leave_days
всегда возвращается 15.taken_leve_days
Всегда возвращает фактические утвержденные отпуска за текущий год сотрудника.remaining_leave_days
дает вам разницу между ними. Вы должны быть более четкими в своих вопросах. `