alchemy_crm 2.0.4.1 → 2.0.5

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.
@@ -1,12 +1,10 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.8.7
4
3
  - 1.9.2
5
4
  - 1.9.3
6
- - ree
7
5
  branches:
8
6
  only:
9
7
  - 2.0-stable
10
8
  before_script:
11
- - "sh -c 'cd spec/dummy && RAILS_ENV=test bundle exec rake db:schema:load'"
9
+ - "sh -c 'cd spec/dummy; RAILS_ENV=test bundle exec rake db:setup'"
12
10
  script: "bundle exec rspec spec"
@@ -9,6 +9,7 @@ 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'
12
13
 
13
14
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
15
  gem.files = `git ls-files`.split("\n")
@@ -19,7 +20,7 @@ Gem::Specification.new do |gem|
19
20
 
20
21
  gem.add_dependency 'alchemy_cms', ["~> 2.1.12"]
21
22
  gem.add_dependency 'vcard', ['~> 0.1.1']
22
- gem.add_dependency 'csv_magic', ['~> 0.2.2']
23
+ gem.add_dependency 'csv_magic', ['~> 0.2.3']
23
24
  gem.add_dependency 'delayed_job_active_record', ["~> 0.3.2"]
24
25
  gem.add_dependency 'acts-as-taggable-on', ['~> 2.1.0']
25
26
  gem.add_dependency 'rails3-jquery-autocomplete', ['~> 1.0.4']
@@ -40,8 +40,10 @@ module AlchemyCrm
40
40
  @contacts = @contacts.page(params[:page] || 1).per(per_page_value_for_screen_size)
41
41
  }
42
42
  format.csv {
43
- @columns = AlchemyCrm::Contact::EXPORTABLE_COLUMNS
44
- send_data render_to_string, :content_type => 'text/csv', :disposition => 'attachment', :filename => "contacts-#{Time.now.strftime('%Y-%m-%d_%H-%M')}.csv"
43
+ export_file_as(:csv)
44
+ }
45
+ format.xls {
46
+ export_file_as(:xls)
45
47
  }
46
48
  end
47
49
  end
@@ -68,9 +70,13 @@ module AlchemyCrm
68
70
  end
69
71
 
70
72
  def export
71
- @contact = Contact.find(params[:id])
72
- @contact.to_vcard
73
- send_file("#{Rails.root.to_s}/tmp/#{@contact.fullname}.vcf")
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
74
80
  end
75
81
 
76
82
  def autocomplete_tag_list
@@ -133,6 +139,12 @@ module AlchemyCrm
133
139
  content.starts_with?("BEGIN:VCARD")
134
140
  end
135
141
 
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
+
136
148
  end
137
149
  end
138
150
  end
@@ -0,0 +1,32 @@
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,7 +1,17 @@
1
- <%- csv = CSV.generate(:col_sep => ";", :row_sep => "\r\n", :force_quotes => true) do |csv| -%>
2
- <%- csv << @columns.map { |h| ::I18n.t(h, :scope => 'activerecord.attributes.alchemy_crm/contact', :default => h.humanize) } -%>
3
- <%- @contacts.each do |contact| -%>
4
- <%- csv << @columns.map { |a| value = contact.send(a).to_s.strip; a == 'salutation' && !value.blank? ? ::I18n.t(value.to_sym, :scope => 'alchemy_crm.salutations', :default => value) : value } -%>
5
- <%- end -%>
6
- <%- end -%>
7
- <%=raw csv %>
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 %>
@@ -33,10 +33,12 @@
33
33
  {
34
34
  :icon => :file_download,
35
35
  :label => alchemy_crm_t(:export_contacts),
36
- :url => alchemy_crm.admin_contacts_path(:format => :csv, :query => params[:query]),
36
+ :url => alchemy_crm.export_admin_contacts_path(:query => params[:query]),
37
37
  :title => alchemy_crm_t(:export_contacts),
38
- :overlay => false,
39
- :loading_indicator => false,
38
+ :overlay_options => {
39
+ :title => alchemy_crm_t(:export_contacts),
40
+ :size => '200x150'
41
+ },
40
42
  :if_permitted_to => [:index, :alchemy_crm_admin_contacts]
41
43
  }
