brisk-bills 0.7.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (396) hide show
  1. data/CHANGELOG +7 -0
  2. data/Gemfile +11 -0
  3. data/Gemfile.lock +55 -0
  4. data/TODO.txt +36 -67
  5. data/app/controllers/admin/activities_controller.rb +4 -3
  6. data/app/controllers/admin/activities_with_prices_controller.rb +28 -14
  7. data/app/controllers/admin/client_accounting_controller.rb +11 -8
  8. data/app/controllers/admin/client_representatives_controller.rb +34 -5
  9. data/app/controllers/admin/clients_controller.rb +1 -1
  10. data/app/controllers/admin/draft_invoices_controller.rb +92 -0
  11. data/app/controllers/admin/{employee_client_labor_rate_controller.rb → employee_client_labor_rates_controller.rb} +1 -1
  12. data/app/controllers/admin/employees_controller.rb +3 -4
  13. data/app/controllers/admin/invoices_controller.rb +111 -53
  14. data/app/controllers/admin/payments_controller.rb +168 -41
  15. data/app/controllers/authentication_controller.rb +3 -3
  16. data/app/helpers/admin/activities_helper.rb +16 -13
  17. data/app/helpers/admin/activities_helper/labor_helper.rb +4 -4
  18. data/app/helpers/admin/activities_helper/proposal_helper.rb +1 -1
  19. data/app/helpers/admin/activities_helper/slimtimer_helper.rb +1 -1
  20. data/app/helpers/admin/activities_with_prices_helper.rb +2 -2
  21. data/app/helpers/admin/activity_type_controller_helper.rb +6 -0
  22. data/app/helpers/admin/activity_type_field_helper.rb +9 -9
  23. data/app/helpers/admin/adjustments_helper.rb +9 -1
  24. data/app/helpers/admin/client_accounting_helper.rb +2 -2
  25. data/app/helpers/admin/client_financial_transactions_helper.rb +1 -1
  26. data/app/helpers/admin/client_representatives_helper.rb +16 -12
  27. data/app/helpers/admin/clients_helper.rb +2 -0
  28. data/app/helpers/admin/draft_invoices_helper.rb +24 -0
  29. data/app/helpers/admin/{employee_client_labor_rate_helper.rb → employee_client_labor_rates_helper.rb} +8 -8
  30. data/app/helpers/admin/employees_helper.rb +6 -0
  31. data/app/helpers/admin/has_credential_column_helper.rb +8 -8
  32. data/app/helpers/admin/invoices_helper.rb +71 -16
  33. data/app/helpers/admin/is_active_column_helper.rb +2 -2
  34. data/app/helpers/admin/labors_helper.rb +12 -1
  35. data/app/helpers/admin/labors_helper/slimtimer_helper.rb +1 -1
  36. data/app/helpers/admin/materials_helper.rb +11 -0
  37. data/app/helpers/admin/payments_helper.rb +204 -29
  38. data/app/helpers/admin/proposals_helper.rb +10 -0
  39. data/app/helpers/admin/settings_helper.rb +1 -1
  40. data/app/helpers/admin_layout_helper.rb +3 -6
  41. data/app/helpers/authentication_helper.rb +7 -10
  42. data/app/helpers/money_model_helper.rb +1 -2
  43. data/app/models/activity.rb +17 -7
  44. data/app/models/client.rb +35 -8
  45. data/app/{model_views → models}/client_financial_transaction.rb +0 -0
  46. data/app/models/client_representative.rb +6 -14
  47. data/app/models/credential.rb +1 -1
  48. data/app/models/employee.rb +9 -11
  49. data/app/models/invoice.rb +13 -9
  50. data/app/models/invoice_payment.rb +1 -1
  51. data/app/models/notifier.rb +2 -2
  52. data/app/models/payment.rb +51 -7
  53. data/app/models/setting.rb +3 -1
  54. data/app/views/active_scaffold_overrides/add_existing.js.rjs +25 -0
  55. data/app/views/admin/activities/_adjustment_column.html.erb +10 -0
  56. data/app/views/admin/activities/{_form.rhtml → _form.html.erb} +0 -0
  57. data/app/views/admin/activities/{_form_attribute.rhtml → _form_attribute.html.erb} +0 -0
  58. data/app/views/admin/activities/{_labor_column.rhtml → _labor_column.html.erb} +0 -0
  59. data/app/views/admin/activities/{_material_column.rhtml → _material_column.html.erb} +0 -0
  60. data/app/views/admin/activities/{_proposal_column.rhtml → _proposal_column.html.erb} +0 -0
  61. data/app/views/admin/activities_with_prices/{move_to_invoice.rhtml → move_to_invoice.html.erb} +2 -2
  62. data/app/views/admin/activities_with_prices/move_to_invoice.js.rjs +5 -0
  63. data/app/views/admin/draft_invoices/batch_create.html.erb +73 -0
  64. data/app/views/admin/draft_invoices/batch_create.js.rjs +5 -0
  65. data/app/views/admin/invoices/confirm_publish_modal.html.erb +48 -0
  66. data/app/views/admin/payments/commit_payment_warning.html.erb +8 -0
  67. data/app/views/admin/payments/observation_error.js.rjs +28 -0
  68. data/app/views/admin/payments/on_assignment_observation.js.rjs +28 -0
  69. data/app/views/authentication/{email.rjs → email.js.rjs} +0 -0
  70. data/app/views/authentication/{login.rhtml → login.html.erb} +21 -26
  71. data/app/views/authentication/{login.rjs → login.js.rjs} +0 -0
  72. data/app/views/authentication/{reset_password_via_token.rhtml → reset_password_via_token.html.erb} +0 -0
  73. data/app/views/authentication/{reset_password_via_token.rjs → reset_password_via_token.js.rjs} +0 -0
  74. data/app/views/authentication/{sign_in_error.rjs → sign_in_error.js.rjs} +0 -0
  75. data/app/views/layouts/{_navigation_tree.rhtml → _navigation_tree.html.erb} +0 -0
  76. data/app/views/layouts/{admin.rhtml → admin.html.erb} +0 -0
  77. data/app/views/layouts/{public.rhtml → public.html.erb} +0 -0
  78. data/app/views/notifier/{_email_footer.html.rhtml → _email_footer.html.erb} +0 -0
  79. data/app/views/notifier/{_email_footer.plain.rhtml → _email_footer.plain.erb} +0 -0
  80. data/app/views/notifier/{_email_header.html.rhtml → _email_header.html.erb} +0 -0
  81. data/app/views/notifier/invoice_available.html.erb +5 -0
  82. data/app/views/notifier/{invoice_available.plain.rhtml → invoice_available.plain.erb} +1 -1
  83. data/app/views/notifier/{reset_password_requested.html.rhtml → reset_password_requested.html.erb} +2 -2
  84. data/app/views/notifier/{reset_password_requested.plain.rhtml → reset_password_requested.plain.erb} +1 -1
  85. data/config/environment.rb +6 -5
  86. data/config/locale/en.rb +9 -0
  87. data/db/migrate/001_create_employees.rb +1 -1
  88. data/db/migrate/002_create_employee_slimtimers.rb +1 -1
  89. data/db/migrate/003_create_slimtimer_tasks.rb +1 -1
  90. data/db/migrate/004_create_slimtimer_time_entries.rb +1 -1
  91. data/db/migrate/005_create_clients.rb +1 -1
  92. data/db/migrate/006_create_client_representatives.rb +1 -1
  93. data/db/migrate/008_create_activities.rb +1 -1
  94. data/db/migrate/009_create_activity_labors.rb +1 -1
  95. data/db/migrate/010_create_employee_client_labor_rates.rb +1 -1
  96. data/db/migrate/011_create_activity_adjustments.rb +1 -1
  97. data/db/migrate/012_create_activity_materials.rb +1 -1
  98. data/db/migrate/013_create_activity_proposals.rb +1 -1
  99. data/db/migrate/014_create_invoices.rb +1 -1
  100. data/db/migrate/015_create_payments.rb +1 -1
  101. data/db/migrate/016_create_payment_methods.rb +1 -1
  102. data/db/migrate/017_create_invoice_payments.rb +1 -1
  103. data/db/migrate/018_create_activity_types.rb +2 -2
  104. data/db/migrate/019_create_settings.rb +1 -1
  105. data/db/migrate/023_create_credentials_migrate_representatives.rb +2 -2
  106. data/db/migrate/028_money_to_cents.rb +2 -2
  107. data/db/schema.rb +10 -10
  108. data/lib/brisk-bills.rb +2 -2
  109. data/lib/brisk-bills/initializer.rb +2 -2
  110. data/lib/generators/instance/templates/instance_environment.rb +1 -1
  111. data/lib/libpptable.rb +48 -0
  112. data/lib/tasks/create_last_months_invoices.rake +1 -14
  113. data/lib/tasks/first_time_setup.rake +2 -2
  114. data/lib/tasks/package.rake +2 -1
  115. data/lib/tasks/payment_assignment_consistency_check.rake +110 -0
  116. data/lib/utilities.rb +4 -4
  117. data/public/images/page-new.gif +0 -0
  118. data/public/javascripts/active_scaffold/default/active_scaffold.js +532 -430
  119. data/public/javascripts/active_scaffold/default/dhtml_history.js +1 -1
  120. data/public/javascripts/active_scaffold/default/form_enhancements.js +7 -4
  121. data/public/stylesheets/active_scaffold/default/stylesheet-ie.css +5 -5
  122. data/public/stylesheets/active_scaffold/default/stylesheet.css +54 -18
  123. data/public/stylesheets/admin/global.css +1 -1
  124. data/public/stylesheets/admin/pages.css +29 -0
  125. data/test/unit/activity/adjustment_test.rb +1 -1
  126. data/test/unit/activity/labor_test.rb +1 -1
  127. data/test/unit/activity/material_test.rb +1 -1
  128. data/test/unit/activity/proposal_test.rb +1 -1
  129. data/test/unit/activity_test.rb +1 -1
  130. data/test/unit/activity_type_test.rb +1 -1
  131. data/test/unit/client_eventlog_test.rb +1 -1
  132. data/test/unit/client_financial_transaction_test.rb +1 -1
  133. data/test/unit/client_representative_test.rb +1 -1
  134. data/test/unit/client_test.rb +37 -6
  135. data/test/unit/credential_test.rb +1 -1
  136. data/test/unit/employee/slimtimer_test.rb +1 -1
  137. data/test/unit/employee_client_labor_rate_test.rb +1 -1
  138. data/test/unit/employee_test.rb +1 -1
  139. data/test/unit/helpers/admin/draft_invoices_helper_test.rb +4 -0
  140. data/test/unit/invoice_payment_test.rb +90 -50
  141. data/test/unit/invoice_test.rb +48 -8
  142. data/test/unit/notifier_test.rb +1 -1
  143. data/test/unit/payment_method_test.rb +1 -1
  144. data/test/unit/payment_test.rb +7 -7
  145. data/test/unit/setting_test.rb +1 -1
  146. data/test/unit/slimtimer_task_test.rb +1 -1
  147. data/test/unit/slimtimer_time_entry_test.rb +1 -1
  148. data/vendor/plugins/active_scaffold/CHANGELOG +3 -1
  149. data/vendor/plugins/active_scaffold/README +18 -5
  150. data/vendor/plugins/active_scaffold/environment.rb +1 -1
  151. data/vendor/plugins/active_scaffold/frontends/default/javascripts/active_scaffold.js +532 -430
  152. data/vendor/plugins/active_scaffold/frontends/default/javascripts/dhtml_history.js +1 -1
  153. data/vendor/plugins/active_scaffold/frontends/default/javascripts/form_enhancements.js +7 -4
  154. data/vendor/plugins/active_scaffold/frontends/default/stylesheets/stylesheet-ie.css +5 -5
  155. data/vendor/plugins/active_scaffold/frontends/default/stylesheets/stylesheet.css +54 -18
  156. data/vendor/plugins/active_scaffold/frontends/default/views/_add_existing_form.html.erb +3 -7
  157. data/vendor/plugins/active_scaffold/frontends/default/views/_create_form.html.erb +10 -7
  158. data/vendor/plugins/active_scaffold/frontends/default/views/_field_search.html.erb +7 -12
  159. data/vendor/plugins/active_scaffold/frontends/default/views/_form.html.erb +3 -3
  160. data/vendor/plugins/active_scaffold/frontends/default/views/_form_association.html.erb +15 -20
  161. data/vendor/plugins/active_scaffold/frontends/default/views/_form_association_footer.html.erb +8 -10
  162. data/vendor/plugins/active_scaffold/frontends/default/views/_form_attribute.html.erb +5 -2
  163. data/vendor/plugins/active_scaffold/frontends/default/views/_form_hidden_attribute.html.erb +2 -1
  164. data/vendor/plugins/active_scaffold/frontends/default/views/_horizontal_subform.html.erb +19 -21
  165. data/vendor/plugins/active_scaffold/frontends/default/views/{_form_association_header.html.erb → _horizontal_subform_header.html.erb} +2 -2
  166. data/vendor/plugins/active_scaffold/frontends/default/views/_horizontal_subform_record.html.erb +31 -0
  167. data/vendor/plugins/active_scaffold/frontends/default/views/_list.html.erb +4 -18
  168. data/vendor/plugins/active_scaffold/frontends/default/views/_list_actions.html.erb +18 -5
  169. data/vendor/plugins/active_scaffold/frontends/default/views/_list_calculations.html.erb +2 -9
  170. data/vendor/plugins/active_scaffold/frontends/default/views/_list_column_headings.html.erb +4 -4
  171. data/vendor/plugins/active_scaffold/frontends/default/views/_list_header.html.erb +6 -6
  172. data/vendor/plugins/active_scaffold/frontends/default/views/_list_inline_adapter.html.erb +2 -1
  173. data/vendor/plugins/active_scaffold/frontends/default/views/_list_messages.html.erb +20 -0
  174. data/vendor/plugins/active_scaffold/frontends/default/views/_list_pagination.html.erb +11 -0
  175. data/vendor/plugins/active_scaffold/frontends/default/views/_list_pagination_links.html.erb +3 -5
  176. data/vendor/plugins/active_scaffold/frontends/default/views/_list_record.html.erb +2 -26
  177. data/vendor/plugins/active_scaffold/frontends/default/views/_list_record_columns.html.erb +9 -0
  178. data/vendor/plugins/active_scaffold/frontends/default/views/_nested.html.erb +3 -12
  179. data/vendor/plugins/active_scaffold/frontends/default/views/_render_fields.js.rjs +11 -0
  180. data/vendor/plugins/active_scaffold/frontends/default/views/_search.html.erb +17 -11
  181. data/vendor/plugins/active_scaffold/frontends/default/views/_show.html.erb +3 -3
  182. data/vendor/plugins/active_scaffold/frontends/default/views/_show_columns.html.erb +8 -7
  183. data/vendor/plugins/active_scaffold/frontends/default/views/_update_actions.html.erb +3 -3
  184. data/vendor/plugins/active_scaffold/frontends/default/views/_update_form.html.erb +9 -6
  185. data/vendor/plugins/active_scaffold/frontends/default/views/_vertical_subform.html.erb +7 -0
  186. data/vendor/plugins/active_scaffold/frontends/default/views/_vertical_subform_record.html.erb +38 -0
  187. data/vendor/plugins/active_scaffold/frontends/default/views/add_existing.js.rjs +2 -1
  188. data/vendor/plugins/active_scaffold/frontends/default/views/delete.html.erb +1 -1
  189. data/vendor/plugins/active_scaffold/frontends/default/views/destroy.js.rjs +2 -2
  190. data/vendor/plugins/active_scaffold/frontends/default/views/edit_associated.js.rjs +20 -15
  191. data/vendor/plugins/active_scaffold/frontends/default/views/list.html.erb +12 -8
  192. data/vendor/plugins/active_scaffold/frontends/default/views/list.js.rjs +1 -0
  193. data/vendor/plugins/active_scaffold/frontends/default/views/mark.js.rjs +6 -0
  194. data/vendor/plugins/active_scaffold/frontends/default/views/on_create.js.rjs +12 -8
  195. data/vendor/plugins/active_scaffold/frontends/default/views/on_update.js.rjs +13 -6
  196. data/vendor/plugins/active_scaffold/frontends/default/views/render_field.js.rjs +1 -0
  197. data/vendor/plugins/active_scaffold/frontends/default/views/search.html.erb +2 -2
  198. data/vendor/plugins/active_scaffold/frontends/default/views/update.html.erb +2 -2
  199. data/vendor/plugins/active_scaffold/frontends/default/views/update_column.js.rjs +4 -3
  200. data/vendor/plugins/active_scaffold/frontends/default/views/update_row.js.rjs +2 -0
  201. data/vendor/plugins/active_scaffold/init.rb +2 -2
  202. data/vendor/plugins/active_scaffold/install.rb +1 -2
  203. data/vendor/plugins/active_scaffold/install_assets.rb +1 -1
  204. data/vendor/plugins/active_scaffold/lib/active_record_permissions.rb +53 -42
  205. data/vendor/plugins/active_scaffold/lib/active_scaffold.rb +96 -23
  206. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/common_search.rb +18 -0
  207. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/core.rb +152 -102
  208. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/create.rb +81 -49
  209. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/delete.rb +44 -17
  210. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/field_search.rb +60 -46
  211. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/list.rb +42 -37
  212. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/mark.rb +72 -0
  213. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/nested.rb +94 -92
  214. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/search.rb +54 -40
  215. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/show.rb +30 -10
  216. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/update.rb +62 -47
  217. data/vendor/plugins/active_scaffold/lib/active_scaffold/attribute_params.rb +187 -185
  218. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/base.rb +28 -3
  219. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/core.rb +43 -3
  220. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/create.rb +8 -15
  221. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/delete.rb +3 -4
  222. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/field_search.rb +19 -17
  223. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/form.rb +2 -9
  224. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/list.rb +46 -9
  225. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/nested.rb +17 -7
  226. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/search.rb +36 -16
  227. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/show.rb +5 -12
  228. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/subform.rb +8 -6
  229. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/update.rb +12 -8
  230. data/vendor/plugins/active_scaffold/lib/active_scaffold/configurable.rb +2 -2
  231. data/vendor/plugins/active_scaffold/lib/active_scaffold/constraints.rb +173 -178
  232. data/vendor/plugins/active_scaffold/lib/active_scaffold/data_structures/action_columns.rb +101 -97
  233. data/vendor/plugins/active_scaffold/lib/active_scaffold/data_structures/action_link.rb +29 -19
  234. data/vendor/plugins/active_scaffold/lib/active_scaffold/data_structures/column.rb +74 -34
  235. data/vendor/plugins/active_scaffold/lib/active_scaffold/data_structures/columns.rb +74 -74
  236. data/vendor/plugins/active_scaffold/lib/active_scaffold/data_structures/set.rb +57 -62
  237. data/vendor/plugins/active_scaffold/lib/active_scaffold/data_structures/sorting.rb +73 -3
  238. data/vendor/plugins/active_scaffold/lib/active_scaffold/finder.rb +304 -234
  239. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/association_helpers.rb +40 -40
  240. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/controller_helpers.rb +39 -24
  241. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/country_helpers.rb +32 -28
  242. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/form_column_helpers.rb +157 -86
  243. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/id_helpers.rb +7 -7
  244. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/list_column_helpers.rb +278 -85
  245. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/pagination_helpers.rb +38 -12
  246. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/search_column_helpers.rb +74 -35
  247. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/show_column_helpers.rb +53 -46
  248. data/vendor/plugins/active_scaffold/lib/active_scaffold/helpers/view_helpers.rb +51 -17
  249. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/de.yml +69 -0
  250. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/en.yml +72 -0
  251. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/es.yml +23 -13
  252. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/fr.yml +68 -0
  253. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/hu.yml +24 -14
  254. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/ja.yml +69 -0
  255. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/ru.yml +72 -0
  256. data/vendor/plugins/active_scaffold/lib/active_scaffold/marked_model.rb +38 -0
  257. data/vendor/plugins/active_scaffold/lib/bridges/calendar_date_select/lib/as_cds_bridge.rb +47 -13
  258. data/vendor/plugins/active_scaffold/lib/bridges/dependent_protect/bridge.rb +10 -0
  259. data/vendor/plugins/active_scaffold/lib/bridges/dependent_protect/lib/dependent_protect_bridge.rb +11 -0
  260. data/vendor/plugins/active_scaffold/lib/bridges/file_column/lib/as_file_column_bridge.rb +3 -6
  261. data/vendor/plugins/active_scaffold/lib/bridges/file_column/lib/form_ui.rb +10 -2
  262. data/vendor/plugins/active_scaffold/lib/bridges/paperclip/bridge.rb +13 -0
  263. data/vendor/plugins/active_scaffold/lib/bridges/paperclip/lib/form_ui.rb +20 -0
  264. data/vendor/plugins/active_scaffold/lib/bridges/paperclip/lib/list_ui.rb +16 -0
  265. data/vendor/plugins/active_scaffold/lib/bridges/paperclip/lib/paperclip_bridge.rb +32 -0
  266. data/vendor/plugins/active_scaffold/lib/bridges/paperclip/lib/paperclip_bridge_helpers.rb +18 -0
  267. data/vendor/plugins/active_scaffold/lib/bridges/record_select/bridge.rb +5 -0
  268. data/vendor/plugins/active_scaffold/lib/bridges/record_select/lib/record_select_bridge.rb +79 -0
  269. data/vendor/plugins/active_scaffold/lib/bridges/semantic_attributes/bridge.rb +5 -0
  270. data/vendor/plugins/active_scaffold/lib/bridges/semantic_attributes/lib/semantic_attributes_bridge.rb +20 -0
  271. data/vendor/plugins/active_scaffold/lib/bridges/tiny_mce/bridge.rb +5 -0
  272. data/vendor/plugins/active_scaffold/lib/bridges/tiny_mce/lib/tiny_mce_bridge.rb +57 -0
  273. data/vendor/plugins/active_scaffold/lib/bridges/unobtrusive_date_picker/bridge.rb +9 -0
  274. data/vendor/plugins/active_scaffold/lib/bridges/unobtrusive_date_picker/lib/form_ui.rb +14 -0
  275. data/vendor/plugins/active_scaffold/lib/bridges/unobtrusive_date_picker/lib/unobtrusive_date_picker_bridge.rb +15 -0
  276. data/vendor/plugins/active_scaffold/lib/bridges/unobtrusive_date_picker/lib/view_helpers.rb +16 -0
  277. data/vendor/plugins/active_scaffold/lib/bridges/validation_reflection/bridge.rb +9 -0
  278. data/vendor/plugins/active_scaffold/lib/bridges/validation_reflection/lib/validation_reflection_bridge.rb +19 -0
  279. data/vendor/plugins/active_scaffold/lib/extensions/action_view_rendering.rb +20 -8
  280. data/vendor/plugins/active_scaffold/lib/extensions/generic_view_paths.rb +2 -2
  281. data/vendor/plugins/active_scaffold/lib/extensions/paginator_extensions.rb +26 -0
  282. data/vendor/plugins/active_scaffold/lib/extensions/resources.rb +6 -5
  283. data/vendor/plugins/active_scaffold/lib/extensions/reverse_associations.rb +26 -20
  284. data/vendor/plugins/active_scaffold/lib/extensions/unsaved_associated.rb +1 -1
  285. data/vendor/plugins/active_scaffold/lib/paginator.rb +1 -1
  286. data/vendor/plugins/active_scaffold/lib/responds_to_parent.rb +1 -1
  287. data/vendor/plugins/active_scaffold/shoulda_macros/macros.rb +136 -0
  288. data/vendor/plugins/active_scaffold/test/bridges/active_scaffold_dependent_protect_test.rb +34 -0
  289. data/vendor/plugins/active_scaffold/test/bridges/bridge_test.rb +43 -0
  290. data/vendor/plugins/active_scaffold/test/bridges/company.rb +81 -0
  291. data/vendor/plugins/active_scaffold/test/bridges/paperclip_test.rb +68 -0
  292. data/vendor/plugins/active_scaffold/test/bridges/tiny_mce_test.rb +27 -0
  293. data/vendor/plugins/active_scaffold/test/bridges/unobtrusive_date_picker_test.rb +49 -0
  294. data/vendor/plugins/active_scaffold/test/bridges/validation_reflection_test.rb +57 -0
  295. data/vendor/plugins/active_scaffold/test/config/base_test.rb +15 -0
  296. data/vendor/plugins/active_scaffold/test/config/core_test.rb +58 -0
  297. data/vendor/plugins/active_scaffold/test/config/create_test.rb +9 -6
  298. data/vendor/plugins/active_scaffold/test/config/delete_test.rb +33 -0
  299. data/vendor/plugins/active_scaffold/test/config/field_search_test.rb +47 -0
  300. data/vendor/plugins/active_scaffold/test/config/list_test.rb +66 -11
  301. data/vendor/plugins/active_scaffold/test/config/nested_test.rb +62 -0
  302. data/vendor/plugins/active_scaffold/test/config/search_test.rb +60 -0
  303. data/vendor/plugins/active_scaffold/test/config/show_test.rb +43 -0
  304. data/vendor/plugins/active_scaffold/test/config/subform_test.rb +17 -0
  305. data/vendor/plugins/active_scaffold/test/config/update_test.rb +27 -4
  306. data/vendor/plugins/active_scaffold/test/data_structures/action_columns_test.rb +2 -8
  307. data/vendor/plugins/active_scaffold/test/data_structures/action_link_test.rb +11 -11
  308. data/vendor/plugins/active_scaffold/test/data_structures/action_links_test.rb +5 -5
  309. data/vendor/plugins/active_scaffold/test/data_structures/association_column_test.rb +4 -3
  310. data/vendor/plugins/active_scaffold/test/data_structures/column_test.rb +29 -5
  311. data/vendor/plugins/active_scaffold/test/data_structures/sorting_test.rb +31 -1
  312. data/vendor/plugins/active_scaffold/test/data_structures/standard_column_test.rb +3 -13
  313. data/vendor/plugins/active_scaffold/test/data_structures/virtual_column_test.rb +0 -11
  314. data/vendor/plugins/active_scaffold/test/extensions/{array.rb → array_test.rb} +0 -0
  315. data/vendor/plugins/active_scaffold/test/helpers/form_column_helpers_test.rb +31 -0
  316. data/vendor/plugins/active_scaffold/test/helpers/list_column_helpers_test.rb +42 -0
  317. data/vendor/plugins/active_scaffold/test/helpers/pagination_helpers_test.rb +59 -0
  318. data/vendor/plugins/active_scaffold/test/misc/active_record_permissions_test.rb +154 -0
  319. data/vendor/plugins/active_scaffold/test/misc/attribute_params_test.rb +146 -0
  320. data/vendor/plugins/active_scaffold/test/misc/configurable_test.rb +2 -2
  321. data/vendor/plugins/active_scaffold/test/misc/constraints_test.rb +26 -8
  322. data/vendor/plugins/active_scaffold/test/misc/finder_test.rb +41 -19
  323. data/vendor/plugins/active_scaffold/test/misc/lang_test.rb +5 -6
  324. data/vendor/plugins/active_scaffold/test/mock_app/app/controllers/application_controller.rb +10 -0
  325. data/vendor/plugins/active_scaffold/test/mock_app/app/helpers/application_helper.rb +3 -0
  326. data/vendor/plugins/active_scaffold/test/mock_app/config/boot.rb +110 -0
  327. data/vendor/plugins/active_scaffold/test/mock_app/config/environment.rb +43 -0
  328. data/vendor/plugins/active_scaffold/test/mock_app/config/environments/development.rb +17 -0
  329. data/vendor/plugins/active_scaffold/test/mock_app/config/environments/production.rb +28 -0
  330. data/vendor/plugins/active_scaffold/test/mock_app/config/environments/test.rb +28 -0
  331. data/vendor/plugins/active_scaffold/test/mock_app/config/initializers/backtrace_silencers.rb +7 -0
  332. data/vendor/plugins/active_scaffold/test/mock_app/config/initializers/inflections.rb +10 -0
  333. data/vendor/plugins/active_scaffold/test/mock_app/config/initializers/mime_types.rb +5 -0
  334. data/vendor/plugins/active_scaffold/test/mock_app/config/initializers/new_rails_defaults.rb +19 -0
  335. data/vendor/plugins/active_scaffold/test/mock_app/config/initializers/session_store.rb +15 -0
  336. data/vendor/plugins/active_scaffold/test/mock_app/config/locales/en.yml +5 -0
  337. data/vendor/plugins/active_scaffold/test/mock_app/config/routes.rb +43 -0
  338. data/vendor/plugins/active_scaffold/test/mock_app/db/test.sqlite3 +1 -0
  339. data/vendor/plugins/active_scaffold/test/mock_app/public/blank.html +33 -0
  340. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +2 -0
  341. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
  342. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
  343. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
  344. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
  345. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
  346. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
  347. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
  348. data/vendor/plugins/active_scaffold/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
  349. data/vendor/plugins/active_scaffold/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +2 -0
  350. data/vendor/plugins/active_scaffold/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +532 -0
  351. data/vendor/plugins/active_scaffold/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +867 -0
  352. data/vendor/plugins/active_scaffold/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +117 -0
  353. data/vendor/plugins/active_scaffold/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +370 -0
  354. data/vendor/plugins/active_scaffold/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +2 -0
  355. data/vendor/plugins/active_scaffold/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +35 -0
  356. data/vendor/plugins/active_scaffold/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +845 -0
  357. data/vendor/plugins/active_scaffold/test/model_stub.rb +17 -1
  358. data/vendor/plugins/active_scaffold/test/test_helper.rb +31 -5
  359. data/vendor/plugins/active_scaffold/uninstall.rb +2 -1
  360. data/vendor/plugins/active_scaffold_form_observation/init.rb +1 -1
  361. data/vendor/plugins/active_scaffold_form_observation/lib/active_scaffold_form_observation.rb +1 -2
  362. data/vendor/plugins/active_scaffold_full_refresh/init.rb +2 -0
  363. data/vendor/plugins/active_scaffold_full_refresh/lib/active_scaffold_full_refresh.rb +29 -0
  364. data/vendor/plugins/acts_as_money/{tasks → lib/tasks}/money_tasks.rake +0 -0
  365. metadata +668 -563
  366. data/app/model_views/client_accounting.rb +0 -5
  367. data/app/model_views/invoices_with_total.rb +0 -41
  368. data/app/views/admin/activities/_adjustment_column.rhtml +0 -23
  369. data/app/views/admin/activities_with_prices/move_to_invoice.rjs +0 -9
  370. data/app/views/notifier/invoice_available.html.rhtml +0 -5
  371. data/public/javascripts/prototype.js-1.6.0.3 +0 -4320
  372. data/test/functional/admin/activities_controller_test.rb +0 -8
  373. data/test/functional/admin/adjustments_controller_test.rb +0 -8
  374. data/test/functional/admin/client_accounting_controller_test.rb +0 -8
  375. data/test/functional/admin/client_financial_transactions_controller_test.rb +0 -8
  376. data/test/functional/admin/client_representatives_controller_test.rb +0 -8
  377. data/test/functional/admin/clients_controller_test.rb +0 -8
  378. data/test/functional/admin/employee_client_labor_rate_controller_test.rb +0 -8
  379. data/test/functional/admin/employees/slimtimer_controller_test.rb +0 -8
  380. data/test/functional/admin/employees_controller_test.rb +0 -8
  381. data/test/functional/admin/invoices_controller_test.rb +0 -8
  382. data/test/functional/admin/labors_controller_test.rb +0 -8
  383. data/test/functional/admin/materials_controller_test.rb +0 -8
  384. data/test/functional/admin/payments_controller_test.rb +0 -8
  385. data/test/functional/admin/proposals_controller_test.rb +0 -8
  386. data/test/functional/admin/settings_controller_test.rb +0 -8
  387. data/test/functional/authentication_controller_test.rb +0 -8
  388. data/vendor/plugins/active_scaffold/frontends/default/views/_form_association_record.html.erb +0 -27
  389. data/vendor/plugins/active_scaffold/frontends/default/views/_live_search.html.erb +0 -25
  390. data/vendor/plugins/active_scaffold/frontends/default/views/form_messages_on_create.js.rjs +0 -2
  391. data/vendor/plugins/active_scaffold/frontends/default/views/form_messages_on_update.js.rjs +0 -2
  392. data/vendor/plugins/active_scaffold/lib/active_scaffold/actions/live_search.rb +0 -46
  393. data/vendor/plugins/active_scaffold/lib/active_scaffold/config/live_search.rb +0 -52
  394. data/vendor/plugins/active_scaffold/lib/active_scaffold/locale/en.rb +0 -66
  395. data/vendor/plugins/active_scaffold/lib/extensions/name_option_for_datetime.rb +0 -12
  396. data/vendor/plugins/active_scaffold/test/misc/active_record_permissions.rb +0 -154
