e9_crm 0.1.16 → 0.1.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/app/controllers/e9_crm/base_controller.rb +0 -2
  2. data/app/controllers/e9_crm/campaigns_controller.rb +1 -1
  3. data/app/controllers/e9_crm/contacts_controller.rb +1 -1
  4. data/app/controllers/e9_crm/deals_controller.rb +18 -0
  5. data/app/controllers/e9_crm/email_templates.controller.rb +4 -0
  6. data/app/controllers/e9_crm/resources_controller.rb +1 -0
  7. data/app/helpers/e9_crm/contacts_helper.rb +1 -0
  8. data/app/helpers/e9_crm/deals_helper.rb +23 -1
  9. data/app/models/campaign.rb +1 -0
  10. data/app/models/contact.rb +1 -1
  11. data/app/models/deal.rb +1 -1
  12. data/app/models/email_template.rb +7 -0
  13. data/app/models/no_campaign.rb +4 -4
  14. data/app/views/e9_crm/affiliate_campaigns/_form_inner.html.haml +1 -1
  15. data/app/views/e9_crm/campaigns/_table.html.haml +3 -3
  16. data/app/views/e9_crm/contact_merges/_form.html.haml +1 -1
  17. data/app/views/e9_crm/contacts/_sidebar.html.haml +4 -4
  18. data/app/views/e9_crm/contacts/_tag_table.html.haml +6 -7
  19. data/app/views/e9_crm/contacts/show.html.haml +2 -2
  20. data/app/views/e9_crm/deals/_form_inner.html.haml +25 -7
  21. data/app/views/e9_crm/deals/_leads_table.html.haml +3 -3
  22. data/app/views/e9_crm/deals/_table.html.haml +6 -5
  23. data/app/views/e9_crm/email_templates/_form_inner.html.haml +1 -1
  24. data/app/views/e9_crm/email_templates/select.html.haml +1 -2
  25. data/app/views/e9_crm/sales_campaigns/_form_inner.html.haml +1 -1
  26. data/app/views/record_attributes/_user.html.haml +1 -1
  27. data/config/locales/e9.en.yml +1 -2
  28. data/config/locales/en.yml +9 -5
  29. data/config/routes.rb +1 -1
  30. data/lib/e9_crm/version.rb +1 -1
  31. metadata +3 -3
@@ -1,5 +1,3 @@
1
1
  class E9Crm::BaseController < AdminController
2
2
  include E9Rails::Helpers::ResourceLinks
3
- include E9Rails::Helpers::Title
4
- include E9Rails::Helpers::Translation
5
3
  end
@@ -26,7 +26,7 @@ class E9Crm::CampaignsController < E9Crm::ResourcesController
26
26
  end
27
27
 
28
28
  def default_ordered_on
29
- 'campaign_group_name,name'
29
+ 'type,campaign_group_name,name'
30
30
  end
31
31
 
32
32
  def default_ordered_dir
@@ -95,7 +95,7 @@ class E9Crm::ContactsController < E9Crm::ResourcesController
95
95
  'first_name'
96
96
  end
97
97
 
98
- def default_ordered_at
98
+ def default_ordered_dir
99
99
  'ASC'
100
100
  end
101
101
  end
@@ -12,6 +12,8 @@ class E9Crm::DealsController < E9Crm::ResourcesController
12
12
  prepend_before_filter :set_leads_index_title, :only => :leads
13
13
  prepend_before_filter :set_reports_index_title, :only => :reports
14
14
 
15
+ before_filter :prepop_deal_owner_contact, :only => [:new, :edit]
16
+
15
17
  ##
16
18
  # All Scopes
17
19
  #
@@ -103,6 +105,14 @@ class E9Crm::DealsController < E9Crm::ResourcesController
103
105
  end
104
106
  end
105
107
 
108
+ def prepop_deal_owner_contact
109
+ object = params[:id] ? resource : build_resource
110
+
111
+ if !object.owner && contact = current_user.contact
112
+ object.owner = contact
113
+ end
114
+ end
115
+
106
116
  def set_leads_index_title
107
117
  @index_title = I18n.t(:index_title, :scope => 'e9.e9_crm.leads')
108
118
  end
@@ -114,4 +124,12 @@ class E9Crm::DealsController < E9Crm::ResourcesController
114
124
  def ordered_if
115
125
  %w(index leads reports).member? params[:action]
116
126
  end
127
+
128
+ def default_ordered_on
129
+ 'name'
130
+ end
131
+
132
+ def default_ordered_dir
133
+ 'ASC'
134
+ end
117
135
  end
@@ -28,6 +28,10 @@ class E9Crm::EmailTemplatesController < E9Crm::ResourcesController
28
28
 