42
44
  ]
@@ -0,0 +1,34 @@
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>
@@ -0,0 +1 @@
1
+ Mime::Type.register "application/xls", :xls
@@ -53,6 +53,7 @@ de:
53
53
  errors_while_importing_contacts: 'Diese Kontakte konnten auf Grund von Fehlern nicht importiert werden:'
54
54
  export_contact: Kontakt exportieren
55
55
  export_contacts: Kontakte exportieren
56
+ 'false': ''
56
57
  fake_contact_attributes:
57
58
  firstname: Kim
58
59
  lastname: Muster
@@ -94,6 +95,7 @@ de:
94
95
  or_replace_it_with_an_existing_tag: 'Oder Sie ersetzen es durch ein vorhandenes Tag'
95
96
  please_check_highlighted_vcards_on_errors: "Bitte überprüfen Sie die markierten Visitenkarten auf Fehler."
96
97
  please_choose: 'Bitte wählen'
98
+ 'Please choose format': 'Bitte wählen Sie ein Format'
97
99
  please_confirm: Bitte bestätigen
98
100
  read_in_browser_notice: "Falls der Newsletter nicht richtig dargestellt wird, klicken Sie bitte %{link}."
99
101
  remove_filter: 'Filter entfernen'
@@ -125,16 +127,21 @@ de:
125
127
  signout_form:
126
128
  button_label: abbestellen
127
129
  statistics: Statistiken
130
+ tags_get_created_while_tagging_contacts: 'Tags werden automatisch erstellt, sobald Sie es bei einem Kontakt das erste mal verwenden.'
128
131
  this_mailing_has_not_been_delivered_yet: 'Dieses Mailing wurde noch nie versendet'
129
132
  this_list_shows_all_deliveries: Dies ist eine Liste aller Sendungen dieses Mailings
130
133
  total_recipients_count: Empfänger insgesamt
131
- tags_get_created_while_tagging_contacts: 'Tags werden automatisch erstellt, sobald Sie es bei einem Kontakt das erste mal verwenden.'
134
+ 'true': 'Ja'
132
135
  without: ohne
133
136
  you_can_rename_this_tag: "Sie können dieses Tag umbenennen"
134
137
  you_can_open_statistics_for_delivered_mailings: Für bereits versendete Mailings können Statistiken aufgerufen werden
135
138
  you_have_no_contact_groups_yet: 'Sie haben noch keine Empfänger Zielgruppen gebildet'
136
139
 
137
140
  activerecord:
141
+ models:
142
+ alchemy_crm/contact:
143
+ one: Kontakt
144
+ other: Kontakte
138
145
  attributes:
139
146
  acts_as_taggable_on/tag:
140
147
  contacts_count: Anzahl der Kontakte
@@ -13,6 +13,7 @@ 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': ''
16
17
  text_interpolation_notice: "Tip: You can insert the contact's name with %{name}."
17
18
  mail_text_interpolation_notice: "Tip: You can insert the contact's name with %{name}. Please insert the confirmation link with %{link}."
18
19
  mandatory_fields: "*Mandatory"
@@ -30,6 +31,7 @@ en:
30
31
  button_label: subscribe
31
32
  signout_form:
32
33
  button_label: unsubscribe
34
+ 'true': 'Yes'
33
35
 
34
36
  activerecord:
35
37
  attributes:
@@ -43,6 +43,7 @@ AlchemyCrm::Engine.routes.draw do
43
43
  resources :contacts do
44
44
  collection do
45
45
  get :import
46
+ get :export
46
47
  get :autocomplete_tag_list
47
48
  post :import
48
49
  end
@@ -1,3 +1,3 @@
1
1
  module AlchemyCrm
2
- VERSION = "2.0.4.1"
2
+ VERSION = "2.0.5"
3
3
  end
@@ -5,7 +5,7 @@ module AlchemyCrm
5
5
 
6
6
  render_views
7
7
 