@@ -1,40 +1,40 @@
1
- module ActiveScaffold
2
- module Helpers
3
- module AssociationHelpers
4
- # Provides a way to honor the :conditions on an association while searching the association's klass
5
- def association_options_find(association, conditions = nil)
6
- association.klass.find(:all, :conditions => controller.send(:merge_conditions, conditions, association.options[:conditions]))
7
- end
8
-
9
- def association_options_count(association, conditions = nil)
10
- association.klass.count(:all, :conditions => controller.send(:merge_conditions, conditions, association.options[:conditions]))
11
- end
12
-
13
- # returns options for the given association as a collection of [id, label] pairs intended for the +options_for_select+ helper.
14
- def options_for_association(association, include_all = false)
15
- available_records = association_options_find(association, include_all ? nil : options_for_association_conditions(association))
16
- available_records ||= []
17
- available_records.sort{|a,b| a.to_label <=> b.to_label}.collect { |model| [ model.to_label, model.id ] }
18
- end
19
-
20
- def options_for_association_count(association)
21
- association_options_count(association, options_for_association_conditions(association))
22
- end
23
-
24
- # A useful override for customizing the records present in an association dropdown.
25
- # Should work in both the subform and form_ui=>:select modes.
26
- # Check association.name to specialize the conditions per-column.
27
- def options_for_association_conditions(association)
28
- return nil if association.options[:through]
29
- case association.macro
30
- when :has_one, :has_many
31
- # Find only orphaned objects
32
- "#{association.primary_key_name} IS NULL"
33
- when :belongs_to, :has_and_belongs_to_many
34
- # Find all
35
- nil
36
- end
37
- end
38
- end
39
- end
40
- end
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module AssociationHelpers
4
+ # Provides a way to honor the :conditions on an association while searching the association's klass
5
+ def association_options_find(association, conditions = nil)
6
+ association.klass.find(:all, :conditions => controller.send(:merge_conditions, conditions, association.options[:conditions]))
7
+ end
8
+
9
+ def association_options_count(association, conditions = nil)
10
+ association.klass.count(:all, :conditions => controller.send(:merge_conditions, conditions, association.options[:conditions]))
11
+ end
12
+
13
+ # returns options for the given association as a collection of [id, label] pairs intended for the +options_for_select+ helper.
14
+ def options_for_association(association, include_all = false)
15
+ available_records = association_options_find(association, include_all ? nil : options_for_association_conditions(association))
16
+ available_records ||= []
17
+ available_records.sort{|a,b| a.to_label <=> b.to_label}.collect { |model| [ model.to_label, model.id ] }
18
+ end
19
+
20
+ def options_for_association_count(association)
21
+ association_options_count(association, options_for_association_conditions(association))
22
+ end
23
+
24
+ # A useful override for customizing the records present in an association dropdown.
25
+ # Should work in both the subform and form_ui=>:select modes.
26
+ # Check association.name to specialize the conditions per-column.
27
+ def options_for_association_conditions(association)
28
+ return nil if association.options[:through]
29
+ case association.macro
30
+ when :has_one, :has_many
31
+ # Find only orphaned objects
32
+ "#{association.primary_key_name} IS NULL"
33
+ when :belongs_to, :has_and_belongs_to_many
34
+ # Find all
35
+ nil
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,25 +1,40 @@
1
- module ActiveScaffold
2
- module Helpers
3
- module ControllerHelpers
4
- def self.included(controller)
5
- controller.class_eval { helper_method :params_for }
6
- end
7
-
8
- include ActiveScaffold::Helpers::IdHelpers
9
-
10
- def params_for(options = {})
11
- # :adapter and :position are one-use rendering arguments. they should not propagate.
12
- # :sort, :sort_direction, and :page are arguments that stored in the session. they need not propagate.
13
- # and wow. no we don't want to propagate :record.
14
- # :commit is a special rails variable for form buttons
15
- blacklist = [:adapter, :position, :sort, :sort_direction, :page, :record, :commit, :_method]
16
- unless @params_for
17
- @params_for = params.clone.delete_if { |key, value| blacklist.include? key.to_sym if key }
18
- @params_for[:controller] = '/' + @params_for[:controller] unless @params_for[:controller].first(1) == '/' # for namespaced controllers
19
- @params_for.delete(:id) if @params_for[:id].nil?
20
- end
21
- @params_for.merge(options)
22
- end
23
- end
24
- end
1
+ module ActiveScaffold
2
+ module Helpers
3
+ module ControllerHelpers
4
+ def self.included(controller)
5
+ controller.class_eval { helper_method :params_for, :main_path_to_return }
6
+ end
7
+
8
+ include ActiveScaffold::Helpers::IdHelpers
9
+
10
+ def params_for(options = {})
11
+ # :adapter and :position are one-use rendering arguments. they should not propagate.
12
+ # :sort, :sort_direction, and :page are arguments that stored in the session. they need not propagate.
13
+ # and wow. no we don't want to propagate :record.
14
+ # :commit is a special rails variable for form buttons
15
+ blacklist = [:adapter, :position, :sort, :sort_direction, :page, :record, :commit, :_method, :authenticity_token, :format]
16
+ unless @params_for
17
+ @params_for = params.clone.delete_if { |key, value| blacklist.include? key.to_sym if key }
18
+ @params_for[:controller] = '/' + @params_for[:controller] unless @params_for[:controller].first(1) == '/' # for namespaced controllers
19
+ @params_for.delete(:id) if @params_for[:id].nil?
20
+ end
21
+ @params_for.merge(options)
22
+ end
23
+
24
+ # Parameters to generate url to the main page (override if the ActiveScaffold is used as a component on another controllers page)
25
+ def main_path_to_return
26
+ parameters = {}
27
+ if params[:parent_controller]
28
+ parameters[:controller] = params[:parent_controller]
29
+ parameters[:eid] = params[:parent_controller]
30
+ end
31
+ parameters[:nested] = nil
32
+ parameters[:parent_column] = nil
33
+ parameters[:parent_id] = nil
34
+ parameters[:action] = "index"
35
+ parameters[:id] = nil
36
+ params_for(parameters)
37
+ end
38
+ end
39
+ end
25
40
  end
