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,15 @@
1
+ class CreateNewsletters < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :newsletters do |t|
4
+ t.string :name
5
+ t.string :layout
6
+ t.boolean :public, :default => false
7
+ t.timestamps
8
+ t.userstamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :newsletters
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ class CreateSentMailings < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :sent_mailings do |t|
4
+ t.string :name
5
+ t.integer :sent_mailing_pdf_id
6
+ t.integer :mailing_id
7
+ t.timestamps
8
+ t.userstamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :sent_mailings
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ class CreateRecipients < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :recipients do |t|
4
+ t.string :email
5
+ t.boolean :bounced, :default => false
6
+ t.boolean :read, :default => false
7
+ t.boolean :reacted, :default => false
8
+ t.integer :sent_mailing_id
9
+ t.integer :contact_id
10
+ t.string :message_id
11
+ t.datetime :read_at
12
+ t.datetime :bounced_at
13
+ t.datetime :reacted_at
14
+ t.timestamps
15
+ end
16
+ end
17
+
18
+ def self.down
19
+ drop_table :recipients
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ class ActsAsTaggableMigration < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :tags do |t|
4
+ t.column :name, :string
5
+ t.timestamps
6
+ t.userstamps
7
+ end
8
+
9
+ create_table :taggings do |t|
10
+ t.column :tag_id, :integer
11
+ t.column :taggable_id, :integer
12
+
13
+ # You should make sure that the column created is
14
+ # long enough to store the required class names.
15
+ t.column :taggable_type, :string
16
+
17
+ t.column :created_at, :datetime
18
+ end
19
+
20
+ add_index :taggings, :tag_id
21
+ add_index :taggings, [:taggable_id, :taggable_type]
22
+ end
23
+
24
+ def self.down
25
+ drop_table :taggings
26
+ drop_table :tags
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ class CreateContactGroupFilters < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :contact_group_filters do |t|
4
+ t.string :column
5
+ t.string :value
6
+ t.string :operator
7
+ t.integer :contact_group_id
8
+
9
+ t.timestamps
10
+ t.userstamps
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :contact_group_filters
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ class CreateNewsletterSubscriptions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :newsletter_subscriptions do |t|
4
+ t.integer :contact_id
5
+ t.integer :newsletter_id
6
+ t.boolean :wants, :default => true
7
+ t.boolean :verified, :default => false
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :newsletter_subscriptions
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ class CreateEssenceElementTeasers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :essence_element_teasers do |t|
4
+ t.string :url
5
+ t.string :title
6
+ t.string :text
7
+ t.userstamps
8
+ t.timestamps
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :essence_element_teasers
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ class CreateContactGroupsNewsletters < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :contact_groups_newsletters, :id => false do |t|
4
+ t.integer :contact_group_id
5
+ t.integer :newsletter_id
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :contact_groups_newsletters
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ class CreateReactions < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :reactions do |t|
4
+ t.integer :recipient_id
5
+ t.integer :page_id
6
+ t.integer :element_id
7
+ t.timestamps
8
+ end
9
+ end
10
+
11
+ def self.down
12
+ drop_table :reactions
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ class ActsAsTaggableOnMigration < ActiveRecord::Migration
2
+ def self.up
3
+ change_table :taggings do |t|
4
+ t.references :tagger, :polymorphic => true
5
+ t.string :context
6
+ end
7
+ remove_index :taggings, [:taggable_id, :taggable_type]
8
+ add_index :taggings, [:taggable_id, :taggable_type, :context]
9
+ end
10
+
11
+ def self.down
12
+ drop_table :taggings
13
+ drop_table :tags
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class AddCounterCacheColumnsForTags < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :contacts, :cached_tag_list, :text
4
+ add_column :contact_groups, :cached_contact_tag_list, :text
5
+ end
6
+
7
+ def self.down
8
+ remove_column :contacts, :cached_tag_list
9
+ remove_column :contact_groups, :cached_contact_tag_list
10
+ end
11
+ end
@@ -0,0 +1,21 @@
1
+ class CreateDelayedJobs < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :delayed_jobs, :force => true do |table|
4
+ table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
5
+ table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
6
+ table.text :handler # YAML-encoded string of the object that will do work
7
+ table.text :last_error # reason for last failure (See Note below)
8
+ table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
9
+ table.datetime :locked_at # Set when a client is working on this object
10
+ table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
11
+ table.string :locked_by # Who is working on this object (if locked)
12
+ table.timestamps
13
+ end
14
+
15
+ add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
16
+ end
17
+
18
+ def self.down
19
+ drop_table :delayed_jobs
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ class AddDeliverAtToSentMailings < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sent_mailings, :deliver_at, :datetime
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sent_mailings, :deliver_at
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class RemoveSentMailingPdfIdFromSentMailings < ActiveRecord::Migration
2
+ def self.up
3
+ remove_column :sent_mailings, :sent_mailing_pdf_id
4
+ end
5
+
6
+ def self.down
7
+ add_column :sent_mailings, :sent_mailing_pdf_id, :integer
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddDeliveredAtToSentMailings < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sent_mailings, :delivered_at, :datetime
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sent_mailings, :delivered_at
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ class NamespaceAlchemyCrmModels < ActiveRecord::Migration
2
+
3
+ def change
4
+ rename_table :mailings, :alchemy_crm_mailings
5
+ rename_table :newsletters, :alchemy_crm_newsletters
6
+ rename_table :contacts, :alchemy_crm_contacts
7
+ rename_table :sent_mailings, :alchemy_crm_deliveries
8
+ rename_table :recipients, :alchemy_crm_recipients
9
+ rename_table :contact_groups, :alchemy_crm_contact_groups
10
+ rename_table :contact_group_filters, :alchemy_crm_contact_group_filters
11
+ rename_table :newsletter_subscriptions, :alchemy_crm_subscriptions
12
+ rename_table :reactions, :alchemy_crm_reactions
13
+ rename_table :essence_element_teasers, :alchemy_essence_element_teasers
14
+ rename_table :contact_groups_newsletters, :alchemy_contact_groups_newsletters
15
+ end
16
+
17
+ end
@@ -0,0 +1,5 @@
1
+ class AddDisabledToAlchemyCrmContacts < ActiveRecord::Migration
2
+ def change
3
+ add_column :alchemy_crm_contacts, :disabled, :boolean, :default => false
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class RenameAlchemyCrmRecipientsSentMailingId < ActiveRecord::Migration
2
+ def change
3
+ rename_column :alchemy_crm_recipients, :sent_mailing_id, :delivery_id
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddUrlToAlchemyCrmReactions < ActiveRecord::Migration
2
+ def change
3
+ add_column :alchemy_crm_reactions, :url, :text
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class AddSha1AndSaltToAlchemyCrmRecipients < ActiveRecord::Migration
2
+ def change
3
+ add_column :alchemy_crm_recipients, :sha1, :string
4
+ add_column :alchemy_crm_recipients, :salt, :string
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ class AddIndexesToAlchemyCrmSha1Columns < ActiveRecord::Migration
2
+ def change
3
+ add_index :alchemy_crm_contacts, :email_sha1
4
+ add_index :alchemy_crm_mailings, :sha1
5
+ add_index :alchemy_crm_recipients, :sha1
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ class AddQueueToDelayedJobs < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :delayed_jobs, :queue, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :delayed_jobs, :queue
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ class AddMoreIndexesToAlchemyCrmTables < ActiveRecord::Migration
2
+ def change
3
+ add_index :alchemy_crm_recipients, :message_id
4
+ add_index :alchemy_crm_recipients, :email
5
+ add_index :alchemy_crm_recipients, :contact_id
6
+ add_index :alchemy_crm_recipients, :delivery_id
7
+ add_index :alchemy_crm_contacts, :email
8
+ add_index :alchemy_crm_reactions, :recipient_id
9
+ add_index :alchemy_contact_groups_newsletters, [:contact_group_id, :newsletter_id], :name => 'contact_group_newsletter_index', :unique => true
10
+ add_index :alchemy_crm_subscriptions, [:contact_id, :newsletter_id], :name => 'contact_newsletter_index', :unique => true
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ if defined?(Rails) && Rails::VERSION::MAJOR == 3
2
+ require 'acts-as-taggable-on'
3
+ require 'localized_country_select'
4
+ require 'rails3-jquery-autocomplete'
5
+ require 'vcard'
6
+ require 'csv_magic'
7
+ require 'digest/sha1'
8
+ require 'delayed_job_active_record'
9
+ require 'alchemy_cms'
10
+ require 'alchemy_crm/version'
11
+ require 'alchemy_crm/config'
12
+ require 'alchemy_crm/engine'
13
+ require 'alchemy_crm/newsletter_layout'
14
+ require "alchemy_crm/seeder"
15
+ require "alchemy_crm/i18n_helpers"
16
+ else
17
+ raise "Alchemy CRM 2.0 needs Rails 3.0 or higher. You are currently using Rails #{Rails::VERSION::MAJOR}"
18
+ end
@@ -0,0 +1,46 @@
1
+ module AlchemyCrm
2
+ class BouncedDelivery
3
+
4
+ attr_accessor :status_info, :original_message_id
5
+ attr_accessor :attr_names
6
+ attr_accessor :message
7
+
8
+ def self.from_email(email)
9
+ returning(bounce = self.new) do
10
+ plain_part = email.parts.detect do |part|
11
+ part.content_type == 'text/plain'
12
+ end
13
+ bounce.message = plain_part.body.strip
14
+
15
+ status_part = email.parts.detect do |part|
16
+ part.content_type == "message/delivery-status"
17
+ end
18
+ statuses = status_part.body.split(/\n/)
19
+
20
+ bounce.status_info = statuses.inject({}) do |hash, line|
21
+ key, value = line.split(/:/)
22
+ hash[key] = value.strip rescue nil
23
+ hash
24
+ end
25
+ original_message_part = email.parts.detect do |part|
26
+ part.content_type == "message/rfc822" or
27
+ part.content_type == "text/rfc822-headers"
28
+ end
29
+ parsed_msg = Mail.parse(original_message_part.body)
30
+ bounce.original_message_id = parsed_msg.message_id
31
+ end
32
+ end
33
+
34
+ def status
35
+ case status_info['Status']
36
+ when /^5/
37
+ 'Failure'
38
+ when /^4/
39
+ 'Temporary Failure'
40
+ when /^2/
41
+ 'Success'
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ module AlchemyCrm
2
+ class Config
3
+
4
+ # Returns the configuration for given parameter
5
+ def self.get(name)
6
+ read_file[name.to_s]
7
+ end
8
+
9
+ def self.show
10
+ read_file
11
+ end
12
+
13
+ private
14
+
15
+ def self.read_file
16
+ app_config = Rails.root.join('config/alchemy_crm.config.yml')
17
+ default_config = File.join(File.dirname(__FILE__), '..', '..', 'config/alchemy_crm.config.yml')
18
+ if File.exist?(app_config)
19
+ YAML.load_file(app_config)
20
+ elsif File.exist?(default_config)
21
+ YAML.load_file(default_config)
22
+ else
23
+ raise "No config file found!"
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ module AlchemyCrm
2
+ class Engine < Rails::Engine
3
+
4
+ isolate_namespace AlchemyCrm
5
+ engine_name 'alchemy_crm'
6
+
7
+ initializer 'alchemy_crm.register_as_alchemy_module' do
8
+ Alchemy::Modules.register_module(YAML.load_file(File.join(File.dirname(__FILE__), '../..', 'config/module_definition.yml')))
9
+ end
10
+
11
+ # Loading authorization rules and register them to auth engine instance
12
+ initializer "alchemy_crm.add_authorization_rules" do
13
+ Alchemy::AuthEngine.get_instance.load(File.join(File.dirname(__FILE__), '../..', 'config/authorization_rules.rb'))
14
+ end
15
+
16
+ initializer "alchemy_crm.add_newsletter_layouts" do
17
+ newsletter_layouts_file = Rails.root.join('config', 'alchemy', 'newsletter_layouts.yml')
18
+ if File.exist? newsletter_layouts_file
19
+ YAML.load_file(newsletter_layouts_file).each do |newsletter_layout|
20
+ newsletter_layout['name'] = Mailing::MAILING_PAGE_LAYOUT_PREFIX + newsletter_layout['name']
21
+ Alchemy::PageLayout.add(newsletter_layout.merge({'newsletter' => true}))
22
+ end
23
+ else
24
+ puts "!!! Alchemy CRM Warning: Newsletter Layouts File not found!\nPlease run 'rails generate alchemy_crm:scaffold' or create a 'newsletter_layouts.yml' file in config/alchemy folder."
25
+ end
26
+ end
27
+
28
+ # initializer "alchemy_crm.inject_helpers" do
29
+ # ActionView::Base.send :include, AlchemyCrm::BaseHelper
30
+ # end
31
+
32
+ # Loading all alchemy core extensions found in app folder.
33
+ config.to_prepare do
34
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_extension.rb")) do |e|
35
+ Rails.env.production? ? require(e) : load(e)
36
+ end
37
+ end
38
+
39
+ end
40
+ end