alchemy_crm 2.0.5 → 2.1.0a

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 (35) hide show
  1. data/.travis.yml +4 -2
  2. data/Gemfile +3 -3
  3. data/README.md +2 -2
  4. data/alchemy_crm.gemspec +4 -5
  5. data/app/controllers/alchemy_crm/admin/contacts_controller.rb +3 -36
  6. data/app/controllers/alchemy_crm/admin/mailings_controller.rb +1 -1
  7. data/app/helpers/alchemy/pages_helper_extension.rb +2 -2
  8. data/app/helpers/alchemy_crm/mailings_helper.rb +31 -31
  9. data/app/models/alchemy_crm/contact.rb +4 -31
  10. data/app/models/alchemy_crm/contact_group.rb +6 -0
  11. data/app/models/alchemy_crm/contact_group_filter.rb +6 -0
  12. data/app/models/alchemy_crm/delivery.rb +6 -0
  13. data/app/models/alchemy_crm/mailing.rb +9 -0
  14. data/app/models/alchemy_crm/newsletter.rb +7 -0
  15. data/app/models/alchemy_crm/recipient.rb +5 -0
  16. data/app/views/alchemy_crm/admin/contact_groups/index.html.erb +1 -1
  17. data/app/views/alchemy_crm/admin/contacts/index.html.erb +1 -12
  18. data/app/views/alchemy_crm/admin/deliveries/index.html.erb +1 -1
  19. data/app/views/alchemy_crm/admin/mailings/index.html.erb +1 -1
  20. data/app/views/alchemy_crm/admin/newsletters/index.html.erb +1 -1
  21. data/config/locales/alchemy_crm.de.yml +5 -15
  22. data/config/locales/alchemy_crm.en.yml +3 -4
  23. data/config/routes.rb +0 -1
  24. data/lib/alchemy_crm/version.rb +1 -1
  25. data/lib/generators/alchemy_crm/scaffold/files/elements.yml +0 -1
  26. data/lib/generators/alchemy_crm/scaffold/files/page_layouts.yml +0 -1
  27. data/lib/generators/alchemy_crm/scaffold/scaffold_generator.rb +2 -2
  28. data/spec/spec_helper.rb +0 -4
  29. metadata +21 -29
  30. data/app/views/alchemy_crm/admin/contacts/export.html.erb +0 -32
  31. data/app/views/alchemy_crm/admin/contacts/index.csv.erb +0 -17
  32. data/app/views/alchemy_crm/admin/contacts/index.xls.erb +0 -34
  33. data/config/initializers/xls_mime_type.rb +0 -1
  34. data/spec/controllers/alchemy_crm/admin/contacts_controller_spec.rb +0 -110
  35. data/spec/support/factories.rb +0 -21
data/.travis.yml CHANGED
@@ -1,10 +1,12 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 1.8.7
3
4
  - 1.9.2
4
5
  - 1.9.3
6
+ - ree
5
7
  branches:
6
8
  only:
7
- - 2.0-stable
9
+ - master
8
10
  before_script:
9
- - "sh -c 'cd spec/dummy; RAILS_ENV=test bundle exec rake db:setup'"
11
+ - "sh -c 'cd spec/dummy && RAILS_ENV=test bundle exec rake db:schema:load'"
10
12
  script: "bundle exec rspec spec"
data/Gemfile CHANGED
@@ -3,17 +3,17 @@ source 'http://rubygems.org'
3
3
  # Specify your gem's dependencies in alchemy_crm.gemspec
4
4
  gemspec
5
5
 
6
+ gem "alchemy_cms", :github => "magiclabs/alchemy_cms"
7
+
6
8
  group :development do
7
9
  if !ENV["CI"]
8
10
  gem 'guard-spork'
9
- gem 'debugger', :platform => :ruby_19
11
+ gem 'ruby-debug19', :require => 'ruby-debug', :platform => :ruby_19
10
12
  gem 'ruby-debug', :platform => :ruby_18
11
13
  end
12
14
  end
13
15
 
14
16
  group :test do
15
- gem 'sqlite3'
16
17
  gem "database_cleaner"
17
18
  gem 'email_spec'
