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,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require 'test_helper'
2
2
 
3
3
  class EmployeeTest < ActiveSupport::TestCase
4
4
  fixtures :employees,:credentials
@@ -0,0 +1,4 @@
1
+ require 'test_helper'
2
+
3
+ class Admin::DraftInvoicesHelperTest < ActionView::TestCase
4
+ end
@@ -1,6 +1,5 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require File.dirname(__FILE__) + '/../test_unit_factory_helper'
3
-
1
+ require 'test_helper'
2
+ require 'test_unit_factory_helper'
4
3
 
5
4
  class InvoicePaymentTest < ActiveSupport::TestCase
6
5
 
@@ -26,55 +25,55 @@ class InvoicePaymentTest < ActiveSupport::TestCase
26
25
  assert_equal 0.00, client.balance
27
26
 
28
27
  # Ensure that invoices aren't marked as 'paid' until the invoice_payments have been applied. Even though the balance is 0
29
- assert_equal false, invoices[0].is_paid?
30
- assert_equal false, invoices[1].is_paid?
31
- assert_equal false, invoices[2].is_paid?
28
+ assert_equal false, invoices[0].is_paid?(true)
29
+ assert_equal false, invoices[1].is_paid?(true)
30
+ assert_equal false, invoices[2].is_paid?(true)
32
31
 
33
32
  # Ensure that payments aren't marked as 'paid' until the invoice_payments have been applied. Even though the balance is 0
34
- assert_equal false, payments[0].is_allocated?
35
- assert_equal false, payments[1].is_allocated?
36
- assert_equal false, payments[2].is_allocated?
37
- assert_equal false, payments[3].is_allocated?
38
- assert_equal false, payments[4].is_allocated?
33
+ assert_equal false, payments[0].is_allocated?(true)
34
+ assert_equal false, payments[1].is_allocated?(true)
35
+ assert_equal false, payments[2].is_allocated?(true)
36
+ assert_equal false, payments[3].is_allocated?(true)
37
+ assert_equal false, payments[4].is_allocated?(true)
39
38
 
40
39
  # Now start marking payments/invocies, and testing the corresponding is_ methods :
41
40
  InvoicePayment.quick_create! invoices[0], payments[2], 10.00
42
41
 
43
- assert_equal true, invoices[0].is_paid?
44
- assert_equal false, invoices[1].is_paid?
45
- assert_equal false, invoices[2].is_paid?
46
- assert_equal false, payments[0].is_allocated?
47
- assert_equal false, payments[1].is_allocated?
48
- assert_equal false, payments[2].is_allocated?
49
- assert_equal false, payments[3].is_allocated?
50
- assert_equal false, payments[4].is_allocated?
42
+ assert_equal true, invoices[0].is_paid?(true)
43
+ assert_equal false, invoices[1].is_paid?(true)
44
+ assert_equal false, invoices[2].is_paid?(true)
45
+ assert_equal false, payments[0].is_allocated?(true)
46
+ assert_equal false, payments[1].is_allocated?(true)
47
+ assert_equal false, payments[2].is_allocated?(true)
48
+ assert_equal false, payments[3].is_allocated?(true)
49
+ assert_equal false, payments[4].is_allocated?(true)
51
50
 
52
51
  InvoicePayment.quick_create! invoices[1], payments[2], 1.00
53
52
  InvoicePayment.quick_create! invoices[1], payments[3], 4.00
54
53
  InvoicePayment.quick_create! invoices[1], payments[4], 10.00
55
54
 
56
- assert_equal true, invoices[0].is_paid?
57
- assert_equal true, invoices[1].is_paid?
58
- assert_equal false, invoices[2].is_paid?
59
- assert_equal false, payments[0].is_allocated?
60
- assert_equal false, payments[1].is_allocated?
61
- assert_equal true, payments[2].is_allocated?
62
- assert_equal true, payments[3].is_allocated?
63
- assert_equal true, payments[4].is_allocated?
55
+ assert_equal true, invoices[0].is_paid?(true)
56
+ assert_equal true, invoices[1].is_paid?(true)
57
+ assert_equal false, invoices[2].is_paid?(true)
58
+ assert_equal false, payments[0].is_allocated?(true)
59
+ assert_equal false, payments[1].is_allocated?(true)
60
+ assert_equal true, payments[2].is_allocated?(true)
61
+ assert_equal true, payments[3].is_allocated?(true)
62
+ assert_equal true, payments[4].is_allocated?(true)
64
63
 
65
64
  InvoicePayment.quick_create! invoices[2], payments[0], 2.00
66
65
  InvoicePayment.quick_create! invoices[2], payments[1], 3.00
67
66
 
68
67
  # Everything should be allocated now - retest is_paid/allocated code
69
- assert_equal true, invoices[0].is_paid?
70
- assert_equal true, invoices[1].is_paid?
71
- assert_equal true, invoices[2].is_paid?
72
-
73
- assert_equal true, payments[0].is_allocated?
74
- assert_equal true, payments[1].is_allocated?
75
- assert_equal true, payments[2].is_allocated?
76
- assert_equal true, payments[3].is_allocated?
77
- assert_equal true, payments[4].is_allocated?
68
+ assert_equal true, invoices[0].is_paid?(true)
69
+ assert_equal true, invoices[1].is_paid?(true)
70
+ assert_equal true, invoices[2].is_paid?(true)
71
+
72
+ assert_equal true, payments[0].is_allocated?(true)
73
+ assert_equal true, payments[1].is_allocated?(true)
74
+ assert_equal true, payments[2].is_allocated?(true)
75
+ assert_equal true, payments[3].is_allocated?(true)
76
+ assert_equal true, payments[4].is_allocated?(true)
78
77
  end
79
78
 
80
79
  # How well does find_recomended_invoices work for a negative invoice with a credit/negative amount -payment? Write a test:
@@ -90,9 +89,9 @@ class InvoicePaymentTest < ActiveSupport::TestCase
90
89
  assert_equal -10.00, client.balance
91
90
 
92
91
  # Negative invoices are always marked paid
93
- assert_equal false, invoices[0].is_paid?
94
- assert_equal true, invoices[1].is_paid?
95
- assert_equal true, invoices[2].is_paid?
92
+ assert_equal false, invoices[0].is_paid?(true)
93
+ assert_equal true, invoices[1].is_paid?(true)
94
+ assert_equal true, invoices[2].is_paid?(true)
96
95
 