@@ -1,5 +1,3 @@
1
- I18n.load_path << File.dirname(__FILE__) + '/../../../lib/active_scaffold/locale/en-countries.yml'
2
-
3
1
  module ActiveScaffold
4
2
  module Helpers
5
3
  module CountryHelpers
@@ -18,14 +16,13 @@ module ActiveScaffold
18
16
  #
19
17
  # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
20
18
  def country_options_for_select(selected = nil, priority_countries = nil)
21
- country_options = ""
22
-
23
19
  if priority_countries
24
- country_options += options_for_select(priority_countries, selected)
25
- country_options += "<option value=\"\" disabled=\"disabled\">-------------</option>\n"
20
+ country_options = options_for_select(priority_countries.collect {|country| [I18n.t("countries.#{country}", :default => country.to_s.titleize), country.to_s]} + [['-------------', '']], :selected => selected, :disabled => '')
21
+ else
22
+ country_options = ""
26
23
  end
27
24
 
28
- return country_options + options_for_select(COUNTRIES.collect {|country| [I18n.t("countries.#{country}"), country]}, selected)
25
+ return country_options + options_for_select(COUNTRIES.collect {|country| [I18n.t("countries.#{country}", :default => country.to_s.titleize), country.to_s]}, :selected => selected)
29
26
  end
