alchemy_crm 2.0.0

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 (240) hide show
  1. data/.gitignore +22 -0
  2. data/.travis.yml +12 -0
  3. data/Gemfile +21 -0
  4. data/Guardfile +13 -0
  5. data/LICENSE +24 -0
  6. data/README.md +82 -0
  7. data/Rakefile +27 -0
  8. data/alchemy_crm.gemspec +31 -0
  9. data/app/assets/images/.DS_Store +0 -0
  10. data/app/assets/images/alchemy_crm/.DS_Store +0 -0
  11. data/app/assets/images/alchemy_crm/contact-icons.png +0 -0
  12. data/app/assets/images/alchemy_crm/fill_content.gif +0 -0
  13. data/app/assets/images/alchemy_crm/group-icons.png +0 -0
  14. data/app/assets/images/alchemy_crm/mailing-icons.png +0 -0
  15. data/app/assets/images/alchemy_crm/module_icon.png +0 -0
  16. data/app/assets/images/alchemy_crm/newsletter-icons.png +0 -0
  17. data/app/assets/images/alchemy_crm/statistic.png +0 -0
  18. data/app/assets/images/alchemy_crm/tag-icons.png +0 -0
  19. data/app/assets/javascripts/alchemy_crm/alchemy_crm.base.js +65 -0
  20. data/app/assets/javascripts/alchemy_crm/scripts.js +2 -0
  21. data/app/assets/stylesheets/alchemy_crm/base.css.scss +473 -0
  22. data/app/assets/stylesheets/alchemy_crm/styles.css +3 -0
  23. data/app/controllers/alchemy_crm/admin/base_controller.rb +7 -0
  24. data/app/controllers/alchemy_crm/admin/contact_groups_controller.rb +23 -0
  25. data/app/controllers/alchemy_crm/admin/contacts_controller.rb +112 -0
  26. data/app/controllers/alchemy_crm/admin/deliveries_controller.rb +80 -0
  27. data/app/controllers/alchemy_crm/admin/elements_controller_extension.rb +32 -0
  28. data/app/controllers/alchemy_crm/admin/mailings_controller.rb +47 -0
  29. data/app/controllers/alchemy_crm/admin/newsletters_controller.rb +24 -0
  30. data/app/controllers/alchemy_crm/admin/tags_controller.rb +62 -0
  31. data/app/controllers/alchemy_crm/base_controller.rb +5 -0
  32. data/app/controllers/alchemy_crm/contacts_controller.rb +103 -0
  33. data/app/controllers/alchemy_crm/mailings_controller.rb +20 -0
  34. data/app/controllers/alchemy_crm/recipients_controller.rb +35 -0
  35. data/app/controllers/alchemy_crm/subscriptions_controller.rb +57 -0
  36. data/app/helpers/alchemy/pages_helper_extension.rb +18 -0
  37. data/app/helpers/alchemy_crm/admin/base_helper.rb +12 -0
  38. data/app/helpers/alchemy_crm/mailings_helper.rb +190 -0
  39. data/app/mailers/alchemy_crm/bounce_receiver.rb +13 -0
  40. data/app/mailers/alchemy_crm/contacts_mailer.rb +26 -0
  41. data/app/mailers/alchemy_crm/mailings_mailer.rb +48 -0
  42. data/app/mailers/alchemy_crm/subscriptions_mailer.rb +17 -0
  43. data/app/models/alchemy/essence_element_teaser.rb +19 -0
  44. data/app/models/alchemy_crm/contact.rb +264 -0
  45. data/app/models/alchemy_crm/contact_group.rb +26 -0
  46. data/app/models/alchemy_crm/contact_group_filter.rb +26 -0
  47. data/app/models/alchemy_crm/delivery.rb +57 -0
  48. data/app/models/alchemy_crm/element_extension.rb +28 -0
  49. data/app/models/alchemy_crm/mailing.rb +93 -0
  50. data/app/models/alchemy_crm/newsletter.rb +48 -0
  51. data/app/models/alchemy_crm/reaction.rb +9 -0
  52. data/app/models/alchemy_crm/recipient.rb +48 -0
  53. data/app/models/alchemy_crm/subscription.rb +8 -0
  54. data/app/views/alchemy/admin/elements/_view_not_found.text.erb +0 -0
  55. data/app/views/alchemy/admin/elements/fill.js.erb +13 -0
  56. data/app/views/alchemy/admin/elements/link.js.erb +1 -0
  57. data/app/views/alchemy/elements/_newsletter_article_editor.html.erb +4 -0
  58. data/app/views/alchemy/elements/_newsletter_article_view.html.erb +16 -0
  59. data/app/views/alchemy/elements/_newsletter_article_view.text.erb +5 -0
  60. data/app/views/alchemy/elements/_newsletter_greeting_editor.html.erb +3 -0
  61. data/app/views/alchemy/elements/_newsletter_greeting_view.html.erb +11 -0
  62. data/app/views/alchemy/elements/_newsletter_greeting_view.text.erb +6 -0
  63. data/app/views/alchemy/elements/_newsletter_signout_form_editor.html.erb +3 -0
  64. data/app/views/alchemy/elements/_newsletter_signout_form_view.html.erb +32 -0
  65. data/app/views/alchemy/elements/_newsletter_signout_mail_editor.html.erb +4 -0
  66. data/app/views/alchemy/elements/_newsletter_signup_form_editor.html.erb +6 -0
  67. data/app/views/alchemy/elements/_newsletter_signup_form_view.html.erb +78 -0
  68. data/app/views/alchemy/elements/_newsletter_signup_mail_editor.html.erb +4 -0
  69. data/app/views/alchemy/essences/_essence_date_view.text.erb +3 -0
  70. data/app/views/alchemy/essences/_essence_element_teaser_editor.html.erb +31 -0
  71. data/app/views/alchemy/essences/_essence_element_teaser_view.html.erb +1 -0
  72. data/app/views/alchemy/essences/_essence_element_teaser_view.text.erb +3 -0
  73. data/app/views/alchemy/essences/_essence_richtext_view.text.erb +1 -0
  74. data/app/views/alchemy/essences/_essence_text_view.text.erb +1 -0
  75. data/app/views/alchemy/newsletter_layouts/_standard.html.erb +39 -0
  76. data/app/views/alchemy/newsletter_layouts/_standard.text.erb +5 -0
  77. data/app/views/alchemy_crm/admin/contact_groups/_contact_group.html.erb +32 -0
  78. data/app/views/alchemy_crm/admin/contact_groups/_filter.html.erb +30 -0
  79. data/app/views/alchemy_crm/admin/contact_groups/_form.html.erb +47 -0
  80. data/app/views/alchemy_crm/admin/contact_groups/_tag.html.erb +6 -0
  81. data/app/views/alchemy_crm/admin/contact_groups/add_filter.js.erb +9 -0
  82. data/app/views/alchemy_crm/admin/contact_groups/destroy.rjs +1 -0
  83. data/app/views/alchemy_crm/admin/contact_groups/edit.html.erb +1 -0
  84. data/app/views/alchemy_crm/admin/contact_groups/index.html.erb +41 -0
  85. data/app/views/alchemy_crm/admin/contact_groups/new.html.erb +1 -0
  86. data/app/views/alchemy_crm/admin/contacts/_contact.html.erb +44 -0
  87. data/app/views/alchemy_crm/admin/contacts/_form.html.erb +86 -0
  88. data/app/views/alchemy_crm/admin/contacts/destroy.rjs +1 -0
  89. data/app/views/alchemy_crm/admin/contacts/edit.html.erb +1 -0
  90. data/app/views/alchemy_crm/admin/contacts/import.html.erb +33 -0
  91. data/app/views/alchemy_crm/admin/contacts/import.js.erb +2 -0
  92. data/app/views/alchemy_crm/admin/contacts/index.html.erb +51 -0
  93. data/app/views/alchemy_crm/admin/contacts/new.html.erb +1 -0
  94. data/app/views/alchemy_crm/admin/contacts/vcf_import_result.html.erb +49 -0
  95. data/app/views/alchemy_crm/admin/deliveries/_delivery.html.erb +41 -0
  96. data/app/views/alchemy_crm/admin/deliveries/_form.html.erb +65 -0
  97. data/app/views/alchemy_crm/admin/deliveries/_recipient.html.erb +40 -0
  98. data/app/views/alchemy_crm/admin/deliveries/edit.html.erb +1 -0
  99. data/app/views/alchemy_crm/admin/deliveries/index.html.erb +29 -0
  100. data/app/views/alchemy_crm/admin/deliveries/new.html.erb +1 -0
  101. data/app/views/alchemy_crm/admin/deliveries/show.html.erb +66 -0
  102. data/app/views/alchemy_crm/admin/elements/link.rjs +4 -0
  103. data/app/views/alchemy_crm/admin/elements/teasables.html.erb +57 -0
  104. data/app/views/alchemy_crm/admin/mailings/_form.html.erb +43 -0
  105. data/app/views/alchemy_crm/admin/mailings/_mailing.html.erb +75 -0
  106. data/app/views/alchemy_crm/admin/mailings/edit.html.erb +1 -0
  107. data/app/views/alchemy_crm/admin/mailings/edit_content.html.erb +194 -0
  108. data/app/views/alchemy_crm/admin/mailings/import_result.html.erb +37 -0
  109. data/app/views/alchemy_crm/admin/mailings/index.html.erb +39 -0
  110. data/app/views/alchemy_crm/admin/mailings/new.html.erb +1 -0
  111. data/app/views/alchemy_crm/admin/mailings/show.html.erb +1 -0
  112. data/app/views/alchemy_crm/admin/mailings/show.text.erb +1 -0
  113. data/app/views/alchemy_crm/admin/newsletters/_form.html.erb +54 -0
  114. data/app/views/alchemy_crm/admin/newsletters/_newsletter.html.erb +42 -0
  115. data/app/views/alchemy_crm/admin/newsletters/_tag_with_radiobutton.html.erb +7 -0
  116. data/app/views/alchemy_crm/admin/newsletters/destroy.rjs +1 -0
  117. data/app/views/alchemy_crm/admin/newsletters/edit.html.erb +1 -0
  118. data/app/views/alchemy_crm/admin/newsletters/index.html.erb +42 -0
  119. data/app/views/alchemy_crm/admin/newsletters/new.html.erb +10 -0
  120. data/app/views/alchemy_crm/admin/tags/_radio_tag.html.erb +6 -0
  121. data/app/views/alchemy_crm/admin/tags/_tag.html.erb +32 -0
  122. data/app/views/alchemy_crm/admin/tags/edit.html.erb +40 -0
  123. data/app/views/alchemy_crm/admin/tags/index.html.erb +35 -0
  124. data/app/views/alchemy_crm/admin/tags/new.html.erb +16 -0
  125. data/app/views/alchemy_crm/contacts_mailer/signout_mail.html.erb +8 -0
  126. data/app/views/alchemy_crm/contacts_mailer/signout_mail.text.erb +4 -0
  127. data/app/views/alchemy_crm/contacts_mailer/signup_mail.html.erb +11 -0
  128. data/app/views/alchemy_crm/contacts_mailer/signup_mail.text.erb +4 -0
  129. data/app/views/alchemy_crm/mailings/show.html.erb +1 -0
  130. data/app/views/alchemy_crm/mailings_mailer/verification_mail.html.erb +11 -0
  131. data/app/views/alchemy_crm/subscriptions/index.html.erb +23 -0
  132. data/app/views/alchemy_crm/subscriptions_mailer/overview_mail.html.erb +27 -0
  133. data/app/views/alchemy_crm/subscriptions_mailer/overview_mail.text.erb +19 -0
  134. data/app/views/csv_magic/import_errors.html.erb +44 -0
  135. data/app/views/csv_magic/mapper.html.erb +62 -0
  136. data/app/views/layouts/alchemy_crm/mailings.html.erb +212 -0
  137. data/app/views/layouts/alchemy_crm/mailings.text.erb +3 -0
  138. data/config/alchemy_crm.config.yml +21 -0
  139. data/config/authorization_rules.rb +37 -0
  140. data/config/initializers/assets.rb +4 -0
  141. data/config/initializers/delayed_job.rb +6 -0
  142. data/config/locales/alchemy.de.yml +55 -0
  143. data/config/locales/alchemy.en.yml +52 -0
  144. data/config/locales/alchemy_crm.de.yml +196 -0
  145. data/config/locales/alchemy_crm.en.yml +53 -0
  146. data/config/locales/localized_country_select.de.rb +268 -0
  147. data/config/locales/localized_country_select.en.rb +282 -0
  148. data/config/module_definition.yml +30 -0
  149. data/config/routes.rb +71 -0
  150. data/db/migrate/20100708220434_create_mailings.rb +19 -0
  151. data/db/migrate/20100708220534_create_contacts.rb +27 -0
  152. data/db/migrate/20100708220812_create_contact_groups.rb +13 -0
  153. data/db/migrate/20100708221009_create_newsletters.rb +15 -0
  154. data/db/migrate/20100708221319_create_sent_mailings.rb +15 -0
  155. data/db/migrate/20100708221529_create_recipients.rb +21 -0
  156. data/db/migrate/20100708222620_acts_as_taggable_migration.rb +28 -0
  157. data/db/migrate/20100708223324_create_contact_group_filters.rb +17 -0
  158. data/db/migrate/20100708223727_create_newsletter_subscriptions.rb +14 -0
  159. data/db/migrate/20100708223922_create_essence_element_teasers.rb +15 -0
  160. data/db/migrate/20100714172207_create_contact_groups_newsletters.rb +12 -0
  161. data/db/migrate/20100927152601_create_reactions.rb +14 -0
  162. data/db/migrate/20111028091722_acts_as_taggable_on_migration.rb +15 -0
  163. data/db/migrate/20111028200710_add_counter_cache_columns_for_tags.rb +11 -0
  164. data/db/migrate/20111030204931_create_delayed_jobs.rb +21 -0
  165. data/db/migrate/20111104105854_add_deliver_at_to_sent_mailings.rb +9 -0
  166. data/db/migrate/20111104125306_remove_sent_mailing_pdf_id_from_sent_mailings.rb +9 -0
  167. data/db/migrate/20111104131912_add_delivered_at_to_sent_mailings.rb +9 -0
  168. data/db/migrate/20111124145923_namespace_alchemy_crm_models.rb +17 -0
  169. data/db/migrate/20120306115555_add_disabled_to_alchemy_crm_contacts.rb +5 -0
  170. data/db/migrate/20120307160721_rename_alchemy_crm_recipients_sent_mailing_id.rb +5 -0
  171. data/db/migrate/20120315113522_add_url_to_alchemy_crm_reactions.rb +5 -0
  172. data/db/migrate/20120316161333_add_sha1_and_salt_to_alchemy_crm_recipients.rb +6 -0
  173. data/db/migrate/20120320103412_add_indexes_to_alchemy_crm_sha1_columns.rb +7 -0
  174. data/db/migrate/20120321105455_add_queue_to_delayed_jobs.rb +9 -0
  175. data/db/migrate/20120327174301_add_more_indexes_to_alchemy_crm_tables.rb +12 -0
  176. data/lib/alchemy_crm.rb +18 -0
  177. data/lib/alchemy_crm/bounced_delivery.rb +46 -0
  178. data/lib/alchemy_crm/config.rb +28 -0
  179. data/lib/alchemy_crm/engine.rb +40 -0
  180. data/lib/alchemy_crm/i18n_helpers.rb +35 -0
  181. data/lib/alchemy_crm/newsletter_layout.rb +40 -0
  182. data/lib/alchemy_crm/seeder.rb +30 -0
  183. data/lib/alchemy_crm/version.rb +3 -0
  184. data/lib/generators/alchemy_crm/scaffold/files/_standard.html.erb +1 -0
  185. data/lib/generators/alchemy_crm/scaffold/files/_standard.text.erb +1 -0
  186. data/lib/generators/alchemy_crm/scaffold/files/elements.yml +51 -0
  187. data/lib/generators/alchemy_crm/scaffold/files/newsletter_layouts.yml +3 -0
  188. data/lib/generators/alchemy_crm/scaffold/files/newsletters.html.erb +22 -0
  189. data/lib/generators/alchemy_crm/scaffold/files/newsletters.text.erb +4 -0
  190. data/lib/generators/alchemy_crm/scaffold/files/page_layouts.yml +19 -0
  191. data/lib/generators/alchemy_crm/scaffold/scaffold_generator.rb +26 -0
  192. data/lib/tasks/alchemy_crm.rake +28 -0
  193. data/lib/tasks/routes.rake +29 -0
  194. data/rails/init.rb +1 -0
  195. data/recipes/alchemy-mailings-capistrano-tasks.rb +12 -0
  196. data/spec/alchemy_mailings_spec.rb +7 -0
  197. data/spec/config_spec.rb +28 -0
  198. data/spec/controllers/alchemy_crm/contacts_controller_spec.rb +210 -0
  199. data/spec/controllers/alchemy_crm/mailings_controller_spec.rb +89 -0
  200. data/spec/controllers/alchemy_crm/recipients_controller_spec.rb +155 -0
  201. data/spec/dummy/Rakefile +7 -0
  202. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  203. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  204. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  205. data/spec/dummy/config.ru +4 -0
  206. data/spec/dummy/config/alchemy/config.yml +142 -0
  207. data/spec/dummy/config/alchemy/elements.yml +79 -0
  208. data/spec/dummy/config/alchemy/newsletter_layouts.yml +4 -0
  209. data/spec/dummy/config/alchemy/page_layouts.yml +55 -0
  210. data/spec/dummy/config/application.rb +43 -0
  211. data/spec/dummy/config/boot.rb +10 -0
  212. data/spec/dummy/config/database.yml +22 -0
  213. data/spec/dummy/config/environment.rb +5 -0
  214. data/spec/dummy/config/environments/development.rb +30 -0
  215. data/spec/dummy/config/environments/production.rb +60 -0
  216. data/spec/dummy/config/environments/test.rb +39 -0
  217. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  218. data/spec/dummy/config/initializers/inflections.rb +10 -0
  219. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  220. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  221. data/spec/dummy/config/initializers/session_store.rb +8 -0
  222. data/spec/dummy/config/locales/en.yml +5 -0
  223. data/spec/dummy/config/routes.rb +4 -0
  224. data/spec/dummy/db/schema.rb +452 -0
  225. data/spec/dummy/public/404.html +26 -0
  226. data/spec/dummy/public/422.html +26 -0
  227. data/spec/dummy/public/500.html +26 -0
  228. data/spec/dummy/public/favicon.ico +0 -0
  229. data/spec/dummy/script/rails +6 -0
  230. data/spec/helpers/alchemy_crm/mailings_helper_spec.rb +169 -0
  231. data/spec/mailers/alchemy_crm/contacts_mailer_spec.rb +88 -0
  232. data/spec/mailers/alchemy_crm/mailings_mailer_spec.rb +42 -0
  233. data/spec/models/alchemy_crm/contact_group_spec.rb +41 -0
  234. data/spec/models/alchemy_crm/contact_spec.rb +108 -0
  235. data/spec/models/alchemy_crm/delivery_spec.rb +55 -0
  236. data/spec/models/alchemy_crm/mailing_spec.rb +63 -0
  237. data/spec/models/alchemy_crm/newsletter_spec.rb +45 -0
  238. data/spec/spec_helper.rb +58 -0
  239. data/vendor/assets/javascripts/autocomplete-rails.js +16 -0
  240. metadata +438 -0
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require ./base
3
+ */
@@ -0,0 +1,7 @@
1
+ module AlchemyCrm
2
+ module Admin
3
+ class BaseController < Alchemy::Admin::ResourcesController
4
+ include I18nHelpers
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: UTF-8
2
+ module AlchemyCrm
3
+ module Admin
4
+ class ContactGroupsController < AlchemyCrm::Admin::BaseController
5
+
6
+ before_filter :load_additional_data, :only => [:new, :edit]
7
+
8
+ def add_filter
9
+ @contact_group = ContactGroup.find(params[:contact_group_id])
10
+ @filter = @contact_group.filters.build
11
+ @count = @contact_group.filters.length - 1
12
+ end
13
+
14
+ private
15
+
16
+ def load_additional_data
17
+ @contacts = Contact.all
18
+ @tags = ActsAsTaggableOn::Tag.order("name ASC").all
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,112 @@
1
+ # encoding: UTF-8
2
+ module AlchemyCrm
3
+ module Admin
4
+ class ContactsController < AlchemyCrm::Admin::BaseController
5
+
6
+ include CSVMagic::ControllerActions
7
+
8
+ csv_magic_config(
9
+ :mapping => {
10
+ Contact.human_attribute_name(:salutation).gsub(/\*$/, '') => :salutation,
11
+ Contact.human_attribute_name(:title) => :title,
12
+ Contact.human_attribute_name(:firstname).gsub(/\*$/, '') => :firstname,
13
+ Contact.human_attribute_name(:lastname).gsub(/\*$/, '') => :lastname,
14
+ Contact.human_attribute_name(:email).gsub(/\*$/, '') => :email,
15
+ Contact.human_attribute_name(:organisation) => :organisation,
16
+ Contact.human_attribute_name(:address) => :address,
17
+ Contact.human_attribute_name(:zip) => :zip,
18
+ Contact.human_attribute_name(:city) => :city,
19
+ Contact.human_attribute_name(:country) => :country,
20
+ Contact.human_attribute_name(:phone) => :phone,
21
+ Contact.human_attribute_name(:mobile) => :mobile
22
+ }
23
+ )
24
+
25
+ before_filter :load_tags, :only => [:new, :edit]
26
+
27
+ def new
28
+ @contact = Contact.new(:country => ::I18n.locale.to_s.upcase)
29
+ render :layout => false
30
+ end
31
+
32
+ def import
33
+ if request.post?
34
+ if params[:verified] == "1"
35
+ if params[:fields] || !(params[:file].content_type =~ /csv/i).nil?
36
+ handle_csv_post_request
37
+ elsif !(params[:file].content_type =~ /vcard|directory/i).nil?
38
+ handle_vcf_post_request
39
+ else
40
+ flash[:error] = alchemy_crm_t(:invalid_file_type)
41
+ redirect_to admin_contacts_path
42
+ end
43
+ else
44
+ @error = build_error_message(alchemy_crm_t(:imported_contacts_not_verified))
45
+ end
46
+ else
47
+ render :layout => !request.xhr?
48
+ end
49
+ end
50
+
51
+ def export
52
+ @contact = Contact.find(params[:id])
53
+ @contact.to_vcard
54
+ send_file("#{Rails.root.to_s}/tmp/#{@contact.fullname}.vcf")
55
+ end
56
+
57
+ def autocomplete_tag_list
58
+ items = ActsAsTaggableOn::Tag.where(['LOWER(name) LIKE ?', "#{params[:term].downcase}%"])
59
+ render :json => json_for_autocomplete(items, :name)
60
+ end
61
+
62
+ private
63
+
64
+ def load_tags
65
+ @tags = ActsAsTaggableOn::Tag.order("name ASC").all
66
+ @tags = @tags - @contact.tags.to_a unless @contact.nil?
67
+ end
68
+
69
+ def build_error_message(message)
70
+ heading = "<h1>#{alchemy_crm_t(:errors_while_importing)}</h1>".html_safe
71
+ message = "<p>#{message}</p>".html_safe
72
+ heading + message
73
+ end
74
+
75
+ def create_resource_items_from_csv(*args)
76
+ @csv_import_errors = []
77
+ @contacts = []
78
+ reader = CSVMagic::Reader.new(params)
79
+ reader.each do |row|
80
+ @contacts << contact = Contact.new(row)
81
+ contact.verified = true
82
+ contact.skip_validation = true
83
+ unless contact.save
84
+ @csv_import_errors.push [contact, contact.errors]
85
+ end
86
+ end
87
+ @valid_contacts = @contacts.select(&:valid?)
88
+ reader.remove_file if @csv_import_errors.empty?
89
+ end
90
+
91
+ def render_csv_import_form
92
+ render 'import'
93
+ end
94
+
95
+ def handle_vcf_post_request
96
+ if params[:file].blank?
97
+ @errors = build_error_message(alchemy_crm_t(:missing_vcard))
98
+ else
99
+ @contacts = Contact.new_from_vcard(params[:file], true)
100
+ if @contacts.detect(&:invalid?).nil?
101
+ flash[:notice] = alchemy_crm_t(:successfully_imported_contacts)
102
+ else
103
+ @errors = build_error_message(alchemy_crm_t(:please_check_highlighted_vcards_on_errors))
104
+ end
105
+ end
106
+ @valid_contacts = @contacts.select(&:valid?) || []
107
+ render :vcf_import_result
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: UTF-8
2
+ module AlchemyCrm
3
+ module Admin
4
+ class DeliveriesController < AlchemyCrm::Admin::BaseController
5
+
6
+ before_filter :load_mailing, :only => [:index, :new]
7
+
8
+ def index
9
+ @deliveries = @mailing.deliveries.order('deliver_at DESC')
10
+ render :layout => false
11
+ end
12
+
13
+ def new
14
+ @delivery = Delivery.new(
15
+ :deliver_at => Time.now + 1.hour,
16
+ :mailing => @mailing
17
+ )
18
+ render :layout => false
19
+ end
20
+
21
+ def show
22
+ begin
23
+ @delivery = Delivery.find(params[:id])
24
+ @recipients = @delivery.recipients
25
+ @read = @delivery.recipients.select{|r| r.read}
26
+ @reacted = @delivery.recipients.select{|r| r.reacted}
27
+ @bounced = @delivery.recipients.select{|r| r.bounced}
28
+ rescue
29
+ log_error($!)
30
+ end
31
+ render :layout => false
32
+ end
33
+
34
+ def create
35
+ @delivery = Delivery.new(params[:delivery])
36
+ @mailing = @delivery.mailing = Mailing.find(params[:delivery][:mailing_id])
37
+ if @delivery.save
38
+ @delivery.send_chunks(
39
+ :language_id => session[:language_id],
40
+ :protocol => request.protocol,
41
+ :host => request.host,
42
+ :port => request.port,
43
+ :locale => ::I18n.locale
44
+ )
45
+ flash[:notice] = alchemy_crm_t(:successfully_scheduled_mailing)
46
+ end
47
+ redirect_to admin_mailings_path
48
+ end
49
+
50
+ def edit
51
+ @delivery = Delivery.find(params[:id])
52
+ @mailing = @delivery.mailing
53
+ render :layout => false
54
+ end
55
+
56
+ def update
57
+ @delivery = Delivery.find(params[:id])
58
+ @delivery.update_attributes(params[:delivery])
59
+ render_errors_or_redirect(
60
+ @delivery,
61
+ admin_mailings_path,
62
+ alchemy_crm_t(:successfully_rescheduled_mailing)
63
+ )
64
+ end
65
+
66
+ def destroy
67
+ @delivery = Delivery.find(params[:id])
68
+ @delivery.destroy
69
+ render :js => "window.location.replace('#{admin_mailings_path}'); Alchemy.growl('#{successfully_canceled_delivery}')"
70
+ end
71
+
72
+ private
73
+
74
+ def load_mailing
75
+ @mailing = Mailing.find(params[:mailing_id])
76
+ end
77
+
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+ # Extending Alchemy::Admin::ElementsController
3
+
4
+ Alchemy::Admin::ElementsController.class_eval do
5
+
6
+ def teasables
7
+ @pages = Alchemy::Page.language_root_for(session[:language_id]).descendants
8
+ @content = Content.find(params[:content_id])
9
+ @element = @content.element
10
+ @elements = Alchemy::Element.where(:name => @content.settings[:teasable_elements])
11
+ render :layout => false
12
+ end
13
+
14
+ def fill
15
+ @element = Alchemy::Element.find(params[:id])
16
+ @source_element = Alchemy::Element.find(params[:source_element_id])
17
+ @params = "?page_id=#{@source_element.page.id}&element_id=#{@source_element.id}"
18
+ @content = @element.contents.where(:essence_type => "EssenceRichtext")
19
+ @target_contents = []
20
+ @source_element.contents.each do |content|
21
+ @target_contents << @element.contents.select { |c| c.essence_type == content.essence_type && c.name == content.name }
22
+ end
23
+ end
24
+
25
+ def link
26
+ @element = Alchemy::Element.find(params[:id])
27
+ @source_element = Alchemy::Element.find(params[:source_element_id])
28
+ @content = @element.contents.where(:essence_type => "EssenceElementTeaser")
29
+ @params = "?page_id=#{@source_element.page.id}&element_id=#{@source_element.id}"
30
+ end
31
+
32
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ module AlchemyCrm
3
+ module Admin
4
+ class MailingsController < AlchemyCrm::Admin::BaseController
5
+
6
+ before_filter :load_newsletters, :only => [:new, :edit, :copy]
7
+
8
+ helper 'AlchemyCrm::Mailings'
9
+ helper 'Alchemy::Admin::Pages'
10
+
11
+ def copy
12
+ @mailing = Mailing.copy(params[:id])
13
+ render :action => :new, :layout => false
14
+ end
15
+
16
+ def show
17
+ @mailing = Mailing.find(params[:id])
18
+ @page = @mailing.page
19
+ @contact = Contact.fake
20
+ @recipient = Recipient.new_from_contact(@contact)
21
+ @preview_mode = true
22
+ render :layout => 'alchemy_crm/mailings'
23
+ end
24
+
25
+ def edit_content
26
+ @mailing = Mailing.find(params[:id])
27
+ @page = @mailing.page
28
+ end
29
+
30
+ def update
31
+ @mailing.update_attributes(params[:mailing], :as => current_user.role.to_sym)
32
+ render_errors_or_redirect(
33
+ @mailing,
34
+ :back,
35
+ flash_notice_for_resource_action
36
+ )
37
+ end
38
+
39
+ private
40
+
41
+ def load_newsletters
42
+ @newsletters = Newsletter.all
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ module AlchemyCrm
3
+ module Admin
4
+ class NewslettersController < AlchemyCrm::Admin::BaseController
5
+
6
+ before_filter :load_additional_data, :only => [:new, :edit]
7
+
8
+ def update
9
+ params[:newsletter][:contact_group_ids] ||= []
10
+ @newsletter = Newsletter.find(params[:id])
11
+ @newsletter.update_attributes(params[:newsletter])
12
+ render_errors_or_redirect @newsletter, admin_newsletters_path, alchemy_crm_t(:successfully_updated_newsletter)
13
+ end
14
+
15
+ private
16
+
17
+ def load_additional_data
18
+ @page_layouts = AlchemyCrm::NewsletterLayout.get_layouts_for_select()
19
+ @contact_groups = ContactGroup.order("name ASC").all
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,62 @@
1
+ # encoding: UTF-8
2
+ module AlchemyCrm
3
+ module Admin
4
+ class TagsController < Alchemy::Admin::BaseController
5
+
6
+ include I18nHelpers
7
+ helper 'AlchemyCrm::Admin::Base'
8
+
9
+ before_filter :load_tag, :only => [:edit, :update, :destroy]
10
+
11
+ def index
12
+ @tags = ActsAsTaggableOn::Tag.where(
13
+ "name LIKE '%#{params[:query]}%'"
14
+ ).page(params[:page] || 1).per(per_page_value_for_screen_size).order("name ASC")
15
+ end
16
+
17
+ def new
18
+ @tag = ActsAsTaggableOn::Tag.new
19
+ render :layout => false
20
+ end
21
+
22
+ def create
23
+ @tag = ActsAsTaggableOn::Tag.create(params[:tag])
24
+ render_errors_or_redirect @tag, admin_tags_path, alchemy_crm_t('New Tag Created')
25
+ end
26
+
27
+ def edit
28
+ @tags = ActsAsTaggableOn::Tag.order("name ASC").all - [@tag]
29
+ render :layout => false
30
+ end
31
+
32
+ def update
33
+ if params[:replace]
34
+ @new_tag = ActsAsTaggableOn::Tag.find(params[:tag][:merge_to])
35
+ Contact.replace_tag @tag, @new_tag
36
+ operation_text = alchemy_crm_t('Replaced Tag %{old_tag} with %{new_tag}') % {:old_tag => @tag.name, :new_tag => @new_tag.name}
37
+ @tag.destroy
38
+ else
39
+ @tag.update_attributes(params[:tag])
40
+ @tag.save
41
+ operation_text = t(:successfully_updated_tag)
42
+ end
43
+ render_errors_or_redirect @tag, admin_tags_path, operation_text
44
+ end
45
+
46
+ def destroy
47
+ if request.delete?
48
+ @tag.destroy
49
+ flash[:notice] = t(:successfully_deleted_tag)
50
+ end
51
+ redirect_to admin_tags_path
52
+ end
53
+
54
+ private
55
+
56
+ def load_tag
57
+ @tag = ActsAsTaggableOn::Tag.find(params[:id])
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ module AlchemyCrm
2
+ class BaseController < Alchemy::BaseController
3
+ include I18nHelpers
4
+ end
5
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: UTF-8
2
+ module AlchemyCrm
3
+ class ContactsController < AlchemyCrm::BaseController
4
+
5
+ helper 'Alchemy::Pages'
6
+ layout :layout_for_page
7
+
8
+ before_filter :load_signup_form, :only => [:show, :signup, :verify]
9
+ before_filter :load_signout_form, :only => [:signout, :disable]
10
+
11
+ def show
12
+ @page = @element.page
13
+ @root_page = @page.get_language_root
14
+ render :template => 'alchemy/pages/show'
15
+ end
16
+
17
+ def signup
18
+ @contact = Contact.new(params[:contact])
19
+ if @contact.save
20
+ ContactsMailer.signup_mail(
21
+ @contact,
22
+ Alchemy::Page.find_by_page_layout_and_language_id('newsletter_mails', session[:language_id])
23
+ ).deliver
24
+ @contact_signed_up = true
25
+ else
26
+ @contact_signed_up = false
27
+ end
28
+ @page = @element.page
29
+ @root_page = @page.get_language_root
30
+ render :template => 'alchemy/pages/show'
31
+ end
32
+
33
+ def verify
34
+ @contact = Contact.find_by_email_sha1(params[:token])
35
+ if @contact
36
+ @contact_verified = @contact.update_attribute(:verified, true)
37
+ if params[:newsletter_ids]
38
+ @subscriptions = @contact.subscriptions.where(:newsletter_id => params[:newsletter_ids])
39
+ else
40
+ @subscriptions = @contact.subscriptions
41
+ end
42
+ @subscriptions.each do |subscription|
43
+ subscription.update_attribute(:verified, true)
44
+ end
45
+ @page = @element.page
46
+ @root_page = @page.get_language_root
47
+ render :template => 'alchemy/pages/show'
48
+ else
49
+ contact_not_found
50
+ end
51
+ end
52
+
53
+ def signout
54
+ @contact = Contact.find_by_email_and_verified(params[:email], true)
55
+ if @contact.blank?
56
+ flash[:notice] = ::I18n.t(:contact_unknown, :scope => :alchemy_crm)
57
+ @contact_signed_out = false
58
+ else
59
+ ContactsMailer.signout_mail(
60
+ @contact,
61
+ Alchemy::Page.find_by_page_layout_and_language_id('newsletter_mails', session[:language_id])
62
+ ).deliver
63
+ @contact_signed_out = true
64
+ end
65
+ @page = @element.page
66
+ @root_page = @page.get_language_root
67
+ render :template => 'alchemy/pages/show'
68
+ end
69
+
70
+ def disable
71
+ @contact = Contact.find_by_email_sha1(params[:token])
72
+ if @contact
73
+ @contact_disabled = @contact.disable!
74
+ @page = @element.page
75
+ @root_page = @page.get_language_root
76
+ render :template => 'alchemy/pages/show'
77
+ else
78
+ contact_not_found
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def load_signup_form
85
+ @element = Alchemy::Element.find_by_name('newsletter_signup_form')
86
+ if @element.blank?
87
+ raise ActiveRecord::RecordNotFound, "Alchemy::Element with name 'newsletter_signup_form' not found!"
88
+ end
89
+ end
90
+
91
+ def load_signout_form
92
+ @element = Alchemy::Element.find_by_name('newsletter_signout_form')
93
+ if @element.blank?
94
+ raise ActiveRecord::RecordNotFound, "Alchemy::Element with name 'newsletter_signout_form' not found!"
95
+ end
96
+ end
97
+
98
+ def contact_not_found
99
+ raise ActionController::RoutingError.new('Contact Not Found')
100
+ end
101
+
102
+ end
103
+ end