diff options
Diffstat (limited to 'engines/support/app/models')
-rw-r--r-- | engines/support/app/models/account_extension/tickets.rb | 13 | ||||
-rw-r--r-- | engines/support/app/models/ticket.rb | 112 | ||||
-rw-r--r-- | engines/support/app/models/ticket_comment.rb | 43 | ||||
-rw-r--r-- | engines/support/app/models/ticket_selection.rb | 71 |
4 files changed, 239 insertions, 0 deletions
diff --git a/engines/support/app/models/account_extension/tickets.rb b/engines/support/app/models/account_extension/tickets.rb new file mode 100644 index 0000000..f898b56 --- /dev/null +++ b/engines/support/app/models/account_extension/tickets.rb @@ -0,0 +1,13 @@ +module AccountExtension::Tickets + extend ActiveSupport::Concern + + def destroy_with_tickets + Ticket.destroy_all_from(self.user) + destroy_without_tickets + end + + included do + alias_method_chain :destroy, :tickets + end + +end diff --git a/engines/support/app/models/ticket.rb b/engines/support/app/models/ticket.rb new file mode 100644 index 0000000..bf5df53 --- /dev/null +++ b/engines/support/app/models/ticket.rb @@ -0,0 +1,112 @@ +# +# 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: better validation of email +# +# TODO: don't hardcode strings 'unknown user' and 'unauthenticated user' +# +class Ticket < CouchRest::Model::Base + use_database "tickets" + + property :created_by, String, :protected => true # nil for anonymous tickets, should never be changed + property :regarding_user, String # may be nil or valid username + property :subject, String + property :email, String + property :is_open, TrueClass, :default => true + property :comments, [TicketComment] + + timestamps! + + design do + view :by_updated_at + view :by_created_at + view :by_created_by + + view :by_is_open_and_created_at + view :by_is_open_and_updated_at + + own_path = Pathname.new(File.dirname(__FILE__)) + load_views(own_path.join('..', 'designs', 'ticket')) + end + + validates :subject, :presence => true + + # email can have three states: + # * nil - prefilled with created_by's email + # * "" - cleared + # * valid email address + validates :email, :allow_blank => true, :format => /\A(([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,}))?\Z/ + + def self.search(options = {}) + @selection = TicketSelection.new(options) + @selection.tickets + end + + def self.destroy_all_from(user) + self.by_created_by.key(user.id).each do |ticket| + ticket.destroy + end + end + + def is_creator_validated? + created_by_user.is_a? User + end + + def email + read_attribute(:email) || created_by_user.email + end + + def regarding_user + read_attribute(:regarding_user) || created_by_user.login + end + + def close + self.is_open = false + end + + def reopen + self.is_open = true + end + + 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') + end + else + commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user') + end + end + commenters.join(', ') + end + + # + # update comments. User should be set by controller. + # + def comments_attributes=(attributes) + if attributes + comment = TicketComment.new(attributes.values.first) + comment.posted_at = Time.now + comments << comment + end + end + + def created_by_user + if self.created_by + User.find(self.created_by) || AnonymousUser.new + else + AnonymousUser.new + end + end + + def regarding_user_actual_user + User.find_by_login(self.regarding_user) + end + +end diff --git a/engines/support/app/models/ticket_comment.rb b/engines/support/app/models/ticket_comment.rb new file mode 100644 index 0000000..bed5237 --- /dev/null +++ b/engines/support/app/models/ticket_comment.rb @@ -0,0 +1,43 @@ +class TicketComment + include CouchRest::Model::Embeddable + + #belongs_to :ticket #is this best way to do it? will want to access all of a tickets comments, so maybe this isn't the way? + property :posted_by, String#, :protected => true #Integer#this should be current_user if that is set, meaning the user is logged in #cannot have it be protected and set via comments_attributes=. also, if it is protected and we set in the tickets_controller, it gets unset. TODO---is this okay to have it not protected and manually check it? We do not users to be able to set this. + # if the current user is not set, then we could just say the comment comes from an 'unauthenticated user', which would be somebody with the secret URL + property :posted_at, Time#, :protected => true + #property :posted_verified, TrueClass, :protected => true #should be true if current_user is set when the comment is created + property :body, String + property :private, TrueClass # private comments are only viewable by admins #this is checked when set, to make sure it was set by an admin + + # ? timestamps! + validates :body, :presence => true + #before_validation :set_time#, :set_posted_by + + #design do + # view :by_posted_at + # view :by_body + #end + + def is_comment_validated? + !!posted_by + end + + def posted_by_user + User.find(posted_by) if posted_by + end + +=begin + #TODO. + #this is resetting all comments associated with the ticket: + def set_time + self.posted_at = Time.now + end +=end + +=begin + def set_posted_by + self.posted_by = User.current if User.current + end +=end + +end diff --git a/engines/support/app/models/ticket_selection.rb b/engines/support/app/models/ticket_selection.rb new file mode 100644 index 0000000..74d5b78 --- /dev/null +++ b/engines/support/app/models/ticket_selection.rb @@ -0,0 +1,71 @@ +class TicketSelection + + # + # supported options: + # + # user_id: id of the user (uuid string) + # open_status: open | closed | all + # sort_order: updated_at_desc | updated_at_asc | created_at_desc | created_at_asc + # admin_status: mine | all + # is_admin: true | false + # + def initialize(options = {}) + @user_id = options[:user_id].gsub /[^a-z0-9]/, '' + @open_status = allow options[:open_status], 'open', 'closed', 'all' + @sort_order = allow options[:sort_order], 'updated_at_desc', 'updated_at_asc', 'created_at_desc', 'created_at_asc' + @admin_status = allow options[:admin_status], 'mine', 'all' + @is_admin = allow options[:is_admin], false, true + end + + def tickets + Ticket.send(finder_method).startkey(startkey).endkey(endkey).send(order) + end + + protected + + def allow(source, *allowed) + if allowed.include?(source) + source + else + allowed.first + end + end + + def finder_method + method = 'by_' + method += 'includes_post_by_and_' if only_mine? + method += 'is_open_and_' if @open_status != 'all' + method += @sort_order.sub(/_(de|a)sc$/, '') + end + + def startkey + startkeys = [] + startkeys << @user_id if only_mine? + startkeys << (@open_status == 'open') if @open_status != 'all' + startkeys << 0 + startkeys = startkeys.join if startkeys.length == 1 # want string not array if just one thing in array + startkeys + end + + def endkey + endtime = Time.now + 2.days # TODO. this obviously isn't ideal + if self.startkey.is_a?(Array) + endkeys = self.startkey + endkeys.pop + endkeys << endtime + else + endtime + end + end + + def order + # we have defined the ascending method to return the view itself: + (@sort_order.end_with? 'desc') ? 'descending' : 'ascending' + end + + + def only_mine? + !@is_admin || @admin_status == 'mine' + end + +end |