30
27
 
31
28
  # Returns a string of option tags for the states in the United States. Supply a state name as +selected to
@@ -33,16 +30,16 @@ module ActiveScaffold
33
30
  # in case you want to highligh a local area
34
31
  # NOTE: Only the option tags are returned from this method, wrap it in a <select>
35
32
  def usa_state_options_for_select(selected = nil, priority_states = nil)
36
- state_options = ""
37
33
  if priority_states
38
- state_options += options_for_select(priority_states, selected)
39
- state_options += "<option>-------------</option>\n"
34
+ state_options = options_for_select(priority_states + [['-------------', '']], :selected => selected, :disabled => '')
35
+ else
36
+ state_options = ""
40
37
  end
41
38
 
42
39
  if priority_states && priority_states.include?(selected)
43
- state_options += options_for_select(USASTATES - priority_states, selected)
40
+ state_options += options_for_select(USASTATES - priority_states, :selected => selected)
44
41
  else
45
- state_options += options_for_select(USASTATES, selected)
42
+ state_options += options_for_select(USASTATES, :selected => selected)
46
43
  end
47
44
 
48
45
  return state_options
@@ -305,10 +302,11 @@ module ActiveScaffold
305
302
  html_options = html_options.stringify_keys
306
303
  add_default_name_and_id(html_options)
