fat_free_crm 0.11.3 → 0.11.4

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.

Potentially problematic release.


This version of fat_free_crm might be problematic. Click here for more details.

Files changed (637) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +2 -2
  3. data/CHANGELOG +6 -1
  4. data/CONTRIBUTORS +40 -1
  5. data/Capfile +5 -0
  6. data/Gemfile +25 -6
  7. data/Gemfile.lock +128 -86
  8. data/README.md +23 -16
  9. data/{vendor → app}/assets/images/delete.png +0 -0
  10. data/app/assets/javascripts/admin/fields.js.coffee +62 -0
  11. data/app/assets/javascripts/application.js.erb +8 -1
  12. data/app/assets/javascripts/crm.js +44 -46
  13. data/app/assets/javascripts/crm_chosen.js.coffee +10 -7
  14. data/app/assets/javascripts/datepicker.js.coffee +15 -0
  15. data/app/assets/javascripts/format_buttons.js.coffee +48 -0
  16. data/app/assets/javascripts/{admin/field_groups.js.coffee → groups.js.coffee} +0 -0
  17. data/app/assets/javascripts/lists.js.coffee +1 -1
  18. data/app/assets/javascripts/search.js.coffee +56 -38
  19. data/app/assets/stylesheets/admin/{field_groups.css.scss → fields.css.scss} +4 -0
  20. data/app/assets/stylesheets/advanced_search.css.scss +79 -0
  21. data/app/assets/stylesheets/application.css.erb +4 -0
  22. data/app/assets/stylesheets/base.scss +3 -3
  23. data/app/assets/stylesheets/common.scss +72 -25
  24. data/app/assets/stylesheets/fields.scss +14 -0
  25. data/app/assets/stylesheets/format_buttons.css.scss +30 -0
  26. data/app/assets/stylesheets/groups.css.scss +3 -0
  27. data/app/assets/stylesheets/header.scss +7 -6
  28. data/{vendor/plugins/.gitkeep → app/assets/stylesheets/index_headers.css.scss} +0 -0
  29. data/app/assets/stylesheets/print.css.scss +12 -3
  30. data/app/assets/stylesheets/rails.scss +12 -3
  31. data/app/controllers/admin/application_controller.rb +1 -1
  32. data/app/controllers/admin/field_groups_controller.rb +2 -0
  33. data/app/controllers/admin/fields_controller.rb +41 -17
  34. data/app/controllers/admin/groups_controller.rb +70 -0
  35. data/app/controllers/admin/tags_controller.rb +1 -0
  36. data/app/controllers/admin/users_controller.rb +8 -7
  37. data/app/controllers/application_controller.rb +34 -5
  38. data/app/controllers/comments_controller.rb +2 -3
  39. data/app/controllers/entities/accounts_controller.rb +30 -37
  40. data/app/controllers/entities/campaigns_controller.rb +56 -29
  41. data/app/controllers/entities/contacts_controller.rb +24 -26
  42. data/app/controllers/entities/leads_controller.rb +38 -37
  43. data/app/controllers/entities/opportunities_controller.rb +28 -34
  44. data/app/controllers/entities_controller.rb +71 -43
  45. data/app/controllers/home_controller.rb +29 -27
  46. data/app/controllers/tasks_controller.rb +18 -17
  47. data/app/controllers/users_controller.rb +12 -8
  48. data/app/helpers/accounts_helper.rb +58 -16
  49. data/app/helpers/addresses_helper.rb +4 -1
  50. data/app/helpers/admin/fields_helper.rb +3 -4
  51. data/app/helpers/application_helper.rb +147 -100
  52. data/app/helpers/campaigns_helper.rb +2 -9
  53. data/app/helpers/fields_helper.rb +0 -1
  54. data/app/helpers/groups_helper.rb +2 -0
  55. data/app/helpers/home_helper.rb +11 -0
  56. data/app/helpers/leads_helper.rb +2 -9
  57. data/app/helpers/opportunities_helper.rb +2 -9
  58. data/app/helpers/{crm_tags_helper.rb → tags_helper.rb} +9 -8
  59. data/app/helpers/tasks_helper.rb +5 -21
  60. data/app/helpers/users_helper.rb +14 -7
  61. data/app/helpers/versions_helper.rb +46 -0
  62. data/app/inputs/date_time_input.rb +8 -25
  63. data/app/inputs/datepair_input.rb +77 -0
  64. data/app/inputs/datetimepair_input.rb +37 -0
  65. data/app/mailers/user_mailer.rb +10 -0
  66. data/app/models/entities/account.rb +18 -11
  67. data/app/models/entities/account_contact.rb +4 -3
  68. data/app/models/entities/account_opportunity.rb +0 -1
  69. data/app/models/entities/campaign.rb +6 -7
  70. data/app/models/entities/contact.rb +53 -25
  71. data/app/models/entities/contact_opportunity.rb +0 -1
  72. data/app/models/entities/lead.rb +24 -13
  73. data/app/models/entities/opportunity.rb +34 -16
  74. data/app/models/fields/custom_field.rb +29 -13
  75. data/app/models/fields/custom_field_date_pair.rb +58 -0
  76. data/app/models/fields/custom_field_datetime_pair.rb +28 -0
  77. data/app/models/fields/custom_field_pair.rb +54 -0
  78. data/app/models/fields/field.rb +60 -43
  79. data/app/models/fields/field_group.rb +0 -9
  80. data/app/models/observers/entity_observer.rb +29 -0
  81. data/app/models/observers/opportunity_observer.rb +3 -0
  82. data/app/models/polymorphic/address.rb +14 -0
  83. data/app/models/polymorphic/avatar.rb +13 -1
  84. data/app/models/polymorphic/email.rb +1 -1
  85. data/app/models/polymorphic/task.rb +14 -13
  86. data/app/models/setting.rb +14 -21
  87. data/app/models/users/ability.rb +25 -4
  88. data/app/models/users/group.rb +13 -0
  89. data/app/models/users/permission.rb +3 -1
  90. data/app/models/users/preference.rb +1 -2
  91. data/app/models/users/user.rb +25 -3
  92. data/app/views/accounts/_account.html.haml +5 -39
  93. data/app/views/accounts/_edit.html.haml +3 -2
  94. data/app/views/accounts/_index_brief.html.haml +32 -0
  95. data/app/views/accounts/_index_long.html.haml +42 -0
  96. data/app/views/accounts/_new.html.haml +3 -2
  97. data/app/views/accounts/_sidebar_index.html.haml +3 -4
  98. data/app/views/accounts/_sidebar_show.html.haml +2 -2
  99. data/app/views/accounts/_title_bar.html.haml +11 -0
  100. data/app/views/accounts/_top_section.html.haml +1 -1
  101. data/app/views/accounts/create.js.rjs +1 -2
  102. data/app/views/accounts/destroy.js.rjs +1 -1
  103. data/app/views/accounts/edit.js.rjs +0 -2
  104. data/app/views/accounts/index.html.haml +6 -13
  105. data/app/views/accounts/index.js.rjs +3 -1
  106. data/app/views/accounts/index.xls.builder +82 -0
  107. data/app/views/accounts/new.js.rjs +0 -2
  108. data/app/views/accounts/show.html.haml +17 -15
  109. data/app/views/accounts/show.js.erb +2 -0
  110. data/app/views/admin/custom_fields/_base_field.html.haml +21 -0
  111. data/app/views/admin/custom_fields/_check_boxes_field.html.haml +6 -0
  112. data/app/views/admin/custom_fields/_date_field.html.haml +14 -0
  113. data/app/views/admin/custom_fields/_date_pair_field.html.haml +21 -0
  114. data/app/views/admin/custom_fields/_datetime_field.html.haml +14 -0
  115. data/app/views/admin/custom_fields/_datetime_pair_field.html.haml +21 -0
  116. data/app/views/admin/custom_fields/_radio_field.html.haml +6 -0
  117. data/app/views/admin/custom_fields/_select_field.html.haml +25 -0
  118. data/app/views/admin/custom_fields/_string_field.html.haml +2 -0
  119. data/app/views/admin/field_groups/_field_group.html.haml +7 -5
  120. data/app/views/admin/field_groups/_top_section.html.haml +4 -3
  121. data/app/views/admin/field_groups/create.js.rjs +1 -2
  122. data/app/views/admin/fields/_field.html.haml +5 -3
  123. data/app/views/admin/fields/_form.html.haml +35 -0
  124. data/app/views/admin/fields/_subform.html.haml +6 -0
  125. data/app/views/admin/fields/create.js.erb +19 -0
  126. data/app/views/admin/fields/destroy.js.erb +9 -0
  127. data/app/views/admin/fields/edit.js.erb +1 -0
  128. data/app/views/admin/fields/index.html.haml +11 -8
  129. data/app/views/admin/fields/update.js.erb +13 -0
  130. data/app/views/admin/groups/_edit.html.haml +12 -0
  131. data/app/views/admin/groups/_form.html.haml +13 -0
  132. data/app/views/admin/groups/_group.html.haml +15 -0
  133. data/app/views/admin/groups/_new.html.haml +12 -0
  134. data/app/views/admin/groups/create.js.rjs +11 -0
  135. data/app/views/admin/{fields → groups}/destroy.js.rjs +3 -3
  136. data/app/views/admin/groups/edit.js.rjs +21 -0
  137. data/app/views/admin/groups/index.html.haml +18 -0
  138. data/app/views/admin/groups/index.js.rjs +2 -0
  139. data/app/views/admin/groups/new.js.rjs +9 -0
  140. data/app/views/admin/groups/show.html.haml +11 -0
  141. data/app/views/admin/groups/update.js.rjs +10 -0
  142. data/app/views/admin/users/_profile.html.haml +13 -1
  143. data/app/views/admin/users/_user.html.haml +7 -2
  144. data/app/views/admin/users/index.js.rjs +1 -0
  145. data/app/views/application/index.atom.builder +1 -1
  146. data/app/views/application/index.rss.builder +1 -1
  147. data/app/views/application/show.atom.builder +32 -0
  148. data/app/views/application/show.rss.builder +29 -0
  149. data/app/views/campaigns/_campaign.html.haml +5 -21
  150. data/app/views/campaigns/_edit.html.haml +3 -2
  151. data/app/views/campaigns/_index_brief.html.haml +15 -0
  152. data/app/views/campaigns/_index_long.html.haml +20 -0
  153. data/app/views/campaigns/_new.html.haml +4 -2
  154. data/app/views/campaigns/_sidebar_index.html.haml +3 -3
  155. data/app/views/campaigns/_title_bar.html.haml +11 -0
  156. data/app/views/campaigns/_top_section.html.haml +2 -2
  157. data/app/views/campaigns/create.js.rjs +1 -4
  158. data/app/views/campaigns/destroy.js.rjs +1 -1
  159. data/app/views/campaigns/edit.js.rjs +0 -4
  160. data/app/views/campaigns/index.html.haml +6 -13
  161. data/app/views/campaigns/index.js.rjs +3 -1
  162. data/app/views/campaigns/index.xls.builder +75 -0
  163. data/app/views/campaigns/new.js.rjs +0 -4
  164. data/app/views/campaigns/show.html.haml +17 -15
  165. data/app/views/campaigns/show.js.erb +2 -0
  166. data/app/views/campaigns/update.js.rjs +0 -2
  167. data/app/views/comments/_comment.html.haml +6 -5
  168. data/app/views/comments/_edit.html.haml +5 -5
  169. data/app/views/comments/_new.html.haml +6 -5
  170. data/app/views/comments/create.js.rjs +1 -1
  171. data/app/views/contacts/_contact.html.haml +5 -52
  172. data/app/views/contacts/_contacts.html.haml +1 -0
  173. data/app/views/contacts/_edit.html.haml +3 -2
  174. data/app/views/contacts/_index_brief.html.haml +25 -0
  175. data/app/views/contacts/_index_full.html.haml +57 -0
  176. data/app/views/contacts/_index_long.html.haml +43 -0
  177. data/app/views/contacts/_new.html.haml +4 -2
  178. data/app/views/contacts/_section_extra.html.haml +26 -0
  179. data/app/views/contacts/_section_general.html.haml +22 -0
  180. data/app/views/contacts/_sidebar_index.html.haml +0 -3
  181. data/app/views/contacts/_sidebar_show.html.haml +2 -10
  182. data/app/views/contacts/_title_bar.html.haml +11 -0
  183. data/app/views/contacts/_top_section.html.haml +1 -1
  184. data/app/views/contacts/create.js.rjs +1 -2
  185. data/app/views/contacts/destroy.js.rjs +1 -1
  186. data/app/views/contacts/edit.js.rjs +0 -2
  187. data/app/views/contacts/index.html.haml +6 -14
  188. data/app/views/contacts/index.js.rjs +3 -1
  189. data/app/views/contacts/index.xls.builder +102 -0
  190. data/app/views/contacts/new.js.rjs +0 -2
  191. data/app/views/contacts/show.html.haml +15 -15
  192. data/app/views/contacts/show.js.erb +2 -0
  193. data/app/views/entities/_basic_search.html.haml +22 -0
  194. data/app/views/entities/_permissions.html.haml +41 -0
  195. data/app/views/entities/_search.html.haml +15 -0
  196. data/app/views/entities/_section_custom_fields.html.haml +11 -0
  197. data/app/views/entities/_title_bar.html.haml +12 -0
  198. data/app/views/entities/attach.js.rjs +1 -1
  199. data/app/views/entities/opportunities.js.rjs +1 -1
  200. data/app/views/entities/versions.js.erb +3 -0
  201. data/app/views/fields/_edit_custom_field_group.html.haml +8 -0
  202. data/app/views/fields/_group.html.haml +11 -20
  203. data/app/views/fields/_group_table.html.haml +13 -0
  204. data/app/views/fields/_group_view.html.haml +7 -0
  205. data/app/views/fields/_groups.html.haml +1 -4
  206. data/app/views/fields/_sidebar_show.html.haml +5 -4
  207. data/app/views/home/_account.html.haml +29 -0
  208. data/app/views/home/_activity.html.haml +16 -6
  209. data/app/views/home/_opportunity.html.haml +41 -0
  210. data/app/views/home/_options.html.haml +1 -1
  211. data/app/views/home/_task.html.haml +46 -0
  212. data/app/views/home/index.html.haml +32 -1
  213. data/app/views/home/index.js.rjs +1 -0
  214. data/app/views/layouts/_header.html.haml +3 -3
  215. data/app/views/layouts/_sidebar.html.haml +1 -3
  216. data/app/views/layouts/_tabbed.html.haml +2 -3
  217. data/app/views/layouts/_tabless.html.haml +1 -1
  218. data/app/views/layouts/admin/_header.html.haml +1 -1
  219. data/app/views/layouts/application.html.haml +7 -8
  220. data/app/views/layouts/header.xls.builder +8 -0
  221. data/app/views/leads/_contact.html.haml +1 -2
  222. data/app/views/leads/_convert.html.haml +1 -2
  223. data/app/views/leads/_convert_permissions.html.haml +21 -11
  224. data/app/views/leads/_edit.html.haml +3 -2
  225. data/app/views/leads/_index_brief.html.haml +41 -0
  226. data/app/views/leads/_index_long.html.haml +62 -0
  227. data/app/views/leads/_lead.html.haml +5 -62
  228. data/app/views/leads/_new.html.haml +4 -2
  229. data/app/views/leads/_opportunity.html.haml +1 -1
  230. data/app/views/leads/_sidebar_index.html.haml +3 -3
  231. data/app/views/leads/_sidebar_show.html.haml +3 -3
  232. data/app/views/leads/_status.html.haml +1 -1
  233. data/app/views/leads/_title_bar.html.haml +16 -0
  234. data/app/views/leads/convert.js.rjs +0 -1
  235. data/app/views/leads/create.js.rjs +1 -2
  236. data/app/views/leads/destroy.js.rjs +1 -1
  237. data/app/views/leads/edit.js.rjs +0 -2
  238. data/app/views/leads/index.html.haml +6 -13
  239. data/app/views/leads/index.js.rjs +3 -1
  240. data/app/views/leads/index.xls.builder +100 -0
  241. data/app/views/leads/new.js.rjs +0 -2
  242. data/app/views/leads/promote.js.rjs +0 -1
  243. data/app/views/leads/show.html.haml +13 -18
  244. data/app/views/leads/show.js.erb +2 -0
  245. data/app/views/{shared/_lists.html.haml → lists/_sidebar.html.haml} +0 -0
  246. data/app/views/lists/create.js.rjs +1 -1
  247. data/app/views/opportunities/_edit.html.haml +3 -2
  248. data/app/views/opportunities/_index_brief.html.haml +29 -0
  249. data/app/views/opportunities/_index_long.html.haml +59 -0
  250. data/app/views/opportunities/_new.html.haml +4 -2
  251. data/app/views/opportunities/_opportunity.html.haml +5 -57
  252. data/app/views/opportunities/_sidebar_index.html.haml +3 -3
  253. data/app/views/opportunities/_sidebar_show.html.haml +2 -2
  254. data/app/views/opportunities/_title_bar.html.haml +11 -0
  255. data/app/views/opportunities/_top_section.html.haml +2 -2
  256. data/app/views/opportunities/create.js.rjs +4 -6
  257. data/app/views/opportunities/destroy.js.rjs +1 -1
  258. data/app/views/opportunities/edit.js.rjs +0 -3
  259. data/app/views/opportunities/index.html.haml +6 -14
  260. data/app/views/opportunities/index.js.rjs +3 -1
  261. data/app/views/opportunities/index.xls.builder +69 -0
  262. data/app/views/opportunities/new.js.rjs +1 -5
  263. data/app/views/opportunities/show.html.haml +14 -14
  264. data/app/views/opportunities/show.js.erb +2 -0
  265. data/app/views/opportunities/update.js.rjs +0 -1
  266. data/app/views/passwords/new.html.haml +1 -1
  267. data/app/views/shared/_add_comment.html.haml +8 -0
  268. data/app/views/shared/_address.html.haml +1 -1
  269. data/app/views/shared/_address_show.html.haml +1 -1
  270. data/app/views/shared/_edit_comment.html.haml +2 -2
  271. data/app/views/shared/_export.html.haml +2 -1
  272. data/app/views/shared/_paginate_with_per_page.html.haml +14 -0
  273. data/app/views/shared/_recently.html.haml +1 -1
  274. data/app/views/shared/_search.html.haml +1 -1
  275. data/app/views/shared/_tags.html.haml +1 -2
  276. data/app/views/shared/_tasks.html.haml +2 -2
  277. data/app/views/tasks/_completed.html.haml +3 -3
  278. data/app/views/tasks/_new.html.haml +1 -1
  279. data/app/views/tasks/_pending.html.haml +2 -3
  280. data/app/views/tasks/_sidebar_index.html.haml +2 -2
  281. data/app/views/tasks/_top_section.html.haml +5 -3
  282. data/app/views/tasks/create.js.rjs +3 -4
  283. data/app/views/tasks/edit.js.rjs +2 -4
  284. data/app/views/tasks/index.html.haml +1 -1
  285. data/app/views/tasks/index.xls.builder +47 -0
  286. data/app/views/tasks/new.js.rjs +0 -2
  287. data/app/views/tasks/update.js.rjs +0 -1
  288. data/app/views/user_mailer/assigned_entity_notification.html.haml +3 -0
  289. data/app/views/users/_user.html.haml +2 -2
  290. data/app/views/users/_user_report.html.haml +6 -0
  291. data/app/views/users/opportunities_overview.html.haml +16 -0
  292. data/app/views/users/show.html.haml +2 -3
  293. data/app/views/users/update.js.rjs +1 -1
  294. data/app/views/versions/_version.html.haml +4 -19
  295. data/app/views/versions/_version_item.html.haml +8 -0
  296. data/app/views/versions/_versions.html.haml +9 -9
  297. data/config/application.rb +10 -2
  298. data/config/deploy.example.rb +47 -0
  299. data/config/environments/development.rb +1 -0
  300. data/config/environments/production.rb +1 -3
  301. data/config/environments/staging.rb +1 -1
  302. data/config/initializers/action_mailer.rb +10 -8
  303. data/config/initializers/custom_fields.rb +21 -0
  304. data/config/initializers/gravatar.rb +7 -0
  305. data/config/initializers/paper_trail.rb +1 -0
  306. data/config/initializers/ransack.rb +15 -0
  307. data/config/initializers/simple_form.rb +1 -2
  308. data/config/initializers/views.rb +42 -0
  309. data/config/locales/cz_fat_free_crm.yml +0 -10
  310. data/config/locales/de_fat_free_crm.yml +23 -21
  311. data/config/locales/en-GB_fat_free_crm.yml +241 -25
  312. data/config/locales/en-US_fat_free_crm.yml +139 -57
  313. data/config/locales/en-US_ransack.yml +92 -0
  314. data/config/locales/es_fat_free_crm.yml +0 -6
  315. data/config/locales/fr-CA_fat_free_crm.yml +0 -6
  316. data/config/locales/fr_fat_free_crm.yml +3 -14
  317. data/config/locales/it_fat_free_crm.yml +0 -11
  318. data/config/locales/ja_fat_free_crm.yml +0 -10
  319. data/config/locales/pl_fat_free_crm.yml +0 -6
  320. data/config/locales/pt-BR_fat_free_crm.yml +0 -6
  321. data/config/locales/ru_fat_free_crm.yml +0 -9
  322. data/config/locales/sv-SE_fat_free_crm.yml +0 -10
  323. data/config/locales/th_fat_free_crm.yml +0 -6
  324. data/config/locales/zh-CN.yml +4 -0
  325. data/config/locales/zh-CN_fat_free_crm.yml +78 -47
  326. data/config/routes.rb +13 -0
  327. data/config/settings.default.yml +20 -20
  328. data/db/demo/addresses.yml +2 -2
  329. data/db/migrate/20100928030598_create_sessions.rb +5 -0
  330. data/db/migrate/20100928030627_acts_as_taggable_on_migration.rb +6 -6
  331. data/db/migrate/20111201030535_add_field_groups_klass_name.rb +2 -1
  332. data/db/migrate/20120406082136_create_groups.rb +19 -0
  333. data/db/migrate/20120510025219_add_not_null_constraints_for_timestamp_columns.rb +21 -0
  334. data/db/migrate/20120528102124_increase_length_of_version_events.rb +9 -0
  335. data/db/migrate/20120801032706_add_pair_id_to_fields.rb +5 -0
  336. data/db/migrate/20121003063155_add_settings_to_custom_fields.rb +5 -0
  337. data/db/migrate/20121221033947_fix_country_mapping.rb +32 -0
  338. data/db/schema.rb +25 -6
  339. data/fat_free_crm.gemspec +16 -13
  340. data/lib/fat_free_crm.rb +2 -0
  341. data/lib/fat_free_crm/comment_extensions.rb +23 -0
  342. data/lib/fat_free_crm/core_ext/array.rb +8 -2
  343. data/lib/fat_free_crm/fields.rb +24 -2
  344. data/lib/fat_free_crm/gem_dependencies.rb +7 -1
  345. data/lib/fat_free_crm/permissions.rb +47 -26
  346. data/lib/fat_free_crm/version.rb +1 -1
  347. data/lib/fat_free_crm/view_factory.rb +95 -0
  348. data/lib/plugins/country_select/lib/country_select.rb +393 -374
  349. data/lib/tasks/{plugins.rake → db/migrate.rake} +1 -1
  350. data/lib/tasks/{schema_upgrade.rake → db/schema.rake} +2 -1
  351. data/lib/tasks/{mail_processing.rake → ffcrm/comment_replies.rake} +2 -21
  352. data/lib/tasks/ffcrm/config.rake +33 -0
  353. data/lib/tasks/{demo.rake → ffcrm/demo.rake} +3 -2
  354. data/lib/tasks/ffcrm/dropbox.rake +42 -0
  355. data/lib/tasks/ffcrm/settings.rake +46 -0
  356. data/lib/tasks/{fat_free_crm.rake → ffcrm/setup.rake} +1 -39
  357. data/lib/tasks/ffcrm/update_data.rake +256 -0
  358. data/{acceptance → spec/acceptance}/acceptance_helper.rb +5 -4
  359. data/{acceptance → spec/acceptance}/accounts_spec.rb +36 -10
  360. data/spec/acceptance/admin/groups_spec.rb +26 -0
  361. data/spec/acceptance/admin/users_spec.rb +34 -0
  362. data/spec/acceptance/campaigns_spec.rb +101 -0
  363. data/spec/acceptance/contacts_spec.rb +101 -0
  364. data/spec/acceptance/dashboard_spec.rb +62 -0
  365. data/spec/acceptance/leads_spec.rb +109 -0
  366. data/spec/acceptance/opportunities_overview_spec.rb +82 -0
  367. data/spec/acceptance/opportunities_spec.rb +103 -0
  368. data/{acceptance → spec/acceptance}/support/browser.rb +0 -0
  369. data/{acceptance → spec/acceptance}/support/headless.rb +0 -0
  370. data/{acceptance → spec/acceptance}/support/helpers.rb +8 -1
  371. data/{acceptance → spec/acceptance}/support/maintain_sessions.rb +0 -0
  372. data/spec/acceptance/support/paths.rb +42 -0
  373. data/spec/acceptance/support/selector_helpers.rb +31 -0
  374. data/spec/acceptance/tasks_spec.rb +85 -0
  375. data/spec/controllers/admin/groups_controller_spec.rb +5 -0
  376. data/spec/controllers/admin/users_controller_spec.rb +2 -3
  377. data/spec/controllers/applications_controller_spec.rb +40 -0
  378. data/spec/controllers/comments_controller_spec.rb +5 -6
  379. data/spec/controllers/emails_controller_spec.rb +1 -2
  380. data/spec/controllers/entities/accounts_controller_spec.rb +65 -81
  381. data/spec/controllers/entities/campaigns_controller_spec.rb +69 -85
  382. data/spec/controllers/entities/contacts_controller_spec.rb +78 -95
  383. data/spec/controllers/entities/leads_controller_spec.rb +105 -127
  384. data/spec/controllers/entities/opportunities_controller_spec.rb +88 -103
  385. data/spec/controllers/entities_controller_spec.rb +39 -0
  386. data/spec/controllers/home_controller_spec.rb +101 -11
  387. data/spec/controllers/tasks_controller_spec.rb +27 -32
  388. data/spec/controllers/users_controller_spec.rb +95 -28
  389. data/spec/factories/account_factories.rb +2 -2
  390. data/spec/factories/opportunity_factories.rb +12 -4
  391. data/spec/factories/task_factories.rb +4 -0
  392. data/spec/factories/user_factories.rb +9 -2
  393. data/spec/helpers/application_helper_spec.rb +15 -1
  394. data/spec/helpers/groups_helper_spec.rb +15 -0
  395. data/spec/helpers/users_helper_spec.rb +26 -4
  396. data/spec/lib/comment_extensions_spec.rb +29 -0
  397. data/spec/lib/core_ext/{string.rb → string_spec.rb} +0 -1
  398. data/spec/lib/fields_spec.rb +104 -0
  399. data/spec/lib/permissions_spec.rb +144 -0
  400. data/spec/lib/view_factory_spec.rb +68 -0
  401. data/spec/mailers/subscription_mailer_spec.rb +18 -4
  402. data/spec/mailers/user_mailer_spec.rb +134 -0
  403. data/spec/models/entities/account_spec.rb +44 -4
  404. data/spec/models/entities/campaign_spec.rb +3 -4
  405. data/spec/models/entities/contact_spec.rb +45 -5
  406. data/spec/models/entities/lead_spec.rb +3 -4
  407. data/spec/models/entities/opportunity_spec.rb +105 -9
  408. data/spec/models/fields/custom_field_date_pair_spec.rb +106 -0
  409. data/spec/models/fields/custom_field_pair_spec.rb +94 -0
  410. data/spec/models/fields/custom_field_spec.rb +43 -23
  411. data/spec/models/fields/field_spec.rb +3 -5
  412. data/spec/models/observers/entity_observer_spec.rb +65 -0
  413. data/spec/models/polymorphic/task_spec.rb +74 -118
  414. data/spec/models/polymorphic/version_spec.rb +18 -18
  415. data/spec/models/users/group_spec.rb +5 -0
  416. data/spec/models/users/permission_spec.rb +18 -1
  417. data/spec/models/users/preference_spec.rb +5 -1
  418. data/spec/models/users/user_spec.rb +55 -8
  419. data/spec/shared/models.rb +54 -0
  420. data/spec/spec_helper.rb +82 -87
  421. data/spec/support/auth_macros.rb +2 -3
  422. data/spec/views/accounts/_edit.haml_spec.rb +1 -2
  423. data/spec/views/accounts/_new.haml_spec.rb +1 -2
  424. data/spec/views/accounts/create.rjs_spec.rb +1 -3
  425. data/spec/views/accounts/edit.rjs_spec.rb +3 -4
  426. data/spec/views/accounts/index.haml_spec.rb +9 -6
  427. data/spec/views/accounts/new.rjs_spec.rb +2 -9
  428. data/spec/views/accounts/show.haml_spec.rb +1 -2
  429. data/spec/views/accounts/update.rjs_spec.rb +2 -3
  430. data/spec/views/admin/users/_create.haml_spec.rb +1 -2
  431. data/spec/views/admin/users/create.rjs_spec.rb +1 -2
  432. data/spec/views/campaigns/_edit.haml_spec.rb +2 -3
  433. data/spec/views/campaigns/_new.haml_spec.rb +2 -3
  434. data/spec/views/campaigns/create.rjs_spec.rb +0 -3
  435. data/spec/views/campaigns/destroy.rjs_spec.rb +1 -2
  436. data/spec/views/campaigns/edit.rjs_spec.rb +3 -6
  437. data/spec/views/campaigns/index.haml_spec.rb +6 -3
  438. data/spec/views/campaigns/new.rjs_spec.rb +2 -13
  439. data/spec/views/campaigns/show.haml_spec.rb +4 -6
  440. data/spec/views/campaigns/update.rjs_spec.rb +2 -7
  441. data/spec/views/contacts/_edit.haml_spec.rb +6 -7
  442. data/spec/views/contacts/_new.haml_spec.rb +2 -3
  443. data/spec/views/contacts/create.rjs_spec.rb +1 -3
  444. data/spec/views/contacts/edit.rjs_spec.rb +3 -4
  445. data/spec/views/contacts/index.haml_spec.rb +6 -3
  446. data/spec/views/contacts/new.rjs_spec.rb +2 -11
  447. data/spec/views/contacts/show.haml_spec.rb +1 -2
  448. data/spec/views/contacts/update.rjs_spec.rb +2 -3
  449. data/spec/views/home/index.haml_spec.rb +6 -2
  450. data/spec/views/home/index.rjs_spec.rb +1 -2
  451. data/spec/views/home/options.rjs_spec.rb +1 -2
  452. data/spec/views/leads/_convert.haml_spec.rb +1 -2
  453. data/spec/views/leads/_edit.haml_spec.rb +2 -3
  454. data/spec/views/leads/_new.haml_spec.rb +2 -3
  455. data/spec/views/leads/_sidebar_show.haml_spec.rb +1 -2
  456. data/spec/views/leads/convert.rjs_spec.rb +3 -5
  457. data/spec/views/leads/edit.rjs_spec.rb +4 -5
  458. data/spec/views/leads/index.haml_spec.rb +6 -3
  459. data/spec/views/leads/new.rjs_spec.rb +2 -11
  460. data/spec/views/leads/promote.rjs_spec.rb +3 -5
  461. data/spec/views/leads/show.haml_spec.rb +1 -2
  462. data/spec/views/leads/update.rjs_spec.rb +2 -3
  463. data/spec/views/opportunities/_edit.haml_spec.rb +5 -6
  464. data/spec/views/opportunities/_new.haml_spec.rb +2 -4
  465. data/spec/views/opportunities/create.rjs_spec.rb +0 -2
  466. data/spec/views/opportunities/edit.rjs_spec.rb +3 -4
  467. data/spec/views/opportunities/index.haml_spec.rb +7 -4
  468. data/spec/views/opportunities/new.rjs_spec.rb +2 -12
  469. data/spec/views/opportunities/show.haml_spec.rb +1 -2
  470. data/spec/views/opportunities/update.rjs_spec.rb +2 -3
  471. data/spec/views/tasks/_edit.haml_spec.rb +1 -3
  472. data/spec/views/tasks/complete.rjs_spec.rb +2 -3
  473. data/spec/views/tasks/create.rjs_spec.rb +2 -2
  474. data/spec/views/tasks/edit.rjs_spec.rb +1 -2
  475. data/spec/views/tasks/new.rjs_spec.rb +1 -18
  476. data/spec/views/users/avatar.rjs_spec.rb +1 -2
  477. data/spec/views/users/change_password.rjs_spec.rb +1 -2
  478. data/spec/views/users/edit.rjs_spec.rb +1 -2
  479. data/spec/views/users/password.rjs_spec.rb +1 -1
  480. data/spec/views/users/update.rjs_spec.rb +1 -2
  481. data/spec/views/users/upload_avatar.rjs_spec.rb +6 -7
  482. data/vendor/assets/images/brief.png +0 -0
  483. data/vendor/assets/images/chosen-sprite.png +0 -0
  484. data/vendor/assets/images/full.png +0 -0
  485. data/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  486. data/vendor/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  487. data/vendor/assets/images/jquery-ui/ui-bg_flat_100_ffffff_40x100.png +0 -0
  488. data/vendor/assets/images/jquery-ui/ui-bg_flat_25_3875d7_40x100.png +0 -0
  489. data/vendor/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png +0 -0
  490. data/vendor/assets/images/jquery-ui/ui-bg_flat_65_3875d7_40x100.png +0 -0
  491. data/vendor/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png +0 -0
  492. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  493. data/vendor/assets/images/jquery-ui/{ui-icons_ef8c08_256x240.png → ui-icons_0073ea_256x240.png} +0 -0
  494. data/vendor/assets/images/jquery-ui/ui-icons_466bb1_256x240.png +0 -0
  495. data/vendor/assets/images/jquery-ui/{ui-icons_ffd27a_256x240.png → ui-icons_ff0084_256x240.png} +0 -0
  496. data/vendor/assets/images/long.png +0 -0
  497. data/vendor/assets/javascripts/chosen-jquery.js +3 -0
  498. data/vendor/assets/javascripts/chosen-prototype.js +3 -0
  499. data/vendor/assets/javascripts/chosen.jquery.coffee +574 -0
  500. data/vendor/assets/javascripts/chosen.proto.coffee +580 -0
  501. data/vendor/assets/javascripts/jquery.disable.js +23 -0
  502. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-addon.js +1882 -0
  503. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-af.js +20 -0
  504. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ca.js +20 -0
  505. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-cz.js +20 -0
  506. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-de.js +20 -0
  507. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-el.js +20 -0
  508. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-es.js +20 -0
  509. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-et.js +20 -0
  510. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fi.js +20 -0
  511. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr-CA.js +20 -0
  512. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-fr.js +20 -0
  513. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-gl.js +20 -0
  514. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-he.js +20 -0
  515. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-hu.js +20 -0
  516. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-id.js +20 -0
  517. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-it.js +20 -0
  518. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ja.js +20 -0
  519. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ko.js +20 -0
  520. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-lt.js +20 -0
  521. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-nl.js +20 -0
  522. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-no.js +20 -0
  523. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pl.js +20 -0
  524. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-pt.js +20 -0
  525. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ro.js +20 -0
  526. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-ru.js +20 -0
  527. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sk.js +20 -0
  528. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-sv.js +20 -0
  529. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-tr.js +20 -0
  530. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-vi.js +20 -0
  531. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-CN.js +20 -0
  532. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery-ui-timepicker-zh-TW.js +20 -0
  533. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-cz.js +23 -0
  534. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-de.js +23 -0
  535. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-en-GB.js +23 -0
  536. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-es.js +23 -0
  537. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-fr.js +23 -0
  538. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-it.js +23 -0
  539. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ja.js +23 -0
  540. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pl.js +23 -0
  541. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-pt-BR.js +23 -0
  542. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-ru.js +23 -0
  543. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-sv-SE.js +23 -0
  544. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-th.js +23 -0
  545. data/vendor/assets/javascripts/jquery_ui_datepicker/jquery.ui.datepicker-zh-CN.js +23 -0
  546. data/vendor/assets/javascripts/lib/abstract-chosen.coffee +110 -0
  547. data/vendor/assets/javascripts/lib/select-parser.coffee +51 -0
  548. data/vendor/assets/stylesheets/chosen.css.sass +361 -0
  549. data/vendor/assets/stylesheets/{jquery-ui.custom.css.erb → jquery-ui.custom.css} +70 -70
  550. data/zeus.json +21 -0
  551. metadata +304 -140
  552. data/acceptance/support/database_cleaner.rb +0 -16
  553. data/acceptance/support/paths.rb +0 -9
  554. data/app/views/accounts/_options.html.haml +0 -20
  555. data/app/views/accounts/_permissions.html.haml +0 -24
  556. data/app/views/accounts/options.js.rjs +0 -10
  557. data/app/views/admin/fields/_edit.html.haml +0 -9
  558. data/app/views/admin/fields/_new.html.haml +0 -10
  559. data/app/views/admin/fields/_options.html.haml +0 -12
  560. data/app/views/admin/fields/_top_section.html.haml +0 -54
  561. data/app/views/admin/fields/create.js.rjs +0 -16
  562. data/app/views/admin/fields/edit.js.rjs +0 -35
  563. data/app/views/admin/fields/index.js.rjs +0 -6
  564. data/app/views/admin/fields/new.js.rjs +0 -8
  565. data/app/views/admin/fields/options.js.rjs +0 -10
  566. data/app/views/admin/fields/update.js.rjs +0 -17
  567. data/app/views/campaigns/_options.html.haml +0 -20
  568. data/app/views/campaigns/_permissions.html.haml +0 -24
  569. data/app/views/campaigns/options.js.rjs +0 -10
  570. data/app/views/contacts/_options.html.haml +0 -21
  571. data/app/views/contacts/_permissions.html.haml +0 -24
  572. data/app/views/contacts/options.js.rjs +0 -10
  573. data/app/views/entities/_advanced_search.html.haml +0 -12
  574. data/app/views/entities/_condition_fields.html.haml +0 -14
  575. data/app/views/entities/_grouping_fields.html.haml +0 -12
  576. data/app/views/entities/advanced_search.js.rjs +0 -9
  577. data/app/views/entities/versions.js.rjs +0 -3
  578. data/app/views/leads/_options.html.haml +0 -21
  579. data/app/views/leads/_permissions.html.haml +0 -28
  580. data/app/views/leads/options.js.rjs +0 -10
  581. data/app/views/opportunities/_options.html.haml +0 -20
  582. data/app/views/opportunities/_permissions.html.haml +0 -24
  583. data/app/views/opportunities/options.js.rjs +0 -10
  584. data/app/views/shared/_outline.html.haml +0 -9
  585. data/app/views/shared/_per_page.html.haml +0 -10
  586. data/app/views/shared/_sort_by.html.haml +0 -10
  587. data/config/initializers/cancan.rb +0 -151
  588. data/config/initializers/squeel.rb +0 -5
  589. data/public/blank_iframe.html +0 -2
  590. data/spec/views/accounts/options.rjs_spec.rb +0 -59
  591. data/spec/views/campaigns/options.rjs_spec.rb +0 -60
  592. data/spec/views/contacts/options.rjs_spec.rb +0 -61
  593. data/spec/views/leads/options.rjs_spec.rb +0 -61
  594. data/spec/views/opportunities/options.rjs_spec.rb +0 -60
  595. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  596. data/vendor/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  597. data/vendor/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  598. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  599. data/vendor/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  600. data/vendor/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  601. data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  602. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  603. data/vendor/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  604. data/vendor/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
  605. data/vendor/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  606. data/vendor/assets/javascripts/calendar_date_select/calendar_date_select.js +0 -446
  607. data/vendor/assets/javascripts/calendar_date_select/format_american.js +0 -35
  608. data/vendor/assets/javascripts/calendar_date_select/format_danish.js +0 -31
  609. data/vendor/assets/javascripts/calendar_date_select/format_db.js +0 -27
  610. data/vendor/assets/javascripts/calendar_date_select/format_euro_24hr.js +0 -7
  611. data/vendor/assets/javascripts/calendar_date_select/format_euro_24hr_ymd.js +0 -7
  612. data/vendor/assets/javascripts/calendar_date_select/format_finnish.js +0 -32
  613. data/vendor/assets/javascripts/calendar_date_select/format_french.js +0 -24
  614. data/vendor/assets/javascripts/calendar_date_select/format_hyphen_ampm.js +0 -37
  615. data/vendor/assets/javascripts/calendar_date_select/format_iso_date.js +0 -29
  616. data/vendor/assets/javascripts/calendar_date_select/format_italian.js +0 -24
  617. data/vendor/assets/javascripts/calendar_date_select/locale/ar.js +0 -10
  618. data/vendor/assets/javascripts/calendar_date_select/locale/da.js +0 -11
  619. data/vendor/assets/javascripts/calendar_date_select/locale/de.js +0 -11
  620. data/vendor/assets/javascripts/calendar_date_select/locale/es.js +0 -11
  621. data/vendor/assets/javascripts/calendar_date_select/locale/fi.js +0 -10
  622. data/vendor/assets/javascripts/calendar_date_select/locale/fr.js +0 -11
  623. data/vendor/assets/javascripts/calendar_date_select/locale/it.js +0 -9
  624. data/vendor/assets/javascripts/calendar_date_select/locale/ja.js +0 -11
  625. data/vendor/assets/javascripts/calendar_date_select/locale/nl.js +0 -11
  626. data/vendor/assets/javascripts/calendar_date_select/locale/pl.js +0 -11
  627. data/vendor/assets/javascripts/calendar_date_select/locale/pt.js +0 -11
  628. data/vendor/assets/javascripts/calendar_date_select/locale/ru.js +0 -10
  629. data/vendor/assets/javascripts/calendar_date_select/locale/sl.js +0 -11
  630. data/vendor/assets/javascripts/calendar_date_select/locale/sv.js +0 -9
  631. data/vendor/assets/stylesheets/calendar_date_select/blue.css +0 -130
  632. data/vendor/assets/stylesheets/calendar_date_select/default.css +0 -135
  633. data/vendor/assets/stylesheets/calendar_date_select/green.css +0 -142
  634. data/vendor/assets/stylesheets/calendar_date_select/plain.css +0 -128
  635. data/vendor/assets/stylesheets/calendar_date_select/red.css +0 -135
  636. data/vendor/assets/stylesheets/calendar_date_select/silver.css +0 -133
  637. data/vendor/plugins/.gitkeep~master +0 -0
