module Ecom module Core class OvertimeSheet < ApplicationRecord validates :date, :opened_at, presence: true, uniqueness: { scope: :site_id } validates :status, inclusion: StatusConstants::STATUSES belongs_to :site has_many :overtime_sheet_entries has_many :crew_overtimes, through: :overtime_sheet_entries scope :by_site, ->(id) { where(site_id: id) } scope :by_date, ->(date) { where(date: date) } scope :by_status, ->(status) { where(status: status) } scope :by_date_between, ->(from, to) { where('date BETWEEN ? AND ?', from, to) } def self.open_exists?(site_id) OvertimeSheet .by_site(site_id) .by_status(StatusConstants::OPEN) .exists? end def self.open_for_date_exists?(date, site_id) OvertimeSheet .by_site(site_id) .by_status(StatusConstants::OPEN) .by_date(date) .exists? end def self.exists_for_date?(date, site_id) OvertimeSheet .by_site(site_id) .by_date(date) .exists? end # Overtime sheet should be created using the # method below only. This is because we need to # check if there is an open overtime already, # and also that we have only one open overtime # sheet at a time. def self.create_new(date, site_id) if OvertimeSheet.exists_for_date?(date, site_id) raise 'There is already an overtime sheet for the selected date.' end if OvertimeSheet.open_exists?(site_id) open_overtime_sheet = OvertimeSheet.find_by(status: 'Open') raise "There is already an open overtime sheet for #{open_overtime_sheet.date}. It has to be submitted before creating a new one." end OvertimeSheet.create(date: date, opened_at: Time.now, status: StatusConstants::OPEN, site_id: site_id) end def submit raise 'Overtime sheet is not open and cannot be submitted' if status != StatusConstants::OPEN self.submitted_at = DateTime.now self.status = StatusConstants::SUBMITTED save end def approve raise 'Overtime sheet is not submitted and cannot be approved' unless status == StatusConstants::SUBMITTED self.status = StatusConstants::APPROVED self.approved_at = DateTime.now save end end end end