307
304
  value = value(object)
305
+ selected_value = options.has_key?(:selected) ? options[:selected] : value
308
306
  content_tag("select",
309
307
  add_options(
310
- country_options_for_select(value, priority_countries),
311
- options, value
308
+ country_options_for_select(selected_value, priority_countries),
309
+ options, selected_value
312
310
  ), html_options
313
311
  )
314
312
  end
@@ -316,33 +314,39 @@ module ActiveScaffold
316
314
  def to_usa_state_select_tag(priority_states, options, html_options)
317
315
  html_options = html_options.stringify_keys
318
316
  add_default_name_and_id(html_options)
319
- value = value(object) if method(:value).arity > 0
320
- if html_options[:name.to_s].include?('search')
321
- html_options[:name.to_s] << '[]'
322
- html_options[:multiple] = true
323
- options[:include_blank] = true
324
- end
325
- content_tag("select", add_options(usa_state_options_for_select(value, priority_states), options, value), html_options)
317
+ value = value(object)
318
+ selected_value = options.has_key?(:selected) ? options[:selected] : value
319
+ content_tag("select", add_options(usa_state_options_for_select(selected_value, priority_states), options, selected_value), html_options)
326
320
  end
327
321
  end
328
322
  end
329
323
 
330
324
  module FormColumnHelpers