@@ -19,15 +19,8 @@ module OpportunitiesHelper
19
19
 
20
20
  # Sidebar checkbox control for filtering opportunities by stage.
21
21
  #----------------------------------------------------------------------------
22
- def opportunity_stage_checbox(stage, count)
23
- checked = (session[:opportunities_filter] ? session[:opportunities_filter].split(",").include?(stage.to_s) : count.to_i > 0)
24
- onclick = remote_function(
25
- :url => { :action => :filter },
26
- :with => h(%Q/"stage=" + $$("input[name='stage[]']").findAll(function (el) { return el.checked }).pluck("value")/),
27
- :loading => "$('loading').show()",
28
- :complete => "$('loading').hide()"
29
- )
30
- check_box_tag("stage[]", stage, checked, :id => stage, :onclick => onclick)
22
+ def opportunity_stage_checkbox(stage, count)
23
+ entity_filter_checkbox(:stage, stage, count)
31
24
  end
32
25
 
33
26
  # Opportunity summary for RSS/ATOM feeds.
@@ -15,7 +15,7 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  #------------------------------------------------------------------------------
17
17
 
18
- module CrmTagsHelper
18
+ module TagsHelper
19
19
 
20
20
  # Generate tag links for use on asset index pages.
21
21
  #----------------------------------------------------------------------------