29
29
  protected
30
30
 
31
+ def collection
32
+ @email_templates ||= end_of_association_chain.order(:name).all
33
+ end
34
+
31
35
  def default_ordered_on
32
36
  'name'
33
37
  end
@@ -3,6 +3,7 @@ class E9Crm::ResourcesController < E9Crm::BaseController
3
3
 
4
4
  # NOTE depending on e9_base pagination (which should eventually use this module)
5
5
  #include E9Rails::Helpers::Pagination
6
+ include E9::DestroyRestricted::Controller
6
7
 
7
8
  # TODO implement role on e9_crm models?
8
9
  #include E9::Roles::Controller
@@ -4,6 +4,7 @@ module E9Crm::ContactsHelper
4
4
  @_contact_tags ||= begin
5
5
  relation = Tagging.joins(:tag).select('distinct tags.name')
6
6
  .where(:context => E9Tags.escape_context('users*'))
7
+ .order('tags.name ASC')
7
8
 
8
9
  Tagging.connection.send(:select_values, relation.to_sql, 'Contact Tags Select')
9
10
  end
@@ -32,7 +32,7 @@ module E9Crm::DealsHelper
32
32
  def deal_owner_select_options
33
33
  @_deal_owner_select_options ||= begin
34
34
  options = Contact.deal_owners.all.map {|c| [c.name, c.id] }
35
- options.unshift ['Any Owner', nil]
35
+ options.unshift ['All Responsible', nil]
36
36
  options_for_select(options)
37
37
  end
38
38
  end
@@ -69,4 +69,26 @@ module E9Crm::DealsHelper
69
69
 
70
70
  options_for_select(options)
71
71
  end
72
+
73
+ def deal_cost(deal)
74
+ campaign = deal.campaign
75
+
76
+ if campaign.blank?
77
+ 0
78
+ else
79
+ c = campaign.non_leads.count
80
+ c > 0 ? campaign.cost.to_f / c : campaign.cost
81
+ end.to_money
82
+ end
83
+
84
+ def deal_contacts
85
+ @_eligible_responsible_contacts ||= begin
86
+ roles = E9::Roles.list.map(&:role).select {|r| r > 'user' && r < 'e9_user' }
87
+ User.includes(:contact).for_roles(roles).all.map(&:contact).compact
88
+ end
89
+ end
90
+
91
+ def deal_contacts_array
92
+ deal_contacts.map {|c| [c.name, c.id] }.sort_by {|name, id| name.upcase }
93
+ end
72
94
  end
@@ -13,6 +13,7 @@ class Campaign < ActiveRecord::Base
13
13
  has_many :lost_deals, :class_name => 'Deal', :conditions => ['deals.status = ?', Deal::Status::Lost]
14
14
  has_many :pending_deals, :class_name => 'Deal', :conditions => ['deals.status = ?', Deal::Status::Pending]
15
15
  has_many :leads, :class_name => 'Deal', :conditions => ['deals.status = ?', Deal::Status::Lead]
16
+ has_many :non_leads, :class_name => 'Deal', :conditions => ['deals.status != ?', Deal::Status::Lead]
16
17
  has_many :page_views, :inverse_of => :campaign, :dependent => :nullify
17
18
 
18
19
  # only advertising campaigns use this association
@@ -184,7 +184,7 @@ class Contact < ActiveRecord::Base
184
184
 
185
185
  # The parameters for building the JS template for associated users
186
186
  def self.users_build_parameters # :nodoc:
187
- { :status => User::Status::Prospect }
187
+ { :role => :prospect }
188
188
  end
189
189
 
190
190
  ##
data/app/models/deal.rb CHANGED
@@ -260,7 +260,7 @@ class Deal < ActiveRecord::Base
260
260
  create_user(
261
261
  :email => lead_email,
262
262
  :first_name => lead_name,
263
- :status => User::Status::Prospect
263
+ :role => :prospect
264
264
  )
265
265
  end
266
266
 
@@ -17,4 +17,11 @@ class EmailTemplate < Email
17
17
  hash[:text_body] = render(:text_body)
18
18
  end
19
19
  end
20
+
21
+ protected
22
+
23
+ def ensure_body_field_presence
24
+ self.html_body = self.html_body.presence || ''
25
+ self.text_body = self.text_body.presence || ''
26
+ end
20
27
  end
@@ -1,9 +1,9 @@
1
1
  class NoCampaign < Campaign
2
- #before_create do |record|
3
- #record.code ||= 'nocode'
4
- #end
5
-
6
2
  def name
7
3
  self.class.model_name.human