331
325
  def active_scaffold_input_country(column, options)
332
- priority = ["United States"]
333
326
  select_options = {:prompt => as_(:_select_)}
334
327
  select_options.merge!(options)
335
- country_select(:record, column.name, column.options[:priority] || priority, select_options, column.options)
328
+ options.reverse_merge!(column.options).except!(:prompt, :priority)
329
+ options[:name] += '[]' if options[:multiple]
330
+ country_select(:record, column.name, column.options[:priority] || [:united_states], select_options, options)
336
331
  end
337
332
 
338
333
  def active_scaffold_input_usa_state(column, options)
339
334
  select_options = {:prompt => as_(:_select_)}
340
335
  select_options.merge!(options)
341
- select_options.delete(:size)
342
- options.delete(:prompt)
343
- options.delete(:priority)
344
- usa_state_select(:record, column.name, column.options[:priority], select_options, column.options.merge!(options))
336
+ options.reverse_merge!(column.options).except!(:prompt, :priority)
337
+ options[:name] += '[]' if options[:multiple]
338
+ usa_state_select(:record, column.name, column.options[:priority], select_options, options)
339
+ end
340
+ end
341
+
342
+ module SearchColumnHelpers
343
+ def active_scaffold_search_country(column, options)
344
+ active_scaffold_input_country(column, options.merge!(:selected => options.delete(:value)))
345
+ end
346
+
347
+ def active_scaffold_search_usa_state(column, options)
348
+ active_scaffold_input_usa_state(column, options.merge!(:selected => options.delete(:value)))
345
349
  end
346
350
  end
347
351
  end
348
- end
352
+ end
@@ -4,37 +4,47 @@ module ActiveScaffold
4
4
  module FormColumnHelpers
5
5
  # This method decides which input to use for the given column.
6
6
  # It does not do any rendering. It only decides which method is responsible for rendering.
7
- def active_scaffold_input_for(column, scope = nil)
8
- options = active_scaffold_input_options(column, scope)
9
-
10
- # first, check if the dev has created an override for this specific field
11
- if override_form_field?(column)
12
- send(override_form_field(column), @record, options[:name])
13
-
14
- # second, check if the dev has specified a valid form_ui for this column
15
- elsif column.form_ui and override_input?(column.form_ui)
16
- send(override_input(column.form_ui), column, options)
17
-
18
- # fallback: we get to make the decision
19
- else
20
- if column.association
21
- # if we get here, it's because the column has a form_ui but not one ActiveScaffold knows about.
22
- raise "Unknown form_ui `#{column.form_ui}' for column `#{column.name}'"
23
- elsif column.virtual?
24
- active_scaffold_input_virtual(column, options)
25
-
26
- else # regular model attribute column
27
- # if we (or someone else) have created a custom render option for the column type, use that
28
- if override_input?(column.column.type)
29
- send(override_input(column.column.type), column, options)
30
- # final ultimate fallback: use rails' generic input method
31
- else
32
- # for textual fields we pass different options
33
- text_types = [:text, :string, :integer, :float, :decimal]
34
- options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type)
35
- input(:record, column.name, options.merge(column.options))
7
+ def active_scaffold_input_for(column, scope = nil, options = {})
8
+ begin
9
+ options = active_scaffold_input_options(column, scope, options)
10
+ options = javascript_for_update_column(column, scope, options)
11
+ # first, check if the dev has created an override for this specific field
12
+ if override_form_field?(column)
13
+ send(override_form_field(column), @record, options)
14
+ # second, check if the dev has specified a valid form_ui for this column
15
+ elsif column.form_ui and override_input?(column.form_ui)
16
+ send(override_input(column.form_ui), column, options)
17
+ # fallback: we get to make the decision
18
+ else
19
+ if column.association
20
+ # if we get here, it's because the column has a form_ui but not one ActiveScaffold knows about.
21
+ raise "Unknown form_ui `#{column.form_ui}' for column `#{column.name}'"
22
+ elsif column.virtual?
23
+ active_scaffold_input_virtual(column, options)
24
+
25
+ else # regular model attribute column
26
+ # if we (or someone else) have created a custom render option for the column type, use that
27
+ if override_input?(column.column.type)
28
+ send(override_input(column.column.type), column, options)
29
+ # final ultimate fallback: use rails' generic input method
30
+ else
31
+ # for textual fields we pass different options
32
+ text_types = [:text, :string, :integer, :float, :decimal]
33
+ date_types = [:date, :datetime, :time]
34
+ options = active_scaffold_input_text_options(options) if text_types.include?(column.column.type)
35
+ options = active_scaffold_input_date_options(column, options) if date_types.include?(column.column.type)
36
+ if column.column.type == :string && options[:maxlength].blank?
37
+ options[:maxlength] = column.column.limit
38
+ options[:size] ||= ActionView::Helpers::InstanceTag::DEFAULT_FIELD_OPTIONS["size"]
39
+ end
40
+ options[:value] = format_number_value(@record.send(column.name), column.options) if column.column.number?
41
+ input(:record, column.name, options.merge(column.options))
42
+ end
36
43
  end
