summaryrefslogtreecommitdiff
path: root/help/app/models/ticket.rb
diff options
context:
space:
mode:
Diffstat (limited to 'help/app/models/ticket.rb')
-rw-r--r--help/app/models/ticket.rb202
1 files changed, 185 insertions, 17 deletions
diff --git a/help/app/models/ticket.rb b/help/app/models/ticket.rb
index f38fed2..781216e 100644
--- a/help/app/models/ticket.rb
+++ b/help/app/models/ticket.rb
@@ -20,23 +20,109 @@ class Ticket < CouchRest::Model::Base
#also, both created_by and regarding_user could be nil---say user forgets username, or has general question
property :title, String
property :email, String #verify
-
+
#property :user_verified, TrueClass, :default => false #will be true exactly when user is set
#admins
- property :code, String, :protected => true # only should be set if created_by is nil
+ #property :code, String, :protected => true # only should be set if created_by is nil #instead we will just use couchdb ID
property :is_open, TrueClass, :default => true
property :comments, [TicketComment]
timestamps!
-
+
#before_validation :set_created_by, :set_code, :set_email, :on => :create
- before_validation :set_code, :set_email, :on => :create
+ before_validation :set_email, :on => :create
#named_scope :open, :conditions => {:is_open => true} #??
design do
- view :by_title
+ #TODO--clean this all up
+ view :by_is_open
+ view :by_created_by
+
+ view :by_updated_at
+ view :by_created_at
+
+ view :by_is_open_and_created_by
+ view :by_is_open_and_created_at
+ view :by_is_open_and_updated_at
+
+ view :includes_post_by,
+ :map =>
+ "function(doc) {
+ var arr = {}
+ if (doc['type'] == 'Ticket' && doc.comments) {
+ doc.comments.forEach(function(comment){
+ if (comment.posted_by && !arr[comment.posted_by]) {
+ //don't add duplicates
+ arr[comment.posted_by] = true;
+ emit(comment.posted_by, 1);
+ }
+ });
+ }
+ }", :reduce => "function(k,v,r) { return sum(v); }"
+
+ view :includes_post_by_and_open_status_and_updated_at,
+ :map =>
+ "function(doc) {
+ var arr = {}
+ if (doc['type'] == 'Ticket' && doc.comments) {
+ doc.comments.forEach(function(comment){
+ if (comment.posted_by && !arr[comment.posted_by]) {
+ //don't add duplicates
+ arr[comment.posted_by] = true;
+ emit([comment.posted_by, doc.is_open, doc.updated_at], 1);
+ }
+ });
+ }
+ }", :reduce => "function(k,v,r) { return sum(v); }"
+
+ view :includes_post_by_and_open_status_and_created_at,
+ :map =>
+ "function(doc) {
+ var arr = {}
+ if (doc['type'] == 'Ticket' && doc.comments) {
+ doc.comments.forEach(function(comment){
+ if (comment.posted_by && !arr[comment.posted_by]) {
+ //don't add duplicates
+ arr[comment.posted_by] = true;
+ emit([comment.posted_by, doc.is_open, doc.created_at], 1);
+ }
+ });
+ }
+ }", :reduce => "function(k,v,r) { return sum(v); }"
+
+ view :includes_post_by_and_updated_at,
+ :map =>
+ "function(doc) {
+ var arr = {}
+ if (doc['type'] == 'Ticket' && doc.comments) {
+ doc.comments.forEach(function(comment){
+ if (comment.posted_by && !arr[comment.posted_by]) {
+ //don't add duplicates
+ arr[comment.posted_by] = true;
+ emit([comment.posted_by, doc.updated_at], 1);
+ }
+ });
+ }
+ }", :reduce => "function(k,v,r) { return sum(v); }"
+
+
+ view :includes_post_by_and_created_at,
+ :map =>
+ "function(doc) {
+ var arr = {}
+ if (doc['type'] == 'Ticket' && doc.comments) {
+ doc.comments.forEach(function(comment){
+ if (comment.posted_by && !arr[comment.posted_by]) {
+ //don't add duplicates
+ arr[comment.posted_by] = true;
+ emit([comment.posted_by, doc.created_at], 1);
+ }
+ });
+ }
+ }", :reduce => "function(k,v,r) { return sum(v); }"
+
end
validates :title, :presence => true
@@ -45,20 +131,83 @@ class Ticket < CouchRest::Model::Base
# html5 has built-in validation which isn't ideal, as it says 'please enter an email address' for invalid email addresses, which implies an email address is required, and it is not.
validates :email, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/, :if => :email #email address is optional
-
+
#TODO:
#def set_created_by
# self.created_by = User.current if User.current
#end
-
+
+ def self.for_user(user, options = {}, is_admin = false)
+
+ # TODO: This is obviously super tedious. we will refactor later.
+ # TODO: thought i should reverse keys for descending, but that didn't work. look into whether that should be tweaked, and whether it works okay with pagination (seems to now...)
+ # TODO: Time.now + 2.days is to catch tickets created in future. shouldn't happen but does on my computer now, so this at least catches for now.
+ # TODO handle default values correctly:
+ options[:open_status] = 'open' if !options[:open_status] #hacky. redo this when handling defaults correctly
+
+ if (is_admin && (options[:admin_status] != 'mine'))
+ # show all (selected) tickets to admin
+ if options[:open_status] == 'all'
+ if options[:sort_order] == 'created_at_desc'
+ Ticket.by_created_at.startkey(0).endkey(Time.now + 2.days).descending
+ elsif options[:sort_order] == 'updated_at_asc'
+ Ticket.by_updated_at.startkey(0).endkey(Time.now + 2.days)
+ elsif options[:sort_order] == 'created_at_asc'
+ Ticket.by_created_at.startkey(0).endkey(Time.now + 2.days)
+ else
+ Ticket.by_updated_at.startkey(0).endkey(Time.now + 2.days).descending
+ end
+ else
+ if options[:sort_order] == 'created_at_desc'
+ Ticket.by_is_open_and_created_at.startkey([(options[:open_status] == 'open'), 0]).endkey([(options[:open_status] == 'open'), Time.now + 2.days]).descending
+ elsif options[:sort_order] == 'updated_at_asc'
+ Ticket.by_is_open_and_updated_at.startkey([(options[:open_status] == 'open'), 0]).endkey([(options[:open_status] == 'open'), Time.now + 2.days])
+ elsif options[:sort_order] == 'created_at_asc'
+ Ticket.by_is_open_and_created_at.startkey([(options[:open_status] == 'open'), 0]).endkey([(options[:open_status] == 'open'), Time.now + 2.days])
+ else
+ Ticket.by_is_open_and_updated_at.startkey([(options[:open_status] == 'open'), 0]).endkey([(options[:open_status] == 'open'), Time.now + 2.days]).descending
+ end
+ end
+ else
+ # only show tickets this user has commented on, as user is non-admin or admin viewing only their tickets
+ if options[:open_status] == 'all'
+ if options[:sort_order] == 'created_at_desc'
+ Ticket.includes_post_by_and_created_at.startkey([user.id, 0]).endkey([user.id, Time.now + 2.days]).descending
+ elsif options[:sort_order] == 'updated_at_asc'
+ Ticket.includes_post_by_and_updated_at.startkey([user.id, 0]).endkey([user.id, Time.now + 2.days])
+ elsif options[:sort_order] == 'created_at_asc'
+ Ticket.includes_post_by_and_created_at.startkey([user.id, 0]).endkey([user.id, Time.now + 2.days])
+ else
+ Ticket.includes_post_by_and_updated_at.startkey([user.id, 0]).endkey([user.id, Time.now + 2.days]).descending
+ end
+ else
+ if options[:sort_order] == 'created_at_desc'
+ Ticket.includes_post_by_and_open_status_and_created_at.startkey([user.id, (options[:open_status] == 'open'), 0]).endkey([user.id, (options[:open_status] == 'open'), Time.now + 2.days]).descending
+ elsif options[:sort_order] == 'updated_at_asc'
+ Ticket.includes_post_by_and_open_status_and_updated_at.startkey([user.id, (options[:open_status] == 'open'), 0]).endkey([user.id, (options[:open_status] == 'open'), Time.now + 2.days])
+ elsif options[:sort_order] == 'created_at_asc'
+ Ticket.includes_post_by_and_open_status_and_created_at.startkey([user.id, (options[:open_status] == 'open'), 0]).endkey([user.id, (options[:open_status] == 'open'), Time.now + 2.days])
+ else
+ Ticket.includes_post_by_and_open_status_and_updated_at.startkey([user.id, (options[:open_status] == 'open'), 0]).endkey([user.id, (options[:open_status] == 'open'), Time.now + 2.days]).descending
+ end
+ end
+ end
+ end
+
+ def self.tickets_by_commenter(user_id)#, options = {})
+ Ticket.includes_post_by_and_updated_at.startkey([user_id, 0]).endkey([user_id, Time.now])
+ end
+
def is_creator_validated?
!!created_by
end
- def set_code
+=begin
+ def set_code #let's not use this---can use same show url
# ruby 1.9 provides url-safe option---this is not necessarily url-safe
self.code = SecureRandom.hex(8) if !is_creator_validated?
end
+=end
def set_email
@@ -66,23 +215,42 @@ class Ticket < CouchRest::Model::Base
# in controller set to be current users email if that exists
end
+ #not saving with close and reopen, as we will save in update when they are called.
+ #TODO: not sure if we should bother with these:
def close
self.is_open = false
- save
+ #save
end
def reopen
self.is_open = true
- save
+ #save
end
- def comments_attributes=(attributes)
+ def commenters
+ commenters = []
+ self.comments.each do |comment|
+ if comment.posted_by
+ if user = User.find(comment.posted_by)
+ commenters << user.login if user and !commenters.include?(user.login)
+ else
+ commenters << 'unknown user' if !commenters.include?('unknown user') #todo don't hardcode string 'unknown user'
+ end
+ else
+ commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user') #todo don't hardcode string 'unauthenticated user'
+ end
+ end
+ commenters.join(', ')
+ end
- comment = TicketComment.new(attributes.values.first) #TicketComment.new(attributes)
- #comment.posted_by = User.current.id if User.current #we want to avoid User.current, and current_user won't work here. instead will set in tickets_controller
- comment.posted_at = Time.now
- comments << comment
-
+ def comments_attributes=(attributes)
+ if attributes # could be empty as we will empty if nothing was typed in
+ comment = TicketComment.new(attributes.values.first) #TicketComment.new(attributes)
+ #comment.posted_by = User.current.id if User.current #we want to avoid User.current, and current_user won't work here. instead will set in tickets_controller
+ # what about: comment.posted_by = self.updated_by (will need to add ticket.updated_by)
+ comment.posted_at = Time.now
+ comments << comment
+ end
end
=begin
@@ -91,5 +259,5 @@ class Ticket < CouchRest::Model::Base
errors.add 'email', 'contains an invalid address'
end
end
-=end
+=end
end