8
4
  end
5
+
6
+ def cost
7
+ 0
8
+ end
9
9
  end
@@ -7,4 +7,4 @@
7
7
  = f.collection_select :affiliate_id, Contact.affiliates.ordered.all, :id, :name, {:prompt => true}, :id => 'campaign_affiliate_id'
8
8
  .field
9
9
  = help_label f, :affiliate_fee
10
- = f.text_field :affiliate_fee
10
+ = f.text_field :affiliate_fee, :value => f.object.affiliate_fee.to_s
@@ -2,8 +2,8 @@
2
2
  %thead
3
3
  %tr
4
4
  %th= orderable_column_link(:type)
5
- %th= orderable_column_link(:name)
6
5
  %th= orderable_column_link('campaign_group_name', :campaign_group)
6
+ %th= orderable_column_link(:name)
7
7
  %th= orderable_column_link(:code)
8
8
  %th= orderable_column_link(:affiliate_fee)
9
9
  %th= orderable_column_link(:sales_fee)
@@ -17,10 +17,10 @@
17
17
  %tr{:id => "ids_#{record.id}", :class => cycle('odd', 'even')}
18
18
  %td.record-type
19
19
  = record.type[/(.*)Campaign/, 1]
20
- %td.record-name
21
- = record.name
22
20
  %td.record-campaign-group
23
21
  = record.campaign_group_name || e9_t(:no_group, :scope => 'e9_crm.campaigns')
22
+ %td.record-name
23
+ = record.name
24
24
  %td.record-code
25
25
  = display_campaign_code(record.code)
26
26
  %td.record-affiliate-fee
@@ -7,4 +7,4 @@
7
7
  = render 'field', :column => :company_name, :f => f
8
8
  = render 'field', :column => :title, :f => f
9
9
  .actions
10
- = f.submit
10
+ = f.submit t(:save)
@@ -25,14 +25,14 @@
25
25
  %label= Contact.human_attribute_name(:website_attributes)
26
26
  - resource.website_attributes.each do |website_attribute|
27
27
  .contact-website
28
- - url = website_attribute.value =~/^\w+:\/\// ? website_attribute.value : "http://#{website_attribute.value}"
29
- = link_to(website_attribute.to_s, website_attribute.to_s, :rel => "external nofollow")
28
+ = website_attribute.to_s
30
29
 
31
30
  - if resource.address_attributes.any?
32
31
  .contact-addresses
33
32
  %label= Contact.human_attribute_name(:address_attributes)
34
33
  - resource.address_attributes.each do |address_attribute|
35
34
  .contact-address
36
- .address= address_attribute.to_html
35
+ .address
36
+ = address_attribute.to_s
37
37
  .actions
38
- = google_maps_link(address_attribute)
38
+ = address_attribute.link
@@ -1,9 +1,8 @@
1
1
  - tagged_params = Array.wrap(params[:tagged])
2
+
2
3
  %label= t(:tags_name, :scope => :e9_tags)
3
- .tag-holder
4
- - contact_tags.sort.group_by {|tag| tag[0].upcase }.each do |letter, tags|
5
- %ul.tags
6
- - tags.each do |tag|; tag_id = "tagged-#{tag.downcase.dasherize}"
7
- %li.tag
8
- = label_tag(tag_id, tag)
9
- = check_box_tag('tagged[]', tag, tagged_params.member?(tag), :id => tag_id)
4
+ %ul.tags
5
+ - contact_tags.each do |tag|; tag_id = "tagged-#{tag.downcase.dasherize}"
6
+ %li.tag
7
+ = label_tag(tag_id, tag)
8
+ = check_box_tag('tagged[]', tag, tagged_params.member?(tag), :id => tag_id)
@@ -14,11 +14,11 @@
14
14
  - if (tags = resource.tags(:show_all => true)).present?
15
15
  .contact-tags
16
16
  %label #{Tag.model_name.human.pluralize}:
17
- = contact_tag_list(tags)
17
+ = contact_tag_list(tags.sort)
18
18
 
19
19
  .contact-info
20
20
  %label #{Contact.human_attribute_name(:info)}:
21
- = contact_simple_format(resource.info.presence || t(:none))
21
+ = resource.info.present? && k(resource.info) || t(:none)
22
22
 
23
23
  - if company = resource.company
24
24
  .contact-company
@@ -12,23 +12,41 @@
12
12
  = f.label :category
13
13
  = f.select :category, MenuOption.options_for('Deal Category'), :include_blank => 'No Category'
14
14
  .field
