Permalink
Browse files

added "View conversations" section in admin

  • Loading branch information...
nikolailv authored and valdis committed Sep 18, 2017
1 parent a3d0f2e commit 5523a74bbb4011b76cb688493c8c49ab6534801e
@@ -0,0 +1,82 @@
class Admin::CommunityConversationsController < Admin::AdminBaseController
ConversationQuery = MarketplaceService::Conversation::Query
def index
@selected_left_navi_link = "conversations"
pagination_opts = PaginationViewUtils.parse_pagination_opts(params)
conversations = ConversationQuery.conversations_for_community(
@current_community.id,
simple_sort_column(params[:sort]),
sort_direction,
pagination_opts[:limit],
pagination_opts[:offset]
)
count = ConversationQuery.count_for_community(@current_community.id)
conversations = conversations.map do |conversation|
author = Maybe(conversation[:other_person]).or_else({is_deleted: true})
starter = Maybe(conversation[:starter_person]).or_else({is_deleted: true})
[author, starter].each { |p|
p[:url] = person_path(p[:username]) unless p[:username].nil?
p[:display_name] = PersonViewUtils.person_entity_display_name(p, "fullname")
}
conversation.merge({author: author, starter: starter})
end
conversations = WillPaginate::Collection.create(pagination_opts[:page], pagination_opts[:per_page], count) do |pager|
pager.replace(conversations)
end
render "index", { locals: { community: @current_community, conversations: conversations } }
end
def show
@selected_left_navi_link = "conversations"
conversation_id = params[:id]
conversation = Conversation.find(conversation_id)
conversation = MarketplaceService::Conversation::Query.conversation_for_person(
conversation_id,
conversation.starter.id,
@current_community.id)
transaction = Transaction.find_by_conversation_id(conversation[:id])
if transaction.present?
redirect_to person_transaction_url(@current_user, {:id => transaction.id}) and return
end
author = Maybe(conversation[:other_person]).or_else({is_deleted: true})
starter = Maybe(conversation[:starter_person]).or_else({is_deleted: true})
[author, starter].each { |p|
p[:url] = person_path(p[:username]) unless p[:username].nil?
p[:display_name] = PersonViewUtils.person_entity_display_name(p, "fullname")
}
conversation = conversation.merge({author: author, starter: starter})
messages = TransactionViewUtils.conversation_messages(conversation[:messages], @current_community.name_display_type)
render locals: {
messages: messages.reverse,
conversation_data: conversation
}
end
private
def simple_sort_column(sort_column)
case sort_column
when "last_activity"
"last_message_at"
when "started"
"created_at"
else
"created_at"
end
end
def sort_direction
params[:direction] || "desc"
end
end
@@ -42,6 +42,7 @@ def create_contact
availability: :none, # Always none for free transactions and contacts
listing_quantity: 1,
content: contact_form.content,
starting_page: ::Conversation::LISTING,
payment_gateway: :none,
payment_process: :none}
})
@@ -50,6 +50,7 @@ def new_conversation(params)
conversation_params = params.require(:conversation).permit(
message_attributes: :content
)
conversation_params[:starting_page] = ::Conversation::PROFILE
conversation_params[:message_attributes][:sender_id] = @current_user.id
conversation = Conversation.new(conversation_params.merge(community: @current_community))
@@ -103,6 +103,7 @@ def create
availability: listing_model.availability,
listing_quantity: quantity,
content: form[:message],
starting_page: ::Conversation::PAYMENT,
booking_fields: booking_fields,
payment_gateway: process[:process] == :none ? :none : gateway, # TODO This is a bit awkward
payment_process: process[:process]}
@@ -376,6 +376,13 @@ def admin_links_for(community)
:path => admin_community_transactions_path(@current_community, sort: "last_activity", direction: "desc"),
:name => "transactions"
},
{
:topic => :manage,
:text => t("admin.communities.conversations.conversations"),
:icon_class => icon_class("chat_bubble"),
:path => admin_community_conversations_path(@current_community, direction: "desc"),
:name => "conversations"
},
{
:topic => :configure,
:text => t("admin.communities.edit_details.community_details"),
View
@@ -9,24 +9,33 @@
# updated_at :datetime
# last_message_at :datetime
# community_id :integer
# starting_page :string(255)
#
# Indexes
#
# index_conversations_on_community_id (community_id)
# index_conversations_on_last_message_at (last_message_at)
# index_conversations_on_listing_id (listing_id)
# index_conversations_on_starting_page (starting_page)
#
class Conversation < ApplicationRecord
STARTING_PAGES = [
PROFILE = 'profile',
LISTING = 'listing',
PAYMENT = 'payment'
]
has_many :messages, :dependent => :destroy
has_many :participations
has_many :participants, :through => :participations, :source => :person
belongs_to :listing
has_one :tx, class_name: "Transaction", foreign_key: "transaction_id"
has_one :tx, class_name: "Transaction", foreign_key: "conversation_id"
belongs_to :community
validates :starting_page, inclusion: { in: STARTING_PAGES }, allow_nil: true
scope :for_person, -> (person){
joins(:participations)
.where( { participations: { person_id: person }} )
@@ -11,6 +11,7 @@ module Entity
:messages,
:transaction,
:listing,
:created_at,
:last_message_at,
:starter_person,
:other_person
@@ -33,7 +34,9 @@ def conversation(conversation_model, community_id)
Conversation[{
id: conversation_model.id,
listing: conversation_model.listing,
transaction: conversation_model.tx,
messages: messages(conversation_model.messages, community_id),
created_at: conversation_model.created_at,
last_message_at: conversation_model.last_message_at,
starter_person: PersonEntity.person(conversation_model.starter, community_id),
other_person: PersonEntity.person(conversation_model.other_party(conversation_model.starter), community_id)
@@ -132,6 +135,37 @@ def latest_messages_for_conversations(conversation_ids)
SELECT id, conversation_id, content, created_at FROM messages WHERE conversation_id in (#{params[:conversation_ids].join(',')})
"
}
def conversations_for_community(community_id, sort_field, sort_direction, limit, offset)
query = <<-SQL
SELECT c.* FROM conversations c
WHERE c.community_id = #{community_id}
AND (c.starting_page IS NULL OR c.starting_page != '#{::Conversation::PAYMENT}')
AND c.id NOT IN (SELECT conversation_id FROM transactions
WHERE transactions.community_id = #{community_id}
AND transactions.current_state <> 'free')
ORDER BY #{sort_field} #{sort_direction}
LIMIT #{limit} OFFSET #{offset}
SQL
conversations = ConversationModel.find_by_sql(query)
conversations.map{|conversation| Entity.conversation(conversation, community_id) }
end
def count_for_community(community_id)
query = <<-SQL
SELECT count(*) FROM conversations c
WHERE c.community_id = #{community_id}
AND (c.starting_page IS NULL OR c.starting_page != '#{::Conversation::PAYMENT}')
AND c.id NOT IN (SELECT conversation_id FROM transactions
WHERE transactions.community_id = #{community_id}
AND transactions.current_state <> 'free')
SQL
ActiveRecord::Base.connection.select_value(query)
end
def base_community_conversations_query(community_id)
query
end
end
end
end
@@ -281,8 +281,11 @@ def transaction_with_conversation(transaction_id:, person_id: nil, community_id:
end
def transactions_for_community_sorted_by_column(community_id, sort_column, sort_direction, limit, offset)
sort_column = "transactions.#{sort_column}" if sort_column.index('.').nil?
transactions = TransactionModel
.where(community_id: community_id, deleted: false)
.joins('LEFT JOIN conversations c ON transactions.conversation_id = c.id')
.where('c.starting_page = ? OR c.starting_page IS NULL', ::Conversation::PAYMENT)
.includes(:listing)
.limit(limit)
.offset(offset)
@@ -303,7 +306,11 @@ def transactions_for_community_sorted_by_activity(community_id, sort_direction,
end
def transactions_count_for_community(community_id)
TransactionModel.where(community_id: community_id, deleted: false).count
TransactionModel
.where(community_id: community_id, deleted: false)
.joins('LEFT JOIN conversations c ON transactions.conversation_id = c.id')
.where('c.starting_page = ? OR c.starting_page IS NULL', ::Conversation::PAYMENT)
.count
end
def can_transition_to?(transaction_id, new_status)
@@ -323,6 +330,7 @@ def sql_for_transactions_for_community_sorted_by_activity(community_id, sort_dir
# (this is done by joining the transitions table to itself where created_at < created_at OR sort_key < sort_key, if created_at equals)
LEFT JOIN conversations ON transactions.conversation_id = conversations.id
WHERE transactions.community_id = #{community_id} AND transactions.deleted = 0
AND conversations.starting_page = '#{::Conversation::PAYMENT}' OR conversations.starting_page IS NULL
ORDER BY
GREATEST(COALESCE(transactions.last_transition_at, 0),
COALESCE(conversations.last_message_at, 0)) #{sort_direction}
@@ -27,6 +27,7 @@ module TransactionService::Store::Transaction
[:automatic_confirmation_after_days, :fixnum, :mandatory],
[:minimum_commission, :money, :mandatory],
[:content, :string],
[:starting_page, :string],
[:booking_uuid, :string, transform_with: UUIDUtils::RAW], # :string type for raw bytes
[:booking_fields, :hash])
@@ -87,7 +88,7 @@ module TransactionService::Store::Transaction
def create(opts)
tx_data = HashUtils.compact(NewTransaction.call(opts))
tx_model = TransactionModel.new(tx_data.except(:content, :booking_fields))
tx_model = TransactionModel.new(tx_data.except(:content, :starting_page, :booking_fields))
build_conversation(tx_model, tx_data)
build_booking(tx_model, tx_data)
@@ -204,7 +205,7 @@ def addr_fields(addr)
def build_conversation(tx_model, tx_data)
conversation = tx_model.build_conversation(
tx_data.slice(:community_id, :listing_id))
tx_data.slice(:community_id, :listing_id, :starting_page))
conversation.participations.build(
person_id: tx_data[:listing_author_id],
@@ -0,0 +1,44 @@
- content_for :title_header do
%h1
= t("layouts.admin.admin")
= "-"
= t("admin.communities.conversations.conversations")
= render :partial => "admin/left_hand_navigation", :locals => { :links => admin_links_for(@current_community) }
.left-navi-section
%h2= t("admin.communities.conversations.conversations", community_name: community.name(I18n.locale))
%span#admin_transactions_count= page_entries_info(conversations, :model => "Conversation")
%table#admin_transactions
%thead
%tr
%th=t("admin.communities.conversations.headers.started_from")
%th=t("admin.communities.conversations.headers.status")
%th=render partial: "layouts/sort_link", locals: { column: "started", direction: sort_link_direction("started"), title: t("admin.communities.conversations.headers.started") }
%th=render partial: "layouts/sort_link", locals: { column: "last_activity", direction: sort_link_direction("last_activity"), title: t("admin.communities.conversations.headers.last_activity") }
%th=t("admin.communities.conversations.headers.initiated_by")
%th=t("admin.communities.conversations.headers.other_party")
%tbody
- conversations.each do |conversation|
%tr
- listing = conversation[:listing]
- if listing
- listing_title = listing.title || t("admin.communities.conversations.not_available")
%td=link_to_unless listing.deleted, listing_title, listing_path(listing.id)
- else
%td=Maybe(conversation[:author]).map { |p| link_to_unless(p[:is_deleted], t("admin.communities.conversations.profile", author: p[:display_name]), p[:url]) }.or_else("")
%td
- if conversation[:transaction] && conversation[:transaction][:payment_process] == 'none'
=link_to t("admin.communities.transactions.status.conversation"), admin_community_conversation_path(@current_community.id, conversation[:id])
- else
=link_to t("admin.communities.transactions.status.conversation"), admin_community_conversation_path(@current_community.id, conversation[:id])
%td=l(conversation[:created_at], format: :short_date)
%td=l(conversation[:last_message_at], format: :short_date)
%td=Maybe(conversation[:starter]).map { |p| link_to_unless(p[:is_deleted], p[:display_name], p[:url]) }.or_else("")
%td=Maybe(conversation[:author]).map { |p| link_to_unless(p[:is_deleted], p[:display_name], p[:url]) }.or_else("")
.row
.col-12
= will_paginate conversations
@@ -0,0 +1,20 @@
- content_for :title_header do
%h1
= t("layouts.admin.admin")
= "-"
= t("admin.communities.conversations.conversations")
= render :partial => "admin/left_hand_navigation", :locals => { :links => admin_links_for(@current_community) }
.left-navi-section
%h2
- starter = link_to_unless(conversation_data[:starter][:is_deleted], conversation_data[:starter][:display_name], conversation_data[:starter][:url]).html_safe
- author = link_to_unless(conversation_data[:author][:is_deleted], conversation_data[:author][:display_name], conversation_data[:author][:url]).html_safe
= t("admin.communities.conversations.participants", starter: starter, author: author).html_safe
- listing = conversation_data[:listing]
- if listing
- listing_title = listing.title || t("admin.communities.conversations.not_available")
%h2=link_to_unless listing.deleted, listing_title, listing_path(listing.id)
#messages
= render :partial => "conversations/message", :collection => messages, as: :message_or_action
View
@@ -322,7 +322,8 @@ en:
initiated_by: Starter
other_party: "Other party"
status:
free: Conversation
conversation: Conversation
free: Free transaction
pending: Pending
preauthorized: Preauthorized
accepted: Accepted
@@ -333,7 +334,7 @@ en:
initiated: "Waiting PayPal payment"
pending_ext: "Waiting PayPal payment"
none:
free: Conversation
free: Free transaction
paypal:
free: Conversation
pending: Pending
@@ -357,6 +358,17 @@ en:
initiated: "Waiting Stripe payment"
pending_ext: "Waiting Stripe payment"
not_available: "Not available"
conversations:
conversations: "View conversations"
headers:
started_from: Started from
status: Status
started: Started
last_activity: Latest Activity
initiated_by: Starter
other_party: Other party
participants: "Conversation: %{starter} with %{author}"
profile: "%{author}'s Profile"
custom_fields:
edit:
edit_listing_field: "Edit listing field '%{field_name}'"
View
@@ -262,6 +262,7 @@
end
resources :transactions, controller: :community_transactions, only: :index
resources :conversations, controller: :community_conversations, only: [:index, :show]
resources :emails
resources :community_memberships do
member do
@@ -0,0 +1,14 @@
class AddStartingPageToConversations < ActiveRecord::Migration[5.1]
def up
add_column :conversations, :starting_page, :string
add_index :conversations, :starting_page
ActiveRecord::Base.connection.execute("UPDATE conversations c LEFT JOIN transactions t ON c.id = t.conversation_id SET c.starting_page = 'profile' WHERE t.id IS NULL")
ActiveRecord::Base.connection.execute("UPDATE conversations c LEFT JOIN transactions t ON c.id = t.conversation_id SET c.starting_page = 'listing' WHERE t.payment_gateway = 'none' AND t.current_state = 'free'")
ActiveRecord::Base.connection.execute("UPDATE conversations c LEFT JOIN transactions t ON c.id = t.conversation_id SET c.starting_page = 'payment' WHERE t.payment_gateway != 'none' OR t.current_state != 'free'")
end
def down
remove_index :conversations, :starting_page
remove_column :conversations, :starting_page
end
end
Oops, something went wrong.

0 comments on commit 5523a74

Please sign in to comment.