97
96
  payments = [
98
97
  Factory.generate_payment( client, 5.00, :invoice_assignments =>
@@ -106,9 +105,9 @@ class InvoicePaymentTest < ActiveSupport::TestCase
106
105
  assert_equal -20.00, client.balance
107
106
 
108
107
  # Everything should be paid now:
109
- assert_equal true, invoices[0].is_paid?
110
- assert_equal true, invoices[1].is_paid?
111
- assert_equal true, invoices[2].is_paid?
108
+ assert_equal true, invoices[0].is_paid?(true)
109
+ assert_equal true, invoices[1].is_paid?(true)
110
+ assert_equal true, invoices[2].is_paid?(true)
112
111
 
113
112
  # Now what if the invoice they have an invoice for -$20, and an invoice for +$12. Their outstanding balance is -$8,
114
113
  # but if they try to make a payment for $5, will we freak on them?
@@ -118,20 +117,20 @@ class InvoicePaymentTest < ActiveSupport::TestCase
118
117
 
119
118
  assert_equal -8.00, client.balance
120
119
 
121
- assert_equal true, invoices[0].is_paid?
122
- assert_equal true, invoices[1].is_paid?
123
- assert_equal true, invoices[2].is_paid?
124
- assert_equal false, invoices[3].is_paid?
120
+ assert_equal true, invoices[0].is_paid?(true)
121
+ assert_equal true, invoices[1].is_paid?(true)
122
+ assert_equal true, invoices[2].is_paid?(true)
123
+ assert_equal false, invoices[3].is_paid?(true)
125
124
 
126
125
  payments << Factory.generate_payment( client, 12.00, :invoice_assignments =>
127
126
  [InvoicePayment.new(:invoice => invoices[3], :amount => 12.00 )]
128
127
  )
129
128
 
130
129
  # and make sure we're cool:
131
- assert_equal true, invoices[0].is_paid?
132
- assert_equal true, invoices[1].is_paid?
133
- assert_equal true, invoices[2].is_paid?
134
- assert_equal true, invoices[3].is_paid?
130
+ assert_equal true, invoices[0].is_paid?(true)
131
+ assert_equal true, invoices[1].is_paid?(true)
132
+ assert_equal true, invoices[2].is_paid?(true)
133
+ assert_equal true, invoices[3].is_paid?(true)
135
134
 
136
135
  assert_equal -20.00, client.balance
137
136
  end
@@ -305,6 +304,15 @@ class InvoicePaymentTest < ActiveSupport::TestCase
305
304
  InvoicePayment.new( :invoice => invoice, :amount => 50.00 )
306
305
  ] )
307
306
  end
307
+
308
+ # Test that negative assignments aren't accepted:
309
+ invoice = Factory.generate_invoice( client, 10.00, :is_published => false, :payment_assignments => [])
310
+
311
+ assert_raise(ActiveRecord::RecordInvalid) do
312
+ payment = Factory.generate_payment( client, 5.00 , :invoice_assignments => [
313
+ InvoicePayment.new( :invoice => invoice, :amount => -1.00 )
314
+ ] )
315
+ end
308
316
 
309
317
  # Test InvoicePayment create fails with unpublished unvoice
310
318
  invoice = Factory.generate_invoice( client, 60.00, :is_published => false, :payment_assignments => [])
@@ -315,4 +323,36 @@ class InvoicePaymentTest < ActiveSupport::TestCase
315
323
  assert_raise(ActiveRecord::RecordInvalid) { ip.save! }
316
324
  assert ip.errors.invalid?(:invoice)
317
325
  end
326
+
327
+ # Mostly I did this to test out view-caching isn't screwing anything up here when we manually attach (and don't save InvoicePayment(s)
328
+ def test_payment_amount_unallocated
329
+ client = Factory.create_client
330
+
331
+ invoice = Factory.generate_invoice( client, 50.00, :is_published => false, :payment_assignments => [])
332
+ payment = Factory.generate_payment( client, 60.00, :invoice_assignments => [] )
333
+
334
+ assert_equal Money.new(0), payment.amount_allocated
335
+ assert_equal Money.new(6000), payment.amount_unallocated
336
+
337
+ payment.invoice_assignments << InvoicePayment.new( :invoice => invoice, :amount => 50.00 )
338
+
339
+ assert_equal Money.new(5000), payment.amount_allocated
340
+ assert_equal Money.new(1000), payment.amount_unallocated
341
+ end
342
+
343
+ # Mostly I did this to test out view-caching isn't screwing anything up here when we manually attach (and don't save InvoicePayment(s)
344
+ def test_invoice_amount_outstanding
345
+ client = Factory.create_client
346
+
347
+ invoice = Factory.generate_invoice( client, 60.00, :is_published => false, :payment_assignments => [])
348
+ payment = Factory.generate_payment( client, 50.00, :invoice_assignments => [] )
349
+
350
+ assert_equal Money.new(0), invoice.amount_paid
351
+ assert_equal Money.new(6000), invoice.amount_outstanding
352
+
353
+ invoice.payment_assignments << InvoicePayment.new( :payment => payment, :amount => 50.00 )
354
+
355
+ assert_equal Money.new(1000), invoice.amount_outstanding
356
+ assert_equal Money.new(5000), invoice.amount_paid
357
+ end
318
358
  end
@@ -1,5 +1,5 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require File.dirname(__FILE__) + '/../test_unit_factory_helper.rb'
1
+ require 'test_helper'
2
+ require 'test_unit_factory_helper'
3
3
 
4
4
  require 'date'
5
5
 
@@ -88,7 +88,7 @@ class InvoiceTest < ActiveSupport::TestCase
88
88
  def test_invoice_create_defaults
89
89
  inv = Invoice.create
90
90
 
91
- assert_equal Time.utc(*Time.now.to_a).last_month.end_of_month, inv.issued_on
91
+ assert_equal Time.utc(*Time.now.to_a).prev_month.end_of_month, inv.issued_on
92
92
  assert_equal false, inv.is_published
93
93
  end
94
94
 
@@ -421,7 +421,7 @@ class InvoiceTest < ActiveSupport::TestCase
421
421
 
422
422
  assert_nothing_raised do
423
423
  subactivities.each do |activity_type|
424
- activity_type.activity.move_to_invoice invoice_dest
424
+ activity_type.activity.move_to_invoice! invoice_dest
425
425
  end
426
426
  end
427
427
 
@@ -437,7 +437,7 @@ class InvoiceTest < ActiveSupport::TestCase
437
437
  end
438
438
 
439
439
  assert_nothing_raised do
440
- labor.activity.move_to_invoice invoice_src
440
+ labor.activity.move_to_invoice! invoice_src
441
441
  end
442
442
 
443
443
  assert_equal invoice_src.id, labor.activity.invoice_id
@@ -454,14 +454,54 @@ class InvoiceTest < ActiveSupport::TestCase
454
454
 
455
455
  # Assert fail!
456
456
  labor.activity.reload
457
- assert_raise(StandardError) { labor.activity.move_to_invoice invoice_dest }
457
+ assert_raise(StandardError) { labor.activity.move_to_invoice! invoice_dest }
458
458
 
459
459
  # Assert fail!
460
460
  material.activity.reload
461
- assert_raise(StandardError) { material.activity.move_to_invoice invoice_src }
461
+ assert_raise(StandardError) { material.activity.move_to_invoice! invoice_src }
462
462
 
463
463
  end
464
-
464
+
465
+ def test_activity_unassign
466
+ client_src = Factory.create_client
467
+
468
+ create_act_args = {:occurred_on => (DateTime.now << 1), :client => client_src}
469
+
470
+ labor = Factory.create_labor( {}, create_act_args.merge({:cost => 1.99}) )
471
+ material = Factory.create_material( {}, create_act_args.merge({:cost => 100.0, :tax => 2.0}))
472
+ proposal = Factory.create_proposal( {}, create_act_args)
473
+ adjustment = Factory.create_adjustment( {}, create_act_args.merge({:tax => 26.00}))
474
+
475
+ subactivities = [labor, material, proposal, adjustment]
476
+
477
+ present_date = DateTime.now
478
+
479
+ invoice_src = Invoice.create!(
480
+ :client => client_src,
481
+ :issued_on => present_date,
482
+ :activity_types => @activity_types,
483
+ :activities => Invoice.recommended_activities_for(client_src, present_date, @activity_types)
484
+ )
485
+
486
+ assert_equal 1650.00, invoice_src.amount
487
+ assert_equal 48.01, invoice_src.taxes_total
488
+
489
+ assert_nothing_raised do
490
+ material.activity.move_to_invoice! nil
491
+ end
492
+
493
+ invoice_src.activities(true)
494
+
495
+ material = Activity::Material.find(material.id)
496
+
497
+ assert_equal nil, material.activity.invoice_id
498
+ assert_equal client_src.id, material.activity.client_id
499
+
500
+ assert_equal 1548.0, invoice_src.amount(true)
501
+ assert_equal 46.01, invoice_src.taxes_total
502
+ end
503
+
504
+
465
505
  private
466
506
 
467
507
  def set_published(inv, published_state)
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require 'test_helper'
2
2
 
3
3
  class NotifierTest < ActionMailer::TestCase
4
4
  tests Notifier
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require 'test_helper'
2
2
 
3
3
  class PaymentMethodTest < ActiveSupport::TestCase
4
4
  # Replace this with your real tests.
@@ -1,5 +1,5 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
2
- require File.dirname(__FILE__) + '/../test_unit_factory_helper.rb'
1
+ require 'test_helper'
2
+ require 'test_unit_factory_helper'
3
3
 
4
4
  class PaymentTest < ActiveSupport::TestCase
5
5
 
@@ -41,7 +41,7 @@ class PaymentTest < ActiveSupport::TestCase
41
41
 
42
42
  assert_equal 0.0.to_money, client.balance
43
43
 
44
- assert_equal true, invoices[1].is_paid?
44
+ assert_equal true, invoices[1].is_paid?(true)
45
45
 
46
46
  payments << Factory.generate_payment( client, 300.20)
47
47
 
@@ -60,26 +60,26 @@ class PaymentTest < ActiveSupport::TestCase
60
60
 
61
61
  invoice_one = Factory.generate_invoice client, 290.00
62
62
 
63
- assert_equal true, invoice_one.is_paid?
63
+ assert_equal true, invoice_one.is_paid?(true)
64
64
  assert_equal -10.00, client.balance
65
65
 
66
66
  Factory.generate_payment client, 200.00
67
67
 
68
68
  invoice_two = Factory.generate_invoice client, 220.00
69
69
 
70
- assert_equal false, invoice_two.is_paid?
70
+ assert_equal false, invoice_two.is_paid?(true)
71
71
  assert_equal 10.00, client.balance
72
72
 
73
73
  Factory.generate_payment client, 10.00
74
74
 
75
- assert_equal true, invoice_two.is_paid?
75
+ assert_equal true, invoice_two.is_paid?(true)
76
76
  assert_equal 0.00, client.balance
77
77
 
78
78
  Factory.generate_payment client, 300.00
79
79
 
80
80
  invoice_three = Factory.generate_invoice client, 300.00
81
81
 
82
- assert_equal true, invoice_three.is_paid?
82
+ assert_equal true, invoice_three.is_paid?(true)
83
83
  assert_equal 0.00, client.balance
84
84
  end
85
85
 
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require 'test_helper'
2
2
 
3
3
  class SettingTest < ActiveSupport::TestCase
4
4
  # Replace this with your real tests.
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require 'test_helper'
2
2
 
3
3
  class SlimtimerTaskTest < ActiveSupport::TestCase
4
4
  fixtures :slimtimer_tasks
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../test_helper'
1
+ require 'test_helper'
2
2
 
3
3
  class SlimtimerTimeEntryTest < ActiveSupport::TestCase
4
4
  fixtures :employees, :employee_slimtimers, :credentials
@@ -1,3 +1,5 @@
1
+ This file is not maintained, many more changes were added after 1.2RC1
2
+
1
3
  = 1.2RC1
2
4
 
3
5
  == FEATURES
@@ -149,4 +151,4 @@
149
151
  * fixes for edge rails compatibility
150
152
  * small improvements for localization accessibility
151
153
  * minor string renaming (will affect localization tables, though)
152
- * closed a few XSS holes
154
+ * closed a few XSS holes
@@ -1,8 +1,14 @@
1
- **********************************************************************************
2
- ** For all documentation see the project website: http://www.ActiveScaffold.com **
3
- **********************************************************************************
1
+ ***********************************************************************************************
2
+ ** For all documentation see the wiki: http://wiki.github.com/activescaffold/active_scaffold **
3
+ ***********************************************************************************************
4
4
 
5
- ActiveScaffold plugin by Scott Rutherford (scott@caronsoftware.com), Richard White (rrwhite@gmail.com), Lance Ivy (lance@cainlevy.net), Ed Moss, and Tim Harper
5
+ Read http://wiki.github.com/activescaffold/active_scaffold/getting-started:"Getting Started" guide to start using ActiveScaffold
6
+
7
+ *********************************************************************
8
+ ** For news see the project website: http://www.ActiveScaffold.com **
9
+ *********************************************************************
10
+
11
+ ActiveScaffold plugin by Scott Rutherford (scott@caronsoftware.com), Richard White (rrwhite@gmail.com), Lance Ivy (lance@cainlevy.net), Ed Moss, Tim Harper and Sergio Cambra (sergio@entrecables.com)
6
12
 
7
13
  Uses DhtmlHistory by Brad Neuberg (bkn3@columbia.edu)
8
14
  http://codinginparadise.org
@@ -20,9 +26,16 @@ http://code.google.com/p/recordselect/
20
26
 
21
27
  Please note the following list of Active Scaffold branches and Rails versions. Master will not work with Rails < 2.2
22
28
 
23
- Rails master (edge): Active Scaffold master
29
+ Active Scaffold master currently supports rails-2.3.8, but incompatible changes can be introduced, if you want an stable version, use rails-2.3
30
+
31
+ If you are using rails-2.3 with no deprecation warnings, you can update to master branch, although you will have to update your form and search helper overrides, because they will get an options hash instead of input name.
32
+
33
+ Rails 2.3.*: Active Scaffold rails-2.3
24
34
  Rails 2.2.*: Active Scaffold rails-2.2
25
35
  Rails 2.1.*: Active Scaffold rails-2.1
26
36
  Rails < 2.1: Active Scaffold 1-1-stable (no guarantees)
27
37
 
38
+ Since Rails 2.3, render_component plugin is needed for nested and embbeded scaffolds. It works with rails-2.3 branch from ewildgoose repository:
39
+ script/plugin install git://github.com/ewildgoose/render_component.git -r rails-2.3
40
+
28
41
  Released under the MIT license (included)
