e9_crm 0.1.16 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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