e9_crm 0.1.20 → 0.1.21

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.
@@ -13,7 +13,7 @@ class E9Crm::CampaignsController < E9Crm::ResourcesController
13
13
  end
14
14
 
15
15
  has_scope :of_type, :as => :type, :only => :index do |_, scope, value|
16
- scope.of_type("#{type}_campaign".classify)
16
+ scope.of_type("#{value}_campaign".classify)
17
17
  end
18
18
 
19
19
  protected
@@ -3,6 +3,7 @@ class E9Crm::ContactMergesController < E9Crm::BaseController
3
3
 
4
4
  def create
5
5
  @contact_a.attributes = params[:contact]
6
+ @contact_a.avatar = @contact_b.avatar if params[:contact_avatar] == 'b'
6
7
 
7
8
  if @contact_a.merge_and_destroy!(@contact_b)
8
9
  redirect_to @contact_a
@@ -14,6 +14,8 @@ class E9Crm::DealsController < E9Crm::ResourcesController
14
14
 
15
15
  before_filter :prepop_deal_owner_contact, :only => [:new, :edit]
16
16
 
17
+ before_filter :redirect_for_default_from_time, :only => [:leads, :reports]
18
+
17
19
  ##
18
20
  # All Scopes
19
21
  #
@@ -21,10 +23,13 @@ class E9Crm::DealsController < E9Crm::ResourcesController
21
23
  has_scope :until_time, :as => :until, :unless => 'params[:from].present?'
22
24
 
23
25
  has_scope :from_time, :as => :from do |controller, scope, value|
26
+ #is_reports = controller.params[:action] == 'reports'
27
+ is_reports = false
28
+
24
29
  if controller.params[:until]
25
- scope.for_time_range(value, controller.params[:until])
30
+ scope.for_time_range(value, controller.params[:until], :right_join => is_reports)
26
31
  else
27
- scope.from_time(value)
32
+ scope.from_time(value, :right_join => is_reports)
28
33
  end
29
34
  end
30
35
 
@@ -85,6 +90,7 @@ class E9Crm::DealsController < E9Crm::ResourcesController
85
90
  add_breadcrumb!(@edit_title)
86
91
  end
87
92
 
93
+ # TODO the leads table references offer each row, and it is not joined here
88
94
  def collection
89
95
  get_collection_ivar || begin