@@ -32,6 +32,14 @@ module CrmTagsHelper
32
32
  end.join(" ").html_safe
33
33
  end
34
34
 
35
+ def tags_for_dashboard(model)
36
+ content_tag(:ul) do
37
+ model.tag_list.each do |tag|
38
+ concat(content_tag(:li, tag))
39
+ end
40
+ end.html_safe
41
+ end
42
+
35
43
  # Generate tag links for the asset landing page (shown on a sidebar).
36
44
  #----------------------------------------------------------------------------
37
45
  def tags_for_show(model)
@@ -40,11 +48,4 @@ module CrmTagsHelper
40
48
  end.join(" ").html_safe
41
49
  end
42
50
 
43
- # Return asset tags to be built manually if the asset failed validation.
44
- def unsaved_param_tags(asset)
45
- params[asset][:tag_list].join.split(",").map {|x|
46
- Tag.find_by_name(x.strip)
47
- }.compact.uniq
48
- end
49
51
  end
50
-
@@ -20,7 +20,7 @@ module TasksHelper
20
20
  # Sidebar checkbox control for filtering tasks by due date -- used for
21
21
  # pending and assigned views only.
22
22
  #----------------------------------------------------------------------------
23
- def task_filter_checbox(view, filter, count)
23
+ def task_filter_checkbox(view, filter, count)
24
24
  name = "filter_by_task_#{view}"
25
25
  checked = (session[name] ? session[name].split(",").include?(filter.to_s) : count > 0)
26
26
  onclick = remote_function(
@@ -68,27 +68,12 @@ module TasksHelper
68
68
  onclick << remote_function(:url => complete_task_path(pending), :method => :put, :with => "'bucket=#{bucket}'")
69
69
  end
70
70
 
71
- # Helper to display XLS, CSV, RSS, and ATOM links for tasks.
72
- #----------------------------------------------------------------------------
73
- def links_to_task_export(view)
74
- token = @current_user.single_access_token
75
-
76
- exports = %w(xls csv).map do |format|
77
- link_to(format.upcase, "#{tasks_path}.#{format}?view=#{view}", :title => I18n.t(:"to_#{format}"))
78
- end
79
- feeds = %w(rss atom).map do |format|
80
- link_to(format.upcase, "#{tasks_path}.#{format}?view=#{view}&authentication_credentials=#{token}", :title => I18n.t(:"to_#{format}"))
81
- end
82
-
83
- (exports + feeds).join(' | ')
84
- end
85
-
86
71
  # Task summary for RSS/ATOM feed.
87
72
  #----------------------------------------------------------------------------
88
73
  def task_summary(task)
89
74
  summary = [ task.category.blank? ? t(:other) : t(task.category) ]
90
75
  if @view != "completed"
91
- if @view == "pending" && task.user != @current_user
76
+ if @view == "pending" && task.user != current_user
92
77
  summary << t(:task_from, task.user.full_name)
93
78
  elsif @view == "assigned"
94
79
  summary << t(:task_from, task.assignee.full_name)
@@ -116,7 +101,7 @@ module TasksHelper
116
101
  update_page do |page|
117
102
  page[id].replace ""
118
103
 
119
- if Task.bucket_empty?(bucket, @current_user, @view)
104
+ if Task.bucket_empty?(bucket, current_user, @view)
120
105
  page["list_#{bucket}"].visual_effect :fade, :duration => 0.5
121
106
  end
122
107
  end
@@ -124,7 +109,7 @@ module TasksHelper
124
109
 
125
110
  #----------------------------------------------------------------------------
126
111
  def replace_content(task, bucket = nil)
127
- partial = (task.assigned_to && task.assigned_to != @current_user.id) ? "assigned" : "pending"
112
+ partial = (task.assigned_to && task.assigned_to != current_user.id) ? "assigned" : "pending"
128
113
  update_page do |page|
129
114
  page[dom_id(task)].replace_html :partial => "tasks/#{partial}", :collection => [ task ], :locals => { :bucket => bucket }
130
115
  end
@@ -150,7 +135,7 @@ module TasksHelper
150
135
  #----------------------------------------------------------------------------
151
136
  def reassign(id)
152
137
  update_page do |page|
153
- if @view == "pending" && @task.assigned_to != @current_user.id
138
+ if @view == "pending" && @task.assigned_to != current_user.id
154
139
  page << hide_task_and_possibly_bucket(id, @task_before_update.bucket)
155
140
  page << tasks_flash("#{t(:task_assigned, @task.assignee.full_name)} (" << link_to(t(:view_assigned_tasks), url_for(:controller => :tasks, :view => :assigned)) << ").")
156
141
  elsif @view == "assigned" && @task.assigned_to.blank?
@@ -173,4 +158,3 @@ module TasksHelper
173
158
  end
174
159
 
175
160
  end
176
-
@@ -26,15 +26,22 @@ module UsersHelper
26
26
 
27
27
  def sort_by_language
28
28
  languages.sort.map do |locale, language|
29
- %Q[{ name: "#{language}", on_select: function() { #{redraw(:locale, [ locale, language ], url_for(:action => :redraw))} } }]
29
+ %Q[{ name: "#{language}", on_select: function() { #{redraw(:locale, [ locale, language ], url_for(:action => :redraw, :id => current_user))} } }]
30
30
  end
31
31
  end
32
32
 
33
- def user_select(asset)
34
- collection_select asset, :assigned_to, @users, :id, :full_name,
35
- { :include_blank => "" },
36
- { :"data-placeholder" => t(:myself),
37
- :style => "width:160px" }
33
+ def all_users
34
+ User.by_name
35
+ end
36
+
37
+ def user_select(asset, users, myself)
38
+ user_options = user_options_for_select(users, myself)
39
+ select(asset, :assigned_to, user_options,
40
+ { :include_blank => t(:unassigned) },
41
+ { :style => "width:160px" })
38
42
  end
39
- end
40
43
 
44
+ def user_options_for_select(users, myself)
45
+ (users - [myself]).map{|u| [u.full_name, u.id]}.prepend([t(:myself), myself.id])
46
+ end
47
+ end
@@ -0,0 +1,46 @@
1
+ # Fat Free CRM
2
+ # Copyright (C) 2008-2011 by Michael Dvorkin
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #------------------------------------------------------------------------------
17
+
18
+ module VersionsHelper
19
+
20
+ # Parse the changes for each version
21
+ #----------------------------------------------------------------------------
22
+ def parse_version(attr_name, change)
23
+ if attr_name =~ /^cf_/ and (field = CustomField.where(:name => attr_name).first).present?
24
+ label = field.label
25
+ first = field.render(change.first)
26
+ second = field.render(change.second)
27
+ else
28
+ label = t(attr_name)
29
+ first = change.first
30
+ second = change.second
31
+ end
32
+
33
+ # Find account and link to it.
34
+ if attr_name == 'account_id'
35
+ if first.present? and (account = Account.find_by_id(first))
36
+ first = link_to(h(account.name), account_path(account))
37
+ end
38
+ if second.present? and (account = Account.find_by_id(second))
39
+ second = link_to(h(account.name), account_path(account))
40
+ end
41
+ end
42
+
43
+ [label, first, second]
44
+ end
45
+
46
+ end
@@ -16,17 +16,11 @@
16
16
  #------------------------------------------------------------------------------
17
17
 
18
18
  class DateTimeInput < SimpleForm::Inputs::DateTimeInput
19
- include ActionView::Helpers::TagHelper
20
- include ActionView::Helpers::JavaScriptHelper
21
19
 
22
20
  def input
23
21
  add_autocomplete!
24
- field = @builder.text_field(
25
- attribute_name,
26
- input_html_options.merge(datetime_options(object.send(attribute_name)))
27
- )
28
- element_id = field[/id="([a-z0-9_]*)"/, 1]
29
- field << javascript_tag(%Q{crm.date_select_popup('#{element_id}', false, #{!!(input_type =~ /time/)});})
22
+ input_html_options.merge(input_options)
23
+ @builder.text_field(attribute_name, input_html_options)
30
24
  end
31
25
 
32
26
  def label_target
@@ -35,22 +29,11 @@ class DateTimeInput < SimpleForm::Inputs::DateTimeInput
35
29
 
36
30
  private
37
31
 
38
- def datetime_options(value = nil)
39
- return {} if value.nil?
40
- params = if input_type =~ /time/
41
- [value.localtime, {:format => :mmddyyyy_hhmm}]
42
- else
43
- [value.to_date, {:format => :mmddyyyy}]
44
- end
45
- { :value => I18n.localize(*params).html_safe }
46
- end
47
-
48
- def has_required?
49
- options[:required]
50
- end
32
+ def has_required?
33
+ options[:required]
34
+ end
51
35
 
52
- def add_autocomplete!
53
- input_html_options[:autocomplete] ||= 'off'
54
- end
36
+ def add_autocomplete!
37
+ input_html_options[:autocomplete] ||= 'off'
38
+ end
55
39
  end
56
-
@@ -0,0 +1,77 @@
1
+ # Fat Free CRM
2
+ # Copyright (C) 2008-2011 by Michael Dvorkin
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #------------------------------------------------------------------------------
17
+
18
+ class DatepairInput < SimpleForm::Inputs::Base
19
+
20
+ # Output two date fields: start and end
21
+ #------------------------------------------------------------------------------
22
+ def input
23
+ add_autocomplete!
24
+ out = "<br />".html_safe
25
+
26
+ field1, field2 = get_fields
27
+
28
+ [field1, field2].compact.each do |field|
29
+ out << '<div>'.html_safe
30
+ label = field==field1 ? I18n.t('pair.start') : I18n.t('pair.end')
31
+ [:required, :disabled].each {|k| input_html_options.delete(k)} # ensure these come from field not default options
32
+ input_html_options.merge!(field.input_options)
33
+ input_html_options.merge!(:value => value(field))
34
+ out << "<label#{' class="req"' if input_html_options[:required]}>#{label}</label>".html_safe
35
+ text = @builder.text_field(field.name, input_html_options)
36
+ out << text << '</div>'.html_safe
37
+ end
38
+
39
+ out
40
+ end
41
+
42
+ private
43
+
44
+ # Returns true if either field is required?
45
+ #------------------------------------------------------------------------------
46
+ def required_field?
47
+ get_fields.map(&:required).any?
48
+ end
49
+
50
+ # Turns autocomplete off unless told otherwise.
51
+ #------------------------------------------------------------------------------
52
+ def add_autocomplete!
53
+ input_html_options[:autocomplete] ||= 'off'
54
+ end
55
+
56
+ # Datepicker latches onto the 'date' class.
57
+ #------------------------------------------------------------------------------
58
+ def input_html_classes
59
+ super.push('date')
60
+ end
61
+
62
+ # Returns the pair as [field1, field2]
63
+ #------------------------------------------------------------------------------
64
+ def get_fields
65
+ @field1 ||= CustomField.where(:name => attribute_name).first
66
+ @field2 ||= @field1.try(:paired_with)
67
+ [@field1, @field2]
68
+ end
69
+
70
+ # Serialize into a value recognised by datepicker
71
+ #------------------------------------------------------------------------------
72
+ def value(field)
73
+ val = object.send(field.name)
74
+ val.present? ? val.strftime('%Y-%m-%d') : nil
75
+ end
76
+
77
+ end
@@ -0,0 +1,37 @@
1
+ # Fat Free CRM
2
+ # Copyright (C) 2008-2011 by Michael Dvorkin
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ #------------------------------------------------------------------------------
17
+
18
+ class DatetimepairInput < DatepairInput
19
+
20
+ private
21
+
22
+ # Tell datepicker this is a datetime
23
+ #------------------------------------------------------------------------------
24
+ def input_html_classes
25
+ classes = super.dup
26
+ classes.delete('date')
27
+ classes.push('datetime')
28
+ end
29
+
30
+ # Return value recognised by datepicker and ensure timezone properly set by AR
31
+ #------------------------------------------------------------------------------
32
+ def value(field)
33
+ val = object.send(field.name)
34
+ val.present? ? val.strftime('%Y-%m-%d %H:%M') : nil
35
+ end
36
+
37
+ end
@@ -26,5 +26,15 @@ class UserMailer < ActionMailer::Base
26
26
  :date => Time.now
27
27
  end
28
28
 
29
+ def assigned_entity_notification(entity, assigner)
30
+ @entity_url = url_for(entity)
31
+ @entity_name = entity.name
32
+ @entity_type = entity.class.name
33
+ @assigner_name = assigner.name
34
+ mail :subject => "Fat Free CRM: You have been assigned #{@entity_name} #{@entity_type}",
35
+ :to => entity.assignee.email,
36
+ :from => "Fat Free CRM <notifications@fatfreecrm.com>"
37
+ end
38
+
29
39
  end
30
40
 
@@ -47,12 +47,13 @@ class Account < ActiveRecord::Base
47
47
  has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
48
48
  has_one :billing_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type = 'Billing'"
49
49
  has_one :shipping_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type = 'Shipping'"
50
+ has_many :addresses, :dependent => :destroy, :as => :addressable, :class_name => "Address" # advanced search uses this
50
51
  has_many :emails, :as => :mediator
51
52
 
52
53
  serialize :subscribed_users, Set
53
54
 
54
- accepts_nested_attributes_for :billing_address, :allow_destroy => true
55
- accepts_nested_attributes_for :shipping_address, :allow_destroy => true
55
+ accepts_nested_attributes_for :billing_address, :allow_destroy => true, :reject_if => proc {|attributes| Address.reject_address(attributes)}
56
+ accepts_nested_attributes_for :shipping_address, :allow_destroy => true, :reject_if => proc {|attributes| Address.reject_address(attributes)}
56
57
 
57
58
  scope :state, lambda { |filters|
58
59
  where('category IN (?)' + (filters.delete('other') ? ' OR category IS NULL' : ''), filters)
@@ -60,19 +61,27 @@ class Account < ActiveRecord::Base
60
61
  scope :created_by, lambda { |user| where(:user_id => user.id) }
61
62
  scope :assigned_to, lambda { |user| where(:assigned_to => user.id) }
62
63
 
63
- scope :text_search, lambda { |query|
64
- query = query.gsub(/[^\w\s\-\.'\p{L}]/u, '').strip
65
- where('upper(name) LIKE upper(:m) OR upper(email) LIKE upper(:m)', :m => "%#{query}%")
64
+ scope :text_search, lambda { |query| search('name_or_email_cont' => query).result }
65
+
66
+ scope :visible_on_dashboard, lambda { |user|
67
+ # Show accounts which either belong to the user and are unassigned, or are assigned to the user
68
+ where('(user_id = :user_id AND assigned_to IS NULL) OR assigned_to = :user_id', :user_id => user.id)
66
69
  }
67
70
 
71
+ scope :by_name, order(:name)
72
+
68
73
  uses_user_permissions
69
74
  acts_as_commentable
75
+ uses_comment_extensions
70
76
  acts_as_taggable_on :tags
71
77
  has_paper_trail :ignore => [ :subscribed_users ]
72
78
  has_fields
73
79
  exportable
74
80
  sortable :by => [ "name ASC", "rating DESC", "created_at DESC", "updated_at DESC" ], :default => "created_at DESC"
75
81
 
82
+ has_ransackable_associations %w(contacts opportunities tags activities emails addresses comments tasks)
83
+ ransack_can_autocomplete
84
+
76
85
  validates_presence_of :name, :message => :missing_account_name
77
86
  validates_uniqueness_of :name, :scope => :deleted_at
78
87
  validate :users_for_shared_access
@@ -80,9 +89,8 @@ class Account < ActiveRecord::Base
80
89
 
81
90
  # Default values provided through class methods.
82
91
  #----------------------------------------------------------------------------
83
- def self.per_page ; 20 ; end
84
- def self.outline ; "long" ; end
85
-
92
+ def self.per_page ; 20 ; end
93
+
86
94
  # Extract last line of billing address and get rid of numeric zipcode.
87
95
  #----------------------------------------------------------------------------
88
96
  def location
@@ -111,13 +119,13 @@ class Account < ActiveRecord::Base
111
119
 
112
120
  # Class methods.
113
121
  #----------------------------------------------------------------------------
114
- def self.create_or_select_for(model, params, users)
122
+ def self.create_or_select_for(model, params)
115
123
  if params[:id].present?
116
124
  account = Account.find(params[:id])
117
125
  else
118
126
  account = Account.new(params)
119
127
  if account.access != "Lead" || model.nil?
120
- account.save_with_permissions(users)
128
+ account.save
121
129
  else
122
130
  account.save_with_model_permissions(model)
123
131
  end
@@ -136,4 +144,3 @@ class Account < ActiveRecord::Base
136
144
  self.category = nil if self.category.blank?
137
145
  end
138
146
  end
139
-