18
- gem 'factory_girl'
19
19
  end
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Alchemy CRM Module
2
2
  ==================
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/magiclabs/alchemy_crm.png?branch=2.0-stable)](http://travis-ci.org/magiclabs/alchemy_crm)
4
+ [![Build Status](https://secure.travis-ci.org/magiclabs/alchemy_crm.png?branch=master)](http://travis-ci.org/magiclabs/alchemy_crm)
5
5
 
6
6
  Building and sending Newsletters has never been easier!
7
7
 
@@ -22,7 +22,7 @@ http://guides.alchemy-cms.com/getting_started.html
22
22
  2. Put this line into your projects `Gemfile`:
23
23
 
24
24
  # Gemfile
25
- gem "alchemy_crm", :git => 'git://github.com/magiclabs/alchemy_crm', :branch => '2.0-stable'
25
+ gem "alchemy_crm", :git => 'git://github.com/magiclabs/alchemy_crm'
26
26
 
27
27
  Or install it via Rubygems:
28
28
 
data/alchemy_crm.gemspec CHANGED
@@ -9,7 +9,6 @@ Gem::Specification.new do |gem|
9
9
  gem.summary = %q{A fully featured CRM / Newsletter and Mailings Module for Alchemy CMS.}
10
10
  gem.homepage = "http://alchemy-cms.com"
11
11
  gem.license = 'BSD New'
12
- gem.required_ruby_version = '>= 1.9.2'
13
12
 
14
13
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
14
  gem.files = `git ls-files`.split("\n")
@@ -18,15 +17,15 @@ Gem::Specification.new do |gem|
18
17
  gem.require_paths = ["lib"]
19
18
  gem.version = AlchemyCrm::VERSION
20
19
 
21
- gem.add_dependency 'alchemy_cms', ["~> 2.1.12"]
20
+ gem.add_dependency 'alchemy_cms', ["~> 2.2.rc14"]
22
21
  gem.add_dependency 'vcard', ['~> 0.1.1']
23
- gem.add_dependency 'csv_magic', ['~> 0.2.3']
22
+ gem.add_dependency 'csv_magic', ['~> 0.3.0']
24
23
  gem.add_dependency 'delayed_job_active_record', ["~> 0.3.2"]
25
24
  gem.add_dependency 'acts-as-taggable-on', ['~> 2.1.0']
26
25
  gem.add_dependency 'rails3-jquery-autocomplete', ['~> 1.0.4']
27
26
  gem.add_dependency "magic-localized_country_select", ["~> 0.2.0"]
28
27
 
29
- gem.add_development_dependency 'rspec-rails', ["~> 2.8.0"]
30
- gem.add_development_dependency 'sqlite3', ["~> 1.3.5"]
28
+ gem.add_development_dependency(%q<rspec-rails>)
29
+ gem.add_development_dependency(%q<sqlite3>)
31
30
 
32
31
  end
@@ -1,5 +1,4 @@
1
1
  # encoding: UTF-8
2
-
3
2
  module AlchemyCrm
4
3
  module Admin
5
4
  class ContactsController < AlchemyCrm::Admin::BaseController
@@ -26,28 +25,6 @@ module AlchemyCrm
26
25
 
27
26
  before_filter :load_tags, :only => [:new, :edit]
28
27
 
29
- def index
30
- if params[:query].blank?
31
- @contacts = Contact.scoped
32
- else
33
- search_terms = ActiveRecord::Base.sanitize("%#{params[:query]}%")
34
- @contacts = Contact.where(Contact::SEARCHABLE_ATTRIBUTES.map { |attribute|
35
- "#{Contact.table_name}.#{attribute} LIKE #{search_terms}"
36
- }.join(" OR "))
37
- end
38
- respond_to do |format|
39
- format.html {
40
- @contacts = @contacts.page(params[:page] || 1).per(per_page_value_for_screen_size)
41
- }
42
- format.csv {
43
- export_file_as(:csv)
44
- }
45
- format.xls {
46
- export_file_as(:xls)
47
- }
48
- end
49
- end
50
-
51
28
  def new
52
29
  @contact = Contact.new(:country => ::I18n.locale.to_s.upcase)
53
30
  render :layout => false
@@ -70,13 +47,9 @@ module AlchemyCrm
70
47
  end
71
48
 
72
49
  def export
73
- if params[:id].present?
74
- @contact = Contact.find(params[:id])
75
- @contact.to_vcard
76
- send_file("#{Rails.root.to_s}/tmp/#{@contact.fullname}.vcf")
77
- else
78
- render :layout => false
79
- end
50
+ @contact = Contact.find(params[:id])
51
+ @contact.to_vcard
52
+ send_file("#{Rails.root.to_s}/tmp/#{@contact.fullname}.vcf")
80
53
  end
81
54
 
82
55
  def autocomplete_tag_list
@@ -139,12 +112,6 @@ module AlchemyCrm
139
112
  content.starts_with?("BEGIN:VCARD")
140
113
  end
141
114
 
142
- def export_file_as(format)
143
- @columns = AlchemyCrm::Contact::EXPORTABLE_COLUMNS
144
- filename = "#{AlchemyCrm::Contact.model_name.human(:count => @contacts.count)}-#{Time.now.strftime('%Y-%m-%d_%H-%M')}"
145
- send_data render_to_string, :type => format.to_sym, :filename => "#{filename}.#{format}"
146
- end
147
-
148
115
  end
149
116
  end
150
117
  end
@@ -28,7 +28,7 @@ module AlchemyCrm
28
28
  end
29
29
 
30
30
  def update
31
- @mailing.update_attributes(params[:mailing], :as => current_user.role.to_sym)
31
+ @mailing.update_attributes(params[:mailing])
32
32
  render_errors_or_redirect(
33
33
  @mailing,
34
34
  :back,
@@ -6,9 +6,9 @@ Alchemy::PagesHelper.module_eval do
6
6
  }
7
7
  options = default_options.merge(options)
8
8
  if @page.layout_description['newsletter']
9
- render :partial => "alchemy/newsletter_layouts/#{@page.page_layout.downcase}.#{options[:render_format]}.erb"
9
+ render :partial => "alchemy/newsletter_layouts/#{@page.page_layout.downcase}", :format => options[:render_format]
10
10
  else
11
- render :partial => "alchemy/page_layouts/#{@page.page_layout.downcase}.#{options[:render_format]}.erb"
11
+ render :partial => "alchemy/page_layouts/#{@page.page_layout.downcase}", :format => options[:render_format]
12
12
  end
13
13
  rescue ActionView::MissingTemplate
14
14
  warning("PageLayout: '#{@page.page_layout}' not found. Rendering standard page_layout.")
@@ -4,19 +4,19 @@ module AlchemyCrm
4
4
  include Alchemy::PagesHelper
5
5
 
6
6
  # Renders the newsletter layout for +@mailing.page+
7
- #
7
+ #
8
8
  # The +@mailing.page.page_layout+ must have a +newsletter_layout+ prefix.
9
9
  # The partial itself is named without the +newsletter_layout+ prefix.
10
10
  # The partial resists in +/app/views/newsletter_layouts/+
11
- #
11
+ #
12
12
  # === Example:
13
- #
13
+ #
14
14
  # Given a mailing page with a +standard+ layout has partials named +_standard.html.erb+ and +_standard.text.erb+
15
15
  # But the page page_layout attribute is +newsletter_layout_standard+
16
- #
16
+ #
17
17
  def render_newsletter_layout(options={})
18
18
  options = {:format => 'html'}.update(options)
19
- render "alchemy/newsletter_layouts/#{@page.page_layout.downcase.gsub(Regexp.new(Mailing::MAILING_PAGE_LAYOUT_PREFIX), '')}.#{options[:format]}.erb"
19
+ render :partial => "alchemy/newsletter_layouts/#{@page.page_layout.downcase.gsub(Regexp.new(Mailing::MAILING_PAGE_LAYOUT_PREFIX), '')}", :format => options[:format]
20
20
  end
21
21
 
22
22
  # Renders the tracking image that records the receivement of the mailing inside the mail client.
@@ -32,23 +32,23 @@ module AlchemyCrm
32
32
  end
33
33
 
34
34
  # Renders a link to the unsubscribe page.
35
- #
35
+ #
36
36
  # Please notice that you have to create a page with a +newsletter_signout+ page layout and this page has to be public.
37
- #
37
+ #
38
38
  # The text inside the link is translated.
39
- #
39
+ #
40
40
  # === Example translation:
41
- #
41
+ #
42
42
  # de:
43
43
  # alchemy_crm:
44
44
  # unsubscribe: 'abmelden'
45
- #
45
+ #
46
46
  # === Options:
47
- #
47
+ #
48
48
  # html_options [Hash] # Passed to the link. Useful for styling the link with inline css.
49
- #
49
+ #
50
50
  # You can pass an optional block thats gets passed to +link_to+
51
- #
51
+ #
52
52
  def link_to_unsubscribe_page(html_options={})
53
53
  text = ::I18n.t(:unsubscribe, :scope => :alchemy_crm)
54
54
  if block_given?
@@ -77,20 +77,20 @@ module AlchemyCrm
77
77
  end
78
78
 
79
79
  # Renders a notice to open the mailing inside a browser, if it does not displays correctly.
80
- #
80
+ #
81
81
  # The notice and the link inside are translated via I18n.
82
- #
82
+ #
83
83
  # === Example translation:
84
- #
84
+ #
85
85
  # de:
86
86
  # alchemy_crm:
87
87
  # here: 'hier'
88
88
  # read_in_browser_notice: "Falls der Newsletter nicht richtig dargestellt wird, klicken Sie bitte %{link}."
89
- #
89
+ #
90
90
  # === Options:
91
- #
91
+ #
92
92
  # html_options [Hash] # Passed to the link. Useful for styling the link with inline css.
93
- #
93
+ #
94
94
  def read_in_browser_notice(html_options = {})
95
95
  return "" if @recipient.nil?
96
96
  ::I18n.t(
@@ -110,35 +110,35 @@ module AlchemyCrm
110
110
  end
111
111
 
112
112
  # Use this helper to render an image from your server.
113
- #
113
+ #
114
114
  # The notice and the link inside are translated via I18n.
115
- #
115
+ #
116
116
  # === Example:
117
- #
117
+ #
118
118
  # <%= image_from_server_tag('logo.png', :alt => 'Logo', :width => 230, :height => 116, :style => 'outline:none; text-decoration:none; -ms-interpolation-mode: bicubic;') %>
119
119
  # => <img src="http://example.com/assets/logo.png"
120
- #
120
+ #
121
121
  # === Options:
122
- #
122
+ #
123
123
  # html_options [Hash] # Passed to the image_tag helper.
124
- #
124
+ #
125
125
  def image_from_server_tag(image, html_options={})
126
126
  image_tag([current_server, Rails.application.config.assets.prefix, image].join('/'), html_options)
127
127
  end
128
128
 
129
129
  # Renders a link that tracks the reaction of a recipient.
130
- #
130
+ #
131
131
  # After getting tracked the controller redirects to the url passed in.
132
- #
132
+ #
133
133
  # It has the same arguments that the Rails +link_to+ helper has.
134
- #
134
+ #
135
135
  # === Example:
136
- #
136
+ #
137
137
  # <%= tracked_link_tag('read more', :r => 'http://example.com/my-article', :style => 'color: black') %>
138
138
  # => <a href="http://example.com/recipient/s3cr3tSh41/reacts?r=http%3A%2F%2Fexample.com%2Fmy-article" style="color: black">
139
- #
139
+ #
140
140
  # *NOTE:* You can even pass a block like you could for +link_to+ helper from Rails.
141
- #
141
+ #
142
142
  def tracked_link_tag(*args)
143
143
  if block_given?
144
144
  link_to(tracked_url_for(args.first), args.last) do
@@ -5,7 +5,7 @@ module AlchemyCrm
5
5
 
6
6
  acts_as_taggable
7
7
 
8
- ACCESSIBLE_ATTRIBUTES = [
8
+ attr_accessible(
9
9
  :salutation,
10
10
  :title,
11
11
  :firstname,
@@ -22,10 +22,7 @@ module AlchemyCrm
22
22
  :verified,
23
23
  :disabled,
24
24
  :tag_list
25
- ]
26
-
27
- attr_accessible(*ACCESSIBLE_ATTRIBUTES)
28
- attr_accessible(*ACCESSIBLE_ATTRIBUTES, :as => :admin)
25
+ )
29
26
 
30
27
  has_many :subscriptions, :dependent => :destroy
31
28
  has_many :newsletters, :through => :subscriptions, :uniq => true
@@ -47,40 +44,16 @@ module AlchemyCrm
47
44
  scope :enabled, where(:disabled => false)
48
45
  scope :available, verified.enabled
49
46
 
50
- SEARCHABLE_ATTRIBUTES = [
51
- "salutation",
52
- "title",
53
- "firstname",
54
- "lastname",
55
- "company",
56
- "address",
57
- "zip",
58
- "city",
59
- "country",
60
- "email",
61
- "phone",
62
- "mobile",
63
- "cached_tag_list"
64
- ]
65
-
66
- EXPORTABLE_COLUMNS = SEARCHABLE_ATTRIBUTES + [
67
- "verified",
68
- "disabled"
69
- ]
70
-
71
47
  COLUMN_NAMES = [
72
- [::I18n.t(:salutation, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Salutation'), "salutation"],
73
48
  [::I18n.t(:title, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Title'), "title"],
49
+ [::I18n.t(:salutation, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Salutation'), "salutation"],
74
50
  [::I18n.t(:firstname, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Firstname'), "firstname"],
75
51
  [::I18n.t(:lastname, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Lastname'), "lastname"],
76
- [::I18n.t(:company, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Company'), "company"],
77
52
  [::I18n.t(:address, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Address'), "address"],
78
53
  [::I18n.t(:zip, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Zipcode'), "zip"],
79
54
  [::I18n.t(:city, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'City'), "city"],
80
55
  [::I18n.t(:country, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Country'), "country"],
81
- [::I18n.t(:email, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Email'), "email"],
82
- [::I18n.t(:phone, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Phone'), "phone"],
83
- [::I18n.t(:mobile, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Mobile'), "mobile"]
56
+ [::I18n.t(:company, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => 'Company'), "company"]
84
57
  ]
85
58
 
86
59
  INTERPOLATION_NAME_METHODS = %w(fullname name_with_title firstname lastname name email)
@@ -2,6 +2,12 @@
2
2
  module AlchemyCrm
3
3
  class ContactGroup < ActiveRecord::Base
4
4
 
5
+ attr_accessible(
6
+ :name,
7
+ :contact_tag_list,
8
+ :filters_attributes
9
+ )
10
+
5
11
  acts_as_taggable_on :contact_tags
6
12
 
7
13
  has_many :filters, :dependent => :destroy, :class_name => "AlchemyCrm::ContactGroupFilter"
@@ -2,6 +2,12 @@
2
2
  module AlchemyCrm
3
3
  class ContactGroupFilter < ActiveRecord::Base
4
4
 
5
+ attr_accessible(
6
+ :column,
7
+ :operator,
8
+ :value
9
+ )
10
+
5
11
  belongs_to :contact_group
6
12
 
7
13
  OPERATORS = [
@@ -2,6 +2,12 @@
2
2
  module AlchemyCrm
3
3
  class Delivery < ActiveRecord::Base
4
4
 
5
+ attr_accessible(
6
+ :mailing_id,
7
+ :deliver_at,
8
+ :mailing
9
+ )
10
+
5
11
  attr_accessor :chunk_delay
6
12
 
7
13
  belongs_to :mailing
@@ -2,6 +2,15 @@
2
2
  module AlchemyCrm
3
3
  class Mailing < ActiveRecord::Base
4
4
 
5
+ attr_accessible(
6
+ :newsletter_id,
7
+ :name,
8
+ :subject,
9
+ :additional_email_addresses,
10
+ :creator_id,
11
+ :updater_id
12
+ )
13
+
5
14
  MAILING_PAGE_LAYOUT_PREFIX = "newsletter_layout_"
6
15
 
7
16
  belongs_to :page, :dependent => :destroy, :class_name => 'Alchemy::Page'
@@ -2,6 +2,13 @@
2
2
  module AlchemyCrm
3
3
  class Newsletter < ActiveRecord::Base
4
4
 
5
+ attr_accessible(
6
+ :name,
7
+ :layout,
8
+ :public,
9
+ :contact_group_ids
10
+ )
11
+
5
12
  has_and_belongs_to_many :contact_groups, :join_table => 'alchemy_contact_groups_newsletters'
6
13
  has_many :mailings
7
14
  has_many :subscriptions
@@ -1,6 +1,11 @@
1
1
  module AlchemyCrm
2
2
  class Recipient < ActiveRecord::Base
3
3
 
4
+ attr_accessible(
5
+ :email,
6
+ :contact
7
+ )
8
+
4
9
  belongs_to :delivery
5
10
  belongs_to :contact
6
11
  has_many :reactions
@@ -35,7 +35,7 @@
35
35
  <th class="tools" style="width: 40px"></th>
36
36
  </tr>
37
37
  <%- end -%>
38
- <%= render @contact_groups %>
38
+ <%= render :partial => "alchemy_crm/admin/contact_groups/contact_group", :collection => @contact_groups %>
39
39
  </table>
40
40
 
41
41
  <%= render 'alchemy/admin/partials/pagination_links', :items => @contact_groups, :scope => alchemy_crm %>
@@ -29,17 +29,6 @@
29
29
  :size => '400x300'
30
30
  },
31
31
  :if_permitted_to => [:import, :alchemy_crm_admin_contacts]
32
- },
33
- {
34
- :icon => :file_download,
35
- :label => alchemy_crm_t(:export_contacts),
36
- :url => alchemy_crm.export_admin_contacts_path(:query => params[:query]),
37
- :title => alchemy_crm_t(:export_contacts),
38
- :overlay_options => {
39
- :title => alchemy_crm_t(:export_contacts),
40
- :size => '200x150'
41
- },
42
- :if_permitted_to => [:index, :alchemy_crm_admin_contacts]
43
32
  }
44
33
  ]
45
34
  ) %>
@@ -57,6 +46,6 @@
57
46
  <th class="tools" style="width: 60px"></th>
58
47
  </tr>
59
48
  <%- end -%>
60
- <%= render @contacts %>
49
+ <%= render :partial => "alchemy_crm/admin/contacts/contact", :collection => @contacts %>
61
50
  </table>
62
51
  <%= render 'alchemy/admin/partials/pagination_links', :items => @contacts, :scope => alchemy_crm %>
@@ -21,7 +21,7 @@
21
21
  <th class="center"><%= translate_model_attribute(:delivery, :delivered?) %></th>
22
22
  <th class="center"><%= alchemy_crm_t(:statistics) %></th>
23
23
  </tr>
24
- <%= render @deliveries %>
24
+ <%= render :partial => "alchemy_crm/admin/deliveries/delivery", :collection => @deliveries %>
25
25
  </table>
26
26
  </div>
27
27
  </div>
@@ -34,6 +34,6 @@
34
34
  <th class="tools" style="width: 88px"></th>
35
35
  </tr>
36
36
  <%- end -%>
37
- <%= render @mailings %>
37
+ <%= render :partial => "alchemy_crm/admin/mailings/mailing", :collection => @mailings %>
38
38
  </table>
39
39
  <%= render 'alchemy/admin/partials/pagination_links', :items => @mailings %>
@@ -36,7 +36,7 @@
36
36
  <th class="tools" style="width: 44px"></th>
37
37
  </tr>
38
38
  <%- end -%>
39
- <%= render @newsletters %>
39
+ <%= render :partial => "alchemy_crm/admin/newsletters/newsletter", :collection => @newsletters %>
40
40
  </table>
41
41
 
42
42
  <%= render 'alchemy/admin/partials/pagination_links', :items => @newsletters, :scope => alchemy_crm %>
@@ -52,8 +52,6 @@ de:
52
52
  errors_while_importing: 'Es sind Fehler beim Importieren aufgetaucht!'
53
53
  errors_while_importing_contacts: 'Diese Kontakte konnten auf Grund von Fehlern nicht importiert werden:'
54
54
  export_contact: Kontakt exportieren
55
- export_contacts: Kontakte exportieren
56
- 'false': ''
57
55
  fake_contact_attributes:
58
56
  firstname: Kim
59
57
  lastname: Muster
@@ -95,7 +93,6 @@ de:
95
93
  or_replace_it_with_an_existing_tag: 'Oder Sie ersetzen es durch ein vorhandenes Tag'
96
94
  please_check_highlighted_vcards_on_errors: "Bitte überprüfen Sie die markierten Visitenkarten auf Fehler."
97
95
  please_choose: 'Bitte wählen'
98
- 'Please choose format': 'Bitte wählen Sie ein Format'
99
96
  please_confirm: Bitte bestätigen
100
97
  read_in_browser_notice: "Falls der Newsletter nicht richtig dargestellt wird, klicken Sie bitte %{link}."
101
98
  remove_filter: 'Filter entfernen'
@@ -106,7 +103,6 @@ de:
106
103
  salutations:
107
104
  mr: Herr
108
105
  ms: Frau
109
- mrs: Frau
110
106
  sent_mailings: 'Versendete Mailings'
111
107
  seperate_tags_with_comma: 'Mehrere Tags mit Komma trennen.'
112
108
  seperate_emails_with_comma: 'Die E-Mail-Adressen bitte mit Komma trennen.'
@@ -127,21 +123,16 @@ de:
127
123
  signout_form:
128
124
  button_label: abbestellen
129
125
  statistics: Statistiken
130
- tags_get_created_while_tagging_contacts: 'Tags werden automatisch erstellt, sobald Sie es bei einem Kontakt das erste mal verwenden.'
131
126
  this_mailing_has_not_been_delivered_yet: 'Dieses Mailing wurde noch nie versendet'
132
127
  this_list_shows_all_deliveries: Dies ist eine Liste aller Sendungen dieses Mailings
133
128
  total_recipients_count: Empfänger insgesamt
134
- 'true': 'Ja'
129
+ tags_get_created_while_tagging_contacts: 'Tags werden automatisch erstellt, sobald Sie es bei einem Kontakt das erste mal verwenden.'
135
130
  without: ohne
136
131
  you_can_rename_this_tag: "Sie können dieses Tag umbenennen"
137
132
  you_can_open_statistics_for_delivered_mailings: Für bereits versendete Mailings können Statistiken aufgerufen werden
138
133
  you_have_no_contact_groups_yet: 'Sie haben noch keine Empfänger Zielgruppen gebildet'
139
134
 
140
135
  activerecord:
141
- models:
142
- alchemy_crm/contact:
143
- one: Kontakt
144
- other: Kontakte
145
136
  attributes:
146
137
  acts_as_taggable_on/tag:
147
138
  contacts_count: Anzahl der Kontakte
@@ -161,10 +152,10 @@ de:
161
152
  contact_group_contacts_count: Anzahl der Zielgruppenkontakte
162
153
  contact_groups: Zielgruppen
163
154
  alchemy_crm/contact:
164
- salutation: Anrede
155
+ salutation: "Anrede*"
165
156
  title: Titel
166
- firstname: Vorname
167
- lastname: Name
157
+ firstname: "Vorname*"
158
+ lastname: "Name*"
168
159
  company: Firma
169
160
  address: Adresse
170
161
  zip: PLZ
@@ -172,11 +163,10 @@ de:
172
163
  country: Land
173
164
  phone: Telefon
174
165
  mobile: Mobil
175
- email: E-Mail
166
+ email: "E-Mail*"
176
167
  verified: verifiziert
177
168
  disabled: abgemeldet
178
169
  tag_list: Tags
179
- cached_tag_list: Tags
180
170
  alchemy_crm/contact_group:
181
171
  contacts_count: Anzahl der Kontakte
182
172
  errors:
@@ -13,7 +13,6 @@ en:
13
13
  csv_format: 'A comma seperated file (.csv) with a list of contacts'
14
14
  import_format_notice: 'You may import '
15
15
  invalid_file_type: 'Invalid file type: %{mime_type}'
16
- 'false': ''
17
16
  text_interpolation_notice: "Tip: You can insert the contact's name with %{name}."
18
17
  mail_text_interpolation_notice: "Tip: You can insert the contact's name with %{name}. Please insert the confirmation link with %{link}."
19
18
  mandatory_fields: "*Mandatory"
@@ -24,20 +23,20 @@ en:
24
23
  salutations:
25
24
  mr: Mr
26
25
  ms: Ms
27
- mrs: Mrs
28
26
  show_as_plain_text: "Show as plain text"
29
27
  show_statistics: "Statistics for %{name} from %{date}"
30
28
  subscribe_form:
31
29
  button_label: subscribe
32
30
  signout_form:
33
31
  button_label: unsubscribe
34
- 'true': 'Yes'
35
32
 
36
33
  activerecord:
37
34
  attributes:
38
35
  alchemy_crm/contact:
36
+ salutation: "Salutation*"
37
+ firstname: "Firstname*"
38
+ lastname: "Lastname*"
39
39
  tag_list: Tags
40
- cached_tag_list: Tags
41
40
  disabled: unsubscribed
42
41
  errors:
43
42
  models:
data/config/routes.rb CHANGED
@@ -43,7 +43,6 @@ AlchemyCrm::Engine.routes.draw do
43
43
  resources :contacts do
44
44
  collection do
45
45
  get :import
46
- get :export
47
46
  get :autocomplete_tag_list
48
47
  post :import
49
48
  end
@@ -1,3 +1,3 @@
1
1
  module AlchemyCrm
2
- VERSION = "2.0.5"
2
+ VERSION = "2.1.0a"
3
3
  end
@@ -1,4 +1,3 @@
1
-
2
1
  # These elements are added by the Alchemy CRM module.
3
2
 
4
3
  - name: newsletter_signup_form
@@ -1,4 +1,3 @@
1
-
2
1
  # These page layouts are added by the Alchemy CRM module.
3
2
 
4
3
  - name: newsletter_signup
@@ -16,8 +16,8 @@ module AlchemyCrm
16
16
  copy_file "newsletters.text.erb", "#{Rails.root}/app/views/layouts/alchemy/newsletters.text.erb"
17
17
  copy_file "newsletter_layouts.yml", "#{Rails.root}/config/alchemy/newsletter_layouts.yml"
18
18
 
19
- append_file "#{Rails.root}/config/alchemy/elements.yml", File.open(File.expand_path('files/elements.yml', File.dirname(__FILE__))).read
20
- append_file "#{Rails.root}/config/alchemy/page_layouts.yml", File.open(File.expand_path('files/page_layouts.yml', File.dirname(__FILE__))).read
19
+ append_file "#{Rails.root}/config/alchemy/elements.yml", YAML.load_file(File.expand_path('files/elements.yml', File.dirname(__FILE__))).to_yaml.gsub(/^-{3}\s{2}/, "\n# These elements are added by the Alchemy CRM module.\n\n")
20
+ append_file "#{Rails.root}/config/alchemy/page_layouts.yml", YAML.load_file(File.expand_path('files/page_layouts.yml', File.dirname(__FILE__))).to_yaml.gsub(/^^-{3}\s{2}/, "\n# These page layouts are added by the Alchemy CRM module.\n\n")
21
21
 
22
22
  end
23
23
 
data/spec/spec_helper.rb CHANGED
@@ -15,10 +15,6 @@ def configure
15
15
  require "rails/test_help"
16
16
  require "rspec/rails"
17
17
  require "email_spec"
18
- require 'factory_girl'
19
-
20
- require 'authlogic/test_case'
21
- include Authlogic::TestCase
22
18
 
23
19
  ActionMailer::Base.delivery_method = :test
24
20
  ActionMailer::Base.perform_deliveries = true
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_crm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.5
5
- prerelease:
4
+ version: 2.1.0a
5
+ prerelease: 5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thomas von Deyen
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-25 00:00:00.000000000 Z
12
+ date: 2012-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: alchemy_cms
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 2.1.12
21
+ version: 2.2.rc14
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 2.1.12
29
+ version: 2.2.rc14
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: vcard
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 0.2.3
53
+ version: 0.3.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 0.2.3
61
+ version: 0.3.0
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: delayed_job_active_record
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -128,33 +128,33 @@ dependencies:
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
131
- - - ~>
131
+ - - ! '>='
132
132
  - !ruby/object:Gem::Version
133
- version: 2.8.0
133
+ version: '0'
134
134
  type: :development
135
135
  prerelease: false
136
136
  version_requirements: !ruby/object:Gem::Requirement
137
137
  none: false
138
138
  requirements:
139
- - - ~>
139
+ - - ! '>='
140
140
  - !ruby/object:Gem::Version
141
- version: 2.8.0
141
+ version: '0'
142
142
  - !ruby/object:Gem::Dependency
143
143
  name: sqlite3
144
144
  requirement: !ruby/object:Gem::Requirement
145
145
  none: false
146
146
  requirements:
147
- - - ~>
147
+ - - ! '>='
148
148
  - !ruby/object:Gem::Version
149
- version: 1.3.5
149
+ version: '0'
150
150
  type: :development
151
151
  prerelease: false
152
152
  version_requirements: !ruby/object:Gem::Requirement
153
153
  none: false
154
154
  requirements:
155
- - - ~>
155
+ - - ! '>='
156
156
  - !ruby/object:Gem::Version
157
- version: 1.3.5
157
+ version: '0'
158
158
  description: A fully featured CRM / Newsletter and Mailings Module for Alchemy CMS.
159
159
  Building and sending Newsletters has never been easier!
160
160
  email:
@@ -252,12 +252,9 @@ files:
252
252
  - app/views/alchemy_crm/admin/contacts/_form.html.erb
253
253
  - app/views/alchemy_crm/admin/contacts/destroy.rjs
254
254
  - app/views/alchemy_crm/admin/contacts/edit.html.erb
255
- - app/views/alchemy_crm/admin/contacts/export.html.erb
256
255
  - app/views/alchemy_crm/admin/contacts/import.html.erb
257
256
  - app/views/alchemy_crm/admin/contacts/import.js.erb
258
- - app/views/alchemy_crm/admin/contacts/index.csv.erb
259
257
  - app/views/alchemy_crm/admin/contacts/index.html.erb
260
- - app/views/alchemy_crm/admin/contacts/index.xls.erb
261
258
  - app/views/alchemy_crm/admin/contacts/new.html.erb
262
259
  - app/views/alchemy_crm/admin/contacts/vcf_import_result.html.erb
263
260
  - app/views/alchemy_crm/admin/deliveries/_delivery.html.erb
@@ -307,7 +304,6 @@ files:
307
304
  - config/authorization_rules.rb
308
305
  - config/initializers/assets.rb
309
306
  - config/initializers/delayed_job.rb
310
- - config/initializers/xls_mime_type.rb
311
307
  - config/locales/alchemy.de.yml
312
308
  - config/locales/alchemy.en.yml
313
309
  - config/locales/alchemy_crm.de.yml
@@ -363,7 +359,6 @@ files:
363
359
  - lib/tasks/routes.rake
364
360
  - spec/alchemy_mailings_spec.rb
365
361
  - spec/config_spec.rb
366
- - spec/controllers/alchemy_crm/admin/contacts_controller_spec.rb
367
362
  - spec/controllers/alchemy_crm/contacts_controller_spec.rb
368
363
  - spec/controllers/alchemy_crm/mailings_controller_spec.rb
369
364
  - spec/controllers/alchemy_crm/recipients_controller_spec.rb
@@ -407,7 +402,6 @@ files:
407
402
  - spec/models/alchemy_crm/mailing_spec.rb
408
403
  - spec/models/alchemy_crm/newsletter_spec.rb
409
404
  - spec/spec_helper.rb
410
- - spec/support/factories.rb
411
405
  - vendor/assets/javascripts/autocomplete-rails.js
412
406
  homepage: http://alchemy-cms.com
413
407
  licenses:
@@ -421,16 +415,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
421
415
  requirements:
422
416
  - - ! '>='
423
417
  - !ruby/object:Gem::Version
424
- version: 1.9.2
418
+ version: '0'
419
+ segments:
420
+ - 0
421
+ hash: 4506134847143980101
425
422
  required_rubygems_version: !ruby/object:Gem::Requirement
426
423
  none: false
427
424
  requirements:
428
- - - ! '>='
425
+ - - ! '>'
429
426
  - !ruby/object:Gem::Version
430
- version: '0'
431
- segments:
432
- - 0
433
- hash: 1068326471216601821
427
+ version: 1.3.1
434
428
  requirements: []
435
429
  rubyforge_project:
436
430
  rubygems_version: 1.8.24
@@ -440,7 +434,6 @@ summary: A fully featured CRM / Newsletter and Mailings Module for Alchemy CMS.
440
434
  test_files:
441
435
  - spec/alchemy_mailings_spec.rb
442
436
  - spec/config_spec.rb
443
- - spec/controllers/alchemy_crm/admin/contacts_controller_spec.rb
444
437
  - spec/controllers/alchemy_crm/contacts_controller_spec.rb
445
438
  - spec/controllers/alchemy_crm/mailings_controller_spec.rb
446
439
  - spec/controllers/alchemy_crm/recipients_controller_spec.rb
@@ -484,4 +477,3 @@ test_files:
484
477
  - spec/models/alchemy_crm/mailing_spec.rb
485
478
  - spec/models/alchemy_crm/newsletter_spec.rb
486
479
  - spec/spec_helper.rb
487
- - spec/support/factories.rb
@@ -1,32 +0,0 @@
1
- <div class="with_padding">
2
- <p><%= alchemy_crm_t('Please choose format') %></p>
3
- <table id="export_format">
4
- <tr>
5
- <td class="submit">
6
- <%= link_to(
7
- 'Excel',
8
- alchemy_crm.admin_contacts_path(
9
- :format => :xls,
10
- :query => params[:query]
11
- ),
12
- :class => 'button'
13
- ) %>
14
- </td>
15
- </tr>
16
- <tr>
17
- <td class="submit">
18
- <%= link_to(
19
- 'CSV',
20
- alchemy_crm.admin_contacts_path(
21
- :format => :csv,
22
- :query => params[:query]
23
- ),
24
- :class => 'button'
25
- ) %>
26
- </td>
27
- </tr>
28
- </table>
29
- </div>
30
- <script type="text/javascript">
31
- $('.button', '#export_format').on('click', Alchemy.closeCurrentWindow);
32
- </script>
@@ -1,17 +0,0 @@
1
- <% csv = CSV.generate(:col_sep => ";", :row_sep => "\r\n", :force_quotes => true) do |csv| %>
2
- <% csv << @columns.map { |h| AlchemyCrm::Contact.human_attribute_name(h) } %>
3
- <% @contacts.each do |contact| %>
4
- <%
5
- csv << @columns.map do |a|
6
- value = contact.send(a).to_s.strip
7
- if a == 'salutation' && !value.blank?
8
- ::I18n.t(value.to_sym, :scope => 'alchemy_crm.salutations', :default => value)
9
- elsif !value.blank? && a == 'verified' || a == 'disabled'
10
- alchemy_crm_t(value.to_sym)
11
- else
12
- value
13
- end
14
- end %>
15
- <% end %>
16
- <% end %>
17
- <%= raw csv %>
@@ -1,34 +0,0 @@
1
- <?xml version="1.0"?>
2
- <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
3
- xmlns:o="urn:schemas-microsoft-com:office:office"
4
- xmlns:x="urn:schemas-microsoft-com:office:excel"
5
- xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
6
- xmlns:html="http://www.w3.org/TR/REC-html40">
7
- <Worksheet ss:Name="<%= AlchemyCrm::Contact.model_name.human(:count => @contacts.count) -%>">
8
- <Table>
9
- <Row>
10
- <% @columns.each do |col| %>
11
- <Cell>
12
- <Data ss:Type="String"><%= AlchemyCrm::Contact.human_attribute_name(col) %></Data>
13
- </Cell>
14
- <% end %>
15
- </Row>
16
- <% @contacts.each do |contact| %>
17
- <Row>
18
- <% @columns.each do |col| %>
19
- <% value = contact.send(col).to_s.strip %>
20
- <Cell>
21
- <% if col == 'salutation' && !value.blank? %>
22
- <Data ss:Type="String"><%= ::I18n.t(value.to_sym, :scope => 'alchemy_crm.salutations', :default => value) %></Data>
23
- <% elsif !value.blank? && (col == 'verified' || col == 'disabled') %>
24
- <Data ss:Type="String"><%= alchemy_crm_t(value) %></Data>
25
- <% else %>
26
- <Data ss:Type="String"><%= value %></Data>
27
- <% end %>
28
- </Cell>
29
- <% end %>
30
- </Row>
31
- <% end %>
32
- </Table>
33
- </Worksheet>
34
- </Workbook>
@@ -1 +0,0 @@
1
- Mime::Type.register "application/xls", :xls
@@ -1,110 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module AlchemyCrm
4
- describe Admin::ContactsController do
5
-
6
- render_views
7
-
8
- describe 'exporting contacts' do
9
-
10
- let(:contact) { FactoryGirl.create(:contact) }
11
- let(:jane) { FactoryGirl.create(:contact, :salutation => 'ms', :firstname => 'Jane', :email => 'jane@doe.com') }
12
-
13
- before do
14
- activate_authlogic
15
- Alchemy::UserSession.create FactoryGirl.create(:admin_user)
16
- contact
17
- end
18
-
19
- context "as csv file" do
20
-
21
- it "should return contacts as attached csv file" do
22
- get :index, :format => 'csv', :use_route => :alchemy_crm
23
- response.content_type.should == 'text/csv'
24
- response.headers['Content-Disposition'].should match /attachment/
25
- end
26
-
27
- it "file should contain translated headers" do
28
- get :index, :format => 'csv', :use_route => :alchemy_crm
29
- response.body.should match /Firstname/
30
- end
31
-
32
- it "file should contain translated salutation" do
33
- get :index, :format => 'csv', :use_route => :alchemy_crm
34
- response.body.should match /Mr/
35
- end
36
-
37
- it "contacts shouldn't be paginated" do
38
- jane
39
- controller.stub!(:per_page_value_for_screen_size).and_return(1)
40
- get :index, :format => 'csv', :use_route => :alchemy_crm
41
- response.body.should match /Jane/
42
- end
43
-
44
- it "filename should contain timestamp" do
45
- get :index, :format => 'csv', :use_route => :alchemy_crm
46
- response.headers['Content-Disposition'].should match /[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}/
47
- end
48
-
49
- context "with search query" do
50
-
51
- before { jane }
52
-
53
- it "should return only the matched contacts" do
54
- get :index, :format => 'csv', :use_route => :alchemy_crm, :query => 'Jon'
55
- response.body.should match /Jon/
56
- response.body.should_not match /Jane/
57
- end
58
-
59
- end
60
-
61
- end
62
-
63
- context "as xls file" do
64
-
65
- it "should return contacts as attached xls file" do
66
- get :index, :format => 'xls', :use_route => :alchemy_crm
67
- response.content_type.should == 'application/xls'
68
- response.headers['Content-Disposition'].should match /attachment/
69
- end
70
-
71
- it "file should contain translated headers" do
72
- get :index, :format => 'xls', :use_route => :alchemy_crm
73
- response.body.should match /Firstname/
74
- end
75
-
76
- it "file should contain translated salutation" do
77
- get :index, :format => 'xls', :use_route => :alchemy_crm
78
- response.body.should match /Mr/
79
- end
80
-
81
- it "contacts shouldn't be paginated" do
82
- jane
83
- controller.stub!(:per_page_value_for_screen_size).and_return(1)
84
- get :index, :format => 'xls', :use_route => :alchemy_crm
85
- response.body.should match /Jane/
86
- end
87
-
88
- it "filename should contain timestamp" do
89
- get :index, :format => 'xls', :use_route => :alchemy_crm
90
- response.headers['Content-Disposition'].should match /[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}/
91
- end
92
-
93
- context "with search query" do
94
-
95
- before { jane }
96
-
97
- it "should return only the matched contacts" do
98
- get :index, :format => 'xls', :use_route => :alchemy_crm, :query => 'Jon'
99
- response.body.should match /Jon/
100
- response.body.should_not match /Jane/
101
- end
102
-
103
- end
104
-
105
- end
106
-
107
- end
108
-
109
- end
110
- end
@@ -1,21 +0,0 @@
1
- FactoryGirl.define do
2
-
3
- factory :user, :class => 'Alchemy::User' do
4
- email 'john@doe.com'
5
- login "jdoe"
6
- password 's3cr3t'
7
- password_confirmation 's3cr3t'
8
-
9
- factory :admin_user do
10
- role "admin"
11
- end
12
- end
13
-
14
- factory :contact, :class => 'AlchemyCrm::Contact' do
15
- salutation 'mr'
16
- firstname 'Jon'
17
- lastname 'Doe'
18
- email 'jon@doe.com'
19
- end
20
-
21
- end