Commit iniziale di eminuxCRM: CRM Rails con pipeline, campagne email e Docker.
Include autenticazione, progetti isolati, mail marketing HTML con SMTP, test A/B e editor WYSIWYG. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
class Task < ApplicationRecord
|
||||
include Auditable
|
||||
|
||||
belongs_to :organization
|
||||
belongs_to :contact, optional: true
|
||||
belongs_to :opportunity, optional: true
|
||||
belongs_to :assigned_user, class_name: "User", optional: true
|
||||
|
||||
validates :title, :due_at, presence: true
|
||||
validates :priority, inclusion: { in: Catalog::TASK_PRIORITIES.keys }
|
||||
validates :task_type, inclusion: { in: Catalog::TASK_TYPES.keys }
|
||||
validates :status, inclusion: { in: Catalog::TASK_STATUSES.keys }
|
||||
|
||||
scope :pending, -> { where(status: "pending") }
|
||||
scope :completed, -> { where(status: "completed") }
|
||||
scope :overdue, -> { pending.where("due_at < ?", Time.zone.now.beginning_of_day) }
|
||||
scope :due_today, -> { pending.where(due_at: Time.zone.now.all_day) }
|
||||
scope :upcoming, ->(days = 7) {
|
||||
pending.where(due_at: Time.zone.now.tomorrow.beginning_of_day..(Time.zone.now + days.days).end_of_day)
|
||||
}
|
||||
scope :ordered, -> { order(Arel.sql("CASE priority WHEN 'urgent' THEN 0 WHEN 'high' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END"), :due_at) }
|
||||
scope :for_project, ->(project) {
|
||||
return none if project.nil?
|
||||
|
||||
where(
|
||||
id: left_joins(:opportunity)
|
||||
.joins("INNER JOIN organization_projects ON organization_projects.organization_id = tasks.organization_id")
|
||||
.where(
|
||||
"organization_projects.project_id = :pid OR opportunities.project_id = :pid",
|
||||
pid: project.id
|
||||
)
|
||||
.select("tasks.id")
|
||||
.distinct
|
||||
)
|
||||
}
|
||||
|
||||
def priority_label
|
||||
Catalog.label_for(Catalog::TASK_PRIORITIES, priority)
|
||||
end
|
||||
|
||||
def task_type_label
|
||||
Catalog.label_for(Catalog::TASK_TYPES, task_type)
|
||||
end
|
||||
|
||||
def status_label
|
||||
Catalog.label_for(Catalog::TASK_STATUSES, status)
|
||||
end
|
||||
|
||||
def overdue?
|
||||
pending? && due_at < Time.zone.now.beginning_of_day
|
||||
end
|
||||
|
||||
def due_today?
|
||||
pending? && due_at.to_date == Time.zone.today
|
||||
end
|
||||
|
||||
def pending?
|
||||
status == "pending"
|
||||
end
|
||||
|
||||
def completed?
|
||||
status == "completed"
|
||||
end
|
||||
|
||||
def complete!(user: Current.user, create_activity: true)
|
||||
return false unless pending?
|
||||
|
||||
transaction do
|
||||
update!(status: "completed", completed_at: Time.current, updated_by: user)
|
||||
create_completion_activity!(user) if create_activity && user
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_completion_activity!(user)
|
||||
activities_attrs = {
|
||||
activity_type: activity_type_for_task,
|
||||
subject: title,
|
||||
description: description,
|
||||
happened_at: Time.current,
|
||||
user: user,
|
||||
organization: organization,
|
||||
contact: contact,
|
||||
opportunity: opportunity,
|
||||
created_by: user,
|
||||
updated_by: user
|
||||
}
|
||||
Activity.create!(activities_attrs)
|
||||
end
|
||||
|
||||
def activity_type_for_task
|
||||
{
|
||||
"follow_up" => "follow_up",
|
||||
"call" => "call",
|
||||
"email" => "email_sent",
|
||||
"meeting" => "meeting",
|
||||
"demo" => "demo",
|
||||
"proposal" => "proposal_sent",
|
||||
"generic" => "other"
|
||||
}.fetch(task_type, "other")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user