15
- = f.label :campaign, :for => 'deal_campaign_select'
16
- = f.collection_select :campaign_id, Campaign.ordered.all, :id, :to_s, {:prompt => true}, :id => 'deal_campaign_select'
17
- .field
18
- = f.label :info
15
+ = help_label(f, :info, :key => :markdown_help, :header => 'Markdown Help')
19
16
  = f.text_area :info
20
17
  .field
21
18
  = f.label :value, nil, :class => :req
22
19
  = f.text_field :value
23
20
  .field.select
24
- = f.label :owner
25
- = f.collection_select :contact_id, Contact.sales_persons.all, :id, :name, :prompt => true
21
+ = f.label :campaign, :for => 'deal_campaign_select'
22
+ = f.collection_select :campaign_id, Campaign.ordered.all, :id, :to_s, {:prompt => true}, :id => 'deal_campaign_select'
23
+ .field.select
24
+ = f.label :status
25
+ = f.select :status, Deal::Status::OPTIONS[1..-1]
26
26
  .field.select
27
27
  = f.label :contacts
28
- %input#contact_autocomplete.list{:type => 'text', 'data-values' => f.object.contact_ids.join(','), 'data-iname' => resource_instance_name, 'data-field' => '[contact_ids]'}
28
+ %input#contact_autocomplete.list{:type => 'text', 'data-values' => resource.contact_ids.join(','), 'data-iname' => resource_instance_name, 'data-field' => '[contact_ids]', :id => 'deal_contacts'}
29
29
  %ul.select
30
30
  - f.object.contacts.each do |contact|
31
31
  %li.ui-state-default
32
32
  %span.content= contact.name
33
33
  %input{:type => :hidden, :name => "contact[contact_ids][]", :value => contact.id}
34
34
  %a{:class => :remove, :title => "Remove", :alt => "Remove"} Remove
35
+ .field.select
36
+ = f.label :owner
37
+ = f.select :contact_id, deal_contacts_array, { :prompt => true }, :id => :deal_owner
38
+ .field
39
+ Created At:
40
+ = l(resource.created_at)
41
+ .field
42
+ Closed At:
43
+ = resource.closed_at ? l(resource.closed_at) : 'n/a'
44
+ .field
45
+ Campaign Cost:
46
+ = resource.campaign.try(:cost) || 0
47
+ .field
48
+ Campaign Deal Count:
49
+ = resource.campaign ? resource.campaign.non_leads.count : 0
50
+ .field
51
+ Cost:
52
+ = deal_cost(resource)
@@ -6,7 +6,7 @@
6
6
  %th= orderable_column_link(:campaign_code)
7
7
  %th= orderable_column_link(:lead_name)
8
8
  %th= orderable_column_link(:lead_email)
9
- %th= orderable_column_link(:options, :custom_info)
9
+ %th= orderable_column_link(:info)
10
10
  %th= t(:actions)
11
11
  %tbody
12
12
  - if collection.empty?
@@ -25,8 +25,8 @@
25
25
  = record.lead_name
26
26
  %td.record-lead-email
27
27
  = record.lead_email
28
- %td.record-custom-info
29
- = record.custom_info
28
+ %td.record-info
29
+ = record.info
30
30
  %td.actions
31
31
  - if record.contacts.present?
32
32
  = link_to_show_resource(record.contacts.first)
@@ -25,10 +25,11 @@
25
25
  = record.category
26
26
  %td.record-owner
27
27
  = record.owner_name
28
- %td.record-value
28
+ %td.record-value.num
29
29
  - dat[:value] << record.value
30
- = record.value
31
- %td.actions
30
+ = record.value.to_money.format
31
+ %td.links
32
+ = link_to_show_resource(record)
32
33
  = link_to_edit_resource(record)
33
34
  = link_to_destroy_resource(record)
34
35
 
@@ -36,8 +37,8 @@
36
37
  %tr{:class => 'record-totals'}
37
38
  %td.record-totals-label{:colspan => 4}
38
39
  #{t(:total)}:
39
- %td.record-totals
40
- = dat[:value].sum
40
+ %td.record-totals.num
41
+ = dat[:value].sum.to_money.format
41
42
  %td
42
43
 
43
44
  - if @controller.should_paginate_index
@@ -8,5 +8,5 @@
8
8
  = f.label :subject
9
9
  = f.text_field :subject
10
10
  .field
11
- = f.label :text_body
11
+ = help_label(f, :text_body)
12
12
  = f.text_area :text_body
@@ -1,5 +1,4 @@
1
- = title e9_t(:select_title)
2
- = form_tag email_templates_path, :id => "email_templates_select", :method => :get do
1
+ = form_tag email_templates_path, :class => "email-template-sel", :method => :get do
3
2
  = hidden_field_tag "contact_id", params[:contact_id]