8
- describe 'csv rendering' do
8
+ describe 'exporting contacts' do
9
9
 
10
10
  let(:contact) { FactoryGirl.create(:contact) }
11
11
  let(:jane) { FactoryGirl.create(:contact, :salutation => 'ms', :firstname => 'Jane', :email => 'jane@doe.com') }
@@ -16,42 +16,90 @@ module AlchemyCrm
16
16
  contact
17
17
  end
18
18
 
19
- it "should return contacts as attached csv file" do
20
- get :index, :format => 'csv', :use_route => :alchemy_crm
21
- response.content_type.should == 'text/csv'
22
- response.headers['Content-Disposition'].should match /attachment/
23
- end
19
+ context "as csv file" do
24
20
 
25
- it "csv file should contain translated headers" do
26
- get :index, :format => 'csv', :use_route => :alchemy_crm
27
- response.body.should match /Firstname/
28
- end
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
29
26
 
30
- it "csv file should contain translated salutation" do
31
- get :index, :format => 'csv', :use_route => :alchemy_crm
32
- response.body.should match /Mr/
33
- end
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
34
31
 
35
- it "contacts shouldn't be paginated" do
36
- jane
37
- controller.stub!(:per_page_value_for_screen_size).and_return(1)
38
- get :index, :format => 'csv', :use_route => :alchemy_crm
39
- response.body.should match /Jane/
40
- end
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
41
60
 
42
- it "filename should contain timestamp" do
43
- get :index, :format => 'csv', :use_route => :alchemy_crm
44
- response.headers['Content-Disposition'].should match /[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}/
45
61
  end
46
62
 
47
- context "with search query" do
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 }
48
96
 
49
- before { jane }
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
50
102
 
51
- it "should return only the matched contacts" do
52
- get :index, :format => 'csv', :use_route => :alchemy_crm, :query => 'Jon'
53
- response.body.should match /Jon/
54
- response.body.should_not match /Jane/
55
103
  end
56
104
 
57
105
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_crm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4.1
4
+ version: 2.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-14 00:00:00.000000000 Z
12
+ date: 2012-09-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: alchemy_cms
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 0.2.2
53
+ version: 0.2.3
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.2
61
+ version: 0.2.3
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: delayed_job_active_record
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -252,10 +252,12 @@ 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
255
256
  - app/views/alchemy_crm/admin/contacts/import.html.erb
256
257
  - app/views/alchemy_crm/admin/contacts/import.js.erb
257
258
  - app/views/alchemy_crm/admin/contacts/index.csv.erb
258
259
  - app/views/alchemy_crm/admin/contacts/index.html.erb
260
+ - app/views/alchemy_crm/admin/contacts/index.xls.erb
259
261
  - app/views/alchemy_crm/admin/contacts/new.html.erb
260
262
  - app/views/alchemy_crm/admin/contacts/vcf_import_result.html.erb
261
263
  - app/views/alchemy_crm/admin/deliveries/_delivery.html.erb
@@ -305,6 +307,7 @@ files:
305
307
  - config/authorization_rules.rb
306
308
  - config/initializers/assets.rb
307
309
  - config/initializers/delayed_job.rb
310
+ - config/initializers/xls_mime_type.rb
308
311
  - config/locales/alchemy.de.yml
309
312
  - config/locales/alchemy.en.yml
310
313
  - config/locales/alchemy_crm.de.yml
@@ -418,10 +421,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
418
421
  requirements:
419
422
  - - ! '>='
420
423
  - !ruby/object:Gem::Version
421
- version: '0'
422
- segments:
423
- - 0
424
- hash: -3633263896018909153
424
+ version: 1.9.2
425
425
  required_rubygems_version: !ruby/object:Gem::Requirement
426
426
  none: false
427
427
  requirements:
@@ -430,7 +430,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
430
430
  version: '0'
431
431
  segments:
432
432
  - 0
433
- hash: -3633263896018909153
433
+ hash: 1068326471216601821
434
434
  requirements: []
435
435
  rubyforge_project:
436
436
  rubygems_version: 1.8.24