fat_free_crm 0.12.3 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fat_free_crm might be problematic. Click here for more details.
- checksums.yaml +5 -13
- data/.travis.yml +1 -11
- data/Gemfile +7 -19
- data/Gemfile.lock +166 -166
- data/Procfile +1 -1
- data/README.md +20 -20
- data/app/assets/javascripts/admin/fields.js.coffee +3 -3
- data/app/assets/javascripts/application.js.erb +3 -0
- data/app/assets/javascripts/crm.js +1 -0
- data/app/assets/javascripts/crm_comments.js.coffee +66 -0
- data/app/assets/javascripts/lists.js.coffee +45 -2
- data/app/assets/javascripts/search.js.coffee +2 -0
- data/app/assets/javascripts/timeago.js +17 -0
- data/app/assets/stylesheets/advanced_search.css.scss +49 -25
- data/app/assets/stylesheets/application.css.erb +3 -0
- data/app/assets/stylesheets/common.scss +13 -0
- data/app/assets/stylesheets/format_buttons.css.scss +15 -10
- data/app/assets/stylesheets/header.scss +3 -0
- data/app/assets/stylesheets/lists.css.scss +4 -0
- data/app/controllers/admin/fields_controller.rb +5 -5
- data/app/controllers/admin/users_controller.rb +1 -3
- data/app/controllers/application_controller.rb +23 -23
- data/app/controllers/comments_controller.rb +3 -31
- data/app/controllers/entities/accounts_controller.rb +3 -3
- data/app/controllers/entities/campaigns_controller.rb +4 -4
- data/app/controllers/entities/contacts_controller.rb +2 -2
- data/app/controllers/entities/leads_controller.rb +3 -3
- data/app/controllers/entities/opportunities_controller.rb +4 -3
- data/app/controllers/entities_controller.rb +6 -6
- data/app/controllers/home_controller.rb +1 -1
- data/app/controllers/lists_controller.rb +8 -1
- data/app/controllers/tasks_controller.rb +1 -1
- data/app/controllers/users_controller.rb +46 -23
- data/app/helpers/admin/application_helper.rb +1 -3
- data/app/helpers/admin/field_groups_helper.rb +2 -1
- data/app/helpers/application_helper.rb +37 -16
- data/app/helpers/home_helper.rb +1 -2
- data/app/helpers/leads_helper.rb +5 -6
- data/app/helpers/tasks_helper.rb +36 -50
- data/app/models/entities/account.rb +10 -7
- data/app/models/entities/campaign.rb +4 -4
- data/app/models/entities/contact.rb +8 -5
- data/app/models/entities/lead.rb +8 -8
- data/app/models/entities/opportunity.rb +13 -18
- data/app/models/fields/custom_field.rb +10 -0
- data/app/models/fields/field.rb +3 -3
- data/app/models/fields/field_group.rb +1 -1
- data/app/models/list.rb +1 -0
- data/app/models/polymorphic/address.rb +3 -3
- data/app/models/polymorphic/comment.rb +2 -4
- data/app/models/polymorphic/task.rb +32 -27
- data/app/models/setting.rb +3 -9
- data/app/models/users/ability.rb +2 -13
- data/app/models/users/user.rb +12 -15
- data/app/views/accounts/_edit.html.haml +1 -1
- data/app/views/accounts/_index_brief.html.haml +3 -3
- data/app/views/accounts/_index_long.html.haml +3 -3
- data/app/views/accounts/_new.html.haml +1 -1
- data/app/views/accounts/create.js.haml +17 -0
- data/app/views/accounts/destroy.js.haml +6 -0
- data/app/views/accounts/edit.js.haml +32 -0
- data/app/views/accounts/index.js.haml +11 -0
- data/app/views/accounts/index.xls.builder +9 -7
- data/app/views/accounts/new.js.haml +11 -0
- data/app/views/accounts/show.js.haml +5 -0
- data/app/views/accounts/update.js.haml +17 -0
- data/app/views/admin/field_groups/_edit.html.haml +1 -1
- data/app/views/admin/field_groups/_new.html.haml +1 -1
- data/app/views/admin/field_groups/confirm.js.haml +7 -0
- data/app/views/admin/field_groups/create.js.haml +20 -0
- data/app/views/admin/field_groups/destroy.js.haml +9 -0
- data/app/views/admin/field_groups/edit.js.haml +12 -0
- data/app/views/admin/field_groups/new.js.haml +8 -0
- data/app/views/admin/field_groups/update.js.haml +8 -0
- data/app/views/admin/fields/_field.html.haml +2 -2
- data/app/views/admin/fields/_form.html.haml +2 -2
- data/app/views/admin/fields/create.js.haml +17 -0
- data/app/views/admin/fields/destroy.js.haml +8 -0
- data/app/views/admin/fields/edit.js.haml +3 -0
- data/app/views/admin/fields/update.js.haml +13 -0
- data/app/views/admin/groups/_edit.html.haml +1 -1
- data/app/views/admin/groups/_new.html.haml +1 -1
- data/app/views/admin/groups/create.js.haml +10 -0
- data/app/views/admin/groups/destroy.js.haml +9 -0
- data/app/views/admin/groups/edit.js.haml +14 -0
- data/app/views/admin/groups/index.html.haml +1 -1
- data/app/views/admin/groups/index.js.haml +2 -0
- data/app/views/admin/groups/new.js.haml +9 -0
- data/app/views/admin/groups/update.js.haml +9 -0
- data/app/views/admin/tags/_edit.html.haml +1 -1
- data/app/views/admin/tags/_new.html.haml +1 -1
- data/app/views/admin/tags/confirm.js.haml +7 -0
- data/app/views/admin/tags/create.js.haml +11 -0
- data/app/views/admin/tags/destroy.js.haml +10 -0
- data/app/views/admin/tags/edit.js.haml +20 -0
- data/app/views/admin/tags/new.js.haml +7 -0
- data/app/views/admin/tags/update.js.haml +9 -0
- data/app/views/admin/users/_edit.html.haml +1 -1
- data/app/views/admin/users/_new.html.haml +1 -1
- data/app/views/admin/users/_user.html.haml +1 -1
- data/app/views/admin/users/confirm.js.haml +7 -0
- data/app/views/admin/users/create.js.haml +10 -0
- data/app/views/admin/users/destroy.js.haml +10 -0
- data/app/views/admin/users/edit.js.haml +20 -0
- data/app/views/admin/users/index.js.haml +2 -0
- data/app/views/admin/users/new.js.haml +9 -0
- data/app/views/admin/users/reactivate.js.haml +3 -0
- data/app/views/admin/users/suspend.js.haml +3 -0
- data/app/views/admin/users/update.js.haml +9 -0
- data/app/views/authentications/new.html.haml +1 -1
- data/app/views/campaigns/_edit.html.haml +1 -1
- data/app/views/campaigns/_new.html.haml +1 -1
- data/app/views/campaigns/create.js.haml +20 -0
- data/app/views/campaigns/destroy.js.haml +6 -0
- data/app/views/campaigns/edit.js.haml +33 -0
- data/app/views/campaigns/index.js.haml +11 -0
- data/app/views/campaigns/index.xls.builder +9 -7
- data/app/views/campaigns/new.js.haml +11 -0
- data/app/views/campaigns/show.js.haml +5 -0
- data/app/views/campaigns/update.js.haml +20 -0
- data/app/views/comments/_comment.html.haml +1 -1
- data/app/views/comments/_edit.html.haml +1 -1
- data/app/views/comments/_new.html.haml +3 -2
- data/app/views/comments/create.js.haml +14 -0
- data/app/views/comments/destroy.js.haml +5 -0
- data/app/views/comments/edit.js.haml +11 -0
- data/app/views/comments/update.js.haml +9 -0
- data/app/views/contacts/_edit.html.haml +1 -1
- data/app/views/contacts/_index_full.html.haml +1 -1
- data/app/views/contacts/_index_long.html.haml +2 -1
- data/app/views/contacts/_new.html.haml +1 -1
- data/app/views/contacts/_section_general.html.haml +3 -3
- data/app/views/contacts/create.js.haml +23 -0
- data/app/views/contacts/destroy.js.haml +9 -0
- data/app/views/contacts/edit.js.haml +35 -0
- data/app/views/contacts/index.js.haml +11 -0
- data/app/views/contacts/index.xls.builder +9 -7
- data/app/views/contacts/new.js.haml +13 -0
- data/app/views/contacts/show.js.haml +5 -0
- data/app/views/contacts/update.js.haml +22 -0
- data/app/views/emails/destroy.js.haml +5 -0
- data/app/views/entities/_permissions.html.haml +1 -1
- data/app/views/entities/attach.js.haml +21 -0
- data/app/views/entities/contacts.js.haml +3 -0
- data/app/views/entities/discard.js.haml +6 -0
- data/app/views/entities/leads.js.haml +3 -0
- data/app/views/entities/opportunities.js.haml +3 -0
- data/app/views/entities/subscription_update.js.haml +4 -0
- data/app/views/entities/versions.js.haml +3 -0
- data/app/views/fields/group.js.erb +3 -0
- data/app/views/home/_account.html.haml +3 -3
- data/app/views/home/_opportunity.html.haml +3 -3
- data/app/views/home/index.atom.builder +3 -3
- data/app/views/home/index.js.haml +7 -0
- data/app/views/home/index.rss.builder +2 -2
- data/app/views/home/options.js.haml +7 -0
- data/app/views/layouts/_footer.html.haml +0 -4
- data/app/views/layouts/_sidebar.html.haml +1 -0
- data/app/views/layouts/_tabbed.html.haml +1 -4
- data/app/views/layouts/admin/application.html.haml +0 -1
- data/app/views/layouts/application.html.haml +5 -7
- data/app/views/leads/_convert.html.haml +1 -1
- data/app/views/leads/_edit.html.haml +1 -1
- data/app/views/leads/_index_long.html.haml +2 -2
- data/app/views/leads/_new.html.haml +1 -1
- data/app/views/leads/convert.js.haml +35 -0
- data/app/views/leads/create.js.haml +21 -0
- data/app/views/leads/destroy.js.haml +9 -0
- data/app/views/leads/edit.js.haml +35 -0
- data/app/views/leads/index.js.haml +11 -0
- data/app/views/leads/index.xls.builder +9 -7
- data/app/views/leads/new.js.haml +11 -0
- data/app/views/leads/promote.js.haml +26 -0
- data/app/views/leads/reject.js.haml +12 -0
- data/app/views/leads/show.js.haml +5 -0
- data/app/views/leads/update.js.haml +26 -0
- data/app/views/lists/_personal_sidebar.html.haml +28 -0
- data/app/views/lists/_sidebar.html.haml +10 -7
- data/app/views/lists/create.js.haml +10 -0
- data/app/views/lists/destroy.js.haml +1 -0
- data/app/views/opportunities/_edit.html.haml +1 -1
- data/app/views/opportunities/_index_brief.html.haml +3 -3
- data/app/views/opportunities/_index_long.html.haml +3 -3
- data/app/views/opportunities/_new.html.haml +1 -2
- data/app/views/opportunities/_top_section.html.haml +4 -0
- data/app/views/opportunities/contacts.js.haml +3 -0
- data/app/views/opportunities/create.js.haml +29 -0
- data/app/views/opportunities/destroy.js.haml +13 -0
- data/app/views/opportunities/edit.js.haml +35 -0
- data/app/views/opportunities/index.js.haml +11 -0
- data/app/views/opportunities/index.xls.builder +9 -7
- data/app/views/opportunities/new.js.haml +13 -0
- data/app/views/opportunities/show.js.haml +5 -0
- data/app/views/opportunities/update.js.haml +25 -0
- data/app/views/passwords/edit.html.haml +1 -1
- data/app/views/passwords/new.html.haml +1 -1
- data/app/views/shared/_comment.html.haml +1 -1
- data/app/views/shared/_inline_styles.html.haml +1 -1
- data/app/views/tasks/_edit.html.haml +1 -1
- data/app/views/tasks/_new.html.haml +1 -1
- data/app/views/tasks/complete.js.haml +14 -0
- data/app/views/tasks/create.js.haml +39 -0
- data/app/views/tasks/destroy.js.haml +7 -0
- data/app/views/tasks/discard.js.haml +1 -0
- data/app/views/tasks/edit.js.haml +26 -0
- data/app/views/tasks/filter.js.haml +4 -0
- data/app/views/tasks/index.xls.builder +7 -5
- data/app/views/tasks/new.js.haml +8 -0
- data/app/views/tasks/update.js.haml +19 -0
- data/app/views/users/_password.html.haml +1 -1
- data/app/views/users/_profile.html.haml +1 -1
- data/app/views/users/avatar.js.haml +9 -0
- data/app/views/users/change_password.js.haml +13 -0
- data/app/views/users/edit.js.haml +9 -0
- data/app/views/users/new.html.haml +1 -1
- data/app/views/users/password.js.haml +10 -0
- data/app/views/users/update.js.haml +9 -0
- data/app/views/users/upload_avatar.js.haml +7 -0
- data/app/views/versions/_version.html.haml +1 -1
- data/config/application.rb +1 -4
- data/config/environments/production.rb +3 -2
- data/config/initializers/custom_field_ransack_translations.rb +15 -0
- data/config/initializers/locale.rb +9 -1
- data/config/initializers/secret_token.rb +1 -25
- data/config/initializers/views.rb +20 -20
- data/config/locales/cz.yml +245 -211
- data/config/locales/cz_fat_free_crm.yml +105 -181
- data/config/locales/de.yml +162 -118
- data/config/locales/de_fat_free_crm.yml +760 -731
- data/config/locales/de_ransack.yml +91 -0
- data/config/locales/en-GB.yml +158 -119
- data/config/locales/en-GB_fat_free_crm.yml +161 -279
- data/config/locales/en-US.yml +158 -121
- data/config/locales/en-US_fat_free_crm.yml +185 -179
- data/config/locales/en-US_ransack.yml +81 -82
- data/config/locales/es.yml +164 -123
- data/config/locales/es_fat_free_crm.yml +151 -209
- data/config/locales/fr-CA.yml +167 -130
- data/config/locales/fr-CA_fat_free_crm.yml +142 -202
- data/config/locales/fr.yml +170 -125
- data/config/locales/fr_fat_free_crm.yml +199 -302
- data/config/locales/it.yml +158 -122
- data/config/locales/it_fat_free_crm.yml +105 -168
- data/config/locales/ja.yml +162 -131
- data/config/locales/ja_fat_free_crm.yml +118 -188
- data/config/locales/pl.yml +168 -132
- data/config/locales/pl_fat_free_crm.yml +115 -186
- data/config/locales/pt-BR.yml +160 -127
- data/config/locales/pt-BR_fat_free_crm.yml +125 -182
- data/config/locales/ru.yml +256 -233
- data/config/locales/ru_fat_free_crm.yml +136 -193
- data/config/locales/sv-SE.yml +164 -181
- data/config/locales/sv-SE_fat_free_crm.yml +129 -193
- data/config/locales/th_fat_free_crm.yml +114 -194
- data/config/locales/zh-CN.yml +176 -149
- data/config/locales/zh-CN_fat_free_crm.yml +78 -167
- data/config/routes.rb +1 -1
- data/config/settings.default.yml +74 -23
- data/custom_plan.rb +11 -0
- data/db/migrate/20131207033244_add_user_id_to_lists.rb +6 -0
- data/db/schema.rb +4 -1
- data/fat_free_crm.gemspec +3 -3
- data/lib/fat_free_crm.rb +1 -11
- data/lib/fat_free_crm/export_csv.rb +3 -3
- data/lib/fat_free_crm/fields.rb +10 -0
- data/lib/fat_free_crm/gem_dependencies.rb +1 -2
- data/lib/fat_free_crm/i18n.rb +9 -5
- data/lib/fat_free_crm/version.rb +2 -2
- data/lib/fat_free_crm/view_factory.rb +8 -5
- data/lib/tasks/ffcrm/config.rake +9 -12
- data/lib/tasks/ffcrm/missing_translations.rake +2 -1
- data/spec/controllers/admin/users_controller_spec.rb +6 -4
- data/spec/controllers/applications_controller_spec.rb +4 -4
- data/spec/controllers/authentications_controller_spec.rb +15 -15
- data/spec/controllers/comments_controller_spec.rb +9 -87
- data/spec/controllers/emails_controller_spec.rb +1 -1
- data/spec/controllers/entities/accounts_controller_spec.rb +7 -7
- data/spec/controllers/entities/campaigns_controller_spec.rb +5 -5
- data/spec/controllers/entities/contacts_controller_spec.rb +7 -7
- data/spec/controllers/entities/leads_controller_spec.rb +14 -14
- data/spec/controllers/entities/opportunities_controller_spec.rb +8 -8
- data/spec/controllers/home_controller_spec.rb +6 -6
- data/spec/controllers/tasks_controller_spec.rb +7 -7
- data/spec/controllers/users_controller_spec.rb +22 -50
- data/spec/features/support/selector_helpers.rb +1 -6
- data/spec/features/tasks_spec.rb +2 -2
- data/spec/helpers/application_helper_spec.rb +15 -15
- data/spec/lib/fields_spec.rb +29 -29
- data/spec/lib/mail_processor/base_spec.rb +7 -7
- data/spec/lib/mail_processor/dropbox_spec.rb +3 -3
- data/spec/lib/view_factory_spec.rb +14 -14
- data/spec/models/entities/opportunity_spec.rb +1 -1
- data/spec/models/fields/custom_field_date_pair_spec.rb +14 -14
- data/spec/models/fields/custom_field_pair_spec.rb +13 -13
- data/spec/models/fields/custom_field_spec.rb +5 -5
- data/spec/models/fields/field_spec.rb +2 -2
- data/spec/models/observers/entity_observer_spec.rb +2 -2
- data/spec/models/users/user_spec.rb +7 -7
- data/spec/routing/comments_routing_spec.rb +0 -9
- data/spec/shared/controllers.rb +75 -77
- data/spec/shared/models.rb +1 -1
- data/spec/spec_helper.rb +1 -2
- data/spec/support/auth_macros.rb +3 -3
- data/spec/support/mail_processor_mocks.rb +13 -13
- data/spec/views/accounts/_edit.haml_spec.rb +1 -1
- data/spec/views/accounts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
- data/spec/views/accounts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
- data/spec/views/accounts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
- data/spec/views/accounts/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -11
- data/spec/views/accounts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/accounts/show.haml_spec.rb +1 -1
- data/spec/views/accounts/{update.rjs_spec.rb → update.js.haml_spec.rb} +16 -25
- data/spec/views/admin/field_groups/create.js.haml_spec.rb +31 -0
- data/spec/views/admin/field_groups/destroy.js.haml_spec.rb +31 -0
- data/spec/views/admin/field_groups/edit.js.haml_spec.rb +24 -0
- data/spec/views/admin/field_groups/new.js.haml_spec.rb +25 -0
- data/spec/views/admin/field_groups/update.js.haml_spec.rb +30 -0
- data/spec/views/admin/users/_create.haml_spec.rb +1 -1
- data/spec/views/admin/users/{create.rjs_spec.rb → create.js.haml_spec.rb} +6 -9
- data/spec/views/admin/users/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
- data/spec/views/admin/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +6 -12
- data/spec/views/admin/users/index.haml_spec.rb +0 -0
- data/spec/views/admin/users/{index.rjs_spec.rb → index.js.haml_spec.rb} +3 -5
- data/spec/views/admin/users/{new.rjs_spec.rb → new.js.haml_spec.rb} +4 -6
- data/spec/views/admin/users/{reactivate.rjs_spec.rb → reactivate.js.haml_spec.rb} +2 -4
- data/spec/views/admin/users/show.haml_spec.rb +0 -0
- data/spec/views/admin/users/{suspend.rjs_spec.rb → suspend.js.haml_spec.rb} +2 -4
- data/spec/views/admin/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +6 -10
- data/spec/views/campaigns/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -14
- data/spec/views/campaigns/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -7
- data/spec/views/campaigns/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +11 -19
- data/spec/views/campaigns/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
- data/spec/views/campaigns/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/campaigns/{update.rjs_spec.rb → update.js.haml_spec.rb} +14 -21
- data/spec/views/comments/{new.rjs_spec.rb → edit.js.haml_spec.rb} +12 -9
- data/spec/views/contacts/{create.rjs_spec.rb → create.js.haml_spec.rb} +9 -16
- data/spec/views/contacts/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +6 -8
- data/spec/views/contacts/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -19
- data/spec/views/contacts/index.haml_spec.rb +1 -1
- data/spec/views/contacts/{index.rjs_spec.rb → index.js.html_spec.rb} +7 -11
- data/spec/views/contacts/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -7
- data/spec/views/contacts/{update.rjs_spec.rb → update.js.haml_spec.rb} +20 -35
- data/spec/views/home/{index.rjs_spec.rb → index.js.haml_spec.rb} +2 -4
- data/spec/views/home/{options.rjs_spec.rb → options.js.haml_spec.rb} +7 -12
- data/spec/views/leads/{convert.rjs_spec.rb → convert.js.haml_spec.rb} +12 -20
- data/spec/views/leads/{create.rjs_spec.rb → create.js.haml_spec.rb} +13 -19
- data/spec/views/leads/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -12
- data/spec/views/leads/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +12 -20
- data/spec/views/leads/{index.rjs_spec.rb → index.js.haml_spec.rb} +5 -9
- data/spec/views/leads/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/leads/{promote.rjs_spec.rb → promote.js.haml_spec.rb} +28 -43
- data/spec/views/leads/{reject.rjs_spec.rb → reject.js.haml_spec.rb} +10 -17
- data/spec/views/leads/{update.rjs_spec.rb → update.js.haml_spec.rb} +25 -38
- data/spec/views/opportunities/{create.rjs_spec.rb → create.js.haml_spec.rb} +16 -26
- data/spec/views/opportunities/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +13 -16
- data/spec/views/opportunities/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +10 -18
- data/spec/views/opportunities/{index.rjs_spec.rb → index.js.haml_spec.rb} +7 -12
- data/spec/views/opportunities/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/opportunities/{update.rjs_spec.rb → update.js.haml_spec.rb} +29 -46
- data/spec/views/tasks/_edit.haml_spec.rb +1 -1
- data/spec/views/tasks/{complete.rjs_spec.rb → complete.js.haml_spec.rb} +9 -14
- data/spec/views/tasks/{create.rjs_spec.rb → create.js.haml_spec.rb} +25 -33
- data/spec/views/tasks/{destroy.rjs_spec.rb → destroy.js.haml_spec.rb} +9 -11
- data/spec/views/tasks/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +9 -14
- data/spec/views/tasks/index.haml_spec.rb +1 -2
- data/spec/views/tasks/{new.rjs_spec.rb → new.js.haml_spec.rb} +6 -8
- data/spec/views/tasks/{update.rjs_spec.rb → update.js.haml_spec.rb} +28 -41
- data/spec/views/users/{avatar.rjs_spec.rb → avatar.js.haml_spec.rb} +7 -9
- data/spec/views/users/{change_password.rjs_spec.rb → change_password.js.haml_spec.rb} +10 -12
- data/spec/views/users/{edit.rjs_spec.rb → edit.js.haml_spec.rb} +8 -10
- data/spec/views/users/{password.rjs_spec.rb → password.js.haml_spec.rb} +9 -11
- data/spec/views/users/{update.rjs_spec.rb → update.js.haml_spec.rb} +7 -15
- data/spec/views/users/{upload_avatar.rjs_spec.rb → upload_avatar.js.haml_spec.rb} +8 -10
- data/vendor/assets/javascripts/ajax-chosen-jquery.js +2 -0
- data/vendor/assets/javascripts/ajax-chosen-prototype.js +2 -0
- data/vendor/assets/javascripts/ajax-chosen.jquery.coffee +81 -0
- data/vendor/assets/javascripts/ajax-chosen.proto.coffee +98 -0
- data/vendor/assets/javascripts/jquery_timeago/index.js +17 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.cz.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.de.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-GB.js +20 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.en-US.js +20 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.es.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr-CA.js +17 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.fr.js +17 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.it.js +16 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ja.js +19 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.js +194 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pl.js +31 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.pt-BR.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.ru.js +34 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.sv-SE.js +18 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.th.js +20 -0
- data/vendor/assets/javascripts/jquery_timeago/jquery.timeago.zh-CN.js +20 -0
- data/zeus.json +2 -1
- metadata +240 -245
- data/app/assets/images/delete.png +0 -0
- data/app/assets/images/iconset_attribution.png +0 -0
- data/app/views/accounts/create.js.rjs +0 -14
- data/app/views/accounts/destroy.js.rjs +0 -3
- data/app/views/accounts/edit.js.rjs +0 -33
- data/app/views/accounts/index.js.rjs +0 -8
- data/app/views/accounts/new.js.rjs +0 -9
- data/app/views/accounts/show.js.erb +0 -2
- data/app/views/accounts/update.js.rjs +0 -17
- data/app/views/admin/field_groups/confirm.js.rjs +0 -6
- data/app/views/admin/field_groups/create.js.rjs +0 -20
- data/app/views/admin/field_groups/destroy.js.rjs +0 -11
- data/app/views/admin/field_groups/edit.js.rjs +0 -14
- data/app/views/admin/field_groups/new.js.rjs +0 -9
- data/app/views/admin/field_groups/update.js.rjs +0 -9
- data/app/views/admin/fields/create.js.erb +0 -19
- data/app/views/admin/fields/destroy.js.erb +0 -9
- data/app/views/admin/fields/edit.js.erb +0 -1
- data/app/views/admin/fields/update.js.erb +0 -13
- data/app/views/admin/groups/create.js.rjs +0 -11
- data/app/views/admin/groups/destroy.js.rjs +0 -11
- data/app/views/admin/groups/edit.js.rjs +0 -21
- data/app/views/admin/groups/index.js.rjs +0 -2
- data/app/views/admin/groups/new.js.rjs +0 -9
- data/app/views/admin/groups/update.js.rjs +0 -10
- data/app/views/admin/tags/confirm.js.rjs +0 -6
- data/app/views/admin/tags/create.js.rjs +0 -12
- data/app/views/admin/tags/destroy.js.rjs +0 -11
- data/app/views/admin/tags/edit.js.rjs +0 -21
- data/app/views/admin/tags/new.js.rjs +0 -8
- data/app/views/admin/tags/update.js.rjs +0 -10
- data/app/views/admin/users/confirm.js.rjs +0 -6
- data/app/views/admin/users/create.js.rjs +0 -11
- data/app/views/admin/users/destroy.js.rjs +0 -11
- data/app/views/admin/users/edit.js.rjs +0 -21
- data/app/views/admin/users/index.js.rjs +0 -3
- data/app/views/admin/users/new.js.rjs +0 -8
- data/app/views/admin/users/reactivate.js.rjs +0 -3
- data/app/views/admin/users/suspend.js.rjs +0 -3
- data/app/views/admin/users/update.js.rjs +0 -10
- data/app/views/campaigns/create.js.rjs +0 -18
- data/app/views/campaigns/destroy.js.rjs +0 -3
- data/app/views/campaigns/edit.js.rjs +0 -34
- data/app/views/campaigns/index.js.rjs +0 -8
- data/app/views/campaigns/new.js.rjs +0 -9
- data/app/views/campaigns/show.js.erb +0 -2
- data/app/views/campaigns/update.js.rjs +0 -21
- data/app/views/comments/create.js.rjs +0 -11
- data/app/views/comments/destroy.js.rjs +0 -6
- data/app/views/comments/edit.js.rjs +0 -11
- data/app/views/comments/new.js.rjs +0 -14
- data/app/views/comments/update.js.rjs +0 -11
- data/app/views/contacts/create.js.rjs +0 -19
- data/app/views/contacts/destroy.js.rjs +0 -7
- data/app/views/contacts/edit.js.rjs +0 -36
- data/app/views/contacts/index.js.rjs +0 -8
- data/app/views/contacts/new.js.rjs +0 -11
- data/app/views/contacts/show.js.erb +0 -2
- data/app/views/contacts/update.js.rjs +0 -22
- data/app/views/emails/destroy.js.rjs +0 -6
- data/app/views/entities/attach.js.rjs +0 -24
- data/app/views/entities/contacts.js.rjs +0 -3
- data/app/views/entities/discard.js.rjs +0 -7
- data/app/views/entities/leads.js.rjs +0 -3
- data/app/views/entities/opportunities.js.rjs +0 -3
- data/app/views/entities/subscription_update.js.rjs +0 -4
- data/app/views/entities/versions.js.erb +0 -3
- data/app/views/fields/group.js.rjs +0 -7
- data/app/views/home/index.js.rjs +0 -7
- data/app/views/home/options.js.rjs +0 -8
- data/app/views/leads/convert.js.rjs +0 -37
- data/app/views/leads/create.js.rjs +0 -19
- data/app/views/leads/destroy.js.rjs +0 -7
- data/app/views/leads/edit.js.rjs +0 -36
- data/app/views/leads/index.js.rjs +0 -8
- data/app/views/leads/new.js.rjs +0 -9
- data/app/views/leads/promote.js.rjs +0 -27
- data/app/views/leads/reject.js.rjs +0 -10
- data/app/views/leads/show.js.erb +0 -2
- data/app/views/leads/update.js.rjs +0 -27
- data/app/views/lists/create.js.rjs +0 -9
- data/app/views/lists/destroy.js.rjs +0 -1
- data/app/views/opportunities/contacts.js.rjs +0 -3
- data/app/views/opportunities/create.js.rjs +0 -29
- data/app/views/opportunities/destroy.js.rjs +0 -11
- data/app/views/opportunities/edit.js.rjs +0 -36
- data/app/views/opportunities/index.js.rjs +0 -8
- data/app/views/opportunities/new.js.rjs +0 -12
- data/app/views/opportunities/show.js.erb +0 -2
- data/app/views/opportunities/update.js.rjs +0 -26
- data/app/views/tasks/complete.js.rjs +0 -17
- data/app/views/tasks/create.js.rjs +0 -41
- data/app/views/tasks/destroy.js.rjs +0 -7
- data/app/views/tasks/discard.rjs +0 -1
- data/app/views/tasks/edit.js.rjs +0 -23
- data/app/views/tasks/filter.js.rjs +0 -1
- data/app/views/tasks/new.js.rjs +0 -9
- data/app/views/tasks/update.js.rjs +0 -21
- data/app/views/users/avatar.js.rjs +0 -10
- data/app/views/users/change_password.js.rjs +0 -15
- data/app/views/users/edit.js.rjs +0 -10
- data/app/views/users/password.js.rjs +0 -11
- data/app/views/users/update.js.rjs +0 -10
- data/app/views/users/upload_avatar.js.rjs +0 -8
- data/lib/fat_free_crm/secret_token_generator.rb +0 -65
- data/spec/lib/secret_token_generator_spec.rb +0 -79
- data/spec/models/users/abilities/user_ability_spec.rb +0 -58
- data/spec/support/rjs_support.rb +0 -14
- data/vendor/assets/images/brief.png +0 -0
- data/vendor/assets/images/full.png +0 -0
- data/vendor/assets/images/long.png +0 -0
- data/vendor/assets/images/tab_icons/accounts.png +0 -0
- data/vendor/assets/images/tab_icons/accounts_active.png +0 -0
- data/vendor/assets/images/tab_icons/campaigns.png +0 -0
- data/vendor/assets/images/tab_icons/campaigns_active.png +0 -0
- data/vendor/assets/images/tab_icons/contacts.png +0 -0
- data/vendor/assets/images/tab_icons/contacts_active.png +0 -0
- data/vendor/assets/images/tab_icons/dashboard.png +0 -0
- data/vendor/assets/images/tab_icons/dashboard_active.png +0 -0
- data/vendor/assets/images/tab_icons/leads.png +0 -0
- data/vendor/assets/images/tab_icons/leads_active.png +0 -0
- data/vendor/assets/images/tab_icons/opportunities.png +0 -0
- data/vendor/assets/images/tab_icons/opportunities_active.png +0 -0
- data/vendor/assets/images/tab_icons/tasks.png +0 -0
- data/vendor/assets/images/tab_icons/tasks_active.png +0 -0
@@ -49,6 +49,7 @@
|
|
49
49
|
class CustomField < Field
|
50
50
|
after_validation :update_column, :on => :update
|
51
51
|
before_create :add_column
|
52
|
+
after_create :add_ransack_translation
|
52
53
|
|
53
54
|
SAFE_DB_TRANSITIONS = {
|
54
55
|
:any => [['date', 'time', 'timestamp'], ['integer', 'float']],
|
@@ -129,6 +130,15 @@ class CustomField < Field
|
|
129
130
|
klass.serialize_custom_fields!
|
130
131
|
end
|
131
132
|
|
133
|
+
# Adds custom field translation for Ransack
|
134
|
+
def add_ransack_translation
|
135
|
+
I18n.backend.store_translations(Setting.locale.to_sym, {
|
136
|
+
ransack: {attributes: {klass.model_name.singular => {name => label}}}
|
137
|
+
})
|
138
|
+
# Reset Ransack cache
|
139
|
+
Ransack::Helpers::FormBuilder.cached_searchable_attributes_for_base = {}
|
140
|
+
end
|
141
|
+
|
132
142
|
# Change database column type only if safe to do so
|
133
143
|
# Note: columns will never be renamed or destroyed
|
134
144
|
#------------------------------------------------------------------------------
|
data/app/models/fields/field.rb
CHANGED
@@ -33,9 +33,9 @@ class Field < ActiveRecord::Base
|
|
33
33
|
|
34
34
|
belongs_to :field_group
|
35
35
|
|
36
|
-
scope :core_fields, where(:type => 'CoreField')
|
37
|
-
scope :custom_fields, where("type != 'CoreField'")
|
38
|
-
scope :without_pairs, where(:pair_id => nil)
|
36
|
+
scope :core_fields, -> { where(:type => 'CoreField') }
|
37
|
+
scope :custom_fields, -> { where("type != 'CoreField'") }
|
38
|
+
scope :without_pairs, -> { where(:pair_id => nil) }
|
39
39
|
|
40
40
|
delegate :klass, :klass_name, :klass_name=, :to => :field_group
|
41
41
|
|
@@ -54,7 +54,7 @@ class FieldGroup < ActiveRecord::Base
|
|
54
54
|
# When deleted, transfer fields to default field group
|
55
55
|
def move_fields_to_default_field_group
|
56
56
|
default_group = FieldGroup.find_by_name_and_klass_name("custom_fields", klass_name)
|
57
|
-
default_group.fields << fields
|
57
|
+
default_group.fields << fields if default_group
|
58
58
|
self.reload
|
59
59
|
end
|
60
60
|
|
data/app/models/list.rb
CHANGED
@@ -28,9 +28,9 @@ class Address < ActiveRecord::Base
|
|
28
28
|
|
29
29
|
has_paper_trail :meta => { :related => :addressable }
|
30
30
|
|
31
|
-
scope :business,
|
32
|
-
scope :billing,
|
33
|
-
scope :shipping,
|
31
|
+
scope :business, -> { where("address_type='Business'") }
|
32
|
+
scope :billing, -> { where("address_type='Billing'") }
|
33
|
+
scope :shipping, -> { where("address_type='Shipping'") }
|
34
34
|
|
35
35
|
# Checks if the address is blank for both single and compound addresses.
|
36
36
|
#----------------------------------------------------------------------------
|
@@ -44,12 +44,10 @@ class Comment < ActiveRecord::Base
|
|
44
44
|
|
45
45
|
# Notify subscribed users when a comment is added, unless user created this comment
|
46
46
|
def notify_subscribers
|
47
|
+
return unless Rails.application.config.action_mailer.smtp_settings.present?
|
47
48
|
commentable.subscribed_users.reject{|user_id| user_id == user.id}.each do |subscriber_id|
|
48
49
|
if subscriber = User.find_by_id(subscriber_id)
|
49
|
-
|
50
|
-
if Rails.application.config.action_mailer.smtp_settings.present?
|
51
|
-
SubscriptionMailer.comment_notification(subscriber, self).deliver
|
52
|
-
end
|
50
|
+
SubscriptionMailer.comment_notification(subscriber, self).deliver
|
53
51
|
end
|
54
52
|
end
|
55
53
|
end
|
@@ -37,62 +37,67 @@ class Task < ActiveRecord::Base
|
|
37
37
|
|
38
38
|
# Tasks created by the user for herself, or assigned to her by others. That's
|
39
39
|
# what gets shown on Tasks/Pending and Tasks/Completed pages.
|
40
|
-
scope :my,
|
40
|
+
scope :my, ->(*args) {
|
41
41
|
options = args[0] || {}
|
42
|
-
user_option = options[:user] || User.current_user
|
42
|
+
user_option = (options.is_a?(Hash) ? options[:user] : options) || User.current_user
|
43
43
|
includes(:assignee).
|
44
44
|
where('(user_id = ? AND assigned_to IS NULL) OR assigned_to = ?', user_option, user_option).
|
45
45
|
order(options[:order] || 'name ASC').
|
46
46
|
limit(options[:limit]) # nil selects all records
|
47
47
|
}
|
48
48
|
|
49
|
+
scope :created_by, ->(user) { where(:user_id => user.id) }
|
50
|
+
scope :assigned_to, ->(user) { where(:assigned_to => user.id) }
|
51
|
+
|
49
52
|
# Tasks assigned by the user to others. That's what we see on Tasks/Assigned.
|
50
|
-
scope :assigned_by,
|
53
|
+
scope :assigned_by, ->(user) {
|
51
54
|
includes(:assignee).
|
52
55
|
where('user_id = ? AND assigned_to IS NOT NULL AND assigned_to != ?', user.id, user.id)
|
53
56
|
}
|
54
57
|
|
55
58
|
# Tasks created by the user or assigned to the user, i.e. the union of the two
|
56
59
|
# scopes above. That's the tasks the user is allowed to see and track.
|
57
|
-
scope :tracked_by,
|
60
|
+
scope :tracked_by, ->(user) {
|
58
61
|
includes(:assignee).
|
59
62
|
where('user_id = ? OR assigned_to = ?', user.id, user.id)
|
60
63
|
}
|
61
64
|
|
62
|
-
scope :visible_on_dashboard,
|
65
|
+
scope :visible_on_dashboard, ->(user) {
|
63
66
|
# Show opportunities which either belong to the user and are unassigned, or are assigned to the user
|
64
67
|
where('(user_id = :user_id AND assigned_to IS NULL) OR assigned_to = :user_id', :user_id => user.id).where('completed_at IS NULL')
|
65
68
|
}
|
66
69
|
|
67
|
-
scope :by_due_at,
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
scope :by_due_at, -> {
|
71
|
+
order({
|
72
|
+
"MySQL" => "due_at NOT NULL, due_at ASC",
|
73
|
+
"PostgreSQL" => "due_at ASC NULLS FIRST"
|
74
|
+
}[ActiveRecord::Base.connection.adapter_name] || :due_at)
|
75
|
+
}
|
71
76
|
|
72
77
|
|
73
78
|
# Status based scopes to be combined with the due date and completion time.
|
74
|
-
scope :pending, where('completed_at IS NULL').order('tasks.due_at, tasks.id')
|
75
|
-
scope :assigned, where('completed_at IS NULL AND assigned_to IS NOT NULL').order('tasks.due_at, tasks.id')
|
76
|
-
scope :completed, where('completed_at IS NOT NULL').order('tasks.completed_at DESC')
|
79
|
+
scope :pending, -> { where('completed_at IS NULL').order('tasks.due_at, tasks.id') }
|
80
|
+
scope :assigned, -> { where('completed_at IS NULL AND assigned_to IS NOT NULL').order('tasks.due_at, tasks.id') }
|
81
|
+
scope :completed, -> { where('completed_at IS NOT NULL').order('tasks.completed_at DESC') }
|
77
82
|
|
78
83
|
# Due date scopes.
|
79
|
-
scope :due_asap, where("due_at IS NULL AND bucket = 'due_asap'").order('tasks.id DESC')
|
80
|
-
scope :overdue, where('due_at IS NOT NULL AND due_at < ?', Time.zone.now.midnight.utc).order('tasks.id DESC')
|
81
|
-
scope :due_today, where('due_at >= ? AND due_at < ?', Time.zone.now.midnight.utc, Time.zone.now.midnight.tomorrow.utc).order('tasks.id DESC')
|
82
|
-
scope :due_tomorrow, where('due_at >= ? AND due_at < ?', Time.zone.now.midnight.tomorrow.utc, Time.zone.now.midnight.tomorrow.utc + 1.day).order('tasks.id DESC')
|
83
|
-
scope :due_this_week, where('due_at >= ? AND due_at < ?', Time.zone.now.midnight.tomorrow.utc + 1.day, Time.zone.now.next_week.utc).order('tasks.id DESC')
|
84
|
-
scope :due_next_week, where('due_at >= ? AND due_at < ?', Time.zone.now.next_week.utc, Time.zone.now.next_week.end_of_week.utc + 1.day).order('tasks.id DESC')
|
85
|
-
scope :due_later, where("(due_at IS NULL AND bucket = 'due_later') OR due_at >= ?", Time.zone.now.next_week.end_of_week.utc + 1.day).order('tasks.id DESC')
|
84
|
+
scope :due_asap, -> { where("due_at IS NULL AND bucket = 'due_asap'").order('tasks.id DESC') }
|
85
|
+
scope :overdue, -> { where('due_at IS NOT NULL AND due_at < ?', Time.zone.now.midnight.utc).order('tasks.id DESC') }
|
86
|
+
scope :due_today, -> { where('due_at >= ? AND due_at < ?', Time.zone.now.midnight.utc, Time.zone.now.midnight.tomorrow.utc).order('tasks.id DESC') }
|
87
|
+
scope :due_tomorrow, -> { where('due_at >= ? AND due_at < ?', Time.zone.now.midnight.tomorrow.utc, Time.zone.now.midnight.tomorrow.utc + 1.day).order('tasks.id DESC') }
|
88
|
+
scope :due_this_week, -> { where('due_at >= ? AND due_at < ?', Time.zone.now.midnight.tomorrow.utc + 1.day, Time.zone.now.next_week.utc).order('tasks.id DESC') }
|
89
|
+
scope :due_next_week, -> { where('due_at >= ? AND due_at < ?', Time.zone.now.next_week.utc, Time.zone.now.next_week.end_of_week.utc + 1.day).order('tasks.id DESC') }
|
90
|
+
scope :due_later, -> { where("(due_at IS NULL AND bucket = 'due_later') OR due_at >= ?", Time.zone.now.next_week.end_of_week.utc + 1.day).order('tasks.id DESC') }
|
86
91
|
|
87
92
|
# Completion time scopes.
|
88
|
-
scope :completed_today, where('completed_at >= ? AND completed_at < ?', Time.zone.now.midnight.utc, Time.zone.now.midnight.tomorrow.utc)
|
89
|
-
scope :completed_yesterday, where('completed_at >= ? AND completed_at < ?', Time.zone.now.midnight.yesterday.utc, Time.zone.now.midnight.utc)
|
90
|
-
scope :completed_this_week, where('completed_at >= ? AND completed_at < ?', Time.zone.now.beginning_of_week.utc , Time.zone.now.midnight.yesterday.utc)
|
91
|
-
scope :completed_last_week, where('completed_at >= ? AND completed_at < ?', Time.zone.now.beginning_of_week.utc - 7.days, Time.zone.now.beginning_of_week.utc)
|
92
|
-
scope :completed_this_month, where('completed_at >= ? AND completed_at < ?', Time.zone.now.beginning_of_month.utc, Time.zone.now.beginning_of_week.utc - 7.days)
|
93
|
-
scope :completed_last_month, where('completed_at >= ? AND completed_at < ?', (Time.zone.now.beginning_of_month.utc - 1.day).beginning_of_month.utc, Time.zone.now.beginning_of_month.utc)
|
94
|
-
|
95
|
-
scope :text_search,
|
93
|
+
scope :completed_today, -> { where('completed_at >= ? AND completed_at < ?', Time.zone.now.midnight.utc, Time.zone.now.midnight.tomorrow.utc) }
|
94
|
+
scope :completed_yesterday, -> { where('completed_at >= ? AND completed_at < ?', Time.zone.now.midnight.yesterday.utc, Time.zone.now.midnight.utc) }
|
95
|
+
scope :completed_this_week, -> { where('completed_at >= ? AND completed_at < ?', Time.zone.now.beginning_of_week.utc , Time.zone.now.midnight.yesterday.utc) }
|
96
|
+
scope :completed_last_week, -> { where('completed_at >= ? AND completed_at < ?', Time.zone.now.beginning_of_week.utc - 7.days, Time.zone.now.beginning_of_week.utc) }
|
97
|
+
scope :completed_this_month, -> { where('completed_at >= ? AND completed_at < ?', Time.zone.now.beginning_of_month.utc, Time.zone.now.beginning_of_week.utc - 7.days) }
|
98
|
+
scope :completed_last_month, -> { where('completed_at >= ? AND completed_at < ?', (Time.zone.now.beginning_of_month.utc - 1.day).beginning_of_month.utc, Time.zone.now.beginning_of_month.utc) }
|
99
|
+
|
100
|
+
scope :text_search, ->(query) {
|
96
101
|
query = query.gsub(/[^\w\s\-\.'\p{L}]/u, '').strip
|
97
102
|
where('upper(name) LIKE upper(?)', "%#{query}%")
|
98
103
|
}
|
data/app/models/setting.rb
CHANGED
@@ -101,16 +101,10 @@ class Setting < ActiveRecord::Base
|
|
101
101
|
|
102
102
|
# Loads settings from YAML files
|
103
103
|
def load_settings_from_yaml(file)
|
104
|
-
|
105
|
-
|
106
|
-
settings = YAML.load_file(file)
|
107
|
-
# Merge settings into current settings hash (recursively)
|
108
|
-
@@yaml_settings.deep_merge!(settings)
|
109
|
-
rescue Exception => ex
|
110
|
-
puts "Settings couldn't be loaded from #{file}: #{ex.message}"
|
111
|
-
end
|
112
|
-
yaml_settings
|
104
|
+
settings = YAML.load_file(file)
|
105
|
+
@@yaml_settings.deep_merge!(settings)
|
113
106
|
end
|
107
|
+
|
114
108
|
end
|
115
109
|
|
116
110
|
ActiveSupport.run_load_hooks(:fat_free_crm_setting, self)
|
data/app/models/users/ability.rb
CHANGED
@@ -9,22 +9,11 @@ class Ability
|
|
9
9
|
include CanCan::Ability
|
10
10
|
|
11
11
|
def initialize(user)
|
12
|
-
|
13
|
-
# handle signup
|
14
|
-
can(:create, User) if User.can_signup?
|
15
|
-
|
16
12
|
if user.present?
|
17
13
|
entities = [Account, Campaign, Contact, Lead, Opportunity]
|
18
14
|
|
19
|
-
|
20
|
-
can :
|
21
|
-
|
22
|
-
# Tasks
|
23
|
-
can :create, Task
|
24
|
-
can :manage, Task, user: user.id
|
25
|
-
can :manage, Task, assigned_to: user.id
|
26
|
-
|
27
|
-
# Entities
|
15
|
+
can :create, :all
|
16
|
+
can :read, [User] # for search autocomplete
|
28
17
|
can :manage, entities, :access => 'Public'
|
29
18
|
can :manage, entities + [Task], :user_id => user.id
|
30
19
|
can :manage, entities + [Task], :assigned_to => user.id
|
data/app/models/users/user.rb
CHANGED
@@ -56,27 +56,28 @@ class User < ActiveRecord::Base
|
|
56
56
|
has_many :assigned_opportunities, :class_name => 'Opportunity', :foreign_key => 'assigned_to'
|
57
57
|
has_many :permissions, :dependent => :destroy
|
58
58
|
has_many :preferences, :dependent => :destroy
|
59
|
+
has_many :lists
|
59
60
|
has_and_belongs_to_many :groups
|
60
61
|
|
61
62
|
has_paper_trail :ignore => [:last_request_at, :perishable_token]
|
62
63
|
|
63
64
|
# For some reason this does not play nice with has_paper_trail when set as default scope
|
64
|
-
scope :by_id, order('id DESC')
|
65
|
-
scope :except,
|
66
|
-
scope :by_name, order('first_name, last_name, email')
|
65
|
+
scope :by_id, -> { order('id DESC') }
|
66
|
+
scope :except, ->(user) { where('id != ?', user.id).by_name }
|
67
|
+
scope :by_name, -> { order('first_name, last_name, email') }
|
67
68
|
|
68
|
-
scope :text_search,
|
69
|
+
scope :text_search, ->(query) {
|
69
70
|
query = query.gsub(/[^\w\s\-\.'\p{L}]/u, '').strip
|
70
71
|
where('upper(username) LIKE upper(:s) OR upper(first_name) LIKE upper(:s) OR upper(last_name) LIKE upper(:s)', :s => "%#{query}%")
|
71
72
|
}
|
72
73
|
|
73
|
-
scope :my,
|
74
|
-
accessible_by(User.current_ability)
|
75
|
-
}
|
74
|
+
scope :my, -> { accessible_by(User.current_ability) }
|
76
75
|
|
77
|
-
scope :have_assigned_opportunities,
|
78
|
-
|
79
|
-
|
76
|
+
scope :have_assigned_opportunities, -> {
|
77
|
+
joins("INNER JOIN opportunities ON users.id = opportunities.assigned_to")
|
78
|
+
.where("opportunities.stage <> 'lost' AND opportunities.stage <> 'won'")
|
79
|
+
.select('DISTINCT(users.id), users.*')
|
80
|
+
}
|
80
81
|
|
81
82
|
acts_as_authentic do |c|
|
82
83
|
c.session_class = Authentication
|
@@ -171,7 +172,7 @@ class User < ActiveRecord::Base
|
|
171
172
|
# Prevent deleting a user unless she has no artifacts left.
|
172
173
|
#----------------------------------------------------------------------------
|
173
174
|
def check_if_has_related_assets
|
174
|
-
artifacts = %w(Account Campaign Lead Contact Opportunity Comment).inject(0) do |sum, asset|
|
175
|
+
artifacts = %w(Account Campaign Lead Contact Opportunity Comment Task).inject(0) do |sum, asset|
|
175
176
|
klass = asset.constantize
|
176
177
|
sum += klass.assigned_to(self).count if asset != "Comment"
|
177
178
|
sum += klass.created_by(self).count
|
@@ -187,10 +188,6 @@ class User < ActiveRecord::Base
|
|
187
188
|
Ability.new(User.current_user)
|
188
189
|
end
|
189
190
|
|
190
|
-
def can_signup?
|
191
|
-
[ :allowed, :needs_approval ].include? Setting.user_signup
|
192
|
-
end
|
193
|
-
|
194
191
|
end
|
195
192
|
|
196
193
|
ActiveSupport.run_load_hooks(:fat_free_crm_user, self)
|
@@ -21,11 +21,11 @@
|
|
21
21
|
–
|
22
22
|
%tt
|
23
23
|
= account.location << ", " unless account.location.blank?
|
24
|
-
- user_name = account.
|
24
|
+
- user_name = account.user.try(:full_name)
|
25
25
|
- if user_name
|
26
|
-
= t(:added_by, :time_ago =>
|
26
|
+
= t(:added_by, :time_ago => timeago(account.created_at), :user => h(user_name)).html_safe << " | "
|
27
27
|
- else
|
28
|
-
= t(:added_ago, :value =>
|
28
|
+
= t(:added_ago, :value => timeago(account.created_at)).html_safe << " | "
|
29
29
|
= t('pluralize.contact', account.contacts.count) << " | "
|
30
30
|
= t('pluralize.opportunity', account.opportunities.count)
|
31
31
|
|
@@ -21,11 +21,11 @@
|
|
21
21
|
–
|
22
22
|
%tt
|
23
23
|
= account.location << ", " unless account.location.blank?
|
24
|
-
- user_name = account.
|
24
|
+
- user_name = account.user.try(:full_name)
|
25
25
|
- if user_name
|
26
|
-
= t(:added_by, :time_ago =>
|
26
|
+
= t(:added_by, :time_ago => timeago(account.created_at), :user => h(user_name)).html_safe << " | "
|
27
27
|
- else
|
28
|
-
= t(:added_ago, :value =>
|
28
|
+
= t(:added_ago, :value => timeago(account.created_at)).html_safe << " | "
|
29
29
|
= t('pluralize.contact', account.contacts.count) << " | "
|
30
30
|
= t('pluralize.opportunity', account.opportunities.count)
|
31
31
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
- entity_name = controller.controller_name.singularize.underscore #account
|
2
|
+
- @entity = instance_variable_get("@#{entity_name}")
|
3
|
+
- create_id = "create_#{entity_name}" # create_account
|
4
|
+
|
5
|
+
- if @entity.valid?
|
6
|
+
jQuery('##{create_id}_arrow').html(crm.COLLAPSED);
|
7
|
+
jQuery('##{create_id}_title').html('#{ j t(entity_name.pluralize) }');
|
8
|
+
jQuery('##{create_id}').slideUp(250);
|
9
|
+
jQuery('##{entity_name.pluralize}').prepend('#{ j render(:partial => entity_name, :collection => [ @entity ]) }');
|
10
|
+
jQuery('##{dom_id(@entity)}').effect("highlight", { duration:1500 });
|
11
|
+
= refresh_sidebar(:index, :filters)
|
12
|
+
jQuery('#paginate').html('#{ j render(:partial => "shared/paginate_with_per_page") }');
|
13
|
+
crm.flick('empty', 'remove');
|
14
|
+
- else
|
15
|
+
jQuery('##{create_id}').html('#{ j render(:partial => "new") }');
|
16
|
+
jQuery('##{create_id}').effect("shake", { duration:250, distance: 6 });
|
17
|
+
jQuery('#new_#{entity_name} input[type!=hidden]').first().focus();
|
@@ -0,0 +1,6 @@
|
|
1
|
+
- entity_name = controller.controller_name.singularize.underscore
|
2
|
+
- @entity = instance_variable_get("@#{entity_name}")
|
3
|
+
|
4
|
+
jQuery('##{dom_id(@entity)}').css('background-color', '#ffe4e1').slideUp(250);
|
5
|
+
= refresh_sidebar(:index, :filters)
|
6
|
+
jQuery('#paginate').replaceWith('#{ j render(:partial => "shared/paginate_with_per_page") }');
|
@@ -0,0 +1,32 @@
|
|
1
|
+
- entity_name = controller.controller_name.singularize.underscore #account
|
2
|
+
- @entity = instance_variable_get("@#{entity_name}")
|
3
|
+
- id = dom_id(@entity)
|
4
|
+
|
5
|
+
- if params[:cancel].true? # <--------------------- Hide [Edit]
|
6
|
+
|
7
|
+
- if called_from_landing_page?
|
8
|
+
crm.flip_form('edit_#{entity_name}');
|
9
|
+
crm.set_title('edit_#{entity_name}', '#{h @entity.name}');
|
10
|
+
- else # Called from index page...
|
11
|
+
jQuery('##{id}').replaceWith('#{ j render(:partial => entity_name, :collection => [ @entity ]) }');
|
12
|
+
|
13
|
+
- else # <---------------------------------------- Show [Edit] form.
|
14
|
+
|
15
|
+
- if params[:cancel].blank? # Called from index page...
|
16
|
+
- if @previous # Hide open [Edit] form if any.
|
17
|
+
- if @previous.is_a?(@entity.class)
|
18
|
+
jQuery('##{dom_id(@previous)}').replaceWith('#{ j render(:partial => entity_name, :collection => [ @previous ]) }');
|
19
|
+
- else
|
20
|
+
crm.flick('#{entity_name}_#{@previous}', 'remove');
|
21
|
+
-# Disable onMouseOver for the list item.
|
22
|
+
crm.highlight_off('#{id}');
|
23
|
+
-# Hide [Create] form if any.
|
24
|
+
crm.hide_form('create_#{entity_name}');
|
25
|
+
-# Show [Edit] form.
|
26
|
+
jQuery('##{id}').html('#{ j render(:partial => "edit") }');
|
27
|
+
|
28
|
+
- elsif params[:cancel].false? # Called from title of the landing page...
|
29
|
+
jQuery('#edit_#{entity_name}').html('#{ j render(:partial => "edit") }');
|
30
|
+
crm.flip_form('edit_#{entity_name}');
|
31
|
+
crm.set_title('edit_#{entity_name}', "#{t :edit} #{h @entity.name}");
|
32
|
+
jQuery('#new_#{entity_name} input[type!=hidden]').first().focus();
|
@@ -0,0 +1,11 @@
|
|
1
|
+
- entities = controller.controller_name # accounts
|
2
|
+
- @entities = instance_variable_get("@#{entities}")
|
3
|
+
|
4
|
+
- if @entities.any?
|
5
|
+
jQuery('##{entities}').html('#{ j render(@entities) }');
|
6
|
+
- else
|
7
|
+
jQuery('##{entities}').html('#{ j render(:partial => "shared/empty") }');
|
8
|
+
|
9
|
+
jQuery('#paginate').html('#{ j render(:partial => "shared/paginate_with_per_page") }');
|
10
|
+
jQuery('#export').html('#{ j render(:partial => "shared/export") }');
|
11
|
+
jQuery('#search_results_count').html('#{ j render(:text => t('search_results_count', :count => @search_results_count)) }');
|
@@ -3,7 +3,8 @@ xml.Worksheet 'ss:Name' => I18n.t(:tab_accounts) do
|
|
3
3
|
unless @accounts.empty?
|
4
4
|
# Header.
|
5
5
|
xml.Row do
|
6
|
-
heads = [I18n.t('
|
6
|
+
heads = [I18n.t('id'),
|
7
|
+
I18n.t('user'),
|
7
8
|
I18n.t('assigned_to'),
|
8
9
|
I18n.t('name'),
|
9
10
|
I18n.t('email'),
|
@@ -24,12 +25,12 @@ xml.Worksheet 'ss:Name' => I18n.t(:tab_accounts) do
|
|
24
25
|
I18n.t('zipcode'),
|
25
26
|
I18n.t('country'),
|
26
27
|
I18n.t('address')]
|
27
|
-
|
28
|
+
|
28
29
|
# Append custom field labels to header
|
29
30
|
Account.fields.each do |field|
|
30
31
|
heads << field.label
|
31
32
|
end
|
32
|
-
|
33
|
+
|
33
34
|
heads.each do |head|
|
34
35
|
xml.Cell do
|
35
36
|
xml.Data head,
|
@@ -37,12 +38,13 @@ xml.Worksheet 'ss:Name' => I18n.t(:tab_accounts) do
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
# Account rows.
|
42
43
|
@accounts.each do |account|
|
43
44
|
xml.Row do
|
44
45
|
address = account.billing_address
|
45
|
-
data = [account.
|
46
|
+
data = [account.id,
|
47
|
+
account.user.try(:name),
|
46
48
|
account.assignee.try(:name),
|
47
49
|
account.name,
|
48
50
|
account.email,
|
@@ -63,12 +65,12 @@ xml.Worksheet 'ss:Name' => I18n.t(:tab_accounts) do
|
|
63
65
|
address.try(:zipcode),
|
64
66
|
address.try(:country),
|
65
67
|
address.try(:full_address)]
|
66
|
-
|
68
|
+
|
67
69
|
# Append custom field values.
|
68
70
|
Account.fields.each do |field|
|
69
71
|
data << account.send(field.name)
|
70
72
|
end
|
71
|
-
|
73
|
+
|
72
74
|
data.each do |value|
|
73
75
|
xml.Cell do
|
74
76
|
xml.Data value,
|