90
96
  set_collection_ivar(
@@ -132,4 +138,14 @@ class E9Crm::DealsController < E9Crm::ResourcesController
132
138
  def default_ordered_dir
133
139
  'ASC'
134
140
  end
141
+
142
+ def redirect_for_default_from_time
143
+ format = request.format.blank? || request.format == Mime::ALL ? Mime::HTML : request.format
144
+
145
+ if format.html? && params[:from].blank?
146
+ url = params.slice(:controller, :action)
147
+ url.merge!(:from => Date.today.strftime('%Y/%m'))
148
+ redirect_to url and return false
149
+ end
150
+ end
135
151
  end
@@ -1,4 +1,7 @@
1
1
  class E9Crm::LeadsController < ApplicationController
2
+ # NOTE this controller, contrary to sanity, doesn't handle admin/crm/leads,
3
+ # rather it handles only public side lead creation
4
+
2
5
  # TODO these should all be included in e9_base
3
6
  include E9Rails::Helpers::ResourceLinks
4
7
  include E9Rails::Helpers::Title
@@ -9,6 +9,7 @@ class Contact < ActiveRecord::Base
9
9
 
10
10
  before_validation :ensure_user_references
11
11
  before_destroy :ensure_no_associated_deals
12
+ after_destroy :destroy_or_nullify_users
12
13
 
13
14
  ##
14
15
  # Associations
@@ -17,7 +18,7 @@ class Contact < ActiveRecord::Base
17
18
  has_many :owned_deals, :class_name => 'Deal', :dependent => :restrict
18
19
  has_and_belongs_to_many :associated_deals, :class_name => 'Deal'
19
20
 
20
- has_many :users, :inverse_of => :contact, :dependent => :nullify do
21
+ has_many :users, :inverse_of => :contact do
21
22
 
22
23
  ##
23
24
  # Resets the primary user on a contact
@@ -264,33 +265,33 @@ class Contact < ActiveRecord::Base
264
265
  unless errors.delete(:"users.email").blank?
265
266
  users.dup.each_with_index do |user, i|
266
267
  user.errors[:email].each do |error|
267
- #if error.taken? && users.select {|u| u.email == user.email }.length == 1
268
- #existing_user = User.find_by_email(user.email)
269
-
270
- #if contact = existing_user.contact
271
- #args = if new_record?
272
- #[contact, 'new', {:contact => self.attributes}]
273
- #else
274
- #[contact, self]
275
- #end
276
-
277
- #errors.add(:users, :merge_required, {
278
- #:email => user.email,
279
- #:merge_path => new_contact_merge_path(*args)
280
- #})
281
-
282
- #return false
283
- #else
284
- #self.users.delete(user)
285
- #self.users << existing_user
286
- #end
287
- #else
268
+ if error.taken? && users.select {|u| u.email == user.email }.length == 1
269
+ existing_user = User.find_by_email(user.email)
270
+
271
+ if contact = existing_user.contact
272
+ args = if new_record?
273
+ [contact, 'new', {:contact => self.attributes}]
274
+ else
275
+ [contact, self]
276
+ end
277
+
278
+ errors.add(:users, :merge_required, {
279
+ :email => user.email,
280
+ :merge_path => new_contact_merge_path(*args)
281
+ })
282
+
283
+ return false
284
+ else
285
+ self.users.delete(user)
286
+ self.users << existing_user
287
+ end
288
+ else
288
289
  if error.label
289
290
  errors.add(:users, error.label.to_sym, :email => user.email)
290
291
  else
291
292
  errors.add(:users, nil, :message => error, :email => user.email)
292
293
  end
293
- #end
294
+ end
294
295
  end
295
296
  end
296
297
 
@@ -341,6 +342,14 @@ class Contact < ActiveRecord::Base
341
342
  end
342
343
  end
343
344
 
345
+ def destroy_or_nullify_users
346
+ without_access_control do
347
+ users.prospects.destroy_all
348
+ end
349
+
350
+ users.update_all("contact_id = NULL")
351
+ end
352
+
344
353
  class Drop < ::E9::Liquid::Drops::Base
345
354
  source_methods :first_name, :last_name, :name, :email, :title, :company_name
346
355
  end
data/app/models/deal.rb CHANGED
@@ -3,9 +3,10 @@
3
3
  #
4
4
  class Deal < ActiveRecord::Base
5
5
  include E9Rails::ActiveRecord::Initialization
6
- include E9Rails::ActiveRecord::Scopes::Times
7
6
  include E9Rails::ActiveRecord::InheritableOptions
8
7
 
8
+ include E9::ActiveRecord::TimeScopes
9
+
9
10
  self.options_column = false
10
11
 
11
12
  belongs_to :campaign, :inverse_of => :deals
@@ -164,7 +165,10 @@ class Deal < ActiveRecord::Base
164
165
 
165
166
  # this is for leads
166
167
  def transform_options_column
167
- self.info ||= options.to_hash.map {|k, v| "%s:\n%s\n\n" % [k.to_s.titleize, v] }.join
168
+ self.info ||= options.to_hash.map {|k, v|
169
+ v = v.join(', ') if v.is_a?(Array)
170
+ "**%s:**\n%s\n\n" % [k.to_s.titleize, v]
171
+ }.join
168
172
  end
169
173
 
170
174
  def ensure_denormalized_columns
data/app/models/offer.rb CHANGED
@@ -6,8 +6,8 @@ class Offer < Renderable
6
6
  include E9Rails::ActiveRecord::Initialization
7
7
  include E9Rails::ActiveRecord::InheritableOptions
8
8
 
9
- has_many :deals, :inverse_of => :offer
10
- has_many :leads, :class_name => 'Deal', :conditions => ["deals.status = ?", Deal::Status::Lead]
9
+ has_many :deals, :inverse_of => :offer, :dependent => :restrict
10
+ has_many :leads, :class_name => 'Deal', :conditions => ["deals.status = ?", Deal::Status::Lead], :dependent => :restrict
11
11
 
12
12
  validates :conversion_alert_email, :email => { :allow_blank => true }
13
13
 
@@ -2,6 +2,19 @@
2
2
  = hidden_field_tag :contact_a_id, @contact_a.id
3
3
  = hidden_field_tag :contact_b_id, @contact_b.id
4
4
 
5
+ .field
6
+ = f.label :avatar
7
+
8
+ .contact-a-value
9
+ %label{:for => "contact_avatar_a"}
10
+ <img src="#{@contact_a.avatar_url}" alt="Photo for #{@contact_a.name}" />
11
+ = radio_button_tag 'contact_avatar', 'a', :checked => true
12
+
13
+ .contact-b-value
14
+ %label{:for => "contact_avatar_b"}
15
+ <img src="#{@contact_b.avatar_url}" alt="Photo for #{@contact_b.name}" />
16
+ = radio_button_tag 'contact_avatar', 'b'
17
+
5
18
  = render 'field', :column => :first_name, :f => f
6
19
  = render 'field', :column => :last_name, :f => f
7
20
  = render 'field', :column => :company_name, :f => f
@@ -42,6 +42,9 @@
42
42
 
43
43
  - content_for :bottom_javascripts do
44
44
  = javascript_include_tag templates_contacts_path
45
+
45
46
  #merge-dialog{:title => t(:email_taken_title), 'data-id' => resource.try(:id) }
46
- %p= I18n.t(resource.persisted? ? :edit_conflict : :merge_conflict).html_safe
47
+ = t(resource.persisted? ? :edit_conflict : :merge_conflict).html_safe
48
+ #duplicate-dialog{:title => t(:duplicate_email_title), 'data-id' => resource.try(:id) }
49
+ = t(:duplicate_email_warning).html_safe
47
50
 
@@ -1,36 +1,6 @@
1
- .actions
2
- = link_to_new_resource(Contact)
3
- = link_to_collection(Company)
4
-
5
- - if (etag = contact_email_template_select_tag).present?
6
- %fieldset
7
- %legend= e9_t(:email_actions_legend)
8
- = form_tag new_contact_email_path, :method => :get, :id => 'contact_email_form', 'data-empty' => e9_t(:no_contacts_notification), 'data-count' => @contact_ids.length do
9
- = etag
10
- = hidden_field_tag 'uids', @contact_ids.join(','), :id => 'contact_email_uids'
11
- = submit_tag e9_t(:send_email_template), :name => nil
12
-
13
- -# Search filter options
14
- %fieldset
15
- %legend= e9_t(:search_options_legend)
16
- = form_tag(resource_class, :method => :get, :id => 'contact_search_form') do
17
- = label_tag 'contact_search_field', t(:search)
18
- = text_field_tag 'search', params[:search], :id => 'contact_search_field'
19
- = submit_tag t(:go), :name => nil
20
-
21
- = form_tag(resource_class, :method => :get, :class => 'scope-selects') do
22
- = label_tag 'contact_company_select', Company.model_name.human
23
- %select{:name => 'company', :id => 'contact_company_select'}
24
- = company_select_options
25
-
26
- .field#contact_tag_list
27
- %label{:for => 'contact_tag_autocomplete'} Tags
28
- %input#contact_tag_autocomplete.list{:type => 'text', 'data-iname' => 'contact', 'data-field' => '[tagged]', :placeholder => 'Enter a tag...'}
29
- %ul#contact_tag_select.select
30
- - Array.wrap(params[:tagged]).each do |tag|
31
- %li.ui-state-default
32
- %span.content= tag
33
- %a{:class => :remove, :title => "Remove", :alt => "Remove"} Remove
34
-
35
- .actions
36
- = submit_tag t(:clear_all_filters), :name => nil, :id => 'contact_search_clear'
1
+ #sidebar-actions
2
+ = render 'sidebar_actions'
3
+ #sidebar-email-form
4
+ = render 'sidebar_email_form'
5
+ #sidebar-search-form
6
+ = render 'sidebar_search_form'
@@ -0,0 +1,3 @@
1
+ .actions
2
+ = link_to_new_resource(Contact)
3
+ = link_to_collection(Company)
@@ -0,0 +1,7 @@
1
+ - if (etag = contact_email_template_select_tag).present?
2
+ %fieldset
3
+ %legend= e9_t(:email_actions_legend)
4
+ = form_tag new_contact_email_path, :method => :get, :id => 'contact_email_form', 'data-empty' => e9_t(:no_contacts_notification), 'data-count' => @contact_ids.length do
5
+ = etag
6
+ = hidden_field_tag 'uids', @contact_ids.join(','), :id => 'contact_email_uids'
7
+ = submit_tag e9_t(:send_email_template), :name => nil
@@ -0,0 +1,22 @@
1
+ %fieldset
2
+ %legend= e9_t(:search_options_legend)
3
+ .actions
4
+ = submit_tag t(:clear_all_filters), :name => nil, :id => 'contact_search_clear'
5
+
6
+ = form_tag(resource_class, :method => :get, :id => 'contact_search_form') do
7
+ = label_tag 'contact_search_field', t(:search)
8
+ = text_field_tag 'search', params[:search], :id => 'contact_search_field'
9
+
10
+ = form_tag(resource_class, :method => :get, :class => 'scope-selects') do
11
+ = label_tag 'contact_company_select', Company.model_name.human
12
+ %select{:name => 'company', :id => 'contact_company_select'}
13
+ = company_select_options
14
+
15
+ .field#contact_tag_list
16
+ %label{:for => 'contact_tag_autocomplete'} Tags
17
+ %input#contact_tag_autocomplete.list{:type => 'text', 'data-iname' => 'contact', 'data-field' => '[tagged]', :placeholder => 'Enter a tag...'}
18
+ %ul#contact_tag_select.select
19
+ - Array.wrap(params[:tagged]).each do |tag|
20
+ %li.ui-state-default
21
+ %span.content= tag
22
+ %a{:class => :remove, :title => "Remove", :alt => "Remove"} Remove
@@ -1,5 +1,6 @@
1
1
  <% new_title = @index_title || e9_t(:index_title) %>
2
- $('#index-sidebar').html("<%= escape_javascript(render('index_sidebar')) %>");
2
+ //$('#index-sidebar').html("<%= escape_javascript(render('index_sidebar')) %>");
3
+ $('#sidebar-email-form').html("<%= escape_javascript(render('sidebar_email_form')) %>");
3
4
  $('#records_table').html("<%= escape_javascript(render('table', :resources => collection)) %>");
4
5
  document.title = "<%= escape_javascript(meta_title(new_title)) %>";
5
6
  $("h1.title, ul.breadcrumbs li.last").html("<%= escape_javascript(new_title) %>");
@@ -36,33 +36,48 @@
36
36
  %span.contact-actions
37
37
  = link_to_new_resource(Deal, :deal => { :contact_ids => [resource.id] })
38
38
 
39
- %ul
40
- - if (deals = resource.associated_deals.leads(false).limit(5)).blank?
41
- %li= resource_humanize(:no_deals)
42
- - else
43
- - deals.each do |deal|
44
- %li
45
- .contact-deal-status
46
- = deal.status
47
- .contact-deal-name
48
- = link_to deal.name, deal
49
- .contact-deal-value
50
- = deal.value
39
+ %table
40
+ %thead
41
+ %tr
42
+ %th= Deal.human_attribute_name(:status)
43
+ %th= Deal.human_attribute_name(:name)
44
+ %th= Deal.human_attribute_name(:value)
45
+
46
+ %tbody
47
+ - if (deals = resource.associated_deals.leads(false)).blank?
48
+ %tr
49
+ %td{:colspan => 3}= resource_humanize(:no_deals)
50
+ - else
51
+ - deals.each do |deal|
52
+ %tr
53
+ %td.contact-deal-name
54
+ = link_to deal.name, deal
55
+ %td.contact-deal-status
56
+ = deal.status
57
+ %td.contact-deal-value
58
+ = deal.value
51
59
 
52
60
  .contact.leads
53
61
  %h2
54
62
  %span.contact-subheader Leads
55
63
 
56
- %ul
57
- - if (leads = resource.associated_deals.leads.limit(5)).blank?
58
- %li= resource_humanize(:no_leads)
59
- - else
60
- - leads.each do |lead|
61
- %li
62
- .contact-lead-created-at
63
- = l(lead.created_at)
64
- .contact-lead-name
65
- = link_to lead.offer_name, edit_deal_path(lead)
64
+ %table
65
+ %thead
66
+ %tr
67
+ %th= Deal.human_attribute_name(:created_at)
68
+ %th= Deal.human_attribute_name(:offer_name)
69
+
70
+ %tbody
71
+ - if (leads = resource.associated_deals.leads).blank?
72
+ %tr
73
+ %td{:colspan => 2}= resource_humanize(:no_leads)
74
+ - else
75
+ - leads.each do |lead|
76
+ %tr
77
+ %td.contact-lead-name
78
+ = link_to lead.offer_name, edit_deal_path(lead)
79
+ %td.contact-lead-created-at
80
+ = l(lead.created_at)
66
81
 
67
82
  .contact-sidebar
68
83
  = render 'sidebar'
@@ -32,18 +32,27 @@
32
32
  .field.select
33
33
  = f.label :owner
34
34
  = f.select :contact_id, deal_contacts_array, { :prompt => true }, :id => :deal_owner
35
- .field
36
- Created At:
37
- = l(resource.created_at)
38
- .field
39
- Closed At:
40
- = resource.closed_at ? l(resource.closed_at) : 'n/a'
41
- .field
42
- Campaign Cost:
43
- = resource.campaign.try(:cost) || 0
44
- .field
45
- Campaign Deal Count:
46
- = resource.campaign ? resource.campaign.non_leads.count : 0
47
- .field
48
- Cost:
49
- = deal_cost(resource)
35
+
36
+ .debug-fields
37
+ .field.date-picker
38
+ = f.label :created_at
39
+ = f.text_field :created_at, :class => 'date-picker', :value => l(resource.created_at.try(:to_date))
40
+ .field.date-picker
41
+ = f.label :closed_at
42
+ = f.text_field :closed_at, :class => 'date-picker', :value => l(resource.closed_at.try(:to_date))
43
+
44
+ .field
45
+ Created At:
46
+ = l(resource.created_at)
47
+ .field
48
+ Closed At:
49
+ = resource.closed_at ? l(resource.closed_at) : 'n/a'
50
+ .field
51
+ Campaign Cost:
52
+ = resource.campaign.try(:cost) || 0
53
+ .field
54
+ Campaign Deal Count:
55
+ = resource.campaign ? resource.campaign.non_leads.count : 0
56
+ .field
57
+ Cost:
58
+ = deal_cost(resource)
@@ -18,7 +18,7 @@
18
18
  %td.record-created-at
19
19
  = I18n.l(record.created_at)
20
20
  %td.record-offer-name
21
- = record.offer_name
21
+ = record.offer.try(:name) || t(:no_offer_value)
22
22
  %td.record-campaign-code
23
23
  = record.campaign_code
24
24
  %td.record-lead-name
@@ -26,7 +26,7 @@
26
26
  %td.record-lead-email
27
27
  = record.lead_email
28
28
  %td.record-info
29
- = record.info
29
+ = k record.info
30
30
  %td.actions
31
31
  - if record.contacts.present?
32
32
  = link_to 'View Contact', record.contacts.first
@@ -0,0 +1,13 @@
1
+ = title e9_t(:show_title)
2
+
3
+ .deal-header
4
+ .deal-category
5
+ = resource.category
6
+ .deal-value
7
+ = resource.value.format
8
+ .deal-status
9
+ = resource.status
10
+
11
+ .deal-body
12
+ .deal-info
13
+ = k(resource.info)
@@ -4,7 +4,8 @@
4
4
  - if f.object.persisted?
5
5
  = f.hidden_field :id
6
6
  = f.hidden_field :_destroy, :value => 0
7
- .field
7
+ .field.contact-email
8
+ <input type="hidden" value="#{f.object.email}"/>
8
9
  = f.object.email
9
10
  - else
10
11
  .field.contact-email
@@ -1,7 +1,10 @@
1
1
  en:
2
2
  email_taken_title: Oops!
3
+ duplicate_email_title: Oops!
3
4
  edit_conflict: "<p>This email is already attached to another contact and cannot be used.</p><p>Do you want to merge these contacts now?</p><p>Be careful! If you have made extensive edits you may want to save first and come back to merge.</p>"
4
5
  merge_conflict: "<p>This email is already attached to another contact and cannot be used.</p><p>Do you want to edit that contact instead?</p>"
6
+ duplicate_email_warning: "<p>You cannot enter the same email twice.</p>"
7
+ no_offer_value: No Offer
5
8
 
6
9
  actions: Actions
7
10
  clear: Clear
@@ -58,6 +61,10 @@ en:
58
61
  users:
59
62
  taken: "Two or more of the login accounts entered share a duplicate email."
60
63
  invalid: "One or more of the emails you entered is invalid."
64
+ offer:
65
+ attributes:
66
+ deals:
67
+ delete_restricted: "You cannot delete this offer because it has leads and/or deals."
61
68
  contact_email:
62
69
  attributes:
63
70
  contact_ids:
@@ -3,7 +3,7 @@ module E9Crm
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- before_filter :check_for_new_session
6
+ prepend_before_filter :check_for_new_session
7
7
  after_filter :track_page_view
8
8
 
9
9
  prepend_before_filter do
@@ -22,10 +22,13 @@ module E9Crm
22
22
  # only happen once per session.
23
23
  #
24
24
  def check_for_new_session
25
- if request.session_options[:id].blank?
25
+ if request.session_options[:id].blank? && request.get?
26
26
  E9Crm.log("No session found, page view will increment campaign counter cache")
27
27
  @_should_cache = true
28
28
  end
29
+
30
+ E9Crm.log("session id: #{request.session_options[:id]}")
31
+ E9Crm.log("session get?: #{request.get?}")
29
32
  end
30
33
 
31
34
  #
@@ -48,16 +51,18 @@ module E9Crm
48
51
  # has been assigned.
49
52
  #
50
53
  def track_page_view
51
- @_page_view ||= tracking_cookie.page_views.create({
52
- :request_path => request.fullpath,
53
- :user_agent => request.user_agent,
54
- :referer => request.referer,
55
- :remote_ip => request.remote_ip,
56
- :session => request.session_options[:id],
57
- :campaign => tracking_campaign,
58
- :new_visit => session[:new_visit].present?,
59
- :should_cache => !!@_should_cache
60
- })
54
+ if request.get?
55
+ @_page_view ||= tracking_cookie.page_views.create({
56
+ :request_path => request.fullpath,
57
+ :user_agent => request.user_agent,
58
+ :referer => request.referer,
59
+ :remote_ip => request.remote_ip,
60
+ :session => request.session_options[:id],
61
+ :campaign => tracking_campaign,
62
+ :new_visit => session[:new_visit].present?,
63
+ :should_cache => !!@_should_cache
64
+ })
65
+ end
61
66
  end
62
67
  end
63
68
  end
@@ -1,3 +1,3 @@
1
1
  module E9Crm
2
- VERSION = '0.1.20'
2
+ VERSION = '0.1.21'
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: e9_crm
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.20
5
+ version: 0.1.21
6
6
  platform: ruby
7
7
  authors:
8
8
  - Travis Cox
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-09-15 00:00:00 Z
13
+ date: 2011-09-16 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -239,6 +239,9 @@ files:
239
239
  - app/views/e9_crm/contacts/_header.html.haml
240
240
  - app/views/e9_crm/contacts/_index_sidebar.html.haml
241
241
  - app/views/e9_crm/contacts/_sidebar.html.haml
242
+ - app/views/e9_crm/contacts/_sidebar_actions.html.haml
243
+ - app/views/e9_crm/contacts/_sidebar_email_form.html.haml
244
+ - app/views/e9_crm/contacts/_sidebar_search_form.html.haml
242
245
  - app/views/e9_crm/contacts/_table.html.haml
243
246
  - app/views/e9_crm/contacts/_tag_table.html.haml
244
247
  - app/views/e9_crm/contacts/_who.html.haml
@@ -269,6 +272,7 @@ files:
269
272
  - app/views/e9_crm/deals/offer_form.html.haml
270
273
  - app/views/e9_crm/deals/reports.html.haml
271
274
  - app/views/e9_crm/deals/reports.js.erb
275
+ - app/views/e9_crm/deals/show.html.haml
272
276
  - app/views/e9_crm/email_campaigns/_form_inner.html.haml
273
277
  - app/views/e9_crm/email_templates/_form_inner.html.haml
274
278
  - app/views/e9_crm/email_templates/_header.html.haml