@@ -14,4 +14,4 @@ ActiveRecord::Base.class_eval {include ActiveRecordPermissions::Permissions}
14
14
 
15
15
  require 'bridges/bridge.rb'
16
16
 
17
- I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'lib', 'active_scaffold', 'locale', '*.{rb,yml}')]
17
+ I18n.load_path.unshift *Dir[File.join(File.dirname(__FILE__), 'lib', 'active_scaffold', 'locale', '*.{rb,yml}')]
@@ -1,430 +1,532 @@
1
- if (typeof Prototype == 'undefined')
2
- {
3
- warning = "ActiveScaffold Error: Prototype could not be found. Please make sure that your application's layout includes prototype.js (e.g. <%= javascript_include_tag :defaults %>) *before* it includes active_scaffold.js (e.g. <%= active_scaffold_includes %>).";
4
- alert(warning);
5
- }
6
- if (Prototype.Version.substring(0, 3) != '1.6')
7
- {
8
- warning = "ActiveScaffold Error: Prototype version 1.6.x is required. Please update prototype.js (rake rails:update:javascripts).";
9
- alert(warning);
10
- }
11
-
12
- /*
13
- * Simple utility methods
14
- */
15
-
16
- var ActiveScaffold = {
17
- records_for: function(tbody_id) {
18
- var rows = [];
19
- var child = $(tbody_id).down('.record');
20
- while (child) {
21
- rows.push(child);
22
- child = child.next('.record');
23
- }
24
- return rows;
25
- },
26
- stripe: function(tbody_id) {
27
- var even = false;
28
- var rows = this.records_for(tbody_id);
29
- for (var i = 0; i < rows.length; i++) {
30
- var child = rows[i];
31
- //Make sure to skip rows that are create or edit rows or messages
32
- if (child.tagName != 'SCRIPT'
33
- && !child.hasClassName("create")
34
- && !child.hasClassName("update")
35
- && !child.hasClassName("inline-adapter")
36
- && !child.hasClassName("active-scaffold-calculations")) {
37
-
38
- if (even) child.addClassName("even-record");
39
- else child.removeClassName("even-record");
40
-
41
- even = !even;
42
- }
43
- }
44
- },
45
- hide_empty_message: function(tbody, empty_message_id) {
46
- if (this.records_for(tbody).length != 0) {
47
- $(empty_message_id).hide();
48
- }
49
- },
50
- reload_if_empty: function(tbody, url) {
51
- var content_container_id = tbody.replace('tbody', 'content');
52
- if (this.records_for(tbody).length == 0) {
53
- new Ajax.Updater($(content_container_id), url, {
54
- method: 'get',
55
- asynchronous: true,
56
- evalScripts: true
57
- });
58
- }
59
- },
60
- removeSortClasses: function(scaffold_id) {
61
- $$('#' + scaffold_id + ' td.sorted').each(function(element) {
62
- element.removeClassName("sorted");
63
- });
64
- $$('#' + scaffold_id + ' th.sorted').each(function(element) {
65
- element.removeClassName("sorted");
66
- element.removeClassName("asc");
67
- element.removeClassName("desc");
68
- });
69
- },
70
- decrement_record_count: function(scaffold_id) {
71
- // decrement the last record count, firsts record count are in nested lists
72
- count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
73
- count.innerHTML = parseInt(count.innerHTML) - 1;
74
- },
75
- increment_record_count: function(scaffold_id) {
76
- // increment the last record count, firsts record count are in nested lists
77
- count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
78
- count.innerHTML = parseInt(count.innerHTML) + 1;
79
- },
80
-
81
- server_error_response: '',
82
- report_500_response: function(active_scaffold_id) {
83
- messages_container = $(active_scaffold_id).down('td.messages-container');
84
- new Insertion.Top(messages_container, this.server_error_response);
85
- }
86
- }
87
-
88
- /*
89
- * DHTML history tie-in
90
- */
91
- function addActiveScaffoldPageToHistory(url, active_scaffold_id) {
92
- if (typeof dhtmlHistory == 'undefined') return; // it may not be loaded
93
-
94
- var array = url.split('?');
95
- var qs = new Querystring(array[1]);
96
- var sort = qs.get('sort')
97
- var dir = qs.get('sort_direction')
98
- var page = qs.get('page')
99
- if (sort || dir || page) dhtmlHistory.add(active_scaffold_id+":"+page+":"+sort+":"+dir, url);
100
- }
101
-
102
- /*
103
- * Add-ons/Patches to Prototype
104
- */
105
-
106
- /* patch to support replacing TR/TD/TBODY in Internet Explorer, courtesy of http://dev.rubyonrails.org/ticket/4273 */
107
- Element.replace = function(element, html) {
108
- element = $(element);
109
- if (element.outerHTML) {
110
- try {
111
- element.outerHTML = html.stripScripts();
112
- } catch (e) {
113
- var tn = element.tagName;
114
- if(tn=='TBODY' || tn=='TR' || tn=='TD')
115
- {
116
- var tempDiv = document.createElement("div");
117
- tempDiv.innerHTML = '<table id="tempTable" style="display: none">' + html.stripScripts() + '</table>';
118
- element.parentNode.replaceChild(tempDiv.getElementsByTagName(tn).item(0), element);
119
- }
120
- else throw e;
121
- }
122
- } else {
123
- var range = element.ownerDocument.createRange();
124
- /* patch to fix <form> replaces in Firefox. see http://dev.rubyonrails.org/ticket/8010 */
125
- range.selectNodeContents(element.parentNode);
126
- element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);
127
- }
128
- setTimeout(function() {html.evalScripts()}, 10);
129
- return element;
130
- };
131
-
132
- /*
133
- * URL modification support. Incomplete functionality.
134
- */
135
- Object.extend(String.prototype, {
136
- append_params: function(params) {
137
- url = this;
138
- if (url.indexOf('?') == -1) url += '?';
139
- else if (url.lastIndexOf('&') != url.length) url += '&';
140
-
141
- url += $H(params).collect(function(item) {
142
- return item.key + '=' + item.value;
143
- }).join('&');
144
-
145
- return url;
146
- }
147
- });
148
-
149
- /*
150
- * Prototype's implementation was throwing an error instead of false
151
- */
152
- Element.Methods.Simulated = {
153
- hasAttribute: function(element, attribute) {
154
- var t = Element._attributeTranslations;
155
- attribute = (t.names && t.names[attribute]) || attribute;
156
- // Return false if we get an error here
157
- try {
158
- return $(element).getAttributeNode(attribute).specified;
159
- } catch (e) {
160
- return false;
161
- }
162
- }
163
- };
164
-
165
- /**
166
- * A set of links. As a set, they can be controlled such that only one is "open" at a time, etc.
167
- */
168
- ActiveScaffold.Actions = new Object();
169
- ActiveScaffold.Actions.Abstract = function(){}
170
- ActiveScaffold.Actions.Abstract.prototype = {
171
- initialize: function(links, target, loading_indicator, options) {
172
- this.target = $(target);
173
- this.loading_indicator = $(loading_indicator);
174
- this.options = options;
175
- this.links = links.collect(function(link) {
176
- return this.instantiate_link(link);
177
- }.bind(this));
178
- },
179
-
180
- instantiate_link: function(link) {
181
- throw 'unimplemented'
182
- }
183
- }
184
-
185
- /**
186
- * A DataStructures::ActionLink, represented in JavaScript.
187
- * Concerned with AJAX-enabling a link and adapting the result for insertion into the table.
188
- */
189
- ActiveScaffold.ActionLink = new Object();
190
- ActiveScaffold.ActionLink.Abstract = function(){}
191
- ActiveScaffold.ActionLink.Abstract.prototype = {
192
- initialize: function(a, target, loading_indicator) {
193
- this.tag = $(a);
194
- this.url = this.tag.href;
195
- this.method = 'get';
196
- if(this.url.match('_method=delete')){
197
- this.method = 'delete';
198
- } else if(this.url.match('_method=post')){
199
- this.method = 'post';
200
- }
201
- this.target = target;
202
- this.loading_indicator = loading_indicator;
203
- this.hide_target = false;
204
- this.position = this.tag.getAttribute('position');
205
- this.page_link = this.tag.getAttribute('page_link');
206
-
207
- this.onclick = this.tag.onclick;
208
- this.tag.onclick = null;
209
- this.tag.observe('click', function(event) {
210
- this.open();
211
- Event.stop(event);
212
- }.bind(this));
213
-
214
- this.tag.action_link = this;
215
- },
216
-
217
- open: function() {
218
- if (this.is_disabled()) return;
219
-
220
- if (this.tag.hasAttribute( "dhtml_confirm")) {
221
- if (this.onclick) this.onclick();
222
- return;
223
- } else {
224
- if (this.onclick && !this.onclick()) return;//e.g. confirmation messages
225
- this.open_action();
226
- }
227
- },
228
-
229
- open_action: function() {
230
- if (this.position) this.disable();
231
-
232
- if (this.page_link) {
233
- window.location = this.url;
234
- } else {
235
- if (this.loading_indicator) this.loading_indicator.style.visibility = 'visible';
236
- new Ajax.Request(this.url, {
237
- asynchronous: true,
238
- evalScripts: true,
239
- method: this.method,
240
- onSuccess: function(request) {
241
- if (this.position) {
242
- this.insert(request.responseText);
243
- if (this.hide_target) this.target.hide();
244
- } else {
245
- request.evalResponse();
246
- }
247
- }.bind(this),
248
-
249
- onFailure: function(request) {
250
- ActiveScaffold.report_500_response(this.scaffold_id());
251
- if (this.position) this.enable()
252
- }.bind(this),
253
-
254
- onComplete: function(request) {
255
- if (this.loading_indicator) this.loading_indicator.style.visibility = 'hidden';
256
- }.bind(this)
257
- });
258
- }
259
- },
260
-
261
- insert: function(content) {
262
- throw 'unimplemented'
263
- },
264
-
265
- close: function() {
266
- this.enable();
267
- this.adapter.remove();
268
- if (this.hide_target) this.target.show();
269
- },
270
-
271
- register_cancel_hooks: function() {
272
- // anything in the insert with a class of cancel gets the closer method, and a reference to this object for good measure
273
- var self = this;
274
- this.adapter.select('.cancel').each(function(elem) {
275
- elem.observe('click', this.close_handler.bind(this));
276
- elem.link = self;
277
- }.bind(this))
278
- },
279
-
280
- reload: function() {
281
- this.close();
282
- this.open();
283
- },
284
-
285
- get_new_adapter_id: function() {
286
- var id = 'adapter_';
287
- var i = 0;
288
- while ($(id + i)) i++;
289
- return id + i;
290
- },
291
-
292
- enable: function() {
293
- return this.tag.removeClassName('disabled');
294
- },
295
-
296
- disable: function() {
297
- return this.tag.addClassName('disabled');
298
- },
299
-
300
- is_disabled: function() {
301
- return this.tag.hasClassName('disabled');
302
- },
303
-
304
- scaffold_id: function() {
305
- return this.tag.up('div.active-scaffold').id;
306
- }
307
- }
308
-
309
- /**
310
- * Concrete classes for record actions
311
- */
312
- ActiveScaffold.Actions.Record = Class.create();
313
- ActiveScaffold.Actions.Record.prototype = Object.extend(new ActiveScaffold.Actions.Abstract(), {
314
- instantiate_link: function(link) {
315
- var l = new ActiveScaffold.ActionLink.Record(link, this.target, this.loading_indicator);
316
- l.refresh_url = this.options.refresh_url;
317
- if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
318
- l.set = this;
319
- return l;
320
- }
321
- });
322
-
323
- ActiveScaffold.ActionLink.Record = Class.create();
324
- ActiveScaffold.ActionLink.Record.prototype = Object.extend(new ActiveScaffold.ActionLink.Abstract(), {
325
- close_previous_adapter: function() {
326
- this.set.links.each(function(item) {
327
- if (item.url != this.url && item.is_disabled() && item.adapter) item.close();
328
- }.bind(this));
329
- },
330
-
331
- insert: function(content) {
332
- this.close_previous_adapter();
333
-
334
- if (this.position == 'replace') {
335
- this.position = 'after';
336
- this.hide_target = true;
337
- }
338
-
339
- if (this.position == 'after') {
340
- new Insertion.After(this.target, content);
341
- this.adapter = this.target.next();
342
- }
343
- else if (this.position == 'before') {
344
- new Insertion.Before(this.target, content);
345
- this.adapter = this.target.previous();
346
- }
347
- else {
348
- return false;
349
- }
350
-
351
- this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
352
- this.register_cancel_hooks();
353
-
354
- new Effect.Highlight(this.adapter.down('td'));
355
- },
356
-
357
- close_handler: function(event) {
358
- this.close_with_refresh();
359
- if (event) Event.stop(event);
360
- },
361
-
362
- /* it might simplify things to just override the close function. then the Record and Table links could share more code ... wouldn't need custom close_handler functions, for instance */
363
- close_with_refresh: function() {
364
- new Ajax.Request(this.refresh_url, {
365
- asynchronous: true,
366
- evalScripts: true,
367
- method: this.method,
368
- onSuccess: function(request) {
369
- Element.replace(this.target, request.responseText);
370
- var new_target = $(this.target.id);
371
- if (this.target.hasClassName('even-record')) new_target.addClassName('even-record');
372
- this.target = new_target;
373
- this.close();
374
- }.bind(this),
375
-
376
- onFailure: function(request) {
377
- ActiveScaffold.report_500_response(this.scaffold_id());
378
- }
379
- });
380
- },
381
-
382
- enable: function() {
383
- this.set.links.each(function(item) {
384
- if (item.url != this.url) return;
385
- item.tag.removeClassName('disabled');
386
- }.bind(this));
387
- },
388
-
389
- disable: function() {
390
- this.set.links.each(function(item) {
391
- if (item.url != this.url) return;
392
- item.tag.addClassName('disabled');
393
- }.bind(this));
394
- }
395
- });
396
-
397
- /**
398
- * Concrete classes for table actions
399
- */
400
- ActiveScaffold.Actions.Table = Class.create();
401
- ActiveScaffold.Actions.Table.prototype = Object.extend(new ActiveScaffold.Actions.Abstract(), {
402
- instantiate_link: function(link) {
403
- var l = new ActiveScaffold.ActionLink.Table(link, this.target, this.loading_indicator);
404
- if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
405
- return l;
406
- }
407
- });
408
-
409
- ActiveScaffold.ActionLink.Table = Class.create();
410
- ActiveScaffold.ActionLink.Table.prototype = Object.extend(new ActiveScaffold.ActionLink.Abstract(), {
411
- insert: function(content) {
412
- if (this.position == 'top') {
413
- new Insertion.Top(this.target, content);
414
- this.adapter = this.target.immediateDescendants().first();
415
- }
416
- else {
417
- throw 'Unknown position "' + this.position + '"'
418
- }
419
-
420
- this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
421
- this.register_cancel_hooks();
422
-
423
- new Effect.Highlight(this.adapter.down('td'));
424
- },
425
-
426
- close_handler: function(event) {
427
- this.close();
428
- if (event) Event.stop(event);
429
- }
430
- });
1
+ if (typeof Prototype == 'undefined')
2
+ {
3
+ warning = "ActiveScaffold Error: Prototype could not be found. Please make sure that your application's layout includes prototype.js (e.g. <%= javascript_include_tag :defaults %>) *before* it includes active_scaffold.js (e.g. <%= active_scaffold_includes %>).";
4
+ alert(warning);
5
+ }
6
+ if (Prototype.Version.substring(0, 3) < '1.6')
7
+ {
8
+ warning = "ActiveScaffold Error: Prototype version 1.6.x or higher is required. Please update prototype.js (rake rails:update:javascripts).";
9
+ alert(warning);
10
+ }
11
+ if (!Element.Methods.highlight) Element.addMethods({highlight: Prototype.emptyFunction});
12
+
13
+
14
+ /*
15
+ * Simple utility methods
16
+ */
17
+
18
+ var ActiveScaffold = {
19
+ records_for: function(tbody_id) {
20
+ var rows = [];
21
+ var child = $(tbody_id).down('.record');
22
+ while (child) {
23
+ rows.push(child);
24
+ child = child.next('.record');
25
+ }
26
+ return rows;
27
+ },
28
+ stripe: function(tbody_id) {
29
+ var even = false;
30
+ var rows = this.records_for(tbody_id);
31
+ for (var i = 0; i < rows.length; i++) {
32
+ var child = rows[i];
33
+ //Make sure to skip rows that are create or edit rows or messages
34
+ if (child.tagName != 'SCRIPT'
35
+ && !child.hasClassName("create")
36
+ && !child.hasClassName("update")
37
+ && !child.hasClassName("inline-adapter")
38
+ && !child.hasClassName("active-scaffold-calculations")) {
39
+
40
+ if (even) child.addClassName("even-record");
41
+ else child.removeClassName("even-record");
42
+
43
+ even = !even;
44
+ }
45
+ }
46
+ },
47
+ hide_empty_message: function(tbody, empty_message_id) {
48
+ if (this.records_for(tbody).length != 0) {
49
+ $(empty_message_id).hide();
50
+ }
51
+ },
52
+ reload_if_empty: function(tbody, url) {
53
+ if (this.records_for(tbody).length == 0) {
54
+ new Ajax.Request(url, {
55
+ method: 'get',
56
+ asynchronous: true,
57
+ evalScripts: true
58
+ });
59
+ }
60
+ },
61
+ removeSortClasses: function(scaffold_id) {
62
+ $$('#' + scaffold_id + ' td.sorted').each(function(element) {
63
+ element.removeClassName("sorted");
64
+ });
65
+ $$('#' + scaffold_id + ' th.sorted').each(function(element) {
66
+ element.removeClassName("sorted");
67
+ element.removeClassName("asc");
68
+ element.removeClassName("desc");
69
+ });
70
+ },
71
+ decrement_record_count: function(scaffold_id) {
72
+ // decrement the last record count, firsts record count are in nested lists
73
+ count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
74
+ if (count) count.update(parseInt(count.innerHTML, 10) - 1);
75
+ },
76
+ increment_record_count: function(scaffold_id) {
77
+ // increment the last record count, firsts record count are in nested lists
78
+ count = $$('#' + scaffold_id + ' span.active-scaffold-records').last();
79
+ if (count) count.update(parseInt(count.innerHTML, 10) + 1);
80
+ },
81
+ update_row: function(row, html) {
82
+ row = $(row);
83
+ Element.replace(row, html);
84
+ var new_row = $(row.id);
85
+ if (row.hasClassName('even-record')) new_row.addClassName('even-record');
86
+ new_row.highlight();
87
+ },
88
+
89
+ server_error_response: '',
90
+ report_500_response: function(active_scaffold_id) {
91
+ messages_container = $(active_scaffold_id).down('td.messages-container');
92
+ new Insertion.Top(messages_container, this.server_error_response);
93
+ }
94
+ }
95
+
96
+ /*
97
+ * DHTML history tie-in
98
+ */
99
+ function addActiveScaffoldPageToHistory(url, active_scaffold_id) {
100
+ if (typeof dhtmlHistory == 'undefined') return; // it may not be loaded
101
+
102
+ var array = url.split('?');
103
+ var qs = new Querystring(array[1]);
104
+ var sort = qs.get('sort')
105
+ var dir = qs.get('sort_direction')
106
+ var page = qs.get('page')
107
+ if (sort || dir || page) dhtmlHistory.add(active_scaffold_id+":"+page+":"+sort+":"+dir, url);
108
+ }
109
+
110
+ /*
111
+ * Add-ons/Patches to Prototype
112
+ */
113
+
114
+ /* patch to support replacing TR/TD/TBODY in Internet Explorer, courtesy of http://dev.rubyonrails.org/ticket/4273 */
115
+ Element.replace = function(element, html) {
116
+ element = $(element);
117
+ if (element.outerHTML) {
118
+ try {
119
+ element.outerHTML = html.stripScripts();
120
+ } catch (e) {
121
+ var tn = element.tagName;
122
+ if(tn=='TBODY' || tn=='TR' || tn=='TD')
123
+ {
124
+ var tempDiv = document.createElement("div");
125
+ tempDiv.innerHTML = '<table id="tempTable" style="display: none">' + html.stripScripts() + '</table>';
126
+ element.parentNode.replaceChild(tempDiv.getElementsByTagName(tn).item(0), element);
127
+ }
128
+ else throw e;
129
+ }
130
+ } else {
131
+ var range = element.ownerDocument.createRange();
132
+ /* patch to fix <form> replaces in Firefox. see http://dev.rubyonrails.org/ticket/8010 */
133
+ range.selectNodeContents(element.parentNode);
134
+ element.parentNode.replaceChild(range.createContextualFragment(html.stripScripts()), element);
135
+ }
136
+ setTimeout(function() {html.evalScripts()}, 10);
137
+ return element;
138
+ };
139
+
140
+ /*
141
+ * URL modification support. Incomplete functionality.
142
+ */
143
+ Object.extend(String.prototype, {
144
+ append_params: function(params) {
145
+ url = this;
146
+ if (url.indexOf('?') == -1) url += '?';
147
+ else if (url.lastIndexOf('&') != url.length) url += '&';
148
+
149
+ url += $H(params).collect(function(item) {
150
+ return item.key + '=' + item.value;
151
+ }).join('&');
152
+
153
+ return url;
154
+ }
155
+ });
156
+
157
+ /*
158
+ * Prototype's implementation was throwing an error instead of false
159
+ */
160
+ Element.Methods.Simulated = {
161
+ hasAttribute: function(element, attribute) {
162
+ var t = Element._attributeTranslations;
163
+ attribute = (t.names && t.names[attribute]) || attribute;
164
+ // Return false if we get an error here
165
+ try {
166
+ return $(element).getAttributeNode(attribute).specified;
167
+ } catch (e) {
168
+ return false;
169
+ }
170
+ }
171
+ };
172
+
173
+ /**
174
+ * A set of links. As a set, they can be controlled such that only one is "open" at a time, etc.
175
+ */
176
+ ActiveScaffold.Actions = new Object();
177
+ ActiveScaffold.Actions.Abstract = Class.create({
178
+ initialize: function(links, target, loading_indicator, options) {
179
+ this.target = $(target);
180
+ this.loading_indicator = $(loading_indicator);
181
+ this.options = options;
182
+ this.links = links.collect(function(link) {
183
+ return this.instantiate_link(link);
184
+ }.bind(this));
185
+ },
186
+
187
+ instantiate_link: function(link) {
188
+ throw 'unimplemented'
189
+ }
190
+ });
191
+
192
+ /**
193
+ * A DataStructures::ActionLink, represented in JavaScript.
194
+ * Concerned with AJAX-enabling a link and adapting the result for insertion into the table.
195
+ */
196
+ ActiveScaffold.ActionLink = new Object();
197
+ ActiveScaffold.ActionLink.Abstract = Class.create({
198
+ initialize: function(a, target, loading_indicator) {
199
+ this.tag = $(a);
200
+ this.url = this.tag.href;
201
+ this.method = 'get';
202
+ if(this.url.match('_method=delete')){
203
+ this.method = 'delete';
204
+ } else if(this.url.match('_method=post')){
205
+ this.method = 'post';
206
+ } else if(this.url.match('_method=put')){
207
+ this.method = 'put';
208
+ }
209
+ this.target = target;
210
+ this.loading_indicator = loading_indicator;
211
+ this.hide_target = false;
212
+ this.position = this.tag.getAttribute('position');
213
+ this.page_link = this.tag.getAttribute('page_link');
214
+
215
+ this.onclick = this.tag.onclick;
216
+ this.tag.onclick = null;
217
+ this.tag.observe('click', function(event) {
218
+ this.open();
219
+ Event.stop(event);
220
+ }.bind(this));
221
+
222
+ this.tag.action_link = this;
223
+ },
224
+
225
+ open: function() {
226
+ if (this.is_disabled()) return;
227
+
228
+ if (this.tag.hasAttribute( "dhtml_confirm")) {
229
+ if (this.onclick) this.onclick();
230
+ return;
231
+ } else {
232
+ if (this.onclick && !this.onclick()) return;//e.g. confirmation messages
233
+ this.open_action();
234
+ }
235
+ },
236
+
237
+ open_action: function() {
238
+ if (this.position) this.disable();
239
+
240
+ if (this.page_link) {
241
+ window.location = this.url;
242
+ } else {
243
+ if (this.loading_indicator) this.loading_indicator.style.visibility = 'visible';
244
+ new Ajax.Request(this.url, {
245
+ asynchronous: true,
246
+ evalScripts: true,
247
+ method: this.method,
248
+ onSuccess: function(request) {
249
+ if (this.position) {
250
+ this.insert(request.responseText);
251
+ if (this.hide_target) this.target.hide();
252
+ } else {
253
+ request.evalResponse();
254
+ }
255
+ }.bind(this),
256
+
257
+ onFailure: function(request) {
258
+ ActiveScaffold.report_500_response(this.scaffold_id());
259
+ if (this.position) this.enable()
260
+ }.bind(this),
261
+
262
+ onComplete: function(request) {
263
+ if (this.loading_indicator) this.loading_indicator.style.visibility = 'hidden';
264
+ }.bind(this)
265
+ });
266
+ }
267
+ },
268
+
269
+ insert: function(content) {
270
+ throw 'unimplemented'
271
+ },
272
+
273
+ close: function() {
274
+ this.enable();
275
+ this.adapter.remove();
276
+ if (this.hide_target) this.target.show();
277
+ },
278
+
279
+ close_handler: function(event) {
280
+ this.close();
281
+ if (event) Event.stop(event);
282
+ },
283
+
284
+ register_cancel_hooks: function() {
285
+ // anything in the insert with a class of cancel gets the closer method, and a reference to this object for good measure
286
+ var self = this;
287
+ this.adapter.select('.cancel').each(function(elem) {
288
+ elem.observe('click', this.close_handler.bind(this));
289
+ elem.link = self;
290
+ }.bind(this))
291
+ },
292
+
293
+ reload: function() {
294
+ this.close();
295
+ this.open();
296
+ },
297
+
298
+ get_new_adapter_id: function() {
299
+ var id = 'adapter_';
300
+ var i = 0;
301
+ while ($(id + i)) i++;
302
+ return id + i;
303
+ },
304
+
305
+ enable: function() {
306
+ return this.tag.removeClassName('disabled');
307
+ },
308
+
309
+ disable: function() {
310
+ return this.tag.addClassName('disabled');
311
+ },
312
+
313
+ is_disabled: function() {
314
+ return this.tag.hasClassName('disabled');
315
+ },
316
+
317
+ scaffold_id: function() {
318
+ return this.tag.up('div.active-scaffold').id;
319
+ }
320
+ });
321
+
322
+ /**
323
+ * Concrete classes for record actions
324
+ */
325
+ ActiveScaffold.Actions.Record = Class.create(ActiveScaffold.Actions.Abstract, {
326
+ instantiate_link: function(link) {
327
+ var l = new ActiveScaffold.ActionLink.Record(link, this.target, this.loading_indicator);
328
+ l.refresh_url = this.options.refresh_url;
329
+ if (link.hasClassName('delete')) {
330
+ l.url = l.url.replace(/\/delete(\?.*)?$/, '$1');
331
+ l.url = l.url.replace(/\/delete\/(.*)/, '/destroy/$1');
332
+ }
333
+ if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
334
+ l.set = this;
335
+ return l;
336
+ }
337
+ });
338
+
339
+ ActiveScaffold.ActionLink.Record = Class.create(ActiveScaffold.ActionLink.Abstract, {
340
+ close_previous_adapter: function() {
341
+ this.set.links.each(function(item) {
342
+ if (item.url != this.url && item.is_disabled() && item.adapter) {
343
+ item.enable();
344
+ item.adapter.remove();
345
+ }
346
+ }.bind(this));
347
+ },
348
+
349
+ insert: function(content) {
350
+ this.close_previous_adapter();
351
+
352
+ if (this.position == 'replace') {
353
+ this.position = 'after';
354
+ this.hide_target = true;
355
+ }
356
+
357
+ if (this.position == 'after') {
358
+ new Insertion.After(this.target, content);
359
+ this.adapter = this.target.next();
360
+ }
361
+ else if (this.position == 'before') {
362
+ new Insertion.Before(this.target, content);
363
+ this.adapter = this.target.previous();
364
+ }
365
+ else {
366
+ return false;
367
+ }
368
+
369
+ this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
370
+ this.register_cancel_hooks();
371
+
372
+ this.adapter.down('td').down().highlight();
373
+ },
374
+
375
+ close: function($super, updatedRow) {
376
+ if (updatedRow) {
377
+ ActiveScaffold.update_row(this.target, updatedRow);
378
+ $super();
379
+ } else {
380
+ new Ajax.Request(this.refresh_url, {
381
+ asynchronous: true,
382
+ evalScripts: true,
383
+ method: this.method,
384
+ onSuccess: function(request) {
385
+ ActiveScaffold.update_row(this.target, request.responseText);
386
+ $super();
387
+ }.bind(this),
388
+
389
+ onFailure: function(request) {
390
+ ActiveScaffold.report_500_response(this.scaffold_id());
391
+ }
392
+ });
393
+ }
394
+ },
395
+
396
+ enable: function() {
397
+ this.set.links.each(function(item) {
398
+ if (item.url != this.url) return;
399
+ item.tag.removeClassName('disabled');
400
+ }.bind(this));
401
+ },
402
+
403
+ disable: function() {
404
+ this.set.links.each(function(item) {
405
+ if (item.url != this.url) return;
406
+ item.tag.addClassName('disabled');
407
+ }.bind(this));
408
+ }
409
+ });
410
+
411
+ /**
412
+ * Concrete classes for table actions
413
+ */
414
+ ActiveScaffold.Actions.Table = Class.create(ActiveScaffold.Actions.Abstract, {
415
+ instantiate_link: function(link) {
416
+ var l = new ActiveScaffold.ActionLink.Table(link, this.target, this.loading_indicator);
417
+ if (l.position) l.url = l.url.append_params({adapter: '_list_inline_adapter'});
418
+ return l;
419
+ }
420
+ });
421
+
422
+ ActiveScaffold.ActionLink.Table = Class.create(ActiveScaffold.ActionLink.Abstract, {
423
+ insert: function(content) {
424
+ if (this.position == 'top') {
425
+ new Insertion.Top(this.target, content);
426
+ this.adapter = this.target.immediateDescendants().first();
427
+ }
428
+ else {
429
+ throw 'Unknown position "' + this.position + '"'
430
+ }
431
+
432
+ this.adapter.down('a.inline-adapter-close').observe('click', this.close_handler.bind(this));
433
+ this.register_cancel_hooks();
434
+
435
+ this.adapter.down('td').down().highlight();
436
+ }
437
+ });
438
+
439
+ if (Ajax.InPlaceEditor) {
440
+ ActiveScaffold.InPlaceEditor = Class.create(Ajax.InPlaceEditor, {
441
+ setFieldFromAjax: function(url, options) {
442
+ var ipe = this;
443
+ $(ipe._controls.editor).remove();
444
+ new Ajax.Request(url, {
445
+ method: 'get',
446
+ onComplete: function(response) {
447
+ ipe._form.insert({top: response.responseText});
448
+ if (options.plural) {
449
+ ipe._form.getElements().each(function(el) {
450
+ if (el.type != "submit" && el.type != "image") {
451
+ el.name = ipe.options.paramName + '[]';
452
+ el.className = 'editor_field';
453
+ }
454
+ });
455
+ } else {
456
+ var fld = ipe._form.findFirstElement();
457
+ fld.name = ipe.options.paramName;
458
+ fld.className = 'editor_field';
459
+ if (ipe.options.submitOnBlur)
460
+ fld.onblur = ipe._boundSubmitHandler;
461
+ ipe._controls.editor = fld;
462
+ }
463
+ }
464
+ });
465
+ },
466
+
467
+ clonePatternField: function() {
468
+ var patternNodes = this.getPatternNodes(this.options.inplacePatternSelector);
469
+ if (patternNodes.editNode == null) {
470
+ alert('did not find any matching node for ' + this.options.editFieldSelector);
471
+ return;
472
+ }
473
+
474
+ var fld = patternNodes.editNode.cloneNode(true);
475
+ if (fld.id.length > 0) fld.id += this.options.nodeIdSuffix;
476
+ fld.name = this.options.paramName;
477
+ fld.className = 'editor_field';
478
+ this.setValue(fld, this._controls.editor.value);
479
+ if (this.options.submitOnBlur)
480
+ fld.onblur = this._boundSubmitHandler;
481
+ $(this._controls.editor).remove();
482
+ this._controls.editor = fld;
483
+ this._form.appendChild(this._controls.editor);
484
+
485
+ $A(patternNodes.additionalNodes).each(function(node) {
486
+ var patternNode = node.cloneNode(true);
487
+ if (patternNode.id.length > 0) {
488
+ patternNode.id = patternNode.id + this.options.nodeIdSuffix;
489
+ }
490
+ this._form.appendChild(patternNode);
491
+ }.bind(this));
492
+ },
493
+
494
+ getPatternNodes: function(inplacePatternSelector) {
495
+ var nodes = {editNode: null, additionalNodes: []};
496
+ var selectedNodes = $$(inplacePatternSelector);
497
+ var firstNode = selectedNodes.first();
498
+
499
+ if (typeof(firstNode) !== 'undefined') {
500
+ // AS inplace_edit_control_container -> we have to select all child nodes
501
+ // Workaround for ie which does not support css > selector
502
+ if (firstNode.className.indexOf('as_inplace_pattern') !== -1) {
503
+ selectedNodes = firstNode.childElements();
504
+ }
505
+ nodes.editNode = selectedNodes.first();
506
+ selectedNodes.shift();
507
+ nodes.additionalNodes = selectedNodes;
508
+ }
509
+ return nodes;
510
+ },
511
+
512
+ setValue: function(editField, textValue) {
513
+ var function_name = 'setValueFor' + editField.nodeName.toLowerCase();
514
+ if (typeof(this[function_name]) == 'function') {
515
+ this[function_name](editField, textValue);
516
+ } else {
517
+ editField.value = textValue;
518
+ }
519
+ },
520
+
521
+ setValueForselect: function(editField, textValue) {
522
+ var len = editField.options.length;
523
+ var i = 0;
524
+ while (i < len && editField.options[i].text != textValue) {
525
+ i++;
526
+ }
527
+ if (i < len) {
528
+ editField.value = editField.options[i].value
529
+ }
530
+ }
531
+ });
532
+ }