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
@@ -21,9 +21,11 @@ class Client < ActiveRecord::Base
21
21
  end
22
22
 
23
23
  def uninvoiced_activities_balance( force_reload = false )
24
- (attribute_present? :uninvoiced_activities_balance_in_cents and !force_reload) ?
25
- Money.new(read_attribute(:uninvoiced_activities_balance_in_cents).to_i) :
26
- (Activity.sum( Invoice::ACTIVITY_TOTAL_SQL, :conditions => ['client_id = ? AND is_published = ? AND invoice_id IS NULL',id, true] ) or 0)
24
+ Money.new(
25
+ (attribute_present? :uninvoiced_activities_balance_in_cents and !force_reload) ?
26
+ read_attribute(:uninvoiced_activities_balance_in_cents).to_i :
27
+ Activity.sum( Invoice::ACTIVITY_TOTAL_SQL, :conditions => ['client_id = ? AND is_published = ? AND invoice_id IS NULL',id, true] ).to_i
28
+ )
27
29
  end
28
30
 
29
31
  # THis is the client's outstanding balance. This value is calculated based off the total invoices amount - total payments amount. And is
@@ -62,12 +64,17 @@ class Client < ActiveRecord::Base
62
64
  end
63
65
 
64
66
  def ensure_not_referenced_on_destroy
65
- errors.add_to_base "Can't destroy a referenced employee" and return false unless authorized_for? {:destroy}
67
+ unless authorized_for?(:action => :delete)
68
+ errors.add_to_base "Can't destroy a referenced employee"
69
+ return false
70
+ end
66
71
  end
67
72
 
68
73
  def authorized_for?(options)
69
- case options[:action]
70
- when :destroy
74
+ return true unless options.try(:[],:action)
75
+
76
+ case options[:action].to_sym
77
+ when :delete
71
78
  [Invoice, Payment, Activity].each{ |k| return false if k.count(:all, :conditions => ['client_id = ?', id] ) > 0 }
72
79
 
73
80
  true
@@ -123,7 +130,7 @@ class Client < ActiveRecord::Base
123
130
  # Returns an array of unsaved InvoicePayment objects, with unset invoice_ids, and 'recommended' amounts.
124
131
  # If the provided amount exactly equals an payment's unalloated amount, we return a InvoicePayment for the oldest such matching payment.
125
132
  # Otherwise, we start applying the amount to payments in ascending order by issued_date.
126
- def recommend_payment_assignments_for(amount, verbose_inclusion = false)
133
+ def recommend_payment_assignments_for(amount)
127
134
  amount = amount.to_money
128
135
 
129
136
  pymnts = unassigned_payments(
@@ -180,4 +187,24 @@ class Client < ActiveRecord::Base
180
187
  )
181
188
  end
182
189
 
183
- end
190
+ # This is mostly used by the batch create feature. Here, we return an array of clients, which have approved,
191
+ # unassigned activity which occurred before the specified_date
192
+ def self.find_invoiceable_clients_at(occurred_at)
193
+ find(
194
+ :all,
195
+ :select => 'DISTINCT `clients`.*',
196
+ :joins => 'LEFT JOIN `activities` ON `clients`.id = `activities`.client_id',
197
+ :conditions => [
198
+ [
199
+ '`activities`.occurred_on <= ?',
200
+ '`activities`.is_published = ?',
201
+ '`activities`.invoice_id IS NULL'
202
+ ].join(" AND "),
203
+ occurred_at,
204
+ true
205
+ ],
206
+ :order => ["`clients`.company_name ASC","`clients`.id ASC"].join(",")
207
+ )
208
+ end
209
+
210
+ end
@@ -10,21 +10,13 @@ class ClientRepresentative < ActiveRecord::Base
10
10
  )
11
11
 
12
12
  def name
13
- ret = String.new
14
-
15
- ret += self.first_name if !self.first_name.nil? and self.first_name.length > 0
16
-
17
- ret += (ret.length > 0) ? " #{self.last_name}" : self.last_name if !self.last_name.nil? and self.last_name.length > 0
18
-
19
- ret
13
+ [
14
+ first_name, last_name
15
+ ].find_all{|x| x.try(:length).try(:>,0)}.join(' ')
20
16
  end
21
17
 
22
- # This fixes (I guess its a bug?) in _add_existing_form.html when ClientReps are being shown
23
- # as a sublist in Clients, and the user chooses to "Add Existing". Without this - the order
24
- # Is totally effed.
25
- def self.find(*args)
26
- (args == [:all]) ? super(:all, :order => 'first_name ASC, last_name ASC') : super(*args)
18
+ # This is used by the Nested Add_existing control label
19
+ def self.human_name
20
+ 'Representative'
27
21
  end
28
-
29
-
30
22
  end
@@ -23,7 +23,7 @@ class Credential < ActiveRecord::Base
23
23
  begin
24
24
  @salt = Rails.configuration.authentication_salt
25
25
  rescue
26
- @salt = "Salt is missing - No Salt is a bad idea!"
26
+ @salt = t(:salt_is_missing)
27
27
  logger.error @salt # cheeky?
28
28
  end unless @salt
29
29
 
@@ -15,13 +15,9 @@ class Employee < ActiveRecord::Base
15
15
  validates_numericality_of :phone_extension, :allow_nil => true
16
16
 
17
17
  def name
18
- ret = String.new
19
-
20
- ret += first_name if !first_name.nil? and first_name.length > 0
21
-
22
- ret += (ret.length > 0) ? " #{last_name}" : last_name if !last_name.nil? and last_name.length > 0
23
-
24
- ret
18
+ [
19
+ first_name, last_name
20
+ ].find_all{|x| x.try(:length).try(:>,0)}.join(' ')
25
21
  end
26
22
 
27
23
  def short_name
@@ -33,16 +29,18 @@ class Employee < ActiveRecord::Base
33
29
  end
34
30
 
35
31
  def ensure_not_referenced_on_destroy
36
- ( errors.add_to_base "Can't destroy a referenced employee" and return false ) unless authorized_for? :action => :destroy
32
+ ( errors.add_to_base "Can't destroy a referenced employee" and return false ) unless authorized_for? :action => :delete
37
33
  end
38
34
 
39
35
  def authorized_for?(options)
40
- case options[:action]
41
- when :destroy
36
+ return true unless options.try(:[],:action)
37
+
38
+ case options[:action].to_sym
39
+ when :delete
42
40
  ( Activity::Labor.count( :all, :conditions => ['employee_id = ?', id] ) > 0 ) ? false : true
43
41
  else
44
42
  true
45
- end
43
+ end
46
44
  end
47
45
 
48
46
  # There were some issues in rails 2.3.2 that caused associations (slimtimer/credential/etc) to not save without this hack
@@ -11,7 +11,7 @@ class Invoice < ActiveRecord::Base
11
11
 
12
12
  belongs_to :client
13
13
  has_many :activities, :dependent => :nullify
14
- has_many :payments, :through => :assigned_payments
14
+ has_many :payments, :through => :payment_assignments
15
15
  has_many :payment_assignments, :class_name => 'InvoicePayment', :dependent => :delete_all
16
16
 
17
17
  has_and_belongs_to_many(
@@ -31,7 +31,7 @@ class Invoice < ActiveRecord::Base
31
31
 
32
32
  def initialize(*args)
33
33
  super(*args)
34
- end_of_last_month = Time.utc(*Time.now.to_a).last_month.end_of_month
34
+ end_of_last_month = Time.utc(*Time.now.to_a).prev_month.end_of_month
35
35
  self.issued_on = end_of_last_month unless self.issued_on
36
36
  end
37
37
 
@@ -78,8 +78,12 @@ class Invoice < ActiveRecord::Base
78
78
  end
79
79
 
80
80
  def authorized_for?(options)
81
- case options[:action].to_s
82
- when /^(destroy)$/
81
+ return true unless options.try(:[],:action)
82
+
83
+ case options[:action].to_sym
84
+ when :delete
85
+ !is_published
86
+ when :edit
83
87
  !is_published
84
88
  else
85
89
  true
@@ -107,7 +111,7 @@ class Invoice < ActiveRecord::Base
107
111
  alias :grand_total :amount
108
112
 
109
113
  def name
110
- '"%s" Invoice on %s' % [ (client) ? client.company_name : '(Unknown Client)', issued_on.strftime("%m/%d/%Y %I:%M %p") ]
114
+ '%s Invoice on %s' % [ (client) ? client.company_name : '(Unknown Client)', issued_on.strftime("%m/%d/%Y %I:%M %p") ]
111
115
  end
112
116
 
113
117
  def long_name
@@ -120,7 +124,7 @@ class Invoice < ActiveRecord::Base
120
124
  end
121
125
 
122
126
  def paid_on
123
- raise StandardError unless is_paid?
127
+ raise StandardError unless is_paid?(true)
124
128
 
125
129
  InvoicePayment.find(
126
130
  :first,
@@ -136,21 +140,21 @@ class Invoice < ActiveRecord::Base
136
140
  def is_paid?( force_reload = false )
137
141
  (attribute_present? :is_paid and !force_reload) ?
138
142
  (read_attribute(:is_paid).to_i == 1) :
139
- amount_outstanding(true) <= 0
143
+ amount_outstanding(force_reload) <= 0
140
144
  end
141
145
 
142
146
  def amount_paid( force_reload = false )
143
147
  Money.new(
144
148
  (attribute_present? :amount_paid_in_cents and !force_reload) ?
145
149
  read_attribute(:amount_paid_in_cents).to_i :
146
- InvoicePayment.sum( :amount_in_cents, :conditions => ['invoice_id = ?', id] ).to_i
150
+ (payment_assignments(force_reload).collect(&:amount_in_cents).sum || 0)
147
151
  )
148
152
  end
149
153
 
150
154
  def amount_outstanding( force_reload = false )
151
155
  (attribute_present? :amount_outstanding_in_cents and !force_reload) ?
152
156
  Money.new(read_attribute(:amount_outstanding_in_cents).to_i) :
153
- (amount(true) - amount_paid(true))
157
+ (amount(force_reload) - amount_paid(force_reload))
154
158
  end
155
159
 
156
160
  # This is a shortcut to the self.recommended_activities_for , and is provided as a shortcut when its necessary to update an existing invoice's
@@ -16,7 +16,7 @@ class InvoicePayment < ActiveRecord::Base
16
16
  end
17
17
 
18
18
  def label
19
- '%s @ (Invoice %d, Payment %d)' % [amount.format, invoice.id,payment.id, ]
19
+ '%s @ (Invoice %d, Payment %d)' % [amount.format, invoice.id,payment.id ]
20
20
  end
21
21
 
22
22
  # This is just to make the code a little easier to type/read. Its a create!, just without all the option verbosity.
@@ -76,8 +76,8 @@ class Notifier < ActionMailer::Base
76
76
  def generate_view_parts(view_name, tmpl)
77
77
  part( :content_type => "multipart/alternative" ) do |p|
78
78
  [
79
- { :content_type => "text/plain", :body => render_message("#{view_name.to_s}.plain.rhtml", tmpl) },
80
- { :content_type => "text/html", :body => render_message("#{view_name.to_s}.html.rhtml", tmpl.merge({:part_container => p})) }
79
+ { :content_type => "text/plain", :body => render_message("#{view_name.to_s}.plain.erb", tmpl) },
80
+ { :content_type => "text/html", :body => render_message("#{view_name.to_s}.html.erb", tmpl.merge({:part_container => p})) }
81
81
  ].each { |parms| p.part parms.merge( { :charset => "UTF-8", :transfer_encoding => "7bit"} ) }
82
82
  end
83
83
  end
@@ -5,13 +5,21 @@ class Payment < ActiveRecord::Base
5
5
  belongs_to :client
6
6
  belongs_to :payment_method
7
7
 
8
- has_many :invoices, :through => :assigned_payments
9
- has_many :invoice_assignments, :class_name => 'InvoicePayment', :dependent => :delete_all
8
+ has_many :invoices, :through => :invoice_assignments
9
+
10
+ # We have to make sure this doesnt validate since :amount_not_greater_than_payment_or_invoice_totals ,
11
+ # will trip things up if we're in the processing of manipulating invoice_assignments on payment that
12
+ # already has some assignments
13
+ has_many :invoice_assignments, :class_name => 'InvoicePayment', :dependent => :delete_all, :validate =>false, :autosave => true
10
14
 
11
15
  validates_presence_of :client_id, :payment_method_id
12
16
  validates_numericality_of :amount, :allow_nil => false
13
17
  validates_numericality_of :amount, :greater_than_or_equal_to => 0
14
18
  validate :validate_invoice_payments_not_greater_than_amount
19
+
20
+ validate :validate_invoice_payments_not_greater_than_invoice_amount
21
+ validate :validate_invoice_payments_only_assigned_to_published_invoices
22
+ validate :validate_invoice_payments_not_negative
15
23
 
16
24
  money :amount, :currency => false
17
25
 
@@ -23,21 +31,21 @@ class Payment < ActiveRecord::Base
23
31
  def amount_unallocated( force_reload = false )
24
32
  (attribute_present? :amount_unallocated_in_cents and !force_reload) ?
25
33
  Money.new(read_attribute(:amount_unallocated_in_cents).to_i) :
26
- (amount - amount_allocated)
34
+ (amount(force_reload) - amount_allocated(force_reload))
27
35
  end
28
36
 
29
37
  def amount_allocated( force_reload = false )
30
38
  Money.new(
31
39
  (attribute_present? :amount_allocated_in_cents and !force_reload) ?
32
40
  read_attribute(:amount_allocated_in_cents).to_i :
33
- ( InvoicePayment.sum(:amount_in_cents, :conditions => ['payment_id = ?', id]) || 0 )
41
+ ( invoice_assignments(force_reload).collect(&:amount_in_cents).sum || 0 )
34
42
  )
35
43
  end
36
44
 
37
45
  def is_allocated?( force_reload = false )
38
46
  (attribute_present? :is_allocated and !force_reload) ?
39
47
  (read_attribute(:is_allocated).to_i == 1) :
40
- amount_unallocated(true).zero?
48
+ amount_unallocated(force_reload).zero?
41
49
  end
42
50
 
43
51
  def validate_invoice_payments_not_greater_than_amount
@@ -50,12 +58,48 @@ class Payment < ActiveRecord::Base
50
58
  )
51
59
  end
52
60
 
61
+ def validate_invoice_payments_not_greater_than_invoice_amount
62
+ invoice_assignments.each do |asgn|
63
+ errors.add(
64
+ :invoice_assignments,
65
+ "has an invalid assignment whose amount (%s) is greater than invoice #%d's amount (%s)" % [
66
+ asgn.amount.to_s,
67
+ asgn.invoice.id,
68
+ asgn.invoice.amount.to_s
69
+ ]
70
+ ) if asgn.amount > asgn.invoice.amount
71
+ end
72
+ end
73
+
74
+ def validate_invoice_payments_only_assigned_to_published_invoices
75
+ invoice_assignments.each do |asgn|
76
+ errors.add(
77
+ :invoice_assignments,
78
+ "has an invalid assignment which is applied to an unpublished invoice #%d" % [
79
+ asgn.invoice.id
80
+ ]
81
+ ) unless asgn.invoice.is_published
82
+ end
83
+ end
84
+
85
+ def validate_invoice_payments_not_negative
86
+ invoice_assignments.each do |asgn|
87
+ errors.add(
88
+ :invoice_assignments,
89
+ "has an invalid assignment with a negative value applied to invoice #%d" % [
90
+ asgn.invoice.id
91
+ ]
92
+ ) if asgn.amount < 0
93
+ end
94
+ end
95
+
96
+ # We don't want any actual fields changing on update. But, we do want the assignments to be changeable...
53
97
  def validate_on_update
54
- errors.add_to_base "Payments can't be updated after creation"
98
+ errors.add_to_base "Payments can't be updated after creation" if changed.length > 0
55
99
  end
56
100
 
57
101
  def name
58
- '%.2f Payment from %s' % [ amount, client.company_name ]
102
+ '%s Payment from %s' % [ amount.format, client.company_name ]
59
103
  end
60
104
 
61
105
  def self.find_with_totals( how_many = :all, options = {} )
@@ -33,7 +33,9 @@ class Setting < ActiveRecord::Base
33
33
  end
34
34
 
35
35
  def authorized_for?(options)
36
- (options[:action] == :destroy) ? false : true
36
+ return true unless options.try(:[],:action)
37
+
38
+ (options[:action].to_sym != :delete)
37
39
  end
38
40
 
39
41
  end
@@ -0,0 +1,25 @@
1
+ # NOTE: We overide this templayte b/c it seems as if there's a bug in active scaffold
2
+ # that causes nested forms to always stay open after submit. We didn't want that, so
3
+ # this version is only slightly different than the dist
4
+ page.insert_html :top, active_scaffold_tbody_id, :partial => 'list_record', :locals => {:record => @record}
5
+ page.replace active_scaffold_calculations_id, :partial => 'list_calculations' if active_scaffold_config.list.columns.any? {|c| c.calculation?}
6
+ page << "ActiveScaffold.stripe($('#{active_scaffold_tbody_id}'))"
7
+ page << "ActiveScaffold.hide_empty_message('#{active_scaffold_tbody_id}','#{empty_message_id}');"
8
+ page << "ActiveScaffold.increment_record_count('#{active_scaffold_id}');"
9
+ logger.error "HMM : #{element_form_id(:action => :new_existing)}"
10
+ # Modified
11
+ form_stays_open = nil
12
+ if (form_stays_open)
13
+ # /Modified
14
+ # why not just re-render the form? that wouldn't utilize a possible do_new override which sets default values.
15
+ page << "$('#{element_form_id}').reset()"
16
+ page.replace_html element_messages_id(:action => :add_existing), :partial => 'form_messages'
17
+ # have to delay the focus, because there's no "firstElement" in prototype until at least one element is not disabled
18
+ page.delay 0.1 do
19
+ page << "Form.focusFirstElement('#{element_form_id}');"
20
+ end
21
+ else
22
+ # Modified
23
+ page << "$$('##{element_form_id(:action => :add_existing)} a.cancel').first().link.close();"
24
+ # /Modified
25
+ end
@@ -0,0 +1,10 @@
1
+ <ul class="activity_show activity_adjustment_show">
2
+ <li class="type">Adjustment</li>
3
+ <li class="client"><%=h (record.client.nil?) ? '(Unknown)' : record.client.company_name %></li>
4
+ <% if record.adjustment -%>
5
+ <li class="label"><%=h record.adjustment.label %></li>
6
+ <% if record.adjustment.comments and record.adjustment.comments.length > 0 -%>
7
+ <li class="comments"><%=h record.adjustment.comments %></li>
8
+ <% end -%>
9
+ <% end -%>
10
+ </ul>
@@ -28,14 +28,14 @@
28
28
  <%= select_tag(
29
29
  'move_to_invoice_id',
30
30
  options_for_select(
31
- @dest_invoices.collect{|inv| [inv.long_name, inv.id]},
31
+ [['(None)', nil]]+@dest_invoices.collect{|inv| [inv.long_name, inv.id]},
32
32
  params[:move_to_invoice_id].to_i
33
33
  )
34
34
  ) %>
35
35
  <% else -%>
36
36
  <p class="warning-message">We're sorry, but no un-published invoices were available in the database for this move.</p>
37
37
  <% end -%>
38
- <p>This activity's client and invoice association will be matched with the selected destination.</p>
38
+ <p>This activity's client and invoice association will be matched with the selected destination. If "(None)" is selected, this actvity will be removed from its current invoice, and placed back in the unassigned activity queue.</p>
39
39
  <p>
40
40
  <%= submit_tag 'Move...', :class => "MB_focusable" %>
41
41
  or
@@ -0,0 +1,5 @@
1
+ if @errors_during_move.length > 0
2
+ page.alert @errors_during_move.to_s
3
+ else
4
+ page.replace_html active_scaffold_content_id, :partial => 'list'
5
+ end
@@ -0,0 +1,73 @@
1
+ <div class="active-scaffold">
2
+ <div class="batch_create-view <%= "#{params[:controller]}-view" %> view">
3
+ <%= form_remote_tag(
4
+ :url => url_for(:action => :batch_create),
5
+ :after => [
6
+ "$('#{loading_indicator_id(:action => :batch_create)}').style.visibility = 'visible'",
7
+ "Form.disable('#{element_form_id(:action => :batch_create)}')"
8
+ ].join(';'),
9
+ :complete => [
10
+ "$('#{loading_indicator_id(:action => :batch_create)}').style.visibility = 'hidden'",
11
+ "Form.enable('#{element_form_id(:action => :batch_create)}')"
12
+ ].join(';'),
13
+ :failure => "ActiveScaffold.report_500_response('#{active_scaffold_id}')",
14
+ :html => {
15
+ :href => url_for(:action => :batch_create),
16
+ :onsubmit => onsubmit,
17
+ :id => element_form_id(:action => :batch_create),
18
+ :class => 'create'
19
+ }
20
+ ) %>
21
+ <h4>Batch Create</h4>
22
+ <div id="<%= element_messages_id(:action => :create) %>" class="messages-container"></div>
23
+
24
+ <ol class="form">
25
+ <li>
26
+ <p>Batch Create will automatically create unpublished invoices for the below specified clients. Invoices
27
+ will be populated with all the approved, unassigned activity in their queue, which occured on or before the specified date.</p>
28
+ </li>
29
+ <li class="form-element required">
30
+ <dl>
31
+ <dt><label>Invoice Date</label></dt>
32
+ <dd>
33
+ <% invoice_date_at_fields = [:year, :month, :day, :hour, :minute, :second] %>
34
+ <%=select_datetime(
35
+ @invoice_date_at,
36
+ :prefix => 'batch_invoice_date_at',
37
+ :datetime_separator => ' — ',
38
+ :time_separator => ' : ',
39
+ :include_seconds => true
40
+ ) %>
41
+ <%= invoice_date_at_fields.collect{|field_id|
42
+ observe_field(
43
+ 'batch_invoice_date_at_%s' % field_id,
44
+ :url => url_for(:action => :batch_create_on_date_change),
45
+ :with => invoice_date_at_fields.collect{|f|
46
+ "'batch_invoice_date_at[%s]='+$F('batch_invoice_date_at_%s')" % ([f]*2)
47
+ }.compact.join("+'&'+"),
48
+ :update => 'batch_invoice_clients_list'
49
+ )
50
+ }.join %>
51
+ </dd>
52
+ </dl>
53
+ </li>
54
+ <li class="form-element required">
55
+ <dl>
56
+ <dt><label>Clients</label></dt>
57
+ <dd><%= batch_create_clients_form_column @invoice_date_at %></dd>
58
+ </dl>
59
+ </li>
60
+ </ol>
61
+
62
+ <p class="form-footer">
63
+ <%= submit_tag "Batch Create", :class => "submit" %>
64
+ <%= link_to as_(:cancel), main_path_to_return, :class => 'cancel' %>
65
+ <%= loading_indicator_tag(:action => :batch_create) %>
66
+ </p>
67
+
68
+ </form>
69
+ <script type="text/javascript">
70
+ Form.focusFirstElement('<%= element_form_id(:action => :batch_create) -%>');
71
+ </script>
72
+ </div>
73
+ </div>