37
44
  end
45
+ rescue Exception => e
46
+ logger.error Time.now.to_s + "#{e.inspect} -- on the ActiveScaffold column = :#{column.name} in #{@controller.class}"
47
+ raise e
38
48
  end
39
49
  end
40
50
 
@@ -47,44 +57,77 @@ module ActiveScaffold
47
57
  options
48
58
  end
49
59
 
60
+ # the standard active scaffold options used for date, datetime and time inputs
61
+ def active_scaffold_input_date_options(column, options = {})
62
+ options[:include_blank] = true if column.column.null
63
+ options[:prefix] = options[:name].gsub("[#{column.name}]", '')
64
+ options
65
+ end
66
+
50
67
  # the standard active scaffold options used for class, name and scope
51
- def active_scaffold_input_options(column, scope = nil)
68
+ def active_scaffold_input_options(column, scope = nil, options = {})
52
69
  name = scope ? "record#{scope}[#{column.name}]" : "record[#{column.name}]"
53
70
 
54
71
  # Fix for keeping unique IDs in subform
55
72
  id_control = "record_#{column.name}_#{[params[:eid], params[:id]].compact.join '_'}"
56
73
  id_control += scope.gsub(/(\[|\])/, '_').gsub('__', '_').gsub(/_$/, '') if scope
57
74
 
58
- { :name => name, :class => "#{column.name}-input", :id => id_control}
75
+ { :name => name, :class => "#{column.name}-input", :id => id_control}.merge(options)
59
76
  end
60
-
77
+
78
+ def javascript_for_update_column(column, scope, options)
79
+ if column.update_column
80
+ form_action = :create
81
+ form_action = :update if params[:action] == 'edit'
82
+ url_params = {
83
+ :action => 'render_field',
84
+ :id => params[:id],
85
+ :column => column.name,
86
+ :update_column => column.update_column,
87
+ :eid => params[:eid],
88
+ :scope => scope
89
+ }
90
+ url_params[:controller] = controller.class.active_scaffold_controller_for(@record.class).controller_path if scope
91
+ ajax_options = {:method => :get,
92
+ :url => url_for(url_params), :with => column.send_form_on_update_column ? "Form.serialize('#{element_form_id(:action => form_action)}')" : "'value=' + this.value",
93
+ :after => "$('#{loading_indicator_id(:action => form_action, :id => params[:id])}').style.visibility = 'visible'; Form.disable('#{element_form_id(:action => form_action)}');",
94
+ :complete => "$('#{loading_indicator_id(:action => form_action, :id => params[:id])}').style.visibility = 'hidden'; Form.enable('#{element_form_id(:action => form_action)}');"}
95
+ options[:onchange] = "#{remote_function(ajax_options)};#{options[:onchange]}"
96
+ end
97
+ options
98
+ end
99
+
61
100
  ##
62
101
  ## Form input methods
63
102
  ##
64
103
 
65
- def active_scaffold_input_singular_association(column, options)
104
+ def active_scaffold_input_singular_association(column, html_options)
66
105
  associated = @record.send(column.association.name)
67
106
 
68
107
  select_options = options_for_association(column.association)
69
108
  select_options.unshift([ associated.to_label, associated.id ]) unless associated.nil? or select_options.find {|label, id| id == associated.id}
70
109
 
71
- selected = associated.nil? ? nil : associated.id
72
- method = column.association.macro == :belongs_to ? column.association.primary_key_name : column.name
73
- options[:name] += '[id]'
74
- select(:record, method, select_options.uniq, {:selected => selected, :include_blank => as_(:_select_)}, options)
110
+ method = column.name
111
+ #html_options[:name] += '[id]'
112
+ options = {:include_blank => as_(:_select_)}
113
+
114
+ html_options.update(column.options[:html_options] || {})
115
+ options.update(column.options)
116
+ options[:selected] = associated.id unless associated.nil?
117
+ select(:record, method, select_options.uniq, options, html_options)
75
118
  end
76
119
 
77
120
  def active_scaffold_input_plural_association(column, options)
78
121
  associated_options = @record.send(column.association.name).collect {|r| [r.to_label, r.id]}
79
122
  select_options = associated_options | options_for_association(column.association)
80
- return as_(:no_options) if select_options.empty?
123
+ return content_tag(:span, as_(:no_options), :id => options[:id]) if select_options.empty?
81
124
 
82
125
  html = "<ul class=\"checkbox-list\" id=\"#{options[:id]}\">"
83
126
 
84
127
  associated_ids = associated_options.collect {|a| a[1]}
85
128
  select_options.each_with_index do |option, i|
86
129
  label, id = option
87
- this_name = "#{options[:name]}[#{i}][id]"
130
+ this_name = "#{options[:name]}[]"
88
131
  this_id = "#{options[:id]}_#{i}_id"
89
132
  html << "<li>"
90
133
  html << check_box_tag(this_name, id, associated_ids.include?(id), :id => this_id)
@@ -96,47 +139,44 @@ module ActiveScaffold
96
139
 
97
140
  html << '</ul>'
98
141
  html << javascript_tag("new DraggableLists('#{options[:id]}')") if column.options[:draggable_lists]
99
- html
142
+ html.html_safe
143
+ end
144
+
145
+ def active_scaffold_translated_option(column, text, value = nil)
146
+ value = text if value.nil?
147
+ [(text.is_a?(Symbol) ? column.active_record_class.human_attribute_name(text) : text), value.to_s]
100
148
  end
101
149
 
102
- def active_scaffold_input_select(column, options)
150
+ def active_scaffold_translated_options(column)
151
+ column.options[:options].collect do |text, value|
152
+ active_scaffold_translated_option(column, text, value)
153
+ end
154
+ end
155
+
156
+ def active_scaffold_input_select(column, html_options)
103
157
  if column.singular_association?
104
- active_scaffold_input_singular_association(column, options)
158
+ active_scaffold_input_singular_association(column, html_options)
105
159
  elsif column.plural_association?
106
- active_scaffold_input_plural_association(column, options)
160
+ active_scaffold_input_plural_association(column, html_options)
107
161
  else
108
- select(:record, column.name, column.options, { :selected => @record.send(column.name) }, options)
162
+ options = { :selected => @record.send(column.name).to_s }
163
+ options_for_select = active_scaffold_translated_options(column)
164
+ html_options.update(column.options[:html_options] || {})
165
+ options.update(column.options)
166
+ select(:record, column.name, options_for_select, options, html_options)
109
167
  end
110
168
  end
111
169
 
112
- # only works for singular associations
113
- # requires RecordSelect plugin to be installed and configured.
114
- # ... maybe this should be provided in a bridge?
115
- def active_scaffold_input_record_select(column, options)
116
- unless column.association
117
- raise ArgumentError, "record_select can only work against associations (and #{column.name} is not). A common mistake is to specify the foreign key field (like :user_id), instead of the association (:user)."
170
+ def active_scaffold_input_radio(column, html_options)
171
+ html_options.update(column.options[:html_options] || {})
172
+ column.options[:options].inject('') do |html, (text, value)|
173
+ text, value = active_scaffold_translated_option(column, text, value)
174
+ html << content_tag(:label, radio_button(:record, column.name, value, html_options.merge(:id => html_options[:id] + '-' + value.to_s)) + text)
118
175
  end
119
- remote_controller = active_scaffold_controller_for(column.association.klass).controller_path
120
-
121
- # if the opposite association is a :belongs_to (in that case association in this class must be has_one or has_many)
122
- # then only show records that have not been associated yet
123
- if [:has_one, :has_many].include?(column.association.macro)
124
- params.merge!({column.association.primary_key_name => ''})
125
- end
126
-
127
- record_select_options = {:controller => remote_controller, :id => options[:id]}
128
- record_select_options.merge!(active_scaffold_input_text_options)
129
- record_select_options.merge!(column.options)
130
-
131
- if column.singular_association?
132
- record_select_field(options[:name], (@record.send(column.name) || column.association.klass.new), record_select_options)
133
- elsif column.plural_association?
134
- record_multi_select_field(options[:name], @record.send(column.name), record_select_options)
135
- end
136
176
  end
137
177
 
138
178
  def active_scaffold_input_checkbox(column, options)
139
- check_box(:record, column.name, options)
179
+ check_box(:record, column.name, options.merge(column.options))
140
180
  end
141
181
 
142
182
  def active_scaffold_input_password(column, options)
@@ -145,9 +185,9 @@ module ActiveScaffold
145
185
  end
146
186
 
147
187
  def active_scaffold_input_textarea(column, options)
148
- text_area(:record, column.name, options.merge(:cols => column.options[:cols], :rows => column.options[:rows]))
188
+ text_area(:record, column.name, options.merge(:cols => column.options[:cols], :rows => column.options[:rows], :size => column.options[:size]))
149
189
  end
150
-
190
+
151
191
  def active_scaffold_input_virtual(column, options)
152
192
  options = active_scaffold_input_text_options(options)
153
193
  text_field :record, column.name, options.merge(column.options)
@@ -163,7 +203,7 @@ module ActiveScaffold
163
203
  select_options << [as_(:true), true]
164
204
  select_options << [as_(:false), false]
165
205
 
166
- select_tag(options[:name], options_for_select(select_options, @record.send(column.name)))
206
+ select_tag(options[:name], options_for_select(select_options, @record.send(column.name)), options)
167
207
  end
168
208
 
169
209
  def onsubmit
@@ -174,32 +214,40 @@ module ActiveScaffold
174
214
  ##
175
215
 
176
216
  # add functionality for overriding subform partials from association class path
177
- def override_subform_partial?(column)
178
- path, partial_name = partial_pieces(override_subform_partial(column))
217
+ def override_subform_partial?(column, subform_partial)
218
+ path, partial_name = partial_pieces(override_subform_partial(column, subform_partial))
179
219
  template_exists?(File.join(path, "_#{partial_name}"))
180
220
  end
181
221
 
182
- def override_subform_partial(column)
183
- File.join(active_scaffold_controller_for(column.association.klass).controller_path, "subform") if column_renders_as(column) == :subform
222
+ def override_subform_partial(column, subform_partial)
223
+ File.join(active_scaffold_controller_for(column.association.klass).controller_path, subform_partial) if column_renders_as(column) == :subform
184
224
  end
185
225
 
186
226
  def override_form_field_partial?(column)
187
227
  path, partial_name = partial_pieces(override_form_field_partial(column))
188
- template_exists?(File.join(path, "_#{partial_name}"))
228
+ template_exists?(File.join(path, "_#{partial_name}"), true)
189
229
  end
190
230
 
191
- # the naming convention for overriding form fields with partials
231
+ # the naming convention for overriding form fields with helpers
192
232
  def override_form_field_partial(column)
193
- "#{column.name}_form_column"
233
+ path = active_scaffold_controller_for(column.active_record_class).controller_path
234
+ File.join(path, "#{clean_column_name(column.name)}_form_column")
194
235
  end
195
236
 
196
- def override_form_field?(column)
197
- respond_to?(override_form_field(column))
237
+ def override_form_field(column)
238
+ method = override_form_field_name(column)
239
+ return method if respond_to?(method)
240
+ old_method = override_form_field_name(column, true)
241
+ if respond_to?(old_method)
242
+ ActiveSupport::Deprecation.warn("You are using an old naming schema for overrides, you should name the helper #{method} instead of #{old_method}")
243
+ old_method
244
+ end
198
245
  end
246
+ alias_method :override_form_field?, :override_form_field
199
247
 
200
248
  # the naming convention for overriding form fields with helpers
201
- def override_form_field(column)
202
- "#{column.name}_form_column"
249
+ def override_form_field_name(column, old = false)
250
+ "#{clean_class_name(column.active_record_class.name) + '_' unless old}#{clean_column_name(column.name)}_form_column"
203
251
  end
204
252
 
205
253
  def override_input?(form_ui)
@@ -224,10 +272,11 @@ module ActiveScaffold
224
272
  end
225
273
 
226
274
  def subform_partial_for_column(column)
227
- if override_subform_partial?(column)
228
- override_subform_partial(column)
275
+ subform_partial = "#{active_scaffold_config_for(column.association.klass).subform.layout}_subform"
276
+ if override_subform_partial?(column, subform_partial)
277
+ override_subform_partial(column, subform_partial)
229
278
  else
230
- "horizontal_subform"
279
+ subform_partial
231
280
  end
232
281
  end
233
282
 
@@ -238,7 +287,7 @@ module ActiveScaffold
238
287
  def column_renders_as(column)
239
288
  if column.is_a? ActiveScaffold::DataStructures::ActionColumns
240
289
  return :subsection
241
- elsif column.active_record_class.locking_column.to_s == column.name.to_s
290
+ elsif column.active_record_class.locking_column.to_s == column.name.to_s or column.form_ui == :hidden
242
291
  return :hidden
243
292
  elsif column.association.nil? or column.form_ui or !active_scaffold_config_for(column.association.klass).actions.include?(:subform)
244
293
  return :field
@@ -262,6 +311,28 @@ module ActiveScaffold
262
311
  "[#{column.name}]"
263
312
  end
264
313
  end
314
+
315
+ def active_scaffold_add_existing_input(options)
316
+ if controller.respond_to?(:record_select_config)
317
+ remote_controller = active_scaffold_controller_for(record_select_config.model).controller_path
318
+ options.merge!(:controller => remote_controller)
319
+ options.merge!(active_scaffold_input_text_options)
320
+ record_select_field(options[:name], @record, options)
321
+ else
322
+ column = active_scaffold_config_for(params[:parent_model]).columns[params[:parent_column]]
323
+ select_options = options_for_select(options_for_association(column.association)) unless column.through_association?
324
+ select_options ||= options_for_select(active_scaffold_config.model.find(:all).collect {|c| [h(c.to_label), c.id]})
325
+ select_tag 'associated_id', '<option value="">' + as_(:_select_) + '</option>' + select_options unless select_options.empty?
326
+ end
327
+ end
328
+
329
+ def active_scaffold_add_existing_label
330
+ if controller.respond_to?(:record_select_config)
331
+ record_select_config.model.human_name
332
+ else
333
+ active_scaffold_config.model.human_name
334
+ end
335
+ end
265
336
  end
266
337
  end
267
338
  end