4
3
  = hidden_field_tag "user_id", params[:user_id]
5
4
  = select_tag "id", options_for_select(collection.map {|e| [e.name, e.id] })
@@ -7,4 +7,4 @@
7
7
  = f.collection_select :sales_person_id, Contact.sales_persons.ordered.all, :id, :name, :prompt => true
8
8
  .field
9
9
  = help_label f, :sales_fee
10
- = f.text_field :sales_fee
10
+ = f.text_field :sales_fee, :value => f.object.sales_fee.to_s
@@ -1,5 +1,5 @@
1
1
  .record-attribute.nested-association
2
- = f.hidden_field :status
2
+ = f.hidden_field :role
3
3
 
4
4
  - if f.object.persisted?
5
5
  = f.hidden_field :id
@@ -28,8 +28,7 @@ en:
28
28
  deals:
29
29
  new_title: Create Deal
30
30
  email_templates:
31
- select_title: Choose a Template
32
- select_submit: Go
31
+ select_submit: Send Email Now
33
32
  leads:
34
33
  index_title: Leads
35
34
  reports:
@@ -12,16 +12,12 @@ en:
12
12
  total: Total
13
13
  totals: Totals
14
14
  view: View
15
+ save: Save
15
16
 
16
17
  e9_crm:
17
18
  add_record_attribute: Add
18
19
  destroy_record_attribute: Remove
19
20
 
20
- # activemodel translation looks to %{i18n_scope}.attributes.%{model_name}.%{attribute}
21
- # then simply attributes.%{attribute}, dropping i18n_scope, e.g "activerecord"
22
- attributes:
23
- markdown_help: "You can style the text in this field using the Markdown syntax as follows:\n\nA line break is created by putting 2 spaces\n\nat the end of the line above and then a return.\n\nA paragraph is created by putting a blank line between the first paragraph and the second paragraph.\n\nThis is the start of the next paragraph.\n\n*italics*\n\n**bold**\n\n***bold and italic text***\n\n* Item in a bulleted list\n\t* A sub-item, indented with 4 spaces\n* Another item in a bulleted list\n\n1. Item in numbered list\n2. Another Item in numbered list\n3. Another Item in numbered list\n\n# First-level heading\n\n## Second-level heading\n\n### Third-level heading\n\n#### Fourth-level heading\n\n> This is a blockquote.\n> Blockquote with hard wrap\n>\n> This is the second paragraph in the blockquote.\n>\n> ## This is an H2 in a blockquote\n\n[This is a link](http://www.google.com \"Google\")\n\n![Image Alt Text](image url \"Image Title\")\n\n--- Horizontal rules are created by 3 hyphens\n\nIf you need to actually render the following characters AND they are NOT rendering, place a backslash before the character like \*italics\* will actually render with the asterisks instead of italicizing the word.\n\n\\\tbackslash\n*\tasterisk\n_\tunderscore\n{}\tcurly braces\n[]\tsquare brackets\n()\tparentheses\n#\thash mark\n+\tplus sign\n-\tminus sign (hyphen)\n.\tdot\n!\texclamation mark"
24
-
25
21
  activerecord:
26
22
  titles:
27
23
  show: 'Show %{model}'
@@ -119,6 +115,14 @@ en:
119
115
  no_leads: 'There are no leads associated with this contact.'
120
116
  company:
121
117
  info: Background Information
118
+ email_template:
119
+ text_body_help: |
120
+ <h3>Variables:</h3>
121
+ <p>You can insert the following to render variable data in the field</p>
122
+ <p>
123
+ &#123;&#123;contact.first_name&#125;&#125;<br/>
124
+ &#123;&#123;recipient.email&#125;&#125;<br/>
125
+ </p>
122
126
  deal:
123
127
  info: Details
124
128
  lead_email: Email
data/config/routes.rb CHANGED
@@ -27,7 +27,7 @@ Rails.application.routes.draw do
27
27
  end
28
28
  end
29
29
 
30
- resources :deals, :except => :show
30
+ resources :deals
31
31
 
32
32
  # contact_emails are generated by email templates, and end up in the sent emails list
33
33
  resources :contact_emails, :except => [:index, :show]
@@ -1,3 +1,3 @@
1
1
  module E9Crm
2
- VERSION = '0.1.16'
2
+ VERSION = '0.1.17'
3
3
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 16
9
- version: 0.1.16
8
+ - 17
9
+ version: 0.1.17
10
10
  platform: ruby
11
11
  authors:
12
12
  - Travis Cox
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-09-07 00:00:00 -04:00
17
+ date: 2011-09-09 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency