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
@@ -18,12 +18,16 @@
18
18
  class EntitiesController < ApplicationController
19
19
  before_filter :require_user
20
20
  before_filter :set_current_tab, :only => [ :index, :show ]
21
+ before_filter :set_view, :only => [ :index, :show, :redraw ]
22
+
23
+ before_filter :set_options, :only => :index
24
+ before_filter :load_ransack_search, :only => :index
21
25
 
22
26
  load_and_authorize_resource
23
27
 
24
28
  after_filter :update_recently_viewed, :only => :show
25
29
 
26
- helper_method :entity, :entities, :search
30
+ helper_method :entity, :entities
27
31
 
28
32
  # Common attach handler for all core controllers.
29
33
  #----------------------------------------------------------------------------
@@ -87,6 +91,17 @@ class EntitiesController < ApplicationController
87
91
  def versions
88
92
  end
89
93
 
94
+ #----------------------------------------------------------------------------
95
+ def field_group
96
+ if @tag = Tag.find_by_name(params[:tag].strip)
97
+ if @field_group = FieldGroup.find_by_tag_id_and_klass_name(@tag.id, klass.to_s)
98
+ @asset = klass.find_by_id(params[:asset_id]) || klass.new
99
+ render 'fields/group' and return
100
+ end
101
+ end
102
+ render :text => ''
103
+ end
104
+
90
105
  protected
91
106
 
92
107
  #----------------------------------------------------------------------------
@@ -108,50 +123,63 @@ protected
108
123
  def entities
109
124
  instance_variable_get("@#{controller_name}") || klass.my
110
125
  end
126
+
127
+ def set_options
128
+ unless params[:cancel].true?
129
+ klass = controller_name.classify.constantize
130
+ action = params['action']
131
+ @per_page = current_user.pref[:"#{controller_name}_per_page"] || klass.per_page
132
+ @sort_by = current_user.pref[:"#{controller_name}_sort_by"] || klass.sort_by
133
+ end
134
+ end
111
135
 
112
136
  private
113
137
 
114
- #----------------------------------------------------------------------------
115
- def get_users
116
- @users ||= User.except(current_user)
117
- end
118
-
119
- #----------------------------------------------------------------------------
120
- def search
121
- @search ||= begin
122
- search = klass.search(params[:q])
123
- search.build_grouping unless search.groupings.any?
124
- search
125
- end
138
+ def ransack_search
139
+ @ransack_search ||= load_ransack_search
140
+ @ransack_search.build_sort if @ransack_search.sorts.empty?
141
+ @ransack_search
126
142
  end
127
143
 
128
144
  # Get list of records for a given model class.
129
145
  #----------------------------------------------------------------------------
130
146
  def get_list_of_records(options = {})
131
- options[:query] ||= params[:query] if params[:query]
132
- self.current_page = options[:page] if options[:page]
133
- query, tags = parse_query_and_tags(options[:query]) if options[:query]
147
+ options[:query] ||= params[:query] if params[:query]
148
+ self.current_page = options[:page] if options[:page]
149
+ query, tags = parse_query_and_tags(options[:query])
134
150
  self.current_query = query
151
+ advanced_search = params[:q].present?
152
+ wants = request.format
135
153
 
136
- order = current_user.pref[:"#{controller_name}_sort_by"] || klass.sort_by
137
-
138
- pages = {
139
- :page => current_page,
140
- :per_page => current_user.pref[:"#{controller_name}_per_page"]
141
- }
154
+ scope = entities.merge(ransack_search.result(:distinct => true))
142
155
 
143
- # Use default processing if no hooks are present. Note that comma-delimited
144
- # export includes deleted records, and the pagination is enabled only for
145
- # plain HTTP, Ajax and XML API requests.
146
- wants = request.format
147
- filter = session[:"#{controller_name}_filter"].to_s.split(',')
156
+ # Get filter from session, unless running an advanced search
157
+ unless advanced_search
158
+ filter = session[:"#{controller_name}_filter"].to_s.split(',')
159
+ scope = scope.state(filter) if filter.present?
160
+ end
148
161
 
149
- scope = entities.merge(search.result)
150
- scope = scope.state(filter) if filter.present?
151
162
  scope = scope.text_search(query) if query.present?
152
163
  scope = scope.tagged_with(tags, :on => :tags) if tags.present?
153
- scope = scope.order(order)
154
- scope = scope.paginate(pages) if wants.html? || wants.js? || wants.xml?
164
+
165
+ # Ignore this order when doing advanced search
166
+ unless advanced_search
167
+ order = current_user.pref[:"#{controller_name}_sort_by"] || klass.sort_by
168
+ scope = scope.order(order)
169
+ end
170
+
171
+ @search_results_count = scope.count
172
+
173
+ # Pagination is disabled for xls and csv requests
174
+ unless (wants.xls? || wants.csv?)
175
+ per_page = if options[:per_page]
176
+ options[:per_page] == 'all' ? @search_results_count : options[:per_page]
177
+ else
178
+ current_user.pref[:"#{controller_name}_per_page"]
179
+ end
180
+ scope = scope.paginate(:page => current_page, :per_page => per_page)
181
+ end
182
+
155
183
  scope
156
184
  end
157
185
 
@@ -160,25 +188,15 @@ private
160
188
  entity.versions.create(:event => :view, :whodunnit => PaperTrail.whodunnit)
161
189
  end
162
190
 
163
- #----------------------------------------------------------------------------
164
- def field_group
165
- if @tag = Tag.find_by_name(params[:tag].strip)
166
- if @field_group = FieldGroup.find_by_tag_id_and_klass_name(@tag.id, klass.to_s)
167
- @asset = klass.find_by_id(params[:asset_id]) || klass.new
168
- render 'fields/group' and return
169
- end
170
- end
171
- render :text => ''
172
- end
173
-
174
191
  # Somewhat simplistic parser that extracts query and hash-prefixed tags from
175
192
  # the search string and returns them as two element array, for example:
176
193
  #
177
194
  # "#real Billy Bones #pirate" => [ "Billy Bones", "real, pirate" ]
178
195
  #----------------------------------------------------------------------------
179
196
  def parse_query_and_tags(search_string)
197
+ return ['', ''] if search_string.blank?
180
198
  query, tags = [], []
181
- search_string.scan(/[\w@\-\.#]+/).each do |token|
199
+ search_string.strip.split(/\s+/).each do |token|
182
200
  if token.starts_with?("#")
183
201
  tags << token[1 .. -1]
184
202
  else
@@ -192,4 +210,14 @@ private
192
210
  def timeline(asset)
193
211
  (asset.comments + asset.emails).sort { |x, y| y.created_at <=> x.created_at }
194
212
  end
213
+
214
+ # Sets the current template view for entities in this context
215
+ #----------------------------------------------------------------------------
216
+ def set_view
217
+ if params['view']
218
+ controller = params['controller']
219
+ action = (params['action'] == 'show') ? 'show' : 'index' # create update redraw filter index actions all use index view
220
+ current_user.pref[:"#{controller}_#{action}_view"] = params['view']
221
+ end
222
+ end
195
223
  end
@@ -26,6 +26,9 @@ class HomeController < ApplicationController
26
26
  hook(:home_controller, self, :params => "it works!")
27
27
 
28
28
  @activities = get_activities
29
+ @my_tasks = Task.visible_on_dashboard(current_user).by_due_at
30
+ @my_opportunities = Opportunity.visible_on_dashboard(current_user).by_closes_on.by_amount
31
+ @my_accounts = Account.visible_on_dashboard(current_user).by_name
29
32
  respond_with(@activities)
30
33
  end
31
34
 
@@ -33,10 +36,10 @@ class HomeController < ApplicationController
33
36
  #----------------------------------------------------------------------------
34
37
  def options
35
38
  unless params[:cancel].true?
36
- @asset = @current_user.pref[:activity_asset] || "all"
37
- @action = @current_user.pref[:activity_event] || "all_events"
38
- @user = @current_user.pref[:activity_user] || "all_users"
39
- @duration = @current_user.pref[:activity_duration] || "two_days"
39
+ @asset = current_user.pref[:activity_asset] || "all"
40
+ @action = current_user.pref[:activity_event] || "all_events"
41
+ @user = current_user.pref[:activity_user] || "all_users"
42
+ @duration = current_user.pref[:activity_duration] || "two_days"
40
43
  @all_users = User.order("first_name, last_name")
41
44
  end
42
45
  end
@@ -44,10 +47,10 @@ class HomeController < ApplicationController
44
47
  # POST /home/redraw AJAX
45
48
  #----------------------------------------------------------------------------
46
49
  def redraw
47
- @current_user.pref[:activity_asset] = params[:asset] if params[:asset]
48
- @current_user.pref[:activity_event] = params[:event] if params[:event]
49
- @current_user.pref[:activity_user] = params[:user] if params[:user]
50
- @current_user.pref[:activity_duration] = params[:duration] if params[:duration]
50
+ current_user.pref[:activity_asset] = params[:asset] if params[:asset]
51
+ current_user.pref[:activity_event] = params[:event] if params[:event]
52
+ current_user.pref[:activity_user] = params[:user] if params[:user]
53
+ current_user.pref[:activity_duration] = params[:duration] if params[:duration]
51
54
 
52
55
  @activities = get_activities
53
56
  render :index
@@ -101,13 +104,14 @@ class HomeController < ApplicationController
101
104
  options[:event] ||= activity_event
102
105
  options[:user] ||= activity_user
103
106
  options[:duration] ||= activity_duration
107
+ options[:max] ||= 500
104
108
 
105
- Version.latest(options).visible_to(@current_user)
109
+ Version.latest(options).visible_to(current_user)
106
110
  end
107
111
 
108
112
  #----------------------------------------------------------------------------
109
113
  def activity_asset
110
- asset = @current_user.pref[:activity_asset]
114
+ asset = current_user.pref[:activity_asset]
111
115
  if asset.nil? || asset == "all"
112
116
  nil
113
117
  else
@@ -117,7 +121,7 @@ class HomeController < ApplicationController
117
121
 
118
122
  #----------------------------------------------------------------------------
119
123
  def activity_event
120
- event = @current_user.pref[:activity_event]
124
+ event = current_user.pref[:activity_event]
121
125
  if event == "all_events"
122
126
  %w(create update destroy)
123
127
  else
@@ -127,28 +131,27 @@ class HomeController < ApplicationController
127
131
 
128
132
  #----------------------------------------------------------------------------
129
133
  def activity_user
130
- user = @current_user.pref[:activity_user]
131
- if user && user != "all users"
132
- user = if user =~ /\s/ # first_name middle_name last_name any_name
133
- name_query = if user.include?(" ")
134
- user.name_permutations.map{ |first, last|
135
- "(upper(first_name) LIKE upper('%#{first}%') AND upper(last_name) LIKE upper('%#{last}%'))"
136
- }.join(" OR ")
137
- else
138
- "upper(first_name) LIKE upper('%#{user}%') OR upper(last_name) LIKE upper('%#{user}%')"
134
+ user = current_user.pref[:activity_user]
135
+ if user && user != "all_users"
136
+ user = if user =~ /@/ # email
137
+ User.where(:email => user).first
138
+ else # first_name middle_name last_name any_name
139
+ name_query = if user.include?(" ")
140
+ user.name_permutations.map{ |first, last|
141
+ "(upper(first_name) LIKE upper('%#{first}%') AND upper(last_name) LIKE upper('%#{last}%'))"
142
+ }.join(" OR ")
143
+ else
144
+ "upper(first_name) LIKE upper('%#{user}%') OR upper(last_name) LIKE upper('%#{user}%')"
145
+ end
146
+ User.where(name_query).first
139
147
  end
140
-
141
- User.where(name_query).first
142
- elsif user =~ /@/ # email
143
- User.where(:email => user).first
144
- end
145
148
  end
146
149
  user.is_a?(User) ? user.id : nil
147
150
  end
148
151
 
149
152
  #----------------------------------------------------------------------------
150
153
  def activity_duration
151
- duration = @current_user.pref[:activity_duration]
154
+ duration = current_user.pref[:activity_duration]
152
155
  if duration
153
156
  words = duration.split("_") # "two_weeks" => 2.weeks
154
157
  if %w(one two).include?(words.first)
@@ -158,4 +161,3 @@ class HomeController < ApplicationController
158
161
  end
159
162
 
160
163
  end
161
-
@@ -19,20 +19,23 @@ class TasksController < ApplicationController
19
19
  before_filter :require_user
20
20
  before_filter :set_current_tab, :only => [ :index, :show ]
21
21
  before_filter :update_sidebar, :only => :index
22
-
22
+
23
23
  # GET /tasks
24
24
  #----------------------------------------------------------------------------
25
25
  def index
26
26
  @view = params[:view] || "pending"
27
- @tasks = Task.find_all_grouped(@current_user, @view)
27
+ @tasks = Task.find_all_grouped(current_user, @view)
28
28
 
29
- respond_with(@tasks)
29
+ respond_with @tasks do |format|
30
+ format.xls { render :layout => 'header' }
31
+ format.csv { render :csv => @tasks.map(&:second).flatten }
32
+ end
30
33
  end
31
34
 
32
35
  # GET /tasks/1
33
36
  #----------------------------------------------------------------------------
34
37
  def show
35
- @task = Task.tracked_by(@current_user).find(params[:id])
38
+ @task = Task.tracked_by(current_user).find(params[:id])
36
39
 
37
40
  respond_with(@task)
38
41
  end
@@ -42,12 +45,11 @@ class TasksController < ApplicationController
42
45
  def new
43
46
  @view = params[:view] || "pending"
44
47
  @task = Task.new
45
- @users = User.except(@current_user).by_name
46
48
  @bucket = Setting.unroll(:task_bucket)[1..-1] << [ t(:due_specific_date, :default => 'On Specific Date...'), :specific_time ]
47
49
  @category = Setting.unroll(:task_category)
48
50
 
49
51
  if params[:related]
50
- model, id = params[:related].split('_')
52
+ model, id = params[:related].split(/_(\d+)/)
51
53
  if related = model.classify.constantize.my.find_by_id(id)
52
54
  instance_variable_set("@asset", related)
53
55
  else
@@ -62,14 +64,13 @@ class TasksController < ApplicationController
62
64
  #----------------------------------------------------------------------------
63
65
  def edit
64
66
  @view = params[:view] || "pending"
65
- @task = Task.tracked_by(@current_user).find(params[:id])
66
- @users = User.except(@current_user).by_name
67
+ @task = Task.tracked_by(current_user).find(params[:id])
67
68
  @bucket = Setting.unroll(:task_bucket)[1..-1] << [ t(:due_specific_date, :default => 'On Specific Date...'), :specific_time ]
68
69
  @category = Setting.unroll(:task_category)
69
70
  @asset = @task.asset if @task.asset_id?
70
71
 
71
72
  if params[:previous].to_s =~ /(\d+)\z/
72
- @previous = Task.tracked_by(@current_user).find_by_id($1) || $1.to_i
73
+ @previous = Task.tracked_by(current_user).find_by_id($1) || $1.to_i
73
74
  end
74
75
 
75
76
  respond_with(@task)
@@ -92,7 +93,7 @@ class TasksController < ApplicationController
92
93
  #----------------------------------------------------------------------------
93
94
  def update
94
95
  @view = params[:view] || "pending"
95
- @task = Task.tracked_by(@current_user).find(params[:id])
96
+ @task = Task.tracked_by(current_user).find(params[:id])
96
97
  @task_before_update = @task.clone
97
98
 
98
99
  if @task.due_at && (@task.due_at < Date.today.to_time)
@@ -105,7 +106,7 @@ class TasksController < ApplicationController
105
106
  if @task.update_attributes(params[:task])
106
107
  @task.bucket = @task.computed_bucket
107
108
  if called_from_index_page?
108
- if Task.bucket_empty?(@task_before_update.bucket, @current_user, @view)
109
+ if Task.bucket_empty?(@task_before_update.bucket, current_user, @view)
109
110
  @empty_bucket = @task_before_update.bucket
110
111
  end
111
112
  update_sidebar
@@ -118,11 +119,11 @@ class TasksController < ApplicationController
118
119
  #----------------------------------------------------------------------------
119
120
  def destroy
120
121
  @view = params[:view] || "pending"
121
- @task = Task.tracked_by(@current_user).find(params[:id])
122
+ @task = Task.tracked_by(current_user).find(params[:id])
122
123
  @task.destroy
123
124
 
124
125
  # Make sure bucket's div gets hidden if we're deleting last task in the bucket.
125
- if Task.bucket_empty?(params[:bucket], @current_user, @view)
126
+ if Task.bucket_empty?(params[:bucket], current_user, @view)
126
127
  @empty_bucket = params[:bucket]
127
128
  end
128
129
 
@@ -133,11 +134,11 @@ class TasksController < ApplicationController
133
134
  # PUT /tasks/1/complete
134
135
  #----------------------------------------------------------------------------
135
136
  def complete
136
- @task = Task.tracked_by(@current_user).find(params[:id])
137
- @task.update_attributes(:completed_at => Time.now, :completed_by => @current_user.id) if @task
137
+ @task = Task.tracked_by(current_user).find(params[:id])
138
+ @task.update_attributes(:completed_at => Time.now, :completed_by => current_user.id) if @task
138
139
 
139
140
  # Make sure bucket's div gets hidden if it's the last completed task in the bucket.
140
- if Task.bucket_empty?(params[:bucket], @current_user)
141
+ if Task.bucket_empty?(params[:bucket], current_user)
141
142
  @empty_bucket = params[:bucket]
142
143
  end
143
144
 
@@ -179,7 +180,7 @@ private
179
180
  def update_sidebar
180
181
  @view = params[:view]
181
182
  @view = "pending" unless %w(pending assigned completed).include?(@view)
182
- @task_total = Task.totals(@current_user, @view)
183
+ @task_total = Task.totals(current_user, @view)
183
184
 
184
185
  # Update filters session if we added, deleted, or completed a task.
185
186
  if @task
@@ -19,9 +19,9 @@ class UsersController < ApplicationController
19
19
 
20
20
  before_filter :require_no_user, :only => [ :new, :create ]
21
21
  before_filter :require_user, :only => [ :show, :redraw ]
22
- before_filter :set_current_tab, :only => [ :show ] # Don't hightlight any tabs.
22
+ before_filter :set_current_tab, :only => [ :show, :opportunities_overview ] # Don't hightlight any tabs.
23
23
  before_filter :require_and_assign_user, :except => [ :new, :create, :show, :avatar, :upload_avatar ]
24
- before_filter :assign_given_or_current_user, :only => [ :show, :avatar, :upload_avatar ]
24
+ before_filter :assign_given_or_current_user, :only => [ :show, :avatar, :upload_avatar, :edit, :update ]
25
25
 
26
26
  load_resource
27
27
 
@@ -76,7 +76,6 @@ class UsersController < ApplicationController
76
76
  #----------------------------------------------------------------------------
77
77
  def update
78
78
  @user.update_attributes(params[:user])
79
-
80
79
  respond_with(@user)
81
80
  end
82
81
 
@@ -146,19 +145,24 @@ class UsersController < ApplicationController
146
145
  # POST /users/1/redraw AJAX
147
146
  #----------------------------------------------------------------------------
148
147
  def redraw
149
- @current_user.preference[:locale] = params[:locale]
150
- render(:update) { |page| page.redirect_to user_path(@current_user) }
148
+ current_user.preference[:locale] = params[:locale]
149
+ render(:update) { |page| page.redirect_to user_path(current_user) }
150
+ end
151
+
152
+ def opportunities_overview
153
+ @users_with_opportunities = User.have_assigned_opportunities.order(:first_name)
154
+ @unassigned_opportunities = Opportunity.unassigned.pipeline.order(:stage)
151
155
  end
152
156
 
153
- private
157
+ private
154
158
 
155
159
  #----------------------------------------------------------------------------
156
160
  def require_and_assign_user
157
161
  require_user
158
- @user = @current_user
162
+ @user = current_user
159
163
  end
160
164
 
161
165
  def assign_given_or_current_user
162
- @user = params[:id] ? User.find(params[:id]) : @current_user
166
+ @user = params[:id] ? User.find(params[:id]) : current_user
163
167
  end
164
168
  end
@@ -19,15 +19,8 @@ module AccountsHelper
19
19
 
20
20
  # Sidebar checkbox control for filtering accounts by category.
21
21
  #----------------------------------------------------------------------------
22
- def account_category_checbox(category, count)
23
- checked = (session[:accounts_filter] ? session[:accounts_filter].split(",").include?(category.to_s) : count.to_i > 0)
24
- onclick = remote_function(
25
- :url => { :action => :filter },
26
- :with => h(%Q/"category=" + $$("input[name='category[]']").findAll(function (el) { return el.checked }).pluck("value")/),
27
- :loading => "$('loading').show()",
28
- :complete => "$('loading').hide()"
29
- )
30
- check_box_tag("category[]", category, checked, :id => category, :onclick => onclick)
22
+ def account_category_checkbox(category, count)
23
+ entity_filter_checkbox(:category, category, count)
31
24
  end
32
25
 
33
26
  # Quick account summary for RSS/ATOM feeds.
@@ -40,7 +33,7 @@ module AccountsHelper
40
33
  t('pluralize.comment', account.comments.count)
41
34
  ].join(', ')
42
35
  end
43
-
36
+
44
37
  def account_select(options = {})
45
38
  # Generates a select list with the first 25 accounts,
46
39
  # and prepends the currently selected account, if available
@@ -50,28 +43,77 @@ module AccountsHelper
50
43
  {:"data-placeholder" => t(:select_an_account),
51
44
  :style => "width:330px; display:none;" }
52
45
  end
53
-
46
+
54
47
  # Select an existing account or create a new one.
55
48
  #----------------------------------------------------------------------------
56
49
  def account_select_or_create(form, &block)
57
50
  options = {}
58
51
  yield options if block_given?
59
-
52
+
60
53
  content_tag(:div, :class => 'label') do
61
54
  t(:account).html_safe +
62
-
55
+
63
56
  content_tag(:span, :id => 'account_create_title') do
64
57
  "(#{t :create_new} #{t :or} <a href='#' onclick='crm.select_account(1); return false;'>#{t :select_existing}</a>):".html_safe
65
58
  end.html_safe +
66
-
59
+
67
60
  content_tag(:span, :id => 'account_select_title') do
68
61
  "(<a href='#' onclick='crm.create_account(1); return false;'>#{t :create_new}</a> #{t :or} #{t :select_existing}):".html_safe
69
62
  end.html_safe +
70
-
63
+
71
64
  content_tag(:span, ':', :id => 'account_disabled_title').html_safe
72
65
  end.html_safe +
73
-
66
+
74
67
  account_select(options).html_safe +
75
68
  form.text_field(:name, :style => 'width:324px; display:none;')
76
69
  end
70
+
71
+ # Output account url for a given contact
72
+ # - a helper so it is easy to override in plugins that allow for several accounts
73
+ #----------------------------------------------------------------------------
74
+ def account_with_url_for(contact)
75
+ contact.account ? link_to(h(contact.account.name), account_path(contact.account)) : ""
76
+ end
77
+
78
+ # Output account with title and department
79
+ # - a helper so it is easy to override in plugins that allow for several accounts
80
+ #----------------------------------------------------------------------------
81
+ def account_with_title_and_department(contact)
82
+ text = if !contact.title.blank? && contact.account
83
+ # works_at: "{{h(job_title)}} at {{h(company)}}"
84
+ content_tag :div, t(:works_at, :job_title => h(contact.title), :company => account_with_url_for(contact)).html_safe
85
+ elsif !contact.title.blank?
86
+ content_tag :div, h(contact.title)
87
+ elsif contact.account
88
+ content_tag :div, account_with_url_for(contact)
89
+ end
90
+ text << t(:department_small, h(contact.department)) unless contact.department.blank?
91
+ text
92
+ end
93
+
94
+ # "title, department at Account name" used in index_brief and index_long
95
+ # - a helper so it is easy to override in plugins that allow for several accounts
96
+ #----------------------------------------------------------------------------
97
+ def brief_account_info(contact)
98
+ text = ""
99
+ title = contact.title
100
+ department = contact.department
101
+ account = contact.account
102
+ account_text = ""
103
+ account_text = link_to_if(can?(:read, account), h(account.name), account_path(account)) if account.present?
104
+
105
+ text << if title.present? && department.present?
106
+ t(:account_with_title_department, :title => h(title), :department => h(department), :account => account_text)
107
+ elsif title.present?
108
+ t(:account_with_title, :title => h(title), :account => account_text)
109
+ elsif department.present?
110
+ t(:account_with_title, :title => h(department), :account => account_text)
111
+ elsif account_text.present?
112
+ t(:works_at, :job_title => "", :company => account_text)
113
+ else
114
+ ""
115
+ end
116
+ text.html_safe
117
+ end
118
+
77
119
  end