Compare commits

..

492 Commits

Author SHA1 Message Date
ricky d6aebfcb99 Moved strings to Ruby I18n en.yml 2022-02-19 20:46:39 -05:00
ricky 2085eb7869 Add gem dependancy faraday_middleware 1.2.0 to fix NoMethodError: undefined method `dependency' for Gzip:Class 2022-02-18 22:42:20 -05:00
ricky c101a86f02 Open Estimate PDF in new windows 2022-02-17 09:19:32 -05:00
ricky 2d32769a59 Error not fatal 2022-02-13 13:19:04 -05:00
ricky a2f755388e Fixed merge error 2022-02-13 12:34:03 -05:00
ricky 8a8f1af2bd Updated Copyright 2022 2022-02-13 11:57:43 -05:00
ricky 4582b8c5b9 Added estimate search in side bar 2022-02-13 10:03:43 -05:00
ricky f66fbf6656 specified the rails version in migrations 2022-02-12 16:14:36 -05:00
ricky 41d49ccce5 Setting.host_name for hooks not a hardcoded URL 2022-02-12 09:24:21 -05:00
ricky c85f450742 Merge branch 'master' into redmine-4 2022-02-12 09:19:36 -05:00
ricky e314dae10d Logging & exception handler for updating invoices 2022-02-12 09:12:11 -05:00
ricky b1192a1912 Use host name from settings for auth & added exception handing in QboInvoice 2022-02-06 16:37:00 -05:00
ricky 7cc8a946fd Inital update for redmine 4.0+ compatibility 2022-02-01 20:53:20 -05:00
ricky 4b34852c72 Don't include open issues in closed issue list 2020-03-30 20:56:38 -04:00
ricky 5d7fc9dabd Don't include open issues in closed issue list 2020-03-28 20:39:04 -04:00
ricky db61952e67 added notes to regaurding customer autocomplete field 2020-03-28 20:19:58 -04:00
ricky 016dca242c Added comments to clearify methods 2020-03-28 20:16:54 -04:00
ricky 983811af97 Added comments to clearify methods 2020-03-28 20:08:44 -04:00
ricky d18a9726ac Added onchange event to customer_id 2020-03-28 19:56:42 -04:00
ricky cdef838d3e comment out missing method call 2020-03-26 20:31:00 -04:00
ricky 7703d724e1 Update issues_save_hook_listener.rb
titleize all subjects
2020-03-26 20:22:07 -04:00
ricky 94b5efbd00 forgot a comma 2020-03-26 12:53:59 -04:00
ricky f43020b864 Update issues_form_hook_listener.rb
Added onchange listener to customer form field
2020-03-26 12:50:32 -04:00
ricky 0d0f808305 Merge branch 'master' of github.com:rickbarrette/redmine_qbo 2020-01-24 13:55:15 -05:00
ricky 279e8b15e0 Added open/closed issue lists for customer/vehicles 2020-01-24 13:54:26 -05:00
ricky 099f729303 Update README.md 2020-01-06 08:52:36 -05:00
ricky 5150a31cdb Removed unused gems 2020-01-05 12:33:52 -05:00
ricky b5d17dc862 Removed oauth1 database columns & updated settings 2020-01-05 12:21:36 -05:00
ricky e6c5feb3f3 Remove uneeded columns from qbos table 2020-01-05 12:03:19 -05:00
ricky 5573e941c6 Cleaning up uneeded code 2020-01-05 11:58:27 -05:00
ricky 29dbca20e0 Update copyright 2020-01-05 11:44:02 -05:00
ricky d6c114d52b Version 0.8.1 2020-01-05 09:20:23 -05:00
ricky 87b8daf283 Fixed expired token check 2020-01-05 09:17:50 -05:00
ricky 719abe20a6 Update qbo.rb 2020-01-05 01:22:27 -05:00
ricky 4a5b83265d Update qbo.rb 2020-01-05 01:20:23 -05:00
ricky 8d103d3fc6 Update qbo.rb 2020-01-05 01:12:48 -05:00
ricky 9310f207a3 Update qbo.rb 2020-01-05 01:08:42 -05:00
ricky 000b67b329 Added employee 2020-01-05 00:08:00 -05:00
ricky ebee9395ba Update qbo_employee.rb 2020-01-05 00:06:45 -05:00
ricky 2cd6731f0c Update qbo_employee.rb 2020-01-05 00:05:25 -05:00
ricky ebdbd25082 Update qbo.rb 2020-01-04 23:45:00 -05:00
ricky 18ada91fcd Update qbo.rb 2020-01-04 23:38:46 -05:00
ricky 1cf3926585 Update qbo.rb 2020-01-04 23:33:33 -05:00
ricky e776deeece Update qbo.rb 2020-01-04 23:07:53 -05:00
ricky 8c2f30949a Update qbo.rb 2020-01-04 23:04:09 -05:00
ricky 015a989f72 Update qbo.rb 2020-01-04 22:57:53 -05:00
ricky 0d4d5a6136 Update qbo.rb 2020-01-04 22:52:01 -05:00
ricky 0364989fe1 Update qbo_controller.rb 2020-01-04 22:46:20 -05:00
ricky fb47eaba0e Update qbo.rb 2020-01-04 22:45:31 -05:00
ricky 725d511be5 Update qbo.rb 2020-01-04 22:30:43 -05:00
ricky fd85f296de Update 030_update_qbos_token.rb 2020-01-04 22:16:07 -05:00
ricky 9549bb8fe2 Update qbo.rb 2020-01-04 20:24:29 -05:00
ricky 6a1c8b0551 Update README.md 2020-01-04 16:09:03 -05:00
ricky 086632e804 Version 0.8.0 (OAuth 2.0) 2020-01-04 16:01:16 -05:00
ricky d37ff922fc Update customer.rb 2020-01-04 15:51:04 -05:00
ricky 3483efa100 Oauth2 Upgrade 2020-01-04 15:41:15 -05:00
ricky f65eea2820 Oauth2 Upgrade 2020-01-04 15:37:17 -05:00
ricky a4111e0a11 oAuth2 Upgrade 2020-01-04 15:36:36 -05:00
ricky ebe5373d82 Oauth2 Upgrade 2020-01-04 15:34:57 -05:00
ricky 5b8c7d42c5 Oauth2 Upgrade 2020-01-04 15:34:04 -05:00
ricky b8fc57d583 Oauth2 Upgrade 2020-01-04 15:31:19 -05:00
ricky 7c42197cb1 Oauth2 Upgrade 2020-01-04 15:30:03 -05:00
ricky cc0ffce892 Oauth2 Upgrade 2020-01-04 15:29:18 -05:00
ricky 0fd2abbec3 Oauth2 Upgrade 2020-01-04 15:28:43 -05:00
ricky 215b219a6d Oauth2 Upgrade 2020-01-04 15:28:04 -05:00
ricky ea71542d81 Oauth2 Upgrade 2020-01-04 15:26:35 -05:00
ricky 5dbf486b50 Update qbo_controller.rb 2020-01-04 15:21:14 -05:00
ricky b734125d6b Update qbo_controller.rb 2020-01-04 15:19:31 -05:00
ricky 06e6295c6e Update qbo.rb 2020-01-04 14:32:32 -05:00
ricky fd383ad9d4 Update qbo.rb 2020-01-04 14:29:23 -05:00
ricky 4eb6c533f1 Update qbo.rb 2020-01-04 14:21:07 -05:00
ricky 5af7d73768 Update qbo_controller.rb 2020-01-04 14:18:42 -05:00
ricky 1d0ae34261 Update qbo.rb 2020-01-04 14:13:29 -05:00
ricky 21656b3e14 Update qbo.rb 2020-01-04 14:09:37 -05:00
ricky 131976cd71 Update issue_patch.rb 2020-01-04 14:08:48 -05:00
ricky 88c1b9c9a2 Update issue_patch.rb 2020-01-04 14:06:42 -05:00
ricky 5ea9aed3cb Update qbo.rb 2020-01-04 14:05:00 -05:00
ricky 41e10d9b0e Update qbo.rb 2020-01-04 13:59:09 -05:00
ricky 45859bef3e Update qbo.rb 2020-01-04 13:56:38 -05:00
ricky f5c40738dc Update issue_patch.rb 2020-01-04 13:54:29 -05:00
ricky bfa37ee634 Update issue_patch.rb 2020-01-04 13:51:31 -05:00
ricky 787b55f3d7 Update qbo.rb 2020-01-04 13:46:13 -05:00
ricky 61f882e98c Update qbo.rb 2020-01-04 13:45:00 -05:00
ricky 37db0d3d72 Update qbo.rb 2020-01-04 13:31:40 -05:00
ricky 4f2dec3069 Update qbo.rb 2020-01-04 13:29:36 -05:00
ricky 35a7c3cfeb Create 030_update_qbos_token.rb 2020-01-04 13:28:22 -05:00
ricky cbbaf5a95c Update qbo.rb 2020-01-04 13:22:27 -05:00
ricky 647923e5e6 Update 029_update_qbos_types.rb 2020-01-04 13:19:21 -05:00
ricky 70ca4e9964 Create 029_update_qbos_types.rb 2020-01-04 13:17:15 -05:00
ricky 7fb40ad4a8 Update qbo_controller.rb 2020-01-04 13:09:09 -05:00
ricky 36083d23a0 Update qbo_controller.rb 2020-01-04 13:07:36 -05:00
ricky 2ec57f2bbf Update qbo_controller.rb 2020-01-04 13:06:23 -05:00
ricky 278708e566 Update qbo_controller.rb 2020-01-04 12:47:30 -05:00
ricky 23f2b92e8d Update qbo_controller.rb 2020-01-04 12:45:16 -05:00
ricky 5d92eeddfb Update qbo_controller.rb 2020-01-04 12:44:05 -05:00
ricky 384a8c033c Update qbo_controller.rb 2020-01-04 12:39:23 -05:00
ricky 32b12b60f9 Update qbo_controller.rb 2020-01-04 12:33:54 -05:00
ricky 93db447239 Update qbo_controller.rb 2020-01-04 12:29:54 -05:00
ricky 19a6180e15 Update qbo.rb 2020-01-04 12:26:04 -05:00
ricky 3408ee173c Update qbo.rb 2020-01-04 12:25:12 -05:00
ricky b817e842dd Update qbo.rb 2020-01-04 12:23:59 -05:00
ricky 51c3b8338e Update qbo.rb 2020-01-04 12:23:05 -05:00
ricky c6a3edfbc1 Update qbo_controller.rb 2020-01-04 12:21:45 -05:00
ricky 21d8d90465 Update qbo.rb 2020-01-04 12:21:24 -05:00
ricky 04c0fa57c6 Update qbo_controller.rb 2020-01-04 12:17:26 -05:00
ricky f5ad761712 Update qbo_controller.rb 2020-01-04 12:14:54 -05:00
ricky 9b80485915 Update qbo.rb 2020-01-04 12:14:05 -05:00
ricky 87de865c00 oauth2 2020-01-04 11:51:25 -05:00
ricky 1ea27e8511 Only show error flash if errors are not empty 2019-11-12 12:50:44 -05:00
ricky 8f0ca00b09 Merge branch 'master' of github.com:rickbarrette/redmine_qbo 2019-11-12 12:45:20 -05:00
ricky 859a1d505b always show errors 2019-11-12 12:45:14 -05:00
ricky cd109653a2 Merge branch 'master' of github.com:rickbarrette/redmine_qbo 2019-11-12 12:37:12 -05:00
ricky cab723bbcd Removed styles & removed after find call 2019-11-12 12:36:25 -05:00
ricky 3dd712629b added local vin validation 2019-11-12 12:35:54 -05:00
ricky cdf2603e12 Merge branch 'master' of github.com:rickbarrette/redmine_qbo 2019-11-12 12:16:30 -05:00
ricky 5df9d324bc Update vehicle.rb 2019-11-12 12:15:59 -05:00
ricky f78c0338b4 Made decode_vin not private 2019-11-12 12:08:04 -05:00
ricky fe6aa7908f Merge branch 'master' of github.com:rickbarrette/redmine_qbo 2019-11-12 11:51:54 -05:00
ricky aa45338e36 Update vehicle.rb 2019-11-11 10:10:23 -05:00
ricky 213dca2621 Fixed redicect to :home 2019-07-08 11:30:53 -04:00
ricky fee710d717 Rediect to vehicle if vin is already taken 2019-06-26 11:39:07 -04:00
ricky 65eac58f6c Update customer.rb 2019-06-25 12:48:35 -04:00
ricky b4f5112fc3 Create 028_add_customers_mobile_phone_number.rb 2019-06-25 12:46:03 -04:00
ricky fa5dcbf9a9 Fixed redirect to for new vehicles 2019-06-25 12:37:49 -04:00
ricky e0aebb1c23 Update customer.rb 2019-06-25 11:59:08 -04:00
ricky 6d176acc2b Update customer.rb 2019-06-25 11:54:26 -04:00
ricky 9e9b29fef9 Update 027_add_customers_phone_number.rb 2019-06-25 11:53:40 -04:00
ricky 1af846537d Update customer.rb 2019-06-25 11:50:14 -04:00
ricky d6c5daff49 Added phone number 2019-06-25 11:15:57 -04:00
ricky 61c76ad80a Create 027_add_customers_phone_number.rb 2019-06-25 10:59:34 -04:00
ricky 0d514790fd Moved issue.status.is_closed? check back into issue save hook 2019-03-26 12:15:03 -04:00
ricky 748d431d35 Removed controller_issues_edit_before_save hook 2019-03-26 12:11:54 -04:00
ricky 87b8d99c41 Working on issue.bill_time 2019-03-26 12:09:38 -04:00
ricky a0da53b6cf Fixed formatting & removed search from heading 2018-10-15 21:10:41 -04:00
ricky 02d630c631 Fixed Invoice Link to be HTML safe 2018-10-15 21:07:36 -04:00
ricky 15b214c800 Moved html into partial view 2018-10-15 20:57:03 -04:00
ricky 1b5e185087 Added nil check 2018-10-15 19:42:41 -04:00
ricky 102309600e Merge branch 'master' of github.com:rickbarrette/redmine_qbo 2018-10-15 19:36:09 -04:00
ricky 6acc7db91b Changed Customer search to shown on all pages 2018-10-15 19:34:51 -04:00
ricky 02898883a8 Update line_item.rb 2018-10-14 23:35:13 -04:00
ricky ce02b70bc3 Update line_items_controler.rb 2018-10-14 23:34:17 -04:00
ricky d4d4a555f8 Forgot to add sidebar files 2018-10-14 23:32:07 -04:00
ricky c2663cd0a0 License update 2018-10-14 23:31:17 -04:00
ricky d48609361f Added customer search to sidebar 2018-10-14 23:27:19 -04:00
ricky 70995f6e55 Fixed formating 2018-10-04 20:59:46 -04:00
ricky 05a0472939 Changed redirect to :back 2018-10-04 20:57:24 -04:00
ricky cff9f3fde3 Fixed new vehicle add missing customer 2018-09-22 00:29:54 -04:00
ricky e24b704571 Added qbo partial views 2018-09-19 22:57:45 -04:00
ricky 4d99f54c79 Added autocomplete to vehicle customer field 2018-09-19 22:33:36 -04:00
ricky e65725c334 Update init.rb 2018-09-19 10:15:13 -04:00
ricky 4829daab7c Update new.html.erb 2018-09-19 10:10:54 -04:00
ricky 260e9f3e4a Update _list.html.erb 2018-09-19 10:07:52 -04:00
ricky e3ce2445b8 Update index.html.erb 2018-09-19 10:05:45 -04:00
ricky 2b333667ed Update init.rb 2018-09-19 09:52:58 -04:00
ricky 1077cf214c Update show.html.erb 2018-09-19 09:51:27 -04:00
ricky f27fdf5274 Update index.html.erb 2018-09-19 09:50:58 -04:00
ricky 1dbcca4ca0 Create _search.html.erb 2018-09-19 09:49:51 -04:00
ricky 558e2359f7 Added partial customers/search & fixed formatting 2018-09-19 09:45:36 -04:00
ricky f99ef648b3 Rename _search.erb to _search.html.erb 2018-09-19 09:24:05 -04:00
ricky 5e4e3329c8 Create _search.erb 2018-09-19 09:23:37 -04:00
ricky b0a66aba0a Fixed custom field redering 2018-07-31 15:22:46 -04:00
ricky f2dd500536 Merge branch 'line_items' of github.com:rickbarrette/redmine_qbo into line_items 2018-03-31 08:04:17 -04:00
ricky 7412ac4f91 Added boolean billed 2018-03-31 08:03:26 -04:00
ricky 2acb3efe5a Create line_items_controler.rb 2018-03-31 08:00:56 -04:00
ricky 2cc0d06bc5 Merge branch 'master' into line_items 2018-03-29 22:42:54 -04:00
ricky 4070cb7c49 Merge branch 'master' of github.com:rickbarrette/redmine_qbo 2018-03-29 22:42:03 -04:00
ricky fcd196355a Create line_item.rb 2018-03-29 10:17:01 -04:00
ricky ea502d5b7b Create 026_create_line_items.rb 2018-03-29 10:05:37 -04:00
ricky 1f33009f89 Update LICENSE 2018-03-28 15:24:44 -04:00
ricky 3509ae9725 Removed squish_vin and added last 8 of vin to vehicle name 2018-03-27 09:40:01 -04:00
ricky 49858c45c9 do a full search by setting the full parameter to true. 2018-03-27 09:38:44 -04:00
ricky b78cd44cc9 don't bill time if not assigned to anyone EE 2018-03-05 08:58:33 -05:00
ricky 39fcd6d4dd Removed Drive & Doors 2018-03-03 13:55:22 -05:00
ricky 8838d36793 Fixed vin decoding 2018-03-03 13:54:19 -05:00
ricky 63fa94e6f2 Merge branch 'master' into nhtsa_vin 2018-03-03 13:14:05 -05:00
ricky 17183f9643 Update vehicle.rb 2018-03-03 13:11:58 -05:00
ricky 667d0bfa97 Remove Edmunds API & Added NhtsaVin 2018-03-03 12:38:56 -05:00
ricky 88a6be0d27 Remove Edmunds API Key Setting 2018-03-03 12:26:25 -05:00
ricky c3eaddff97 Start work to switch from edmunds_vin to nhtsa_vin 2018-03-03 12:22:44 -05:00
ricky f03adad463 Update issues_form_hook_listener.rb 2017-11-19 22:17:25 -05:00
ricky bd03e3ac32 Did things 2017-11-19 22:14:40 -05:00
ricky 299a28a0d2 Create controller_issues_listener.rb 2017-11-19 22:01:20 -05:00
ricky cee8ddced1 Added safe_attributes for ProjecT 2017-11-17 20:54:14 -05:00
ricky 738cd21b1f Update issues_form_hook_listener.rb 2017-11-17 10:56:13 -05:00
ricky b8186e4b52 More customer/project relations 2017-11-17 10:51:25 -05:00
ricky d98a8b8cc4 Fixed Project releationships and database migration 2017-11-17 10:14:05 -05:00
ricky dba6c4b131 Update vehicle.rb 2017-11-13 22:19:20 -05:00
ricky 118812f16f Update vehicle.rb 2017-11-13 22:17:03 -05:00
ricky 0b96a1412c Rename app/views/qbo/list_simple.html.erb to app/views/issues/_list_simple.html.erb 2017-11-13 22:07:12 -05:00
ricky 29de191d26 Rename app/views/issues/list_simple.html.erb to app/views/qbo/list_simple.html.erb 2017-11-13 22:06:45 -05:00
ricky f86af9ca71 Create list_simple.html.erb 2017-11-13 22:04:04 -05:00
ricky d25de7b30f Merge remote-tracking branch 'origin/dev' 2017-11-13 21:37:28 -05:00
ricky 273bd3d6be Update application.js 2017-11-13 21:01:17 -05:00
ricky ac446723f1 Update application.js 2017-11-13 20:59:45 -05:00
ricky c21bc1333f Update projects_form_hook_listener.rb 2017-11-13 20:38:33 -05:00
ricky 4e4255995e Update projects_form_hook_listener.rb 2017-11-13 20:37:59 -05:00
ricky c68b540597 Update projects_form_hook_listener.rb 2017-11-13 20:36:44 -05:00
ricky 1358871ccc Update init.rb 2017-11-13 20:31:16 -05:00
ricky 908511f299 Update init.rb 2017-11-13 20:30:28 -05:00
ricky 6260de21f9 Update query_patch.rb 2017-11-13 20:28:19 -05:00
ricky e2f276097c Update query_patch.rb 2017-11-13 20:27:36 -05:00
ricky 205bb67a6a Update query_patch.rb 2017-11-13 20:20:46 -05:00
ricky 05edafec4c Update query_patch.rb 2017-11-13 20:13:26 -05:00
ricky 4a073d3a71 Update query_patch.rb 2017-11-13 20:12:23 -05:00
ricky f2cbf31e17 Create projects_form_hook_listener.rb 2017-11-13 19:53:37 -05:00
ricky 22b22780ea Create project_patch.rb
Add relationships to projects
2017-11-13 19:47:39 -05:00
ricky 71cfa28817 Create 025_update_projects.rb
Added customer & vehicle reference to a project.
2017-11-13 19:40:14 -05:00
ricky 8b2d88f80b Create qbo_controller.rb 2017-06-14 09:43:52 -04:00
ricky eaf0a57e51 Create qbo_controller.rb 2017-06-13 21:58:42 -04:00
ricky 512f5ad7ba Create index.html.erb 2017-06-13 21:55:13 -04:00
ricky 8d2351d3f9 Create vehicle.rb 2017-06-13 21:51:36 -04:00
ricky c5a20c9e7f Create vehicle.rb 2017-06-13 21:50:50 -04:00
ricky 4a3b663333 Create vehicle.rb 2017-06-13 21:49:10 -04:00
ricky e43635b5d8 Update vehicle.rb 2017-06-13 12:31:07 -04:00
ricky 7044377f16 Update vehicle.rb 2017-06-13 12:27:22 -04:00
ricky 7ced1bf942 Create vehicle.rb 2017-06-13 12:22:48 -04:00
ricky 7ca3315ce5 Update vehicle.rb 2017-06-13 11:44:46 -04:00
ricky 2b8c4b4d4d Update vehicle.rb 2017-06-06 08:58:11 -04:00
ricky a359e8815b Update issues_form_hook_listener.rb 2017-06-06 08:53:36 -04:00
ricky 01cf82813c Update vehicle.rb 2017-06-06 08:32:21 -04:00
ricky 625e400c48 Update vehicle.rb 2017-06-06 08:27:55 -04:00
ricky 56793cee7c Update vehicle.rb 2017-06-06 08:25:35 -04:00
ricky 3ba5337812 Update vehicle.rb
Updated regex to remove invalid chars
2017-06-06 08:22:50 -04:00
ricky 129e3d4821 Update issues_form_hook_listener.rb 2017-06-06 08:12:08 -04:00
ricky 4d524a7d61 Update issues_form_hook_listener.rb 2017-06-06 08:10:28 -04:00
ricky 429fb920fb Update index.html.erb 2017-04-04 22:29:06 -04:00
ricky 77c7f0b6fe Update index.html.erb 2017-04-04 22:28:20 -04:00
ricky 1a043bea76 Added Permission Check 2017-04-04 22:26:58 -04:00
ricky e4d770c272 Update index.html.erb 2017-04-04 22:23:33 -04:00
ricky fce3931858 Added new customer button 2017-04-04 22:22:29 -04:00
ricky 43cdade6e1 Merge branch 'master' into dev 2017-04-04 09:32:50 -04:00
ricky 4374f9436c Removed .service from get_base call 2017-04-04 09:31:02 -04:00
ricky 7c63c3c816 Fixed typo 2017-04-04 08:49:08 -04:00
ricky b3f491a60b Fixed logic 2017-04-04 08:48:36 -04:00
ricky 4adcbba840 Update vehicle.rb 2017-04-04 08:47:15 -04:00
ricky baccb42455 Merge branch 'dev' of github.com:rickbarrette/redmine_qbo into dev 2017-04-04 08:46:44 -04:00
ricky d0842dd803 Merge branch 'dev' of github.com:rickbarrette/redmine_qbo into dev 2017-04-04 08:45:45 -04:00
ricky 02aabe6045 Forgot End 2017-04-04 08:45:34 -04:00
ricky 0e47f9eb5f Some Cleanup & Fixed to_s to report vin
to_s to report vin when year,make,model are nil
2017-04-04 08:44:14 -04:00
ricky f1d2d63f20 Removed un-needed initializer 2017-04-04 08:37:49 -04:00
ricky f322f9f7ab Update Copyright 2017-04-04 08:34:03 -04:00
ricky 6db8b76902 Update Copyright 2017-04-04 08:33:37 -04:00
ricky 61adce1299 0.5.0 2017-04-03 22:59:09 -04:00
ricky daffb3719e Copyright Update & Formating 2017-04-03 22:57:25 -04:00
ricky 1b8626d28f Update init.rb 2017-04-03 22:53:34 -04:00
ricky b119344fad Copyright Update 2017-04-03 22:52:37 -04:00
ricky 4381d403d4 Copyright Update 2017-04-03 22:52:14 -04:00
ricky 26bfaca1d6 Copyright Update 2017-04-03 22:52:00 -04:00
ricky 0c68d8094a Copyright Update 2017-04-03 22:51:43 -04:00
ricky 6230175ba5 Copyright Update 2017-04-03 22:51:25 -04:00
ricky 5dc4dc5637 Copyright Update 2017-04-03 22:51:03 -04:00
ricky ac15307fb8 Copyright Update 2017-04-03 22:50:50 -04:00
ricky ec5ce497d8 Copyright Update 2017-04-03 22:50:38 -04:00
ricky 01fe52157d Update issue_patch.rb 2017-04-03 22:50:19 -04:00
ricky 75737cf2fd Copyright Update 2017-04-03 22:50:05 -04:00
ricky 7824edf5aa Copyright Update 2017-04-03 22:49:52 -04:00
ricky 6b70b447a5 Copyright Update 2017-04-03 22:48:07 -04:00
ricky 5a6b679099 Copyright Update 2017-04-03 22:47:49 -04:00
ricky 72835dcf65 Copyright Update 2017-04-03 22:47:36 -04:00
ricky b9e2349983 Update qbo.rb 2017-04-03 22:47:21 -04:00
ricky ef13ec7e11 Update qbo_employee.rb 2017-04-03 22:47:10 -04:00
ricky 00b40da8c4 Copyright Update 2017-04-03 22:46:48 -04:00
ricky 2be25adf18 Copyright Update 2017-04-03 22:46:35 -04:00
ricky 5ab9a777f6 Copyright Update 2017-04-03 22:46:19 -04:00
ricky 7fbb1d6ba3 Copyright Update 2017-04-03 22:46:04 -04:00
ricky 786c80609c Copyright Update 2017-04-03 22:45:21 -04:00
ricky efb554824d Update vehicles_controller.rb 2017-04-03 22:44:40 -04:00
ricky c615abc896 Update qbo_controller.rb 2017-04-03 22:44:29 -04:00
ricky 8ecc3414da Update payments_controller.rb 2017-04-03 22:44:17 -04:00
ricky 505def8d23 Update invoice_controller.rb 2017-04-03 22:44:03 -04:00
ricky da155de514 Copyright Update 2017-04-03 22:43:42 -04:00
ricky 7d727e1ad8 Copyright Update 2017-04-03 22:43:25 -04:00
ricky 3dcb5155fc Add Blank Option 2017-04-03 22:40:07 -04:00
ricky 4424593e63 Add Blank to Select 2017-04-03 22:38:45 -04:00
ricky 8eae838ef8 Update filter_estimates_by_customer.js.erb 2017-04-03 22:34:19 -04:00
ricky d5e8b4bbc4 Update qbo_estimate.rb 2017-04-03 22:26:53 -04:00
ricky fc8efa53e9 Merge branch 'dev' of github.com:rickbarrette/redmine_qbo into dev 2017-04-03 22:25:29 -04:00
ricky 15ea3aeaa2 Update qbo_estimate.rb 2017-04-03 22:24:04 -04:00
ricky 35bf300f2d Show only estimates attached to the customer 2017-04-03 22:07:06 -04:00
ricky 72bf10680f Added ajax to update estimates 2017-04-03 21:57:56 -04:00
ricky bd8706deee Create filter_estimates_by_customer.js.erb 2017-04-03 21:55:47 -04:00
ricky e8619529d4 Added routes for filtering estimates & invoices 2017-04-03 21:52:39 -04:00
ricky fd3c8e15e6 Added filter methods for estimates & invoices 2017-04-03 21:49:57 -04:00
ricky 166c1d3002 Add files via upload 2017-04-02 17:13:21 -04:00
ricky 773d60fb23 Delete plugin_issue_view.png 2017-04-02 17:12:53 -04:00
ricky cc46902095 Update qbo_estimate.rb 2017-04-02 08:45:02 -04:00
ricky acb2628c7a Update qbo_estimate.rb 2017-04-02 08:41:36 -04:00
ricky e4914590f8 Moved Invoice Sync up in the order 2017-04-02 08:31:22 -04:00
ricky e3a8e464ae Update qbo_estimate.rb 2017-04-02 08:21:36 -04:00
ricky 8a6bb45b6a Fixed Custom Field Logic 2017-04-02 08:06:07 -04:00
ricky 3decf83a7b Update qbo_invoice.rb 2017-04-02 07:54:33 -04:00
ricky 1b7b286d1b Update qbo_invoice.rb 2017-04-02 07:31:28 -04:00
ricky a8804f6704 Increment the sync token 2017-04-02 07:28:53 -04:00
ricky 5d03e261d1 Added customer association 2017-04-02 07:19:12 -04:00
ricky 1ae766b8bd Added customer association 2017-04-02 07:13:28 -04:00
ricky 119c36569f Added association for invoices & estimates 2017-04-02 07:08:24 -04:00
ricky 3be69d5efd Update 024_update_invoices_and_estimates.rb 2017-04-02 07:00:43 -04:00
ricky b55dd99efd Merge branch 'master' into dev 2017-04-02 06:59:01 -04:00
ricky eff1f97ab2 Create 024_update_invoices_and_estimates.rb 2017-04-02 06:56:17 -04:00
ricky 06050bd139 Removed unused method update_vehicles 2017-03-31 16:23:42 -04:00
ricky a48840ddfb Fixed typo 2017-03-31 16:12:21 -04:00
ricky 9b9aabee11 Format the VIN 2017-03-31 16:11:19 -04:00
ricky 7782627286 Split the VIN 2017-03-31 16:07:09 -04:00
ricky 41a113dc59 Do not hide notes 2017-03-31 16:02:48 -04:00
ricky b84e249dfb 0.4.3 2017-03-23 06:05:43 -04:00
ricky 6b45f767a4 Merge pull request #8 from rickbarrette/permissions
Permissions
2017-03-23 06:03:06 -04:00
ricky a34b6a07fc fixed typos 2017-03-23 05:56:26 -04:00
ricky 2ce811bbbf Update auth_helper.rb 2017-03-23 05:50:31 -04:00
ricky 02153de8b0 Added before filters add_customer, view_customer 2017-03-23 05:47:37 -04:00
ricky 68be20459b Added global_check_permission 2017-03-23 05:45:45 -04:00
ricky bbd03cc337 Update init.rb 2017-03-23 05:42:54 -04:00
ricky 4fc71a93f2 Update init.rb 2017-03-23 05:42:09 -04:00
ricky 8e7e1908e4 Update customers_controller.rb 2017-03-23 05:39:55 -04:00
ricky 89fba883ef Update customers_controller.rb 2017-03-23 05:38:06 -04:00
ricky 15f317fba1 Update customers_controller.rb 2017-03-23 05:36:51 -04:00
ricky 894ee9abfd added check_permission 2017-03-23 05:33:58 -04:00
ricky ca17807117 Update payments_controller.rb 2017-03-23 05:29:54 -04:00
ricky a70ba2f164 Update payments_controller.rb 2017-03-23 05:27:38 -04:00
ricky 78ac97298c Update payments_controller.rb 2017-03-23 05:25:57 -04:00
ricky 72cd349c1b Update payments_controller.rb 2017-03-23 05:23:44 -04:00
ricky 6fc1d27dca Update auth_helper.rb 2017-03-23 05:21:56 -04:00
ricky 525c6b99d6 Update auth_helper.rb 2017-03-23 05:19:13 -04:00
ricky 3eaff0ab30 Update auth_helper.rb 2017-03-23 05:14:47 -04:00
ricky 85b40bc9cf Update payments_controller.rb 2017-03-23 05:11:15 -04:00
ricky 37a2b95447 Update payments_controller.rb 2017-03-23 05:10:05 -04:00
ricky 33feb91713 added permission_checker 2017-03-23 05:08:33 -04:00
ricky f7357f30ce Update payments_controller.rb 2017-03-23 05:03:58 -04:00
ricky c0ae01018b Update payments_controller.rb 2017-03-23 05:01:01 -04:00
ricky 4353e910c8 Update payments_controller.rb 2017-03-23 04:57:22 -04:00
ricky bef9774c4e Update payments_controller.rb 2017-03-23 04:52:19 -04:00
ricky 863437b1b7 Added before filter to check permissions 2017-03-23 04:50:17 -04:00
ricky 7cfa15910a Update init.rb 2017-03-23 04:41:31 -04:00
ricky 2154a3d001 Update init.rb 2017-03-22 23:09:05 -04:00
ricky fdab090a3d Update init.rb 2017-03-22 23:06:12 -04:00
ricky 3f32b7fef1 Update init.rb 2017-03-22 22:53:21 -04:00
ricky 14422bc549 Update init.rb 2017-03-22 22:52:24 -04:00
ricky 6bb66597e8 Added some permissions
view_customers, add_customers, view_payments, add_payments
2017-03-22 22:44:09 -04:00
ricky 32b750b545 Version 0.4.2 2017-03-22 22:38:42 -04:00
ricky 5fd3141746 Merge pull request #7 from rickbarrette/dev
Removed un-needed js files
2017-03-22 22:26:04 -04:00
ricky 2c38361234 Removed un-needed js files 2017-03-22 22:20:12 -04:00
ricky 81b7b1492d Merge pull request #6 from rickbarrette/filter_vehicles_by_customer
Filter vehicles by customer
2017-03-22 22:07:22 -04:00
ricky 57ef1ac5a1 Fixed Typo 2017-03-22 22:05:33 -04:00
ricky 6597c5a13c Update application.js 2017-03-22 22:03:25 -04:00
ricky 8af97072fb Fixed filter_vehicles_by_customer method 2017-03-22 21:55:07 -04:00
ricky 48b6df0cef Update application.js 2017-03-22 21:34:04 -04:00
ricky 853b7ad804 Rename filter_vehicles_by_customerjs.erb to filter_vehicles_by_customer.js.erb 2017-03-22 21:27:15 -04:00
ricky 6a74baff5e Update application.js 2017-03-22 18:56:44 -04:00
ricky 8b21b0ff75 Update application.js 2017-03-22 18:54:47 -04:00
ricky d22a6303cd Update application.js 2017-03-22 18:53:47 -04:00
ricky 807d6643f4 Update application.js 2017-03-22 18:52:38 -04:00
ricky c725c2774c Update application.js 2017-03-22 18:50:21 -04:00
ricky ae0abae333 Update application.js 2017-03-22 18:48:52 -04:00
ricky fed2282212 Added debug 2017-03-22 18:37:06 -04:00
ricky 545960e676 Call autocomplete instead 2017-03-22 18:28:53 -04:00
ricky 66781f0625 Update application.js 2017-03-22 13:12:29 -04:00
ricky 504b9b93e4 Removed { 2017-03-22 13:11:19 -04:00
ricky b71bba473c Provide empty list 2017-03-22 13:09:15 -04:00
ricky aef3c453c4 Do not list all vehicles without customer 2017-03-22 13:04:50 -04:00
ricky 6de3ed94dc Update and rename app/views/filter_vehicles_by_customerjs.erb to app/views/customers/filter_vehicles_by_customerjs.erb
Also changed ID to select#issue_vehicles_id
2017-03-22 12:59:36 -04:00
ricky daada08ea7 Changed select to input 2017-03-22 12:48:43 -04:00
ricky fa37c98500 Removed ID 2017-03-22 12:47:08 -04:00
ricky 0ee59704b3 Fixed Javascript includes to += 2017-03-22 12:43:25 -04:00
ricky a22cbb9520 Added Javascript include for application.js 2017-03-22 11:09:19 -04:00
ricky c0d3f64d82 Create application.js 2017-03-22 11:08:14 -04:00
ricky 66d2bf4aa4 Create filter_vehicles_by_customerjs.erb 2017-03-22 11:04:48 -04:00
ricky 2b90c953ba Added filter_vehicles_by_customer method 2017-03-22 10:29:04 -04:00
ricky 0d5e5d679e Added route for filter_vehicles_by_customer 2017-03-22 10:24:16 -04:00
ricky 4da891cc07 Merge branch 'master' of git://github.com/sempervictus/redmine_qbo into sempervictus-master 2017-02-22 11:10:46 -05:00
ricky d3475a9b53 Delete vehicles.js 2017-02-14 14:42:13 -05:00
ricky eb583f78ec Delete update_vehicles.js.coffee 2017-02-14 14:41:55 -05:00
ricky 47bebf0a1a Delete application.js 2017-02-14 14:41:34 -05:00
ricky f9bd149f21 Commented out un-needed JS 2017-02-14 14:39:58 -05:00
ricky 5371b0f193 Update application.js 2017-01-29 22:40:48 -05:00
ricky 95497e5514 Update issues_form_hook_listener.rb 2017-01-29 22:40:02 -05:00
ricky 1a74abe76c Update issues_form_hook_listener.rb 2017-01-29 22:38:30 -05:00
ricky 7f11d3cdc4 Update issues_form_hook_listener.rb 2017-01-29 22:36:32 -05:00
ricky da01d79325 Update customers_controller.rb 2017-01-29 22:29:15 -05:00
ricky 82807cfede Update customers_controller.rb 2017-01-29 22:26:53 -05:00
ricky a268d10819 Update customers_controller.rb 2017-01-29 22:25:27 -05:00
ricky ba4bdd9ecb Update routes.rb 2017-01-29 22:19:12 -05:00
ricky 0a72e05e03 Update issues_form_hook_listener.rb 2017-01-29 22:05:29 -05:00
ricky 8d143ff06d Update customers_controller.rb 2017-01-29 22:00:19 -05:00
ricky 3ddb585a58 Update customers_controller.rb 2017-01-29 21:58:49 -05:00
ricky 1606ceb743 Update issues_form_hook_listener.rb 2017-01-29 21:49:57 -05:00
ricky 97578f8380 Update issues_form_hook_listener.rb 2017-01-29 21:47:09 -05:00
ricky 32beae70ef Update issues_form_hook_listener.rb 2017-01-29 21:45:13 -05:00
ricky 13fbc9e14f Update issues_form_hook_listener.rb 2017-01-29 21:44:00 -05:00
ricky c57a45c85e Update issues_form_hook_listener.rb 2017-01-29 21:43:25 -05:00
ricky 3711a9ca43 Update issues_form_hook_listener.rb 2017-01-29 21:38:18 -05:00
ricky d0c1693f38 Create autocomplete-rails.js 2017-01-29 21:37:27 -05:00
ricky 36534ee129 Update issues_form_hook_listener.rb 2017-01-29 21:34:28 -05:00
ricky 188c460054 Update issues_form_hook_listener.rb 2017-01-29 21:15:29 -05:00
ricky d9e3cb096b Update application.js 2017-01-29 21:10:41 -05:00
ricky b57b19493f Add files via upload 2017-01-29 21:08:29 -05:00
ricky 8c569db541 Update issues_form_hook_listener.rb 2017-01-29 20:56:30 -05:00
ricky 997257f42d Update issues_form_hook_listener.rb 2017-01-29 20:54:52 -05:00
ricky f9f1af17bc Update issues_form_hook_listener.rb 2017-01-29 20:53:09 -05:00
ricky f1f44d0048 Update issues_form_hook_listener.rb 2017-01-29 20:46:39 -05:00
ricky 7e8511090d Update issues_form_hook_listener.rb 2017-01-29 20:42:18 -05:00
ricky 4ca6a3138b Update issues_form_hook_listener.rb 2017-01-29 20:41:38 -05:00
ricky 21e1132e0e Update issues_form_hook_listener.rb 2017-01-29 20:36:19 -05:00
ricky dc15424014 Update issues_form_hook_listener.rb 2017-01-29 20:30:34 -05:00
ricky f90cdcd86b Update customers_controller.rb 2017-01-29 20:28:17 -05:00
ricky 5e53c18098 Update issues_form_hook_listener.rb 2017-01-29 20:24:06 -05:00
ricky 52d13ea7bc Update customers_controller.rb 2017-01-29 20:18:21 -05:00
ricky 5e24c5084e Update customers_controller.rb 2017-01-29 20:12:38 -05:00
ricky abdb61cc41 Update Gemfile 2017-01-29 20:07:08 -05:00
ricky 03556cc670 Update Gemfile 2017-01-29 20:03:53 -05:00
ricky 7f6cd99aba Update Gemfile 2017-01-29 19:58:11 -05:00
ricky ba513fb950 Update issues_form_hook_listener.rb 2017-01-29 19:47:24 -05:00
ricky 837ddd722c Update issues_form_hook_listener.rb 2017-01-29 19:46:21 -05:00
ricky f2b0cd3748 Update issues_form_hook_listener.rb 2017-01-29 19:45:31 -05:00
ricky f2a8878af4 Update issues_form_hook_listener.rb 2017-01-29 19:40:51 -05:00
ricky 13fccec54b Update routes.rb 2017-01-29 19:36:58 -05:00
ricky eca2b986a9 Update customers_controller.rb 2017-01-29 19:35:45 -05:00
ricky a06599b7f9 Update issues_form_hook_listener.rb 2017-01-29 19:34:31 -05:00
ricky 7fda4dc577 Create application.js 2017-01-29 19:32:59 -05:00
ricky 9e47152e12 Update Gemfile 2017-01-29 19:31:31 -05:00
ricky 83d21da41a Update issues_form_hook_listener.rb 2017-01-29 19:27:23 -05:00
ricky a692f03bfa Update init.rb 2017-01-29 19:17:37 -05:00
ricky 994cdf908f Update init.rb 2017-01-29 19:16:55 -05:00
ricky b022d17fc0 Update init.rb 2017-01-29 19:16:05 -05:00
ricky 644899c0b5 Update email_worker.rb 2017-01-29 19:15:14 -05:00
ricky be3a3b920d Update email_worker.rb 2017-01-27 12:04:58 -05:00
ricky d546eb026f Update email_worker.rb 2017-01-27 12:01:53 -05:00
ricky fdc59feb13 Create email_worker.rb 2017-01-27 11:47:30 -05:00
ricky 186b726a7b Added nil check 2017-01-27 09:38:00 -05:00
RageLtMan fa362bad55 Merge pull request #3 from sempervictus/bug-dont_call_string_method_on_nil_token
Do not permit OAUTH_CONSUMER_SECRET to be nil
2017-01-19 04:09:34 -05:00
RageLtMan fcf55bb504 Do not permit OAUTH_CONSUMER_SECRET to be nil
When QBO plugin is not configured, OAUTH_CONSUMER_SECRET can be
nil, and any codepath hitting the model raises a stack trace.

Set a "safe-ish" value here to allow execution in conditions where
QBO plugin is installed, but not yet configured.
2017-01-19 04:02:59 -05:00
RageLtMan 2185667665 Merge pull request #2 from sempervictus/local
Merge initial changes 20170103
2017-01-03 04:34:58 -05:00
RageLtMan 772483817e Prevent billing if issue has no customer assigned 2017-01-03 04:32:04 -05:00
RageLtMan 178ddd32c7 Remove will_paginate version constraint 2017-01-02 05:01:41 -05:00
ricky 08e047c90e Added done_ratio to partial billing 2016-10-12 10:31:05 -04:00
ricky b3c3314385 Remove Breaks 2016-09-26 16:41:41 -04:00
ricky 9fd5e01bb4 Update qbo_invoice.rb 2016-09-26 16:39:12 -04:00
ricky cd62f65fcd Update qbo_invoice.rb 2016-09-26 16:34:56 -04:00
ricky fb40833abd Update qbo_invoice.rb 2016-09-26 16:33:56 -04:00
ricky 6aae155933 Update qbo_invoice.rb 2016-09-21 19:51:22 -04:00
ricky f9e0ae8fef Update qbo_invoice.rb 2016-09-21 19:48:26 -04:00
ricky 489e335ca4 Update qbo_invoice.rb 2016-09-21 19:46:55 -04:00
ricky 874d0b4db9 Update qbo_invoice.rb 2016-09-21 19:43:40 -04:00
ricky 49e8f70b46 Update qbo_invoice.rb 2016-09-21 16:17:07 -04:00
ricky 77ea20171e Don't tie invoice to issue if customer is diffrent 2016-09-21 16:15:43 -04:00
ricky 11d4034c37 Update query_patch.rb 2016-09-19 23:19:53 -04:00
ricky 64369470de Update auth_helper.rb 2016-09-19 23:01:58 -04:00
ricky 7b483f3290 Update invoice_controller.rb 2016-09-19 23:01:27 -04:00
ricky 32bec79c28 Update invoice_controller.rb 2016-09-19 22:59:44 -04:00
ricky dfd9622ab7 Update invoice_controller.rb 2016-09-19 22:59:02 -04:00
ricky 334d3c930b Update auth_helper.rb 2016-09-19 22:57:19 -04:00
ricky 8cf2f370bf Update invoice_controller.rb 2016-09-19 22:54:58 -04:00
ricky 3965bed6c4 Update invoice_controller.rb 2016-09-19 22:50:18 -04:00
ricky 52396eb384 Update invoice_controller.rb 2016-09-19 22:49:06 -04:00
ricky 9cfab7bea1 Update invoice_controller.rb 2016-09-19 22:44:52 -04:00
ricky c8ef3bbd4e Update invoice_controller.rb 2016-09-19 22:38:48 -04:00
ricky 39e7d3c062 Update invoice_controller.rb 2016-09-19 22:37:53 -04:00
ricky 6fa96e11df Update invoice_controller.rb 2016-09-19 22:35:51 -04:00
ricky ecde64193a Update invoice_controller.rb 2016-09-19 22:32:30 -04:00
ricky f701af9a4d Update auth_helper.rb 2016-09-19 22:30:14 -04:00
ricky 6d99702a11 Update customers_controller.rb 2016-09-19 22:27:03 -04:00
ricky 138f8f2c2f Update auth_helper.rb 2016-09-19 22:21:37 -04:00
ricky 61ddf7378d Update auth_helper.rb 2016-09-19 22:18:19 -04:00
ricky f5b72f30be Update customers_controller.rb 2016-09-19 22:17:15 -04:00
ricky 1863b33955 Update view.html.erb 2016-09-19 22:05:48 -04:00
ricky a4573fce1c Update issue_patch.rb 2016-09-19 22:01:32 -04:00
ricky 0461801ee0 Update issues_form_hook_listener.rb 2016-09-19 21:29:28 -04:00
ricky 4c2eaac013 Update routes.rb 2016-09-19 21:26:40 -04:00
ricky 7ca56ccd2e Update routes.rb 2016-09-19 20:27:26 -04:00
ricky 915a59afa4 Update issues_form_hook_listener.rb 2016-09-19 20:17:00 -04:00
ricky ac61950d48 Update routes.rb 2016-09-19 20:13:57 -04:00
ricky b257fef563 Update customers_controller.rb 2016-09-19 20:10:11 -04:00
ricky 504c27c197 Update qbo_invoice.rb 2016-09-19 11:10:26 -04:00
ricky a7a5e2c731 Update qbo_invoice.rb 2016-09-19 11:07:33 -04:00
ricky 21d72dcc33 Update qbo_invoice.rb 2016-09-19 11:06:35 -04:00
ricky da7ba40e61 Added Private Note Scanning
Also removed redundant checks
2016-09-19 10:59:20 -04:00
ricky b4d6fc55ea Update customers_controller.rb 2016-09-19 07:57:49 -04:00
ricky 515b8feff7 Update attachments_controller_patch.rb 2016-09-19 07:44:03 -04:00
ricky 8bc05db033 Update init.rb 2016-09-19 07:30:07 -04:00
ricky 34cd6b08dc Create attachments_controller_patch.rb 2016-09-19 07:29:16 -04:00
ricky 41195dc095 Update show.html.erb 2016-09-18 22:55:12 -04:00
ricky 33a83c8f76 Update _details.html.erb 2016-09-18 22:53:54 -04:00
ricky 4f613d3fe1 Update show.html.erb 2016-09-18 22:52:48 -04:00
ricky 1c7cdec600 Update show.html.erb 2016-09-18 22:41:24 -04:00
ricky 7ae60c0e62 Update show.html.erb 2016-09-18 22:38:26 -04:00
ricky 5dd04925e0 Update show.html.erb 2016-09-18 22:37:23 -04:00
ricky 92eedbd4d3 Update show.html.erb 2016-09-18 22:32:45 -04:00
ricky 5545d72adf Update view.html.erb 2016-09-16 23:11:59 -04:00
ricky 226d44cd28 Update customers_controller.rb 2016-09-16 23:10:21 -04:00
ricky b7152d6124 Update view.html.erb 2016-09-16 23:07:05 -04:00
ricky f3e9b58c87 Update customers_controller.rb 2016-09-16 23:06:20 -04:00
ricky 5209315236 Update view.html.erb 2016-09-16 23:05:23 -04:00
ricky f38a9e1ff0 Update view.html.erb 2016-09-16 23:04:47 -04:00
ricky 80fb296e24 Update customers_controller.rb 2016-09-16 23:03:07 -04:00
107 changed files with 1419 additions and 770 deletions
+6 -5
View File
@@ -1,12 +1,13 @@
source 'https://rubygems.org'
gem 'quickbooks-ruby'
gem 'quickbooks-ruby-base'
gem 'oauth-plugin'
gem 'oauth'
gem 'oauth2'
gem 'roxml'
gem 'edmunds_vin'
gem 'will_paginate', '~> 3.1.0'
gem 'nhtsa_vin'
gem 'will_paginate'
gem 'rails-jquery-autocomplete'
gem 'jquery-ui-rails'
gem 'faraday_middleware', '1.2.0'
group :assets do
gem 'coffee-rails'
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016 Rick Barrette
Copyright (c) 2022 Rick Barrette
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+10 -8
View File
@@ -1,14 +1,16 @@
#Redmine Quickbooks Online
# Redmine Quickbooks Online
A plugin for Redmine to connect to Quickbooks Online
The goal of this project is to allow Redmine to connect with Quickbooks Online to create `Time Activity Entries` for completed work when an Issue is closed.
`Note: Although the core functionality is complete, this project is still under heavy development. I am still working on refining everthing and adding other features. Tags should be stable`
#### Disclaimer
`Note: I am currently using this in a live production enviroment with no issues`
Note: Although the core functionality is complete, this project is still under heavy development. I am still working on refining everthing and adding other features. Tags should be stable
####Features
Also worth metioning I am currently using this in a live production enviroment with no issues
#### Features
* Issues can be assigned to a `Customer` via drop down in the edit Issue form
* The `Employee` for the Issue is assigned via the assigned Redmine User
- This is set via a drop down in the user admistration page.
@@ -27,14 +29,14 @@ The goal of this project is to allow Redmine to connect with Quickbooks Online t
+ `Invoice` Custom Fields are matched Issue Custom Fileds and are automaticly updated in Quickbooks. For example, this is usefull for extracting the Mileage In / Out from the Issue and updating the Invoice with the information.
- `Customers` are automaticly updated in local database
##Prerequisites
## Prerequisites
* Sign up to become a developer for Intuit https://developer.intuit.com/
* Create your own aplication to obtain your API keys
* Set up webhook service to https://redmine.yourdomain.com/qbo/webhook
- See https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/webhooks
##The Install
## The Install
1. To install, clone this repo into your plugin folder
@@ -73,11 +75,11 @@ Note: After the inital synchronization, this plugin will recieve push notificati
* Fix Issue sort by Customer
* MORE Stuff...
##License
## License
The MIT License (MIT)
Copyright (c) 2016 rick barrette
Copyright (c) 2020 rick barrette
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 106 KiB

+70 -25
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -11,7 +11,7 @@
# This controller class will handle map management
class CustomersController < ApplicationController
unloadable
include AuthHelper
helper :issues
helper :journals
@@ -26,12 +26,37 @@ class CustomersController < ApplicationController
helper :sort
include SortHelper
helper :timelog
before_filter :require_user, :except => :view
skip_before_filter :verify_authenticity_token, :check_if_login_required, :only => [:view]
before_action :add_customer, :only => :new
before_action :view_customer, :except => :new
skip_before_action :verify_authenticity_token, :check_if_login_required, :only => [:view]
default_search_scope :names
autocomplete :customer, :name, :full => true, :extra_data => [:id]
def allowed_params
params.require(:customer).permit(:name, :email, :primary_phone, :mobile_phone, :phone_number)
end
# getter method for a customer's vehicles
# used for customer autocomplete field / issue form
def filter_vehicles_by_customer
@filtered_vehicles = Vehicle.all.where(customer_id: params[:selected_customer])
end
# getter method for a customer's invoices
# used for customer autocomplete field / issue form
def filter_invoices_by_customer
@filtered_invoices = QboInvoice.all.where(customer_id: params[:selected_customer])
end
# getter method for a customer's estimates
# used for customer autocomplete field / issue form
def filter_estimates_by_customer
@filtered_estimates = QboEstimate.all.where(customer_id: params[:selected_customer])
end
# display a list of all customers
def index
if params[:search]
@@ -41,22 +66,24 @@ class CustomersController < ApplicationController
end
end
end
# initialize a new customer
def new
@customer = Customer.new
end
# create a new customer
def create
@customer = Customer.new(params[:customer])
@customer = Customer.new(allowed_params)
if @customer.save
flash[:notice] = "New Customer Created"
redirect_to @customer
else
flash[:error] = @customer.errors.full_messages.to_sentence
flash[:error] = @customer.errors.full_messages.to_sentence
redirect_to new_customer_path
end
end
# display a specific customer
def show
begin
@@ -67,7 +94,7 @@ class CustomersController < ApplicationController
render_404
end
end
# return an HTML form for editing a customer
def edit
begin
@@ -76,12 +103,12 @@ class CustomersController < ApplicationController
render_404
end
end
# update a specific customer
def update
begin
@customer = Customer.find_by_id(params[:id])
if @customer.update_attributes(params[:customer])
if @customer.update_attributes(allowed_params)
flash[:notice] = "Customer updated"
redirect_to @customer
else
@@ -92,7 +119,8 @@ class CustomersController < ApplicationController
render_404
end
end
# delete a customer
def destroy
begin
Customer.find_by_id(params[:id]).destroy
@@ -102,12 +130,17 @@ class CustomersController < ApplicationController
render_404
end
end
# Customer view for an issue
# displays an issue for a customer with a provided security CustomerToken
def view
token = CustomerToken.where("token = ? and expires_at > ?", params[:token], Time.now)
if token.first
@issue = Issue.find token.first.issue_id
User.current = User.find_by lastname: 'Anonymous'
@token = CustomerToken.where("token = ? and expires_at > ?", params[:token], Time.now)
@token = @token.first
if @token
session[:token] = @token.token
@issue = Issue.find @token.issue_id
@journals = @issue.journals.
preload(:details).
preload(:user => :email_address).
@@ -117,10 +150,10 @@ class CustomersController < ApplicationController
Journal.preload_journals_details_custom_fields(@journals)
@journals.select! {|journal| journal.notes? || journal.visible_details.any?}
@journals.reverse! if User.current.wants_comments_in_reverse_order?
@changesets = @issue.changesets.visible.preload(:repository, :user).to_a
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
@relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
@priorities = IssuePriority.active
@@ -130,9 +163,21 @@ class CustomersController < ApplicationController
render_403
end
end
private
# redmine permission - add customers
def add_customer
global_check_permission(:add_customers)
end
# redmine permission - view customers
def view_customer
global_check_permission(:view_customers)
end
# checks to see if there is only one item in an array
# @return true if array only has one item
def only_one_non_zero?( array )
found_non_zero = false
array.each do |val|
+24 -6
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -12,16 +12,34 @@ class EstimateController < ApplicationController
include AuthHelper
before_filter :require_user
before_action :require_user
#
# Downloads and forwards the estimate pdf
#
def show
base = QboEstimate.get_base.service
estimate = base.fetch_by_id(params[:id])
@pdf = base.pdf(estimate)
send_data @pdf, filename: "estimate #{estimate.doc_number}.pdf", :disposition => 'inline', :type => "application/pdf"
e = QboEstimate.find_by_id(params[:id]) if params[:id]
e = QboEstimate.find_by_doc_number(params[:search]) if params[:search]
begin
send_data e.pdf, filename: "estimate #{e.doc_number}.pdf", :disposition => 'inline', :type => "application/pdf"
rescue
redirect_to :back, :flash => { :error => "Estimate not found" }
end
end
#
# Downloads estimate by document number
#
def doc
e = QboEstimate.find_by_doc_number(params[:id]) if params[:id]
e = QboEstimate.find_by_doc_number(params[:search]) if params[:search]
begin
send_data e.pdf, filename: "estimate #{e.doc_number}.pdf", :disposition => 'inline', :type => "application/pdf"
rescue
redirect_to :back, :flash => { :error => "Estimate not found" }
end
end
end
+3 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -12,7 +12,8 @@ class InvoiceController < ApplicationController
include AuthHelper
before_filter :require_user
before_action :require_user, :unless => proc {|c| session[:token].nil? }
skip_before_action :verify_authenticity_token, :check_if_login_required, :unless => proc {|c| session[:token].nil? }
#
# Downloads and forwards the invoice pdf
+94
View File
@@ -0,0 +1,94 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# This controller class will handle map management
class LineItemsController < ApplicationController
unloadable
include AuthHelper
before_action :require_user
# display all line items for an issue
def index
if params[:issue_id]
begin
@line_items = Issue.find_by_id(params[:issue_id]).line_items
rescue ActiveRecord::RecordNotFound
render_404
end
end
end
# return an HTML form for creating a new line item
def new
@line_item = LineItem.new
end
# create a new line item
def create
@line_item = LineItem.new(params[:line_item])
if @line_item.save
flash[:notice] = "New Line Item Created"
redirect_to @line_item.issue
else
flash[:error] = @line_item.errors.full_messages.to_sentence
redirect_to new_line_item_path
end
end
# display a specific line item
def show
begin
@line_item = LineItem.find_by_id(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
end
# return an HTML form for editing a line item
def edit
begin
@line_item = LineItem.find_by_id(params[:id])
rescue ActiveRecord::RecordNotFound
render_404
end
end
# update a specific line item
def update
begin
@line_item = LineItem.find_by_id(params[:id])
if @line_item.update_attributes(params[:line_item])
flash[:notice] = "Line Item updated"
redirect_to @line_item
else
flash[:error] = @line_item.errors.full_messages.to_sentence if @line_item.errors
redirect_to edit_line_item_path
end
rescue ActiveRecord::RecordNotFound
render_404
end
end
# delete a specific line item
def destroy
begin
line_item = LineItem.find_by_id(params[:id])
issue = line_item.issue
line_item.destroy
flash[:notice] = "Line Item deleted successfully"
redirect_to issue
rescue ActiveRecord::RecordNotFound
render_404
end
end
end
+12 -6
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -12,16 +12,16 @@ class PaymentsController < ApplicationController
include AuthHelper
before_filter :require_user
before_action :check_permissions
def new
@payment = Payment.new
@customers = Customer.all.sort_by &:name
@accounts = Qbo.get_base(:account).service.query("SELECT Id, Name FROM Account WHERE AccountType = 'Bank' Order By Name")
@accounts = Qbo.get_base(:account).query("SELECT Id, Name FROM Account WHERE AccountType = 'Bank' Order By Name")
@payment_methods = Qbo.get_base(:payment_method).service.all
@payment_methods = Qbo.get_base(:payment_method).all
end
def create
@@ -32,10 +32,16 @@ class PaymentsController < ApplicationController
else
flash[:error] = @payment.errors.full_messages.to_sentence
redirect_to new_customer_path
end
end
end
private
def check_permissions
if !allowed_to?(:add_payments)
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
end
end
def only_one_non_zero?( array )
found_non_zero = false
+59 -31
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -15,8 +15,8 @@ class QboController < ApplicationController
include AuthHelper
before_filter :require_user, :except => :qbo_webhook
skip_before_filter :verify_authenticity_token, :check_if_login_required, :only => [:qbo_webhook]
before_action :require_user, :except => :qbo_webhook
skip_before_action :verify_authenticity_token, :check_if_login_required, :only => [:qbo_webhook]
#
# Called when the QBO Top Menu us shown
@@ -34,44 +34,61 @@ class QboController < ApplicationController
# Called when the user requests that Redmine to connect to QBO
#
def authenticate
callback = qbo_oauth_callback_url
token = Qbo.get_oauth_consumer.get_request_token(:oauth_callback => callback)
session[:qb_request_token] = Marshal.dump(token)
redirect_to("https://appcenter.intuit.com/Connect/Begin?oauth_token=#{token.token}") and return
oauth2_client = Qbo.get_client
callback = Setting.host_name + "/qbo/oauth_callback/"
#callback = qbo_oauth_callback_url
grant_url = oauth2_client.auth_code.authorize_url(redirect_uri: callback, response_type: "code", state: SecureRandom.hex(12), scope: "com.intuit.quickbooks.accounting")
redirect_to grant_url
end
#
# Called by QBO after authentication has been processed
#
def oauth_callback
at = Marshal.load(session[:qb_request_token]).get_access_token(:oauth_verifier => params[:oauth_verifier])
#There can only be one...
Qbo.destroy_all
# Save the authentication information
qbo = Qbo.new
qbo.qb_token = at.token
qbo.qb_secret = at.secret
qbo.token_expires_at = 6.months.from_now.utc
qbo.reconnect_token_at = 5.months.from_now.utc
qbo.company_id = params['realmId']
if qbo.save!
redirect_to qbo_sync_path, :flash => { :notice => "Successfully connected to Quickbooks" }
else
redirect_to plugin_settings_path(:redmine_qbo), :flash => { :error => "Error" }
if params[:state].present?
oauth2_client = Qbo.get_client
# use the state value to retrieve from your backend any information you need to identify the customer in your system
#redirect_uri = qbo_oauth_callback_url
redirect_uri = Setting.host_name + "/qbo/oauth_callback/"
if resp = oauth2_client.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
# Remove the last authentication information
Qbo.delete_all
# Save the authentication information
qbo = Qbo.new
qbo.company_id = params[:realmId]
# Generate Access Token & Serialize it into the database
access_token = OAuth2::AccessToken.new(oauth2_client, resp.token, refresh_token: resp.refresh_token)
qbo.token = access_token.to_hash
qbo.expire = 1.hour.from_now.utc
if qbo.save!
redirect_to qbo_sync_path, :flash => { :notice => "Successfully connected to Quickbooks" }
else
redirect_to plugin_settings_path(:redmine_qbo), :flash => { :error => "Error" }
end
end
end
end
# Manual Billing
def bill
i = Issue.find_by_id params[:id]
i.bill_time
redirect_to i, :flash => { :notice => "Successfully Billed #{i.customer.name}" }
if i.customer
i.bill_time
redirect_to i, :flash => { :notice => "Successfully Billed #{i.customer.name}" }
else
redirect_to i, :flash => { :error => "Cannot bill without a customer assigned" }
end
end
# Quickbooks Webhook Callback
def qbo_webhook
logger.debug "Quickbooks is calling webhook"
# check the payload
signature = request.headers['intuit-signature']
@@ -95,10 +112,12 @@ class QboController < ApplicationController
# TODO rename all other models!
name.prepend("Qbo") if not name.eql? "Customer"
logger.debug "Casting #{name.constantize} to obj"
# Magicly initialize the correct class
obj = name.constantize
# for merge events
obj.destroy(entity['deletedId']) if entity['deletedId']
@@ -107,7 +126,13 @@ class QboController < ApplicationController
obj.destroy(id)
#if not then update!
else
obj.sync_by_id(id)
begin
obj.sync_by_id(id)
rescue => e
logger.error "Failed to call sync_by_id on obj"
logger.error e.message
logger.error e.backtrace.join("\n")
end
end
end
@@ -119,20 +144,23 @@ class QboController < ApplicationController
else
render nothing: true, status: 400
end
logger.debug "Quickbooks webhook complete"
end
#
# Synchronizes the QboCustomer table with QBO
#
def sync
logger.debug "Syncing EVERYTHING"
# Update info in background
Thread.new do
if Qbo.exists?
Customer.sync
QboInvoice.sync
QboItem.sync
QboEmployee.sync
QboEstimate.sync
QboInvoice.sync
# Record the last sync time
Qbo.update_time_stamp
@@ -140,6 +168,6 @@ class QboController < ApplicationController
ActiveRecord::Base.connection.close
end
redirect_to qbo_path(:redmine_qbo), :flash => { :notice => "Successfully synced to Quickbooks" }
redirect_to :home, :flash => { :notice => "Successfully synced to Quickbooks" }
end
end
+30 -32
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -11,11 +11,15 @@
# This controller class will handle map management
class VehiclesController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
before_action :require_user
def allowed_params
params.require(:vehicle).permit(:year, :make, :model, :customer_id, :notes, :vin)
end
# display a list of all vehicles
def index
if params[:customer_id]
@@ -25,7 +29,8 @@ class VehiclesController < ApplicationController
render_404
end
end
# search for a vehicle by vin
if params[:search]
@vehicles = Vehicle.search(params[:search]).paginate(:page => params[:page])
if only_one_non_zero?(@vehicles)
@@ -37,58 +42,58 @@ class VehiclesController < ApplicationController
# return an HTML form for creating a new vehicle
def new
@vehicle = Vehicle.new
@customers = Customer.all.order(:name)
@customer = params[:customer_id] if params[:customer_id]
@customer = Customer.find_by_id(params[:customer_id]) if params[:customer_id]
end
# create a new vehicle
def create
@vehicle = Vehicle.new(params[:vehicle])
@vehicle = Vehicle.new(allowed_params)
if @vehicle.save
flash[:notice] = "New Vehicle Created"
redirect_to @vehicle
else
flash[:error] = @vehicle.errors.full_messages.to_sentence
redirect_to new_vehicle_path
flash[:error] = @vehicle.errors.full_messages.to_sentence
redirect_to Vehicle.find_by_vin @vehicle.vin
end
end
# display a specific vehicle
def show
begin
@vehicle = Vehicle.find_by_id(params[:id])
@vin = @vehicle.vin.scan(/.{1,9}/) if @vehicle.vin
rescue ActiveRecord::RecordNotFound
render_404
end
end
# return an HTML form for editing a vehicle
def edit
begin
@vehicle = Vehicle.find_by_id(params[:id])
@customer = @vehicle.customer.id
@customers = Customer.all.order(:name)
@customer = @vehicle.customer
rescue ActiveRecord::RecordNotFound
render_404
end
end
# update a specific vehicle
def update
@customer = params[:customer]
begin
begin
@vehicle = Vehicle.find_by_id(params[:id])
if @vehicle.update_attributes(params[:vehicle])
if @vehicle.update_attributes(allowed_params)
flash[:notice] = "Vehicle updated"
redirect_to @vehicle
else
flash[:error] = @vehicle.errors.full_messages.to_sentence if @vehicle.errors
redirect_to edit_vehicle_path
end
#show any errors anyways
flash[:error] = @vehicle.errors.full_messages.to_sentence unless @vehicle.errors.empty?
rescue ActiveRecord::RecordNotFound
render_404
end
end
end
# delete a specific vehicle
def destroy
@@ -100,18 +105,11 @@ class VehiclesController < ApplicationController
render_404
end
end
# returns a dynamic list of vehicles owned by a customer
def update_vehicles
@vehicles = Customer.find_by(customer_id: params[:customer_id].to_i).vehicles
respond_to do |format|
format.html { render(:text => "not implemented") }
format.js
end
end
private
# checks to see if there is only one item in an array
# @return true if array only has one item
def only_one_non_zero?( array )
found_non_zero = false
array.each do |val|
@@ -123,4 +121,4 @@ class VehiclesController < ApplicationController
found_non_zero
end
end
end
+36 -1
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2017 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -11,8 +11,43 @@
module AuthHelper
def require_user
return unless session[:token].nil?
if !User.current.logged?
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
end
end
def allowed_to?(action)
return false if User.current.nil?
project = Project.find(params[:project_id])
return false if project.nil?
return true if User.current.allowed_to?(action, project)
false
end
def check_permission(permission)
if !allowed_to?(permission)
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
end
end
def global_check_permission(permission)
if !globaly_allowed_to?(permission)
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
end
end
def globaly_allowed_to?( action)
return false if User.current.nil?
projects = Project.all
projects.each { |p|
if User.current.allowed_to?(action, p)
return true
end
}
false
end
end
+32 -18
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -13,9 +13,11 @@ class Customer < ActiveRecord::Base
has_many :issues
has_many :qbo_purchases
has_many :qbo_invoices
has_many :qbo_estimates
has_many :vehicles
attr_accessible :name, :notes, :email, :primary_phone, :mobile_phone
#attr_accessible :name, :notes, :email, :primary_phone, :mobile_phone, :phone_number
validates_presence_of :id, :name
self.primary_key = :id
@@ -61,6 +63,8 @@ class Customer < ActiveRecord::Base
pn = Quickbooks::Model::TelephoneNumber.new
pn.free_form_number = n
@details.primary_phone = pn
#update our locally stored number too
update_phone_number
end
# Convenience Method
@@ -81,6 +85,26 @@ class Customer < ActiveRecord::Base
pn = Quickbooks::Model::TelephoneNumber.new
pn.free_form_number = n
@details.mobile_phone = pn
#update our locally stored number too
update_mobile_phone_number
end
# update the localy stored phone number as a plain string with no special chars
def update_phone_number
begin
self.phone_number = self.primary_phone.tr('^0-9', '')
rescue
return nil
end
end
# update the localy stored phone number as a plain string with no special chars
def update_mobile_phone_number
begin
self.mobile_phone_number = self.mobile_phone.tr('^0-9', '')
rescue
return nil
end
end
# Convenience Method
@@ -112,7 +136,7 @@ class Customer < ActiveRecord::Base
# proforms a bruteforce sync operation
# This needs to be simplified
def self.sync
service = Qbo.get_base(:customer).service
service = Qbo.get_base(:customer)
# Sync ALL customers if the database is empty
#if count == 0
@@ -140,26 +164,16 @@ class Customer < ActiveRecord::Base
end
end
# Searchs the database for a customer by name
# Searchs the database for a customer by name or phone number with out special chars
def self.search(search)
customers = where("name LIKE ?", "%#{search}%")
#if customers.empty?
# service = Qbo.get_base(:customer).service
# results = service.query("Select Id From Customer Where PrimaryPhone LIKE '%#{search}%' AND Mobile LIKE '%#{search}%'")
# results.each do |customer|
# customers << Customer.find_by_id(customer.id)
# end
#end
customers = where("name LIKE ? OR phone_number LIKE ? OR mobile_phone_number LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
return customers.order(:name)
end
# proforms a bruteforce sync operation
# This needs to be simplified
def self.sync_by_id(id)
service = Qbo.get_base(:customer).service
service = Qbo.get_base(:customer)
customer = service.fetch_by_id(id)
qbo_customer = Customer.find_or_create_by(id: customer.id)
@@ -179,7 +193,7 @@ class Customer < ActiveRecord::Base
# Push the updates
def save_with_push
begin
@details = Qbo.get_base(:customer).service.update(@details)
@details = Qbo.get_base(:customer).update(@details)
#raise "QBO Fault" if @details.fault?
self.id = @details.id
rescue Exception => e
@@ -197,7 +211,7 @@ class Customer < ActiveRecord::Base
def pull
begin
raise Exception unless self.id
@details = Qbo.get_base(:customer).find_by_id(self.id)
@details = Qbo.get_base(:customer).fetch_by_id(self.id)
rescue Exception => e
@details = Quickbooks::Model::Customer.new
end
+3 -3
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -11,11 +11,11 @@
class CustomerToken < ActiveRecord::Base
unloadable
has_many :issues
attr_accessible :token, :expires_at, :issue_id
#attr_accessible :token, :expires_at, :issue_id
validates_presence_of :expires_at, :issue_id
before_create :generate_token
OAUTH_CONSUMER_SECRET = Setting.plugin_redmine_qbo['settingsOAuthConsumerSecret']
OAUTH_CONSUMER_SECRET = Setting.plugin_redmine_qbo['settingsOAuthConsumerSecret'] || 'CONFIGURE_QBO__' + SecureRandom.uuid
def generate_token
self.token = SecureRandom.base64(15).tr('+/=lIO0', OAUTH_CONSUMER_SECRET)
+34
View File
@@ -0,0 +1,34 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class LineItem < ActiveRecord::Base
unloadable
belongs_to :issue
#attr_accessible :amount, :description, :unit_price, :quantity, :item_id
validates_presence_of :amount, :description, :unit_price, :quantity
def add_to_invoice(invoice)
line_item = Quickbooks::Model::InvoiceLineItem.new
line_item.amount = amount
line_item.description = description
line_item.sales_item! do |detail|
detail.unit_price = unit_price
detail.quantity = quantity
detail.item_id = item_id # Item ID here... Where do i get this???
end
invoice.line_items << line_item
return invoice
end
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2020 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -23,7 +23,7 @@ class Payment
payment.deposit_to_account_id = @account_id.to_i
payment.payment_method_id = @payment_method_id.to_i
payment.total = @total_amount
Qbo.get_base(:payment).service.update(payment)
Qbo.get_base(:payment).update(payment)
end
def save!
+60 -18
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2020 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -10,34 +10,76 @@
class Qbo < ActiveRecord::Base
unloadable
validates_presence_of :qb_token, :qb_secret, :company_id, :token_expires_at, :reconnect_token_at
#validates_presence_of :qb_token, :qb_secret, :company_id, :token_expires_at, :reconnect_token_at
validates_presence_of :token, :company_id, :expire
serialize :token
OAUTH_CONSUMER_KEY = Setting.plugin_redmine_qbo['settingsOAuthConsumerKey']
OAUTH_CONSUMER_SECRET = Setting.plugin_redmine_qbo['settingsOAuthConsumerSecret']
$qb_oauth_consumer = OAuth::Consumer.new(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, {
:site => "https://oauth.intuit.com",
:request_token_path => "/oauth/v1/get_request_token",
:authorize_url => "https://appcenter.intuit.com/Connect/Begin",
:access_token_path => "/oauth/v1/get_access_token"
})
# Configure quickbooks-ruby-base to access our database
Quickbooks::Base.configure do |c|
c.persistent_token = 'qb_token'
c.persistent_secret = 'qb_secret'
c.persistent_company_id = 'company_id'
#
# Getter for quickbooks OAuth2 client
#
def self.get_client
oauth_params = {
site: "https://appcenter.intuit.com/connect/oauth2",
authorize_url: "https://appcenter.intuit.com/connect/oauth2",
token_url: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
}
return OAuth2::Client.new(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, oauth_params)
end
#
# Getter for oauth consumer
#
def self.get_oauth_consumer
# Quickbooks Config Info
return $qb_oauth_consumer
end
# Get a quickbooks base object for type
#
# Get a quickbooks base service object for type
# @params type of base
#
def self.get_base(type)
Quickbooks::Base.new(first, type)
# lets getnourbold access token from the database
oauth2_client = get_client
qbo = self.first
access_token = OAuth2::AccessToken.from_hash(oauth2_client, qbo.token)
# check to see if we need to refresh the acesstoken
if qbo.expire.to_time.utc.past?
puts "Updating access token"
new_access_token_object = access_token.refresh!
qbo.token = new_access_token_object.to_hash
qbo.expire = 1.hour.from_now.utc
qbo.save!
access_token = new_access_token_object
else
puts "Using current token"
end
# build the reqiested service
case type
when :item
return Quickbooks::Service::Item.new(:company_id => qbo.company_id, :access_token => access_token)
when :time_activity
return Quickbooks::Service::TimeActivity.new(:company_id => qbo.company_id, :access_token => access_token)
when :customer
return Quickbooks::Service::Customer.new(:company_id => qbo.company_id, :access_token => access_token)
when :invoice
return Quickbooks::Service::Invoice.new(:company_id => qbo.company_id, :access_token => access_token)
when :estimate
return Quickbooks::Service::Estimate.new(:company_id => qbo.company_id, :access_token => access_token)
when :account
return Quickbooks::Service::Account.new(:company_id => qbo.company_id, :access_token => access_token)
when :employee
return Quickbooks::Service:: Employee.new(:company_id => qbo.company_id, :access_token => access_token)
else
return access_token
end
end
# Get the QBO account
+4 -4
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -11,7 +11,7 @@
class QboEmployee < ActiveRecord::Base
unloadable
has_many :users
attr_accessible :name
#attr_accessible :name
validates_presence_of :id, :name
def self.get_base
@@ -19,7 +19,7 @@ class QboEmployee < ActiveRecord::Base
end
def self.sync
employees = get_base.service.all
employees = get_base.all
transaction do
# Update the item table
@@ -33,7 +33,7 @@ class QboEmployee < ActiveRecord::Base
end
def self.sync_by_id(id)
employee = get_base.service.fetch_by_id(id)
employee = get_base.fetch_by_id(id)
qbo_employee = find_or_create_by(id: employee.id)
qbo_employee.name = employee.display_name
qbo_employee.id = employee.id
+38 -25
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -10,44 +10,57 @@
class QboEstimate < ActiveRecord::Base
unloadable
has_many :issues
attr_accessible :doc_number
validates_presence_of :id, :doc_number
has_and_belongs_to_many :issues
belongs_to :customer
#attr_accessible :doc_number, :id
validates_presence_of :doc_number, :id
self.primary_key = :id
# return the QBO Estimate service
def self.get_base
Qbo.get_base(:estimate)
end
# sync all estimates
def self.sync
estimates = get_base.service.all
# Update the item table
transaction do
estimates.each { |estimate|
qbo_estimate = QboEstimate.find_or_create_by(id: estimate.id)
qbo_estimate.doc_number = estimate.doc_number
qbo_estimate.id = estimate.id
qbo_estimate.save!
}
end
estimates = get_base.all
estimates.each { |estimate|
process_estimate(estimate)
}
#remove deleted estimates
where.not(estimates.map(&:id)).destroy_all
end
# sync only one estimate
def self.sync_by_id(id)
estimate = get_base.service.fetch_by_id(id)
qbo_estimate = QboEstimate.find_or_create_by(id: estimate.id)
process_estimate(get_base.fetch_by_id(id))
end
# update an estimate
def self.update(id)
# Update the item table
estimate = get_base.fetch_by_id(id)
qbo_estimate = find_or_create_by(id: id)
qbo_estimate.doc_number = estimate.doc_number
qbo_estimate.id = estimate.id
qbo_estimate.save!
end
def self.update(id)
# Update the item table
estimate = get_base.service.fetch_by_id(id)
qbo_estimate = QboEstimate.find_or_create_by(id: id)
qbo_estimate.doc_number = estimate.doc_number
qbo_estimate.save!
# process an estimate into the database
def self.process_estimate(estimate)
qbo_estimate = find_or_create_by(id: estimate.id)
qbo_estimate.doc_number = estimate.doc_number
qbo_estimate.customer_id = estimate.customer_ref.value
qbo_estimate.id = estimate.id
qbo_estimate.save!
end
# download the pdf from quickbooks
def pdf
base = QboEstimate.get_base
estimate = base.fetch_by_id(id)
return base.pdf(estimate)
end
end
+110 -76
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -12,16 +12,18 @@ class QboInvoice < ActiveRecord::Base
unloadable
has_and_belongs_to_many :issues
attr_accessible :doc_number, :id
belongs_to :customer
#attr_accessible :doc_number, :id
validates_presence_of :doc_number, :id
self.primary_key = :id
def self.get_base
Qbo.get_base(:invoice).service
Qbo.get_base(:invoice)
end
# sync ALL the invoices
def self.sync
logger.debug "Syncing all invoices"
last = Qbo.first.last_sync
query = "SELECT Id, DocNumber FROM Invoice"
@@ -41,94 +43,126 @@ class QboInvoice < ActiveRecord::Base
#sync by invoice ID
def self.sync_by_id(id)
logger.debug "Syncing invoice #{id}"
#update the information in the database
invoice = get_base.fetch_by_id(id)
process_invoice invoice
end
private
# Attach the invoice to the issue
def self.attach_to_issue(issue, invoice)
return if issue.nil?
# skip this issue if the issue customer is not the same as the invoice customer
return if issue.customer_id != invoice.customer_ref.value.to_i
logger.debug "Attaching invoice #{invoice.id} to issue #{issue.id}"
# Load the invoice into the database
qbo_invoice = QboInvoice.find_or_create_by(id: invoice.id)
qbo_invoice.doc_number = invoice.doc_number
qbo_invoice.id = invoice.id
qbo_invoice.customer_id = invoice.customer_ref
qbo_invoice.save!
unless issue.qbo_invoices.include?(qbo_invoice)
issue.qbo_invoices << qbo_invoice
issue.save!
end
compare_custom_fields(issue, invoice)
end
# processes the invoice into the system
def self.process_invoice(invoice)
is_changed = false
logger.debug "Processing invoice"
# Check the private notes
if not invoice.private_note.nil?
invoice.private_note.scan(/#(\w+)/).flatten.each { |issue|
attach_to_issue(Issue.find_by_id(issue.to_i), invoice)
}
end
# Scan the line items for hashtags and attach to the applicable issues
invoice.line_items.each { |line|
if line.description
line.description.scan(/#(\w+)/).flatten.each { |issue|
i = Issue.find_by_id(issue.to_i)
# Load the invoice into the database
qbo_invoice = QboInvoice.find_or_create_by(id: invoice.id)
qbo_invoice.doc_number = invoice.doc_number
qbo_invoice.id = invoice.id
qbo_invoice.save!
# Attach the invoice to the issue
unless i.qbo_invoices.include?(qbo_invoice)
i.qbo_invoices << qbo_invoice
i.save!
end
# update the invoive custom fields with infomation from the work ticket if available
invoice.custom_fields.each { |cf|
# VIN from the attached vehicle
begin
if cf.name.eql? "VIN"
vin = Vehicle.find(i.vehicles_id).vin
break if vin.nil?
if not cf.string_value.to_s.eql? vin
cf.string_value = vin.to_s
is_changed = true
break
end
end
rescue
#do nothing
end
# Custom Values
begin
value = i.custom_values.find_by(custom_field_id: CustomField.find_by_name(cf.name).id)
# Check to see if the value is blank...
if not value.value.to_s.blank?
# Check to see if the value is diffrent
if not cf.string_value.to_s.eql? value.value.to_s
# Use the lowest Milage
if cf.name.eql? "Mileage In"
if cf.string_value.to_i > value.value.to_i or cf.string_value.blank?
cf.string_value = value.value.to_s
is_changed = true
end
break
end
# Use the max milage
if cf.name.eql? "Mileage Out"
if cf.string_value.to_i < value.value.to_i or cf.string_value.blank?
cf.string_value = value.value.to_s
is_changed = true
end
break
end
# Everything else
cf.string_value = value.value.to_s
is_changed = true
end
end
rescue
# Nothing to do here, there is no match
end
}
attach_to_issue(Issue.find_by_id(issue.to_i), invoice)
}
end
}
# Push updates
get_base.update(invoice) if is_changed
end
def self.compare_custom_fields(issue, invoice)
is_changed = false
# update the invoive custom fields with infomation from the work ticket if available
invoice.custom_fields.each { |cf|
# TODO Add some hooks here
# VIN from the attached vehicle
begin
if cf.name.eql? "VIN"
vin = Vehicle.find(issue.vehicles_id).vin
break if vin.nil?
if not cf.string_value.to_s.eql? vin
cf.string_value = vin.to_s
logger.debug "VIN has changed"
is_changed = true
end
end
rescue
#do nothing
end
# Custom Values
begin
value = issue.custom_values.find_by(custom_field_id: CustomField.find_by_name(cf.name).id)
# Check to see if the value is blank...
if not value.value.to_s.blank?
# Check to see if the value is diffrent
if not cf.string_value.to_s.eql? value.value.to_s
# Use the lowest Milage
if cf.name.eql? "Mileage In"
if cf.string_value.to_i > value.value.to_i or cf.string_value.blank?
cf.string_value = value.value.to_s
is_changed = true
end
# Use the max milage
elsif cf.name.eql? "Mileage Out"
if cf.string_value.to_i < value.value.to_i or cf.string_value.blank?
cf.string_value = value.value.to_s
is_changed = true
end
else
# Everything else
cf.string_value = value.value.to_s
is_changed = true
end
end
end
rescue
# Nothing to do here, there is no match
end
}
# TODO Add some hooks here
# Push updates
#invoice.sync_token += 1 if is_changed
begin
logger.debug "Trying to update invoice"
get_base.update(invoice) if is_changed
rescue
# Do nothing, probaly too many vehicles on the invoice. This is a problem with how it's billed
# TODO Add notes in memo area
logger.error "Failed to update invoice"
end
end
end
+4 -4
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -11,7 +11,7 @@
class QboItem < ActiveRecord::Base
unloadable
has_many :issues
attr_accessible :name
#attr_accessible :name
validates_presence_of :id, :name
self.primary_key = :id
@@ -27,9 +27,9 @@ class QboItem < ActiveRecord::Base
query << " AND Metadata.LastUpdatedTime >= '#{last.iso8601}' " if last
if count == 0
items = get_base.service.all
items = get_base.all
else
items = get_base.service.query(query)
items = get_base.query(query)
end
unless items.count = 0
+4 -4
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -12,7 +12,7 @@ class QboPurchase < ActiveRecord::Base
unloadable
belongs_to :issues
belongs_to :qbo_customer
attr_accessible :description
#attr_accessible :description
validates_presence_of :id, :line_id, :description, :qbo_customer_id
def self.get_base
@@ -20,11 +20,11 @@ class QboPurchase < ActiveRecord::Base
end
def get_purchase(id)
get_base.service.find_by_id(id)
get_base.find_by_id(id)
end
def self.sync
QboPurchase.get_base.service.all.each { |purchase|
QboPurchase.get_base.all.each { |purchase|
purchase.line_items.all? { |line_item|
+43 -48
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -12,36 +12,39 @@ class Vehicle < ActiveRecord::Base
unloadable
API_KEY = Setting.plugin_redmine_qbo['settingsEdmundsAPIKey']
belongs_to :customer
has_many :issues, :foreign_key => 'vehicles_id'
attr_accessible :year, :make, :model, :customer_id, :notes, :vin
#attr_accessible :year, :make, :model, :customer_id, :notes, :vin
validates_presence_of :customer
validates :vin, uniqueness: true
#validates :year, numericality: { only_integer: true }
before_save :decode_vin
after_initialize :get_details
#after_find :get_details
self.primary_key = :id
# returns a human readable string
def to_s
return "#{year} #{make} #{model}"
if year.nil? or make.nil? or model.nil?
return "#{vin}"
else
split_vin = vin.scan(/.{1,9}/)
return "#{year} #{make} #{model} - #{split_vin[1]}"
end
end
# returns the raw JSON details from EMUNDS
def details
get_details if @details.nil?
return @details
end
# returns the style of the vehicle
def style
get_details if @details.nil?
begin
return @details['years'][0]['styles'][0]['name'] if @details
return @details.trim if @details
rescue
return nil
end
@@ -49,21 +52,24 @@ class Vehicle < ActiveRecord::Base
# returns the drive of the vehicle i.e. 2 wheel, 4 wheel, ect.
def drive
return @details['drivenWheels'].to_s.upcase if @details
#todo fix this
#return @details.drive_type if @details
return nil
end
# returns the number of doors of the vehicle
def doors
return @details['numOfDoors'] if @details
get_details if @details.nil?
return @details.doors if @details
end
# Force Upper Case for VIN numbers
# Force Upper Case for make numbers
def make=(val)
# The to_s is in case you get nil/non-string
write_attribute(:make, val.to_s.titleize)
end
# Force Upper Case for VIN numbers
# Force Upper Case for model numbers
def model=(val)
# The to_s is in case you get nil/non-string
write_attribute(:model, val.to_s.titleize)
@@ -71,44 +77,24 @@ class Vehicle < ActiveRecord::Base
# Force Upper Case for VIN numbers
def vin=(val)
# The to_s is in case you get nil/non-string
write_attribute(:vin, val.to_s.scan(/^[A-Za-z0-9]+$/).join.upcase)
#strip VIN of all illegal chars (for barcode scanner)
val = val.to_s.upcase.gsub(/[^A-HJ-NPR-Za-hj-npr-z\d]+/,"")
write_attribute(:vin, val)
end
# search for a vin
def self.search(search)
where("vin LIKE ?", "%#{search}%")
end
private
# init method to pull JSON details from Edmunds
def get_details
if self.vin?
begin
@details = JSON.parse get_decoder.full(self.vin)
raise @details['message'] if @details['status'].to_s.eql? "NOT_FOUND"
raise @details['message'] if @details['status'].to_s.eql? "BAD_REQUEST"
rescue Exception => e
errors.add(:vin, e.message)
end
end
end
# returns the Edmunds decoder service
def get_decoder
#TODO API Code via Settings
return decoder = Edmunds::Vin.new(API_KEY)
end
# decodes a vin and updates self
def decode_vin
get_details
if @details
begin
self.year = @details['years'][0]['year']
self.make = @details['make']['name']
self.model = @details['model']['name']
self.year = @details.year unless @details.year.nil?
self.make = @details.make unless @details.make.nil?
self.model = @details.model unless @details.model.nil?
rescue Exception => e
errors.add(:vin, e.message)
end
@@ -116,15 +102,24 @@ class Vehicle < ActiveRecord::Base
self.name = to_s
end
# makes a squishvin
# https://api.edmunds.com/api/vehicle/v2/squishvins/#{vin}/?fmt=json&api_key=#{ENV['edmunds_key']}
def vin_squish
if not self.vin? or self.vin.size < 11
# this is to go ahead and query the API, letting them handle the error. :P
return '1000000000A'
private
# init method to pull JSON details from Edmunds
def get_details
if self.vin?
#validate the vin before calling a remote server
validation = NhtsaVin.validate(self.vin)
begin
#if the vin validation failed, raise an exception and exit
raise RuntimeError, validation.error unless validation.valid?
# query NHTSA for details on the vin
query = NhtsaVin.get(self.vin)
raise RuntimeError, query.error unless query.valid?
@details = query.response
rescue Exception => e
errors.add(:vin, e.message)
end
end
v = self.vin[0,11]
return v.slice(0,8) + v.slice(9,11)
end
end
+10 -15
View File
@@ -1,58 +1,53 @@
<table>
<tbody>
<tr>
<th>Customer</th>
<td><%= customer.name %></td>
</tr>
<tr>
<th>Email</th>
<th><%=t(:label_email)%></th>
<td><%= customer.email %></td>
</tr>
<tr>
<th>Primary Phone</th>
<th><%=t(:label_primary_phone)%></th>
<td><%= number_to_phone(customer.primary_phone.gsub(/[^\d]/, '').to_i, area_code: true) if customer.primary_phone %></td>
</tr>
<tr>
<th>Mobile Phone</th>
<th><%=t(:label_mobile_phone)%></th>
<td><%= number_to_phone(customer.mobile_phone.gsub(/[^\d]/, '').to_i, area_code: true) if customer.mobile_phone %></td>
</tr>
<tr>
<th>Bill Address</th>
<th><%=t(:label_billing_address)%></th>
<td><%= customer.billing_address %></td>
</tr>
<tr>
<th>Shipping Address</th>
<th><%=t(:label_shipping_address)%></th>
<td><%= customer.shipping_address %></td>
</tr>
<tr>
<th>Issues</th>
<th><%=t(:issues)%></th>
<td><%= customer.issues.count %></td>
</tr>
<tr>
<th>Account Balance</th>
<th><%=t(:label_account_balance)%></th>
<td>$<%= customer.balance %></td>
</tr>
<tr>
<th>Balance With Jobs</th>
<th><%=t(:label_balance_with_jobs)%></th>
<td>$<%= customer.balance_with_jobs %></td>
</tr>
<tr>
<th>Notes</th>
<th><%=t(:field_notes)%></th>
<td><%= customer.notes %></td>
</tr>
<tr>
<td>
<%= button_to "Edit Customer", edit_customer_path(customer), method: :get%>
<%= button_to t(:label_edit_customer), edit_customer_path(customer), method: :get%>
</td>
</tr>
</tbody>
+5 -5
View File
@@ -5,35 +5,35 @@
<%= form_for @customer do |f| %>
<div class="clearfix">
Display Name:
<%=t(:label_display_name)%>
<div class="input">
<%= f.text_field :name, :required => true %>
</div>
</div>
<div class="clearfix">
Phone Number:
<%=t(:label_primary_phone)%>
<div class="input">
<%= f.telephone_field :primary_phone %>
</div>
</div>
<div class="clearfix">
Mobile Phone Number:
<%=t(:label_mobile_phone)%>:
<div class="input">
<%= f.telephone_field :mobile_phone %>
</div>
</div>
<div class="clearfix">
Email:
<%=t(:label_email)%>:
<div class="input">
<%= f.email_field :email %>
</div>
</div>
<div class="clearfix">
Notes:
<%=t(:field_notes)%>:
<div class="input">
<p>
<%= link_to_function content_tag(:span, l(:button_edit), :class => 'icon icon-edit'), '$(this).hide(); $("#issue_description_and_toolbar").show()' unless @customer.new_record? %>
+6
View File
@@ -0,0 +1,6 @@
<%= form_tag(customers_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: t(:label_search_customers) %>
<%= submit_tag t(:label_search) %>
<% end %>
<%= button_to t(:label_new_customer), new_customer_path, method: :get%>
<%= button_to t(:label_sync), qbo_sync_path, method: :get%>
+2
View File
@@ -0,0 +1,2 @@
<h3><%=t(:label_customers)%></h3>
<%= render :partial => 'customers/search' %>
+1 -1
View File
@@ -1,3 +1,3 @@
<h1>Edit Customer</h1>
<h1><%=t(:label_edit_customer)%></h1>
<br/>
<%= render :partial => 'customers/form' %>
@@ -0,0 +1 @@
$('select#issue_qbo_estimate_id').html('<%= j content_tag(:option,'',:value=>"")+options_from_collection_for_select(@filtered_estimates, :id, :doc_number) %>');
@@ -0,0 +1 @@
$('select#issue_vehicles_id').html('<%= j content_tag(:option,'',:value=>"")+options_from_collection_for_select(@filtered_vehicles, :id, :to_s) %>');
+5 -9
View File
@@ -1,10 +1,4 @@
<h1>Customers</h1>
<br/>
<%= form_tag(customers_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search Customers" %>
<%= submit_tag "Search" %>
<% end %>
<br/>
<h2><%=t(:field_customers)%> <span style="float:right"> <%= render :partial => 'customers/search' %> </span> </h2>
<% if @customers.present? %>
<br/>
<% @customers.each do |c| %>
@@ -15,14 +9,16 @@
</div>
<% end %>
<p><%=t(:label_matching)%> <%= @customers.count %> <%=t(:field_customers)%> </p>
<div class="actions">
<%= will_paginate @customers %>
</div>
<% else %>
<p>There are no customers containing the term(s) <%= params[:search] %>.</p>
<p><%=t(:label_no_customers)%> <%= params[:search] %>.</p>
<% end %>
<div>
<%= Customer.count %> Customers - <b>Last Sync: </b> <%= Qbo.last_sync if Qbo.exists? %>
<%= render :partial => 'qbo/stats' %>
</div>
+1 -1
View File
@@ -1,3 +1,3 @@
<h1>New Customer</h1>
<h2><%=t(:label_new_customer)%></h2>
<br/>
<%= render :partial => 'customers/form' %>
+28 -12
View File
@@ -1,12 +1,28 @@
<h1>Customer #<%= @customer.id %></h1>
<br/>
<h2>Details:</h2>
<%= render :partial => 'customers/details', locals: {customer: @customer} %>
<br/>
<h2>Vehicles:</h2>
<%= render :partial => 'vehicles/list' %>
<%= button_to "New Vehicle", new_customer_vehicle_path(@customer), method: :get %>
<br/>
<br/>
<h2>Issues:</h2>
<%= render :partial => 'issues/list_simple', locals: {issues: @issues} %>
<h2><%=t(:field_customer)%> #<%= @customer.id %> - <%= @customer.name %> </h2>
<br/>
<div class="subject">
<div><h3><%=t(:label_details)%>:</h3></div>
</div>
<div class="attributes">
<div class="splitcontent">
<div class="splitcontentleft">
<%= render :partial => 'customers/details', locals: {customer: @customer} %>
</div>
<div class="splitcontentleft">
<h4><%=t(:field_vehicles)%>:</h4>
<%= render :partial => 'vehicles/list' %>
<%= button_to "New Vehicle", new_customer_vehicle_path(@customer), method: :get %>
</div>
</div>
<br/>
<h2><%=t(:label_open_issues)%>:</h2>
<%= render :partial => 'issues/list_simple', locals: {issues: @issues.open} %>
<h2><%=t(:label_closed_issues)%>:</h2>
<%= render :partial => 'issues/list_simple', locals: {issues: (@issues - @issues.open)} %>
</div>
+4 -3
View File
@@ -6,6 +6,7 @@
<div class="subject">
<%= render_issue_subject_with_tree(@issue) %>
<%=t(:label_customer_link_expires)%> <%= distance_of_time_in_words(Time.now, @token.expires_at) %>
</div>
<p class="author">
<%= authoring @issue.created_on, @issue.author %>.
@@ -41,13 +42,13 @@
rows.right l(:field_estimated_hours), issue_estimated_hours_details(@issue), :class => 'estimated-hours'
end
end
if User.current.allowed_to_view_all_time_entries?(@project)
#if User.current.allowed_to_view_all_time_entries?(@project)
if @issue.total_spent_hours > 0
rows.right l(:label_spent_time), issue_spent_hours_details(@issue), :class => 'spent-time'
end
end
#end
end %>
<%= render_custom_fields_rows(@issue) %>
<%= render_full_width_custom_fields_rows(@issue) %>
<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
</div>
+4
View File
@@ -0,0 +1,4 @@
<%= form_tag("/qbo/estimate/doc", :method => "get", id: "est-search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: t(:label_search_estimates) %>
<%= submit_tag t(:label_search), :formtarget => "_blank" %>
<% end %>
+2
View File
@@ -0,0 +1,2 @@
<h3><%=t(:label_estimates) %></h3>
<%= render :partial => 'estimates/search' %>
+29
View File
@@ -0,0 +1,29 @@
<% if issues && issues.any? %>
<%= form_tag({}) do %>
<table class="list issues">
<thead><tr>
<th>#</th>
<th><%=l(:field_project)%></th>
<th><%=l(:field_tracker)%></th>
<th><%=l(:field_subject)%></th>
</tr></thead>
<tbody>
<% for issue in issues %>
<tr id="issue-<%= h(issue.id) %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>">
<td class="id">
<%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %>
<%= link_to(issue.id, issue_path(issue)) %>
</td>
<td class="project"><%= link_to_project(issue.project) %></td>
<td class="tracker"><%= issue.tracker %></td>
<td class="subject">
<%= link_to(issue.subject.truncate(60), issue_path(issue)) %> (<%= issue.status %>)
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>
+4 -4
View File
@@ -5,28 +5,28 @@
<%= form_for @payment do |f| %>
<div class="clearfix">
Customer:
<%=t(:field_customer)%>:
<div class="input">
<%= f.collection_select :customer_id, @customers, :id, :name, include_blank: true, :selected => @customer, :required => true%>
</div>
</div>
<div class="clearfix">
Deposit to Account:
<%=t(:label_deposit_into)%>:
<div class="input">
<%= f.collection_select :account_id, @accounts, :id, :name, include_blank: true, :selected => @account, :required => true%>
</div>
</div>
<div class="clearfix">
Payment Method:
<%=t(:label_payment_method)%>:
<div class="input">
<%= f.collection_select :payment_method_id, @payment_methods, :id, :name, include_blank: true, :selected => @payment_method, :required => true%>
</div>
</div>
<div class="clearfix">
Amount:
<%=t(:label_amount)%>:
<div class="input">
<%= f.number_field :total_amount %>
</div>
+1 -1
View File
@@ -1,3 +1,3 @@
<h1>New Payment</h1>
<h1><%=t(:label_new_payment)%></h1>
<br/>
<%= render :partial => 'payments/form' %>
+1 -1
View File
@@ -1 +1 @@
<%= flash.now[:error] = "Not Authorized" %>
<%= flash.now[:error] = t(:label_401) %>
@@ -0,0 +1,35 @@
<div class="splitcontent">
<div class="splitcontentleft">
<div class="customer_id attribute">
<div class="label"><span><%=t(:field_customer)%></span>:</div>
<div class="value"><%= customer %></div>
</div>
<div class="qbo_estimate_id attribute">
<div class="label"><span><%=t(:field_qbo_estimate)%></span>:</div>
<div class="value"><%= estimate_link %></div>
</div>
<div class="qbo_invoice_id attribute">
<div class="label"><span><%=t(:field_qbo_invoice)%></span>:</div>
<div class="value"><%= invoice_link %></div>
</div>
</div>
<div class="splitcontentleft">
<div class="vehicle attribute">
<div class="label"><span><%=t(:field_vehicle)%></span>:</div>
<div class="value"><%= vehicle %></div>
</div>
<div class="vehicle_vin attribute">
<div class="label"><span><%=t(:field_vin)%></span>:</div>
<div class="value"><%=split_vin[0] if split_vin%><b><%=split_vin[1] if split_vin%></b></div>
</div>
<div class="vehicle_notes attribute">
<div class="label"><span><%=t(:field_notes)%></span>:</div>
<div class="value"><%=notes%></div>
</div>
</div>
</div>
+1
View File
@@ -0,0 +1 @@
<b><%=t(:label_last_sync)%>: </b> <%= Qbo.last_sync if Qbo.exists? %>
+14 -27
View File
@@ -1,7 +1,7 @@
<!--
The MIT License (MIT)
Copyright (c) 2016 rick barrette
Copyright (c) 2020 rick barrette
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
@@ -15,22 +15,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
<!-- configure the Intuit object: 'grantUrl' is a URL in your application which kicks off the flow, see below -->
<script>
intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_authenticate_url %>'});
intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= Setting.host_name %>/qbo/authenticate'});
</script>
<table >
<tbody>
<tr>
<th>Edmunds API Key</th>
<td>
<input type="text" style="width:350px" id="settingsEdmundsAPIKey"
value="<%= settings['settingsEdmundsAPIKey'] %>"
name="settings[settingsEdmundsAPIKey]" >
</td>
</tr>
<tr>
<th>Intuit QBO OAuth Consumer Key</th>
<th><%=t(:label_client_id)%></th>
<td>
<input type="text" style="width:350px" id="settingsOAuthConsumerKey"
value="<%= settings['settingsOAuthConsumerKey'] %>"
@@ -39,7 +31,7 @@ intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_au
</tr>
<tr>
<th>Intuit QBO OAuth Consumer Secret</th>
<th><%=t(:label_client_secret)%></th>
<td>
<input type="text" style="width:350px" id="settingsOAuthConsumerSecret"
value="<%= settings['settingsOAuthConsumerSecret'] %>"
@@ -48,7 +40,7 @@ intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_au
</tr>
<tr>
<th>Intuit QBO Webhook Token</th>
<th><%=t(:label_webhook_token)%></th>
<td>
<input type="text" style="width:350px" id="settingsWebhookToken"
value="<%= settings['settingsWebhookToken'] %>"
@@ -57,20 +49,15 @@ intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_au
</tr>
<tr>
<th>Token Expires At</th>
<td><%= if Qbo.exists? then Qbo.first.token_expires_at end %>
</tr>
<tr>
<th>Reconnect Token At</th>
<td><%= if Qbo.exists? then Qbo.first.reconnect_token_at end %>
<th><%=t(:label_oauth_expires)%></th>
<td><%= if Qbo.exists? then Qbo.first.expire end %>
</tr>
</tbody>
</table>
<br/>
Note: You need to authenticate after saving your key and secret above
<%=t(:label_oauth_note)%>
<br/>
<br/>
@@ -81,27 +68,27 @@ Note: You need to authenticate after saving your key and secret above
<br/>
<div>
<b>Customer Count:</b> <%= Customer.count%>
<b><%=t(:label_customer_count)%>:</b> <%= Customer.count%>
</div>
<div>
<b>Item Count:</b> <%= QboItem.count %>
<b><%=t(:label_item_count)%>:</b> <%= QboItem.count %>
</div>
<div>
<b>Employee Count:</b> <%= QboEmployee.count %>
<b><%=t(:label_employee_count)%>:</b> <%= QboEmployee.count %>
</div>
<div>
<b>Invoice Count:</b> <%= QboInvoice.count %>
<b><%=t(:label_invoice_count)%>:</b> <%= QboInvoice.count %>
</div>
<div>
<b>Estimate Count:</b> <%= QboEstimate.count %>
<b><%=t(:label_estimate_count)%>:</b> <%= QboEstimate.count %>
</div>
<br/>
<div>
<b>Last Sync: </b> <%= Qbo.last_sync if Qbo.exists? %> <%= link_to " Sync Now", qbo_sync_path %>
<b><%=t(:label_last_sync)%> </b> <%= Qbo.last_sync if Qbo.exists? %> <%= link_to " Sync Now", qbo_sync_path %>
</div>
+2
View File
@@ -0,0 +1,2 @@
<%= render :partial => 'customers/sidebar' %>
<%= render :partial => 'estimates/sidebar' %>
+1
View File
@@ -0,0 +1 @@
<%= Customer.count %> <%=t(:field_customers)%> - <%= render :partial => 'qbo/last_sync' %>
+7 -7
View File
@@ -11,32 +11,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-->
<body>
<h1> Redmine Quickbooks</h1>
<h1><%=t(:label_redmine_qbo)%></h1>
<div>
<b>Customer Count:</b> <%= @customer_count.to_s%>
<b><%=t(:label_customer_count)%>:</b> <%= @customer_count.to_s%>
</div>
<div>
<b>Item Count:</b> <%= @qbo_item_count.to_s %>
<b><%=t(:label_item_count)%>:</b> <%= @qbo_item_count.to_s %>
</div>
<div>
<b>Employee Count:</b> <%= @qbo_employee_count.to_s %>
<b><%=t(:label_employee_count)%>:</b> <%= @qbo_employee_count.to_s %>
</div>
<div>
<b>Invoice Count:</b> <%= @qbo_invoice_count.to_s %>
<b><%=t(:label_invoice_count)%>:</b> <%= @qbo_invoice_count.to_s %>
</div>
<div>
<b>Estimate Count:</b> <%= @qbo_estimate_count.to_s %>
<b><%=t(:label_estimate_count)%>:</b> <%= @qbo_estimate_count.to_s %>
</div>
<br/>
<div>
<b>Last Sync: </b> <%= Qbo.last_sync if Qbo.exists? %>
<b><%=t(:label_last_sync)%>: </b> <%= Qbo.last_sync if Qbo.exists? %>
</div>
</body>
+8 -26
View File
@@ -2,52 +2,34 @@
<tbody>
<tr>
<th>Customer</th>
<th><%= t(:field_customer)%></th>
<td><%= link_to vehicle.customer.name, customer_path(vehicle.customer) %></td>
</tr>
<tr>
<th>Vehicle</th>
<th><%= t(:field_vehicle) %></th>
<td><%= vehicle.to_s %></td>
</tr>
<tr>
<th>VIN</th>
<td><%= vehicle.vin %></td>
<th><%= t(:field_vin) %></th>
<td><%= @vin[0] if @vin %><b><%=@vin[1] if @vin%></b></td>
</tr>
<tr>
<th>Style</th>
<td><%= vehicle.style %></td>
</tr>
<tr>
<th>Drive</th>
<td><%= vehicle.drive %></td>
</tr>
<tr>
<th>Doors</th>
<td><%= vehicle.doors %></td>
</tr>
<tr>
<th>Notes</th>
<th><%= t(:field_notes) %></th>
<td><%= vehicle.notes %></td>
</tr>
<tr>
<th>Issues</th>
<th> <%= t(:issues) %> </th>
<td><%= vehicle.issues.count %></td>
</tr>
<tr>
<td/>
<td>
<%= button_to "New Issue", new_issue_path(:vehicle_id => vehicle.id, :customer_id => vehicle.customer.id), method: :get%>
<%= button_to "Edit", edit_vehicle_path(vehicle), method: :get%>
<%= button_to "Delete", vehicle, method: :delete, data: {confirm: "You sure?"} %>
<%= button_to t(:label_edit), edit_vehicle_path(vehicle), method: :get%>
<%= button_to t(:label_delete), vehicle, method: :delete, data: {confirm: t(:warn_ru_sure)} %>
</td>
</tr>
</tbody>
+11 -17
View File
@@ -4,51 +4,45 @@
<%= form_for @vehicle do |f| %>
<div class="clearfix">
Customer:
<div class="input">
<%= f.collection_select :customer_id, @customers, :id, :name, include_blank: true, :selected => @customer, :required => true%>
</div>
<%=t(:field_customer)%>:
<div class="input">
<%= f.autocomplete_field :customer, autocomplete_customer_name_customers_path, :value => @customer.name, :update_elements => {:id => '#customer_id', :value => '#issue_customer'}, :required => true %>
<%= f.hidden_field :customer_id, :id => "customer_id", :value => @customer.id %>
</div>
</div>
<div class="clearfix">
Year:
<%=t(:label_year)%>:
<div class="input">
<%= f.number_field :year %>
</div>
</div>
<div class="clearfix">
Make:
<%=t(:label_make)%>:
<div class="input">
<%= f.text_field :make %>
</div>
</div>
<div class="clearfix">
Model:
<%=t(:label_model)%>:
<div class="input">
<%= f.text_field :model %>
</div>
</div>
<div class="clearfix">
VIN:
<%=t(:field_vin)%>:
<div class="input">
<%= f.text_field :vin , :autofocus => true %>
</div>
</div>
<div class="clearfix">
Notes:
<%=t(:field_notes)%>:
<div class="input">
<p>
<%= content_tag 'span', :id => "issue_description_and_toolbar", :style => (@vehicle.new_record? ? nil : 'display:none') do %>
<%= f.text_area :notes,
:cols => 60,
:rows => 10,
:no_label => true %>
<% end %>
</p>
<%= f.text_area :notes, :cols => 60, :rows => 10, :no_label => true %>
</div>
</div>
+3 -1
View File
@@ -21,6 +21,8 @@
<%= will_paginate @vehicles %>
</div>
<p><%=t(:label_matching)%> <%=@vehicles.count%> <%=t(:field_vehicles) %> </p>
<% else %>
<p>There are no vehicles containing the term(s) <%= params[:search] %>.</p>
<p><%=t(:label_no_vehicles)%> <%= params[:search] %>.</p>
<% end %>
+4
View File
@@ -0,0 +1,4 @@
<%= form_tag(vehicles_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: t(:label_seach_vin) %>
<%= submit_tag t(:label_search) %>
<% end %>
+1 -1
View File
@@ -1,3 +1,3 @@
<h1>Edit Customer Vehicle</h1>
<h1><%=t(:label_edit_customer_vehicle)%></h1>
<br/>
<%= render :partial => 'vehicles/form' %>
+1 -6
View File
@@ -1,9 +1,4 @@
<h1>Customer Vehicles</h1>
<h2><%=t(:label_cusomer_vehicles)%> <span style="float:right"> <%= render :partial => 'vehicles/search' %> </span> </h2>
<br/>
<%= form_tag(vehicles_path, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search Vehicles by VIN" %>
<%= submit_tag "Search" %>
<% end %>
<%= render :partial => 'vehicles/list' %>
+1 -1
View File
@@ -1,3 +1,3 @@
<h1>New Customer Vehicle</h1>
<h2><%=t(:label_new_vehicle)%></h2>
<br/>
<%= render :partial => 'vehicles/form' %>
+9 -3
View File
@@ -1,8 +1,14 @@
<h1>Vehicle #<%=@vehicle.id%> </h1>
<br/>
<h2><%=t(:field_vehicle)%> #<%=@vehicle.id%> <span style="float:right"> <%= render :partial => 'customers/search' %> </span> </h2>
<br/>
<div style="text-align: left; width:90%;">
<%= render :partial => 'vehicles/details', locals: {vehicle: @vehicle} %>
<%= render :partial => 'issues/list_simple', locals: {issues: @vehicle.issues} %>
<p> <b> <%=t(:label_open_issues)%> </b> </p>
<%= render :partial => 'issues/list_simple', locals: {issues: @vehicle.issues.open} %>
<p> <b> <%=t(:label_closed_issues)%> </b> </p>
<%= render :partial => 'issues/list_simple', locals: {issues: (@vehicle.issues - @vehicle.issues.open)} %>
</div>
+23
View File
@@ -0,0 +1,23 @@
$(function() {
$("input#issue_customer_id").on("change", function() {
$.ajax({
url: "/filter_vehicles_by_customer",
type: "GET",
data: { selected_customer: $("input#issue_customer_id").val() }
});
$.ajax({
url: "/filter_estimates_by_customer",
type: "GET",
data: { selected_customer: $("input#issue_customer_id").val() }
});
});
$("input#project_customer_id").on("change", function() {
$.ajax({
url: "/filter_vehicles_by_customer",
type: "GET",
data: { selected_customer: $("input#project_customer_id").val() }
});
});
});
+1
View File
@@ -0,0 +1 @@
!function(t){t.fn.railsAutocomplete=function(e){var a=function(){this.railsAutoCompleter||(this.railsAutoCompleter=new t.railsAutocomplete(this))};if(void 0!==t.fn.on){if(!e)return;return t(document).on("focus",e,a)}return this.live("focus",a)},t.railsAutocomplete=function(t){var e=t;this.init(e)},t.railsAutocomplete.options={showNoMatches:!0,noMatchesLabel:"no existing match"},t.railsAutocomplete.fn=t.railsAutocomplete.prototype={railsAutocomplete:"0.0.1"},t.railsAutocomplete.fn.extend=t.railsAutocomplete.extend=t.extend,t.railsAutocomplete.fn.extend({init:function(e){function a(t){return t.split(e.delimiter)}function i(t){return a(t).pop().replace(/^\s+/,"")}e.delimiter=t(e).attr("data-delimiter")||null,e.min_length=t(e).attr("data-min-length")||t(e).attr("min-length")||2,e.append_to=t(e).attr("data-append-to")||null,e.autoFocus=t(e).attr("data-auto-focus")||!1,t(e).autocomplete({appendTo:e.append_to,autoFocus:e.autoFocus,delay:t(e).attr("delay")||0,source:function(a,r){var n=this.element[0],o={term:i(a.term)};t(e).attr("data-autocomplete-fields")&&t.each(t.parseJSON(t(e).attr("data-autocomplete-fields")),function(e,a){o[e]=t(a).val()}),t.getJSON(t(e).attr("data-autocomplete"),o,function(){var a={};t.extend(a,t.railsAutocomplete.options),t.each(a,function(i,r){if(a.hasOwnProperty(i)){var n=t(e).attr("data-"+i);a[i]=n?n:r}}),0==arguments[0].length&&t.inArray(a.showNoMatches,[!0,"true"])>=0&&(arguments[0]=[],arguments[0][0]={id:"",label:a.noMatchesLabel}),t(arguments[0]).each(function(a,i){var r={};r[i.id]=i,t(e).data(r)}),r.apply(null,arguments),t(n).trigger("railsAutocomplete.source",arguments)})},change:function(e,a){if(t(this).is("[data-id-element]")&&""!==t(t(this).attr("data-id-element")).val()&&(t(t(this).attr("data-id-element")).val(a.item?a.item.id:"").trigger("change"),t(this).attr("data-update-elements"))){var i=t.parseJSON(t(this).attr("data-update-elements")),r=a.item?t(this).data(a.item.id.toString()):{};if(i&&""===t(i.id).val())return;for(var n in i){var o=t(i[n]);o.is(":checkbox")?null!=r[n]&&o.prop("checked",r[n]):o.val(a.item?r[n]:"").trigger("change")}}},search:function(){var t=i(this.value);return t.length<e.min_length?!1:void 0},focus:function(){return!1},select:function(i,r){if(r.item.value=r.item.value.toString(),-1!=r.item.value.toLowerCase().indexOf("no match")||-1!=r.item.value.toLowerCase().indexOf("too many results"))return t(this).trigger("railsAutocomplete.noMatch",r),!1;var n=a(this.value);if(n.pop(),n.push(r.item.value),null!=e.delimiter)n.push(""),this.value=n.join(e.delimiter);else if(this.value=n.join(""),t(this).attr("data-id-element")&&t(t(this).attr("data-id-element")).val(r.item.id).trigger("change"),t(this).attr("data-update-elements")){var o=r.item,l=-1!=r.item.value.indexOf("Create New")?!0:!1,u=t.parseJSON(t(this).attr("data-update-elements"));for(var s in u)"checkbox"===t(u[s]).attr("type")?o[s]===!0||1===o[s]?t(u[s]).attr("checked","checked"):t(u[s]).removeAttr("checked"):l&&o[s]&&-1==o[s].indexOf("Create New")||!l?t(u[s]).val(o[s]).trigger("change"):t(u[s]).val("").trigger("change")}var c=this.value;return t(this).bind("keyup.clearId",function(){t.trim(t(this).val())!=t.trim(c)&&(t(t(this).attr("data-id-element")).val("").trigger("change"),t(this).unbind("keyup.clearId"))}),t(e).trigger("railsAutocomplete.select",r),!1}}),t(e).trigger("railsAutocomplete.init")}}),t(document).ready(function(){t("input[data-autocomplete]").railsAutocomplete("input[data-autocomplete]")})}(jQuery);
@@ -1,2 +0,0 @@
$("#issue_vehicles_id").empty()
.append("<%= escape_javascript(render(:partial => @vehicles)) %>")
-10
View File
@@ -1,10 +0,0 @@
function customerSelected() {
customer_id = $('issue_customer_id').getValue();
console.log(customer_id);
}
document.observe('dom:loaded', function() {
customerSelected();
$('issue_customer_id').observe('change', customerSelected);
});
-3
View File
@@ -1,3 +0,0 @@
Edmunds::Api.configure do |config|
config.api_key = '2dheutzvhxs28dzukx5tgu47'
end
+55 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -9,6 +9,7 @@
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# English strings go here for Rails i18n
# Usage t(:label)
en:
# my_label: "My label"
field_customer: "Customer"
@@ -16,8 +17,60 @@ en:
field_qbo_employee: "Employee"
field_qbo_invoice: "Invoice"
field_qbo_estimate: "Estimate"
field_vehicles: "Vehicle"
field_vehicles: "Vehicles"
field_vehicle: "Vehicle"
field_vin: "VIN"
field_notes: "Notes"
field_qbo_billed: "Billed"
label_week: "Week"
label_search_estimates: "Search Estimates"
label_search: "Search"
label_estimates: "Estimates"
label_401: "Not Authorized"
warn_ru_sure: "You sure?"
label_delete: "Delete"
label_edit: "Edit"
label_year: "Year"
label_make: " Make"
label_model: "Model"
label_no_vehicles: "There are no vehicles containing the term(s)"
label_no_customers: "There are no customers containing the term(s)"
label_matching: "Matching "
label_search_vin: "Search Vehicles by VIN"
label_edit_customer_vehicle: "Edit Customer Vehicle"
label_cusomer_vehicles: "Customer Vehicles"
label_new_vehicle: "New Customer Vehicle"
label_open_issues: "Open Issues"
label_closed_issues: "Closed Issues"
label_sync: "Sync"
label_new_customer: "New Customer"
label_search_customers: "Search Customers"
label_customers: "Customers"
label_edit_customer: "Edit Customer"
label_email: "Email"
label_primary_phone: "Primary Phone"
label_mobile_phone: "Mobile Phone"
label_billing_address: "Billing Address"
label_shipping_address: "Shipping Address"
label_account_balance: "Account Balance"
label_balance_with_jobs: "Balance With Jobs"
label_display_name: "Display Name"
label_details: "Details"
label_customer_link_expires: "This customer link expires in"
label_new_payment: "New Payment"
label_amount: "Amount"
label_payment_method: "Payment Method"
label_deposit_into: "Deposit to Account"
label_last_sync: "Last Sync"
label_redmine_qbo: "Redmine Quickbooks"
label_customer_count: "Customer Count"
label_invoice_count: "Invoice Count"
label_estimate_count: "Estimate Count"
label_item_count: "Item Count"
label_employee_count: "Employee Count"
label_client_id: "Intuit QBO OAuth2 Client ID"
label_client_secret: "Intuit QBO OAuth2 Client Secret"
label_webhook_token: "Intuit QBO Webhook Token"
label_oauth_expires: "OAuth2 Access Token Expires At"
label_oauth_note: "Note: You need to authenticate with Quickbooks after saving your key and secret above"
field_customers: "Customers"
+9 -3
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2017 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -20,6 +20,7 @@ get 'qbo/sync', :to => 'qbo#sync'
# Estimate & Invoice PDF
get 'qbo/estimate/:id', :to => 'estimate#show', as: :estimate
get 'qbo/estimate/doc/:id', :to => 'estimate#doc', as: :estimate_doc
get 'qbo/invoice/:id', :to => 'invoice#show', as: :invoice
#manual billing
@@ -34,13 +35,18 @@ resources :payments
#webhook
post 'qbo/webhook', :to => 'qbo#qbo_webhook'
#ajax
get "update_vehicles" => 'vehicles#update_vehicles', as: 'update_vehicles'
#java script routes
get 'filter_vehicles_by_customer' => 'customers#filter_vehicles_by_customer'
get 'filter_estimates_by_customer' => 'customers#filter_estimates_by_customer'
get 'filter_invoices_by_customer' => 'customers#filter_invoices_by_customer'
# Nest Vehicles under customers
resources :customers do
resources :vehicles
get :autocomplete_customer_name, :on => :collection
end
#allow for just vehicles too
resources :vehicles
#resources :qbo_estimates
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateQbos < ActiveRecord::Migration
class CreateQbos < ActiveRecord::Migration[5.1]
def change
create_table :qbos do |t|
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateQboCustomers < ActiveRecord::Migration
class CreateQboCustomers < ActiveRecord::Migration[5.1]
def change
create_table :qbo_customers, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateIssues < ActiveRecord::Migration
class UpdateIssues < ActiveRecord::Migration[5.1]
def change
add_reference :issues, :qbo_customer, index: true
add_reference :issues, :qbo_item, index: true
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateQboItems < ActiveRecord::Migration
class CreateQboItems < ActiveRecord::Migration[5.1]
def change
create_table :qbo_items, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateQboEmployees < ActiveRecord::Migration
class CreateQboEmployees < ActiveRecord::Migration[5.1]
def change
create_table :qbo_employees, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateUsers < ActiveRecord::Migration
class UpdateUsers < ActiveRecord::Migration[5.1]
def change
add_reference :users, :qbo_employee, index: true
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateTimeEntries < ActiveRecord::Migration
class UpdateTimeEntries < ActiveRecord::Migration[5.1]
def change
add_column :time_entries, :qbo_billed, :boolean, :default => false
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateQboEstimates < ActiveRecord::Migration
class CreateQboEstimates < ActiveRecord::Migration[5.1]
def change
create_table :qbo_estimates, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateQbos < ActiveRecord::Migration
class UpdateQbos < ActiveRecord::Migration[5.1]
def change
rename_column :qbos, :token, :qb_token
rename_column :qbos, :secret, :qb_secret
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateIssuesWithEstimates < ActiveRecord::Migration
class UpdateIssuesWithEstimates < ActiveRecord::Migration[5.1]
def change
add_reference :issues, :qbo_estimate, index: true
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateQboInvoices < ActiveRecord::Migration
class CreateQboInvoices < ActiveRecord::Migration[5.1]
def change
create_table :qbo_invoices, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateIssuesWithInvoices< ActiveRecord::Migration
class UpdateIssuesWithInvoices< ActiveRecord::Migration[5.1]
def change
add_reference :issues, :qbo_invoice, index: true
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateQboPurchases< ActiveRecord::Migration
class CreateQboPurchases< ActiveRecord::Migration[5.1]
def change
create_table :qbo_purchases, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateCustomers < ActiveRecord::Migration
class UpdateCustomers < ActiveRecord::Migration[5.1]
def change
add_reference :qbo_customers, :qbo_purchase, index: true
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateQboPurchases < ActiveRecord::Migration
class UpdateQboPurchases < ActiveRecord::Migration[5.1]
def change
rename_column :qbo_purchases, :customer_id, :qbo_customer_id
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateVehicles < ActiveRecord::Migration
class CreateVehicles < ActiveRecord::Migration[5.1]
def change
create_table :vehicles do |t|
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateIssuesWithVehicles < ActiveRecord::Migration
class UpdateIssuesWithVehicles < ActiveRecord::Migration[5.1]
def change
add_reference :issues, :vehicles, index: true
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateVehicles < ActiveRecord::Migration
class UpdateVehicles < ActiveRecord::Migration[5.1]
def change
add_column :vehicles, :name, :text
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class QbocustomersToCustomers< ActiveRecord::Migration
class QbocustomersToCustomers< ActiveRecord::Migration[5.1]
def change
rename_table :qbo_customers, :customers
rename_column :issues, :qbo_customer_id, :customer_id
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateQbosTimeStamp < ActiveRecord::Migration
class UpdateQbosTimeStamp < ActiveRecord::Migration[5.1]
def change
add_column :qbos, :last_sync, :datetime
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class AddIssuesQboInvoices < ActiveRecord::Migration
class AddIssuesQboInvoices < ActiveRecord::Migration[5.1]
def self.up
create_table :issues_qbo_invoices, :id => false do |t|
t.references :issue
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateIssuesRemoveInvoice < ActiveRecord::Migration
class UpdateIssuesRemoveInvoice < ActiveRecord::Migration[5.1]
def change
remove_reference :issues, :qbo_invoice
end
+2 -2
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -8,7 +8,7 @@
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateCustomerTokens < ActiveRecord::Migration
class CreateCustomerTokens < ActiveRecord::Migration[5.1]
def change
create_table :customer_tokens do |t|
t.string :token
@@ -0,0 +1,16 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateInvoicesAndEstimates < ActiveRecord::Migration[5.1]
def change
add_reference :qbo_invoices, :customer, index: true
add_reference :qbo_estimates, :customer, index: true
end
end
+16
View File
@@ -0,0 +1,16 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateProjects < ActiveRecord::Migration[5.1]
def change
add_reference :projects, :customer, index: true
add_reference :projects, :vehicle, index: true
end
end
+26
View File
@@ -0,0 +1,26 @@
#The License
#
#Copyright (c) 2022 Rick Barrette - All Rights Reserved
#
#Unauthorized copying of this software and associated documentation files (the "Software"), via any medium is strictly prohibited.
#
#Proprietary and confidential
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class CreateLineItems < ActiveRecord::Migration[5.1]
def change
create_table :line_items do |t|
t.integer :item_id
t.float :amount
t.string :description
t.float :unit_price
t.float :quantity
t.boolean :billed
end
add_reference :line_items, :issues, index: true
end
end
@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class AddCustomersPhoneNumber < ActiveRecord::Migration[5.1]
def change
add_column :customers, :phone_number, :string
end
end
@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class AddCustomersMobilePhoneNumber < ActiveRecord::Migration[5.1]
def change
add_column :customers, :mobile_phone_number, :string
end
end
+17
View File
@@ -0,0 +1,17 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateQbosTypes < ActiveRecord::Migration[5.1]
def change
change_column :qbos, :qb_token, :text
change_column :qbos, :qb_secret, :text
end
end
+17
View File
@@ -0,0 +1,17 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class UpdateQbosToken < ActiveRecord::Migration[5.1]
def change
add_column :qbos, :token, :text
add_column :qbos, :expire, :datetime
end
end
+18
View File
@@ -0,0 +1,18 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class RemoveQbosKeys < ActiveRecord::Migration[5.1]
def change
remove_column :qbos, :qb_secret
remove_column :qbos, :token_expires_at
remove_column :qbos, :reconnect_token_at
remove_column :qbos, :qb_token
end
end
+22 -21
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -16,26 +16,27 @@ Redmine::Plugin.register :redmine_qbo do
require_dependency 'issues_show_hook_listener'
require_dependency 'users_show_hook_listener'
require_dependency 'header_footer_hook_listener'
require_dependency 'projects_form_hook_listener'
require_dependency 'view_hook_listener'
# Patches to the Redmine core. Will not work in development mode
require_dependency 'issue_patch'
require_dependency 'project_patch'
require_dependency 'user_patch'
require_dependency 'query_patch'
require_dependency 'time_entry_query_patch'
require_dependency 'pdf_patch'
Rails.configuration.to_prepare do
Redmine::Search.available_search_types << 'customers'
end
require_dependency 'attachments_controller_patch'
# About
name 'Redmine Quickbooks Online plugin'
author 'Rick Barrette'
description 'This is a plugin for Redmine to intergrate with Quickbooks Online to allow for seamless intergration CRM and invoicing of completed issues'
version '0.4.1'
version '1.0.0'
url 'https://github.com/rickbarrette/redmine_qbo'
author_url 'http://rickbarrette.org'
settings :default => {'empty' => true}, :partial => 'qbo/settings'
# Add safe attributes
Issue.safe_attributes 'customer_id'
Issue.safe_attributes 'qbo_item_id'
@@ -44,24 +45,24 @@ Redmine::Plugin.register :redmine_qbo do
Issue.safe_attributes 'vehicles_id'
User.safe_attributes 'qbo_employee_id'
TimeEntry.safe_attributes 'qbo_billed'
Project.safe_attributes 'customer_id'
Project.safe_attributes 'vehicle_id'
# We are playing in the sandbox
#Quickbooks.sandbox_mode = true
# set per_page globally
WillPaginate.per_page = 10
WillPaginate.per_page = 20
# Permissions for security
permission :view_customers, :customers => :index, :public => false
permission :add_customers, :customers => :new, :public => false
permission :view_payments, :payments => :index, :public => false
permission :add_payments, :payments => :new, :public => false
permission :view_vehicles, :payments => :new, :public => false
# Register QBO top menu item
#menu :top_menu, :qbo, { :controller => :qbo, :action => :index }, :caption => 'Quickbooks', :if => Proc.new { User.current.admin? }
menu :top_menu, :customers, { :controller => :customers, :action => :index }, :caption => 'Customers', :if => Proc.new { User.current.logged? }
menu :top_menu, :customers, { :controller => :customers, :action => :index }, :caption => 'Customers', :if => Proc.new {User.current.logged?}
menu :top_menu, :vehicles, { :controller => :vehicles, :action => :index }, :caption => 'Vehicles', :if => Proc.new { User.current.logged? }
menu :application_menu, :new_customer, { :controller => :customers, :action => :new }, :caption => 'New Customer', :if => Proc.new { User.current.logged? }
menu :application_menu, :new_payment, { :controller => :payments, :action => :new }, :caption => 'New Payment', :if => Proc.new { User.current.logged? }
permission :customers, { :customers => [:index, :new] }, :public => false
menu :project_menu, :customers, { :controller => 'customers', :action => 'new' }, :caption => 'New Customer', :after => :new_issue, :param => :project_id
permission :payments, { :payments => [:index, :new] }, :public => false
menu :project_menu, :payments, { :controller => 'payments', :action => 'new' }, :caption => 'New Payment', :after => :customers, :param => :project_id
end
+38
View File
@@ -0,0 +1,38 @@
#The MIT License (MIT)
#
#Copyright (c) 2017 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
require_dependency 'attachments_controller'
module AttachmentsControllerPatch
def self.included(base) # :nodoc:
base.extend(ClassMethods)
base.send(:include, InstanceMethods)
# Same as typing in the class
base.class_eval do
unloadable # Send unloadable so it will not be unloaded in development
skip_before_action :read_authorize
end
end
module ClassMethods
end
module InstanceMethods
end
end
# Add module to AttachmentsController
AttachmentsController.send(:include, AttachmentsControllerPatch)
+1 -1
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2017 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
+19 -9
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2020 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -41,38 +41,48 @@ module IssuePatch
# Create billable time entries
def bill_time
# Check to see if we have everything we need to bill the customer
#return unless status.is_closed?
return if assigned_to.nil?
return unless Qbo.first
return unless customer
# Get unbilled time entries
spent_time = time_entries.where(qbo_billed: [false, nil])
spent_hours ||= spent_time.sum(:hours) || 0
if spent_hours > 0 then
# Prepare to create a new Time Activity
time_service = Qbo.get_base(:time_activity).service
item_service = Qbo.get_base(:item).service
time_service = Qbo.get_base(:time_activity)
item_service = Qbo.get_base(:item)
time_entry = Quickbooks::Model::TimeActivity.new
# Lets total up each activity before billing.
# This will simpify the invoicing with a single billable time entry per time activity
h = Hash.new(0)
spent_time.each do |entry|
# Lets tottal up each activity
h[entry.activity.name] += entry.hours
# update time entries billed status
entry.qbo_billed = true
entry.save
end
# Now letes upload our totals for each activity as their own billable time entry
h.each do |key, val|
# Convert float spent time to hours and minutes
hours = val.to_i
minutesDecimal = (( val - hours) * 60)
minutes = minutesDecimal.to_i
# Lets match the activity to an qbo item
item = item_service.query("SELECT * FROM Item WHERE Name = '#{key}' ").first
next if item.nil?
time_entry.description = "#{tracker} ##{id}: #{subject} #{"(Partial)" if not closed?}"
# Create the new billable time entry and upload it
time_entry.description = "#{tracker} ##{id}: #{subject} #{"(Partial @ #{done_ratio}%)" if not closed?}"
# TODO entry.user.qbo_employee.id
time_entry.employee_id = assigned_to.qbo_employee_id
time_entry.customer_id = customer_id
@@ -93,7 +103,7 @@ module IssuePatch
# Create a shareable link for a customer
def share_token
CustomerToken.create(:expires_at => Time.now + 24.hours, :issue_id => id)
CustomerToken.create(:expires_at => Time.now + 1.month, :issue_id => id)
end
end
+38 -22
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2017 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -9,43 +9,59 @@
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
class IssuesFormHookListener < Redmine::Hook::ViewListener
# Load the javascript
def view_layouts_base_html_head(context = {})
js = javascript_include_tag 'vehicles', :plugin => 'redmine_qbo'
#js += javascript_include_tag 'update_vehicles', :plugin => 'redmine_qbo'
js = javascript_include_tag 'application', :plugin => 'redmine_qbo'
js += javascript_include_tag 'autocomplete-rails', :plugin => 'redmine_qbo'
return js
end
# Edit Issue Form
# Show a dropdown for quickbooks contacts
def view_issues_form_details_bottom(context={})
f = context[:form]
#check project level customer/vehicle ownership first
if context[:project]
selected_customer = context[:project].customer ? context[:project].customer.id : nil
selected_vehicle = context[:project].vehicle ? context[:project].vehicle.id : nil
end
# Check to see if there is a quickbooks user attached to the issue
selected_customer = context[:issue].customer ? context[:issue].customer.id : nil
selected_estimate = context[:issue].qbo_estimate ? context[:issue].qbo_estimate.id : nil
selected_vehicle = context[:issue].vehicles_id ? context[:issue].vehicles_id : nil
# Load customer information without callbacks
# Load customer information
customer = Customer.find_by_id(selected_customer) if selected_customer
select_customer = f.select :customer_id,
Customer.all.pluck(:name, :id).sort,
:selected => selected_customer,
include_blank: true,
onchange: "$customerSelected;"
# Generate the drop down list of quickbooks extimates
select_estimate = f.select :qbo_estimate_id, QboEstimate.all.pluck(:doc_number, :id).sort! {|x, y| y <=> x}, :selected => selected_estimate, include_blank: true
search_customer = f.autocomplete_field :customer,
autocomplete_customer_name_customers_path,
:selected => selected_customer,
:update_elements => { :id => '#issue_customer_id', :value => '#issue_customer' }
customer_id = f.hidden_field :customer_id,
:id => "issue_customer_id",
:onchange => "updateIssueFrom('/issues/#{context[:issue].id}/edit.js', this)"
if context[:issue].customer
vehicles = customer.vehicles.pluck(:name, :id).sort!
if customer.vehicles
vehicles = customer.vehicles.pluck(:name, :id)
else
vehicles = [nil].compact
end
estimates = customer.qbo_estimates.pluck(:doc_number, :id).sort! {|x, y| y <=> x}
else
vehicles = Vehicle.all.order(:name).pluck(:name, :id)
vehicles = [nil].compact
estimates = [nil].compact
end
# Generate the drop down list of quickbooks extimates
select_estimate = f.select :qbo_estimate_id, estimates, :selected => selected_estimate, include_blank: true
vehicle = f.select :vehicles_id, vehicles, :selected => selected_vehicle, include_blank: true
return "<p>#{select_customer}</p> <p>#{select_estimate}</p> <p>#{vehicle}</p>"
return "<p><label for=\"issue_customer\">Customer</label>#{search_customer} #{customer_id}</p> <p>#{select_estimate}</p> <p>#{vehicle}</p>"
end
end
+6 -37
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2017 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -10,47 +10,16 @@
class IssuesSaveHookListener < Redmine::Hook::ViewListener
#Before Issue Saved
# Called Before Issue Saved
def controller_issues_edit_before_save(context={})
issue = context[:issue]
# Check to see if we have registered with QBO
if Qbo.first && issue.customer && issue. qbo_item_id
# if this is a quote, lets create a new estimate based off estimated hours
if issue.tracker.name = "Quote" && issue.status.name = "New" && issue.qbo_estimate
# Get QBO Services
item_service = QboItem.get_base.service
estimate_base = QboEstimate.get_base
# Create the estimate
estimate = estimate_base.qr_model(:estimate)
estimate.customer_id = issue.customer_id
estimate.txn_date = Date.today
# Create the line item for labor
item = item_service.fetch_by_id(issue.qbo_item_id)
line_item = Quickbooks::Model::InvoiceLineItem.new
line_item.amount = item.unit_price * issue.estimated_hours
line_item.description = issue.subject
line_item.sales_item! do |detail|
detail.unit_price = item.unit_price
detail.quantity = issue.estimated_hours
detail.item_id = issue.qbo_item_id
end
# Add the line items to the estimate
estimate.line_items << line_item
end
end
issue.subject = issue.subject.titleize
end
# Called After Issue Saved
# Called After Issue Saved
def controller_issues_edit_after_save(context={})
issue = context[:issue]
issue.bill_time if Qbo.first && issue.customer && issue.status.is_closed?
issue.bill_time if issue.status.is_closed?
end
end
+15 -45
View File
@@ -1,6 +1,6 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 rick barrette
#Copyright (c) 2017 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
@@ -10,11 +10,6 @@
class IssuesShowHookListener < Redmine::Hook::ViewListener
# Additional context fields
# :issue => the issue this is edited
# :f => the form object to create additional fields
#render_on :view_issues_show_details_bottom, :partial => 'hooks/redmine_qbo/_view_issues_show_details_bottom.html.erb'
# View Issue
# Display the quickbooks contact in the issue
def view_issues_show_details_bottom(context={})
@@ -37,6 +32,7 @@ class IssuesShowHookListener < Redmine::Hook::ViewListener
issue.qbo_invoice_ids.each do |i|
invoice = QboInvoice.find i
invoice_link = invoice_link + link_to( invoice.doc_number, "#{Redmine::Utils::relative_url_root}/qbo/invoice/#{i}", :target => "_blank").to_s + " "
invoice_link = invoice_link.html_safe
end
end
@@ -50,46 +46,20 @@ class IssuesShowHookListener < Redmine::Hook::ViewListener
end
split_vin = vin.scan(/.{1,9}/) if vin
return "
<div class=\"splitcontent\">
<div class=\"splitcontentleft\">
<div class=\"customer_id attribute\">
<div class=\"label\"><span>Customer</span>:</div>
<div class=\"value\">#{customer}</div>
</div>
<div class=\"qbo_estimate_id attribute\">
<div class=\"label\"><span>Estimate</span>:</div>
<div class=\"value\">#{estimate_link}</div>
</div>
<div class=\"qbo_invoice_id attribute\">
<div class=\"label\"><span>Invoice</span>:</div>
<div class=\"value\">#{invoice_link}</div>
</div>
</div>
<div class=\"splitcontentleft\">
<div class=\"vehicle attribute\">
<div class=\"label\"><span>Vehicle</span>:</div>
<div class=\"value\">#{vehicle}</div>
</div>
<div class=\"vehicle_vin attribute\">
<div class=\"label\"><span>VIN</span>:</div>
<div class=\"value\">#{split_vin[0] if split_vin}<b>#{split_vin[1] if split_vin}</b></div>
</div>
<div class=\"vehicle_notes attribute\">
<div class=\"label\"><span>Notes</span>:</div>
<div class=\"value\">#{notes}</div>
</div>
</div>
</div>"
context[:controller].send(:render_to_string, {
:partial => 'qbo/issues_show_details',
locals: {
customer: customer,
estimate_link: estimate_link,
invoice_link: invoice_link,
vehicle: vehicle,
split_vin: split_vin,
notes: notes
}
})
end
def view_issues_show_description_bottom(context={})
bill_button = button_to "Bill Time", "#{Redmine::Utils::relative_url_root}/qbo/bill/#{context[:issue].id}", method: :get if User.current.admin?
share_button = button_to "Share", "#{Redmine::Utils::relative_url_root}/customers/view/#{context[:issue].share_token.token}", method: :get if User.current.logged?
+14 -2
View File
@@ -1,3 +1,13 @@
#The MIT License (MIT)
#
#Copyright (c) 2022 rick barrette
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
require_dependency 'redmine/export/pdf'
require_dependency 'redmine/export/pdf/issues_pdf_helper'
@@ -7,7 +17,9 @@ module IssuesPdfHelperPatch
base.send(:include, InstanceMethods)
base.class_eval do
unloadable # Send unloadable so it will not be unloaded in development
alias_method_chain :issue_to_pdf, :patch
alias_method :issue_to_pdf, :issue_to_pdf_with_patch
alias_method :issue_to_pdf_with_patch, :issue_to_pdf
end
end
@@ -51,7 +63,7 @@ module IssuesPdfHelperPatch
vin = v ? v.vin : nil
notes = v ? v.notes : nil
left << [l(:field_vehicles), vehicle]
left << [l(:field_vin), vin.gsub(/(.{9})/, '\1 ')]
left << [l(:field_vin), vin ? vin.gsub(/(.{9})/, '\1 ') : nil]
#left << [l(:field_notes), notes]
right = []

Some files were not shown because too many files have changed in this diff Show More