386 Commits
0.0.2 ... 0.0.5

Author SHA1 Message Date
8812d7a11d Version Bump 0.0.5 2016-04-28 11:28:18 -04:00
fe1388108c Update customers_controller.rb 2016-04-28 10:43:58 -04:00
b98cdbec8b Update qbo_customer.rb 2016-04-28 10:39:35 -04:00
d7f8e51c4a Update qbo_customer.rb 2016-04-28 10:20:41 -04:00
2ce4e8b346 Update qbo_customer.rb 2016-04-28 10:03:52 -04:00
dd8bf530c9 Update qbo_customer.rb 2016-04-28 10:01:25 -04:00
1103355cb7 Update qbo_customer.rb 2016-04-28 09:59:45 -04:00
e400a7cee3 Update _details.html.erb 2016-04-28 09:50:17 -04:00
b32df9525c Update _details.html.erb 2016-04-28 09:48:31 -04:00
967a727392 Update _details.html.erb 2016-04-28 09:41:21 -04:00
79539dd57f Update _details.html.erb 2016-04-28 09:22:29 -04:00
9d96c813e9 Update qbo_customer.rb 2016-04-28 09:20:41 -04:00
073447a4ce Update qbo_customer.rb 2016-04-28 09:18:37 -04:00
1a6b6fb321 Update qbo_customer.rb 2016-04-28 09:15:22 -04:00
543841ad64 Update index.html.erb 2016-04-28 09:14:09 -04:00
5ad4b53b30 Update index.html.erb 2016-04-28 09:12:58 -04:00
bfec64de54 Update qbo_customer.rb 2016-04-28 09:09:59 -04:00
198e2d5934 Update qbo_customer.rb 2016-04-28 09:08:13 -04:00
95c39fb9c5 Update qbo_customer.rb 2016-04-28 09:03:57 -04:00
dc7ee21aad Update qbo_customer.rb 2016-04-28 09:01:48 -04:00
8c8966a859 Merge branch 'vehicles' of github.com:rickbarrette/redmine_qbo into vehicles 2016-04-28 08:57:40 -04:00
b95aa41b3d Fixed bug 2016-04-28 08:57:15 -04:00
2012774ae8 Update _details.html.erb 2016-04-28 08:54:19 -04:00
be7e9ef2cc Update show.html.erb 2016-04-28 08:49:21 -04:00
5ac1c44e41 Update show.html.erb 2016-04-28 08:48:27 -04:00
b1120c3849 Comments 2016-04-28 08:47:31 -04:00
847669376f Comments & Such 2016-04-28 08:43:54 -04:00
c2b62fbf88 Update qbo_customer.rb 2016-04-28 08:07:34 -04:00
21d0d25c78 Update qbo_customer.rb 2016-04-28 08:06:59 -04:00
365a36390b Added an init method and some convenience methods 2016-04-28 08:05:54 -04:00
68846f7910 Update vehicle.rb 2016-04-27 14:44:21 -04:00
3a64e0d5bd Update _details.html.erb 2016-04-27 14:23:56 -04:00
2f5607b8ef Update vehicle.rb 2016-04-27 14:22:48 -04:00
2a713d7f13 Update _details.html.erb 2016-04-27 14:17:12 -04:00
61f0ee6f81 Update _details.html.erb 2016-04-27 14:16:00 -04:00
d6a75f8ed0 Update vehicle.rb 2016-04-27 14:14:43 -04:00
14d10bd0e6 Update vehicle.rb 2016-04-27 14:13:19 -04:00
bb9f251e69 Update vehicle.rb 2016-04-27 14:11:18 -04:00
f2a7c034d0 Update vehicle.rb 2016-04-27 14:10:40 -04:00
3589ea8685 Update vehicles_controller.rb 2016-04-27 14:09:09 -04:00
f71be3f1a5 Update _details.html.erb 2016-04-27 14:08:48 -04:00
cf3983adc4 Update vehicle.rb 2016-04-27 14:06:30 -04:00
55f6666328 Update vehicles_controller.rb 2016-04-27 13:52:32 -04:00
933a0bb12d Update vehicles_controller.rb 2016-04-27 13:51:39 -04:00
0c5d2195d2 Update vehicle.rb 2016-04-27 13:50:31 -04:00
3518f0acfe Update vehicles_controller.rb 2016-04-27 13:45:09 -04:00
d4bcccf598 Update vehicle.rb 2016-04-27 13:41:09 -04:00
3aa2798463 Update vehicle.rb 2016-04-27 13:20:25 -04:00
0cb9863000 Update vehicle.rb 2016-04-27 13:18:17 -04:00
deb648e3d6 Rename update_vehicles.rb to 018_update_vehicles.rb 2016-04-27 13:16:54 -04:00
384854d701 Update vehicle.rb 2016-04-27 13:15:10 -04:00
f192fe8d5f Create update_vehicles.rb 2016-04-27 13:14:22 -04:00
8a89af88c3 Update issues_form_hook_listener.rb 2016-04-27 13:11:10 -04:00
a4944f2a3b Update vehicle.rb 2016-04-27 13:10:16 -04:00
0160a58c86 Update _details.html.erb 2016-04-27 13:01:45 -04:00
f7d809e90a Update _details.html.erb 2016-04-27 13:00:28 -04:00
8e80277a15 Update _details.html.erb 2016-04-27 12:59:47 -04:00
962e954d6e Update _details.html.erb 2016-04-27 12:58:17 -04:00
9d1bfa3951 Update _details.html.erb 2016-04-27 12:54:59 -04:00
b20a343cd2 Formating 2016-04-27 12:41:16 -04:00
593d8e603b Update qbo_controller.rb 2016-04-27 12:34:05 -04:00
5a5a531700 Update invoice_controller.rb 2016-04-27 12:33:35 -04:00
f7464e1d47 Update estimate_controller.rb 2016-04-27 12:33:10 -04:00
c39c9ab95c Update issues_form_hook_listener.rb 2016-04-27 12:25:51 -04:00
5aa32b735f Update issues_form_hook_listener.rb 2016-04-27 12:24:53 -04:00
9d4774a31b Update issues_show_hook_listener.rb 2016-04-27 12:19:14 -04:00
63c446673f Update issues_show_hook_listener.rb 2016-04-27 12:17:22 -04:00
8d1038ac0c Update issues_show_hook_listener.rb 2016-04-27 12:16:50 -04:00
ae903bede2 Update issues_show_hook_listener.rb 2016-04-27 12:15:33 -04:00
b82d5091b7 Update issues_show_hook_listener.rb 2016-04-27 12:14:59 -04:00
48a2c0cb45 Update issues_show_hook_listener.rb 2016-04-27 12:11:47 -04:00
092fa85dd8 Update issues_show_hook_listener.rb 2016-04-27 12:10:54 -04:00
5100b111e9 Update issues_show_hook_listener.rb 2016-04-27 12:09:53 -04:00
69273b5dc8 Update issues_show_hook_listener.rb 2016-04-27 12:09:10 -04:00
52bf4f916d Update issues_show_hook_listener.rb 2016-04-27 12:08:14 -04:00
7fa41d6574 Update issues_show_hook_listener.rb 2016-04-27 12:06:50 -04:00
bbe1b22020 Update vehicle.rb 2016-04-27 11:40:56 -04:00
892e57084d Squish VIN 2016-04-27 11:40:36 -04:00
d6e15f90ef Update vehicle.rb 2016-04-27 11:32:42 -04:00
39872107bc Update _details.html.erb 2016-04-27 10:53:51 -04:00
1de5712f8c Update _details.html.erb 2016-04-27 10:52:45 -04:00
38518fa5e9 Update show.html.erb 2016-04-27 10:43:44 -04:00
46df203e00 Update show.html.erb 2016-04-27 10:42:31 -04:00
642406365d Update vehicle.rb 2016-04-27 10:40:06 -04:00
ee40dbf5a4 Update vehicles_controller.rb 2016-04-27 10:39:02 -04:00
828a59f989 Update vehicle.rb 2016-04-27 10:38:40 -04:00
79d05350db Update vehicle.rb 2016-04-27 10:33:34 -04:00
12aeb22ac3 Update vehicles_controller.rb 2016-04-27 10:30:14 -04:00
09f531ce39 Update vehicles_controller.rb 2016-04-27 10:28:31 -04:00
2b4bba7a88 Update vehicle.rb 2016-04-27 10:25:23 -04:00
9e2f9f5a7a Update vehicle.rb 2016-04-27 09:23:09 -04:00
7a6e35adff Update 401.html.erb 2016-04-27 09:17:25 -04:00
5047077b07 Update customers_controller.rb 2016-04-27 09:10:31 -04:00
5242ed5a94 Update index.html.erb 2016-04-27 09:03:59 -04:00
a316c0f8d6 Update index.html.erb 2016-04-27 09:03:04 -04:00
3c6bce713b Update customers_controller.rb 2016-04-27 08:56:23 -04:00
d4b0ac1e38 Update show.html.erb 2016-04-27 08:49:31 -04:00
d80df26df1 Update show.html.erb 2016-04-27 08:47:18 -04:00
dd9c945fcc Update _details.html.erb 2016-04-27 08:46:54 -04:00
43e6fff6d8 Update index.html.erb 2016-04-27 08:45:27 -04:00
1650577d4d Update index.html.erb 2016-04-27 08:43:56 -04:00
c2b798e32c Update show.html.erb 2016-04-27 08:38:40 -04:00
1817095d00 Update show.html.erb 2016-04-27 08:38:06 -04:00
27bb6ea4a2 Create show.html.erb 2016-04-27 08:37:39 -04:00
ef2aebb7e4 Update _details.html.erb 2016-04-27 08:35:45 -04:00
bc23dfad56 Update index.html.erb 2016-04-27 08:35:04 -04:00
3be2a73422 Create _list.html.erb 2016-04-27 08:34:21 -04:00
4896241df1 Update index.html.erb 2016-04-27 08:18:40 -04:00
75b159bf4e Update index.html.erb 2016-04-27 08:18:15 -04:00
75a651dd3b Update index.html.erb 2016-04-27 08:02:40 -04:00
76e230770b Update index.html.erb 2016-04-27 08:02:11 -04:00
70d7b65741 Update init.rb 2016-04-27 08:01:05 -04:00
c251dc8407 Update index.html.erb 2016-04-27 07:59:37 -04:00
6464904caf Update index.html.erb 2016-04-27 07:55:20 -04:00
98cf1ed140 Update vehicles_controller.rb 2016-04-27 07:54:54 -04:00
0d367245ce Update customers_controller.rb 2016-04-27 07:54:18 -04:00
c053c91a64 Update Gemfile 2016-04-27 07:53:04 -04:00
8f5467638e Update customers_controller.rb 2016-04-27 07:39:32 -04:00
723d9024c1 Update customers_controller.rb 2016-04-27 07:37:18 -04:00
8374f0ae3e Update customers_controller.rb 2016-04-27 07:35:02 -04:00
4f9a3ed046 Update routes.rb 2016-04-27 06:44:14 -04:00
cd5ed4f3a7 Update index.html.erb 2016-04-26 14:09:15 -04:00
792773b945 Update customers_controller.rb 2016-04-26 14:08:27 -04:00
d09f5e9afe Update routes.rb 2016-04-26 14:02:42 -04:00
f07c90cf90 Update routes.rb 2016-04-26 14:01:20 -04:00
774ce239c2 Update routes.rb 2016-04-26 11:50:12 -04:00
3ec2670209 Update _details.html.erb 2016-04-26 10:16:55 -04:00
76cbb42309 Update index.html.erb 2016-04-26 09:24:32 -04:00
3e9138f802 Create _details.html.erb 2016-04-26 09:23:56 -04:00
1ac799d318 Update index.html.erb 2016-04-26 09:20:21 -04:00
5e4d7c7686 Added Customer to top menu 2016-04-26 09:18:22 -04:00
6a6fcf093c Added Resources Customers 2016-04-26 09:17:06 -04:00
ab68b1cf89 Create index.html.erb 2016-04-26 09:16:32 -04:00
b692abcb64 Create customers_controller.rb 2016-04-26 09:13:45 -04:00
94fe2f2d05 Commented out Category & Target Version 2016-04-26 09:02:08 -04:00
26f861a493 Update issues_show_hook_listener.rb 2016-04-26 08:55:44 -04:00
0f94675ba5 Update issues_show_hook_listener.rb 2016-04-26 08:54:23 -04:00
4816229c5e Update vehicle.rb 2016-04-26 06:46:46 -04:00
98b2d2078c Update vehicle.rb 2016-04-26 06:44:58 -04:00
6cf2a2640b before_validation 2016-04-26 06:41:25 -04:00
58c9544a22 Update vehicle.rb 2016-04-26 06:36:26 -04:00
d14b6a1b54 Can't use symbols 2016-04-26 06:34:08 -04:00
ec37439577 Update Gemfile 2016-04-26 06:31:38 -04:00
b5716595e4 Update vehicle.rb 2016-04-26 06:31:09 -04:00
d968885e1e Update vehicle.rb 2016-04-26 06:27:27 -04:00
1231b776b7 Update Gemfile 2016-04-25 12:58:46 -04:00
f8f3870405 Update vehicle.rb 2016-04-25 12:55:06 -04:00
723ad5bc53 Update edmunds.rb 2016-04-25 12:53:58 -04:00
c4c4d6156d Update edmunds.rb 2016-04-25 12:53:38 -04:00
28eaecabff Update Gemfile 2016-04-25 12:49:53 -04:00
6819e2a826 Update vehicle.rb 2016-04-25 12:44:24 -04:00
9e1ae8d40b Update vehicle.rb 2016-04-25 12:43:25 -04:00
467677d73c Update vehicle.rb 2016-04-25 12:42:29 -04:00
ee2be0d8c9 Update vehicle.rb 2016-04-25 12:34:53 -04:00
0fb358edf3 Update vehicle.rb 2016-04-25 12:33:18 -04:00
9972e18632 Added vin decoder 2016-04-25 12:22:48 -04:00
b1c0f965f8 Added Edmunds API Key 2016-04-25 12:06:03 -04:00
d523584ca1 Add edmunds_ruby GEM 2016-04-25 09:32:40 -04:00
de7b534572 Update pdf_patch.rb 2016-04-25 09:15:57 -04:00
24e3c29353 Update pdf_patch.rb 2016-04-25 09:13:27 -04:00
800058a3c0 Update pdf_patch.rb 2016-04-25 09:10:06 -04:00
9c230d6423 Update pdf_patch.rb 2016-04-25 09:09:14 -04:00
497f4661bd Update en.yml 2016-04-25 09:04:44 -04:00
d5b1187076 Added Vehicle to PDF 2016-04-25 09:03:56 -04:00
0468af9e53 Display vheicle info in issues 2016-04-24 12:03:43 -04:00
8ac9cfae93 Fixed vehicles dropdown 2016-04-24 10:54:43 -04:00
c07e4cb427 Fixed Issue Vehicle Selection 2016-04-24 10:49:57 -04:00
380315e207 Fixed vehicles_id 2016-04-24 10:23:23 -04:00
950dfd9af9 Update _dropdown.html.erb 2016-04-22 13:54:36 -04:00
c4abee7415 Update issues_form_hook_listener.rb 2016-04-22 13:38:32 -04:00
27d282f244 Update issues_form_hook_listener.rb 2016-04-22 13:36:47 -04:00
610582bce8 Update issues_form_hook_listener.rb 2016-04-22 13:25:44 -04:00
655f0c3dcd Update issues_form_hook_listener.rb 2016-04-22 13:22:41 -04:00
d9ce3981a3 Update issues_form_hook_listener.rb 2016-04-22 13:21:18 -04:00
8e6bdc6d38 Update issues_form_hook_listener.rb 2016-04-22 13:19:57 -04:00
0a167c33ee Update issues_form_hook_listener.rb 2016-04-22 13:18:05 -04:00
b8002df5af Update issue_patch.rb 2016-04-22 13:16:46 -04:00
7356e99981 Update issues_form_hook_listener.rb 2016-04-22 13:15:14 -04:00
4eb2718b2b Update issues_form_hook_listener.rb 2016-04-22 13:13:29 -04:00
3c849ca5dd Update issues_form_hook_listener.rb 2016-04-22 13:12:35 -04:00
dd40c045cf Update issues_form_hook_listener.rb 2016-04-22 13:10:46 -04:00
6505f8114d Update issues_form_hook_listener.rb 2016-04-22 13:09:00 -04:00
eeb5e96aae Update issues_form_hook_listener.rb 2016-04-22 12:59:57 -04:00
9c61ecd0c0 Update issues_form_hook_listener.rb 2016-04-22 12:44:55 -04:00
a771085a33 Update issues_form_hook_listener.rb 2016-04-22 12:42:03 -04:00
5f1dea77cc Update issues_form_hook_listener.rb 2016-04-22 12:40:51 -04:00
9ae11bac49 Create _dropdown.html.erb 2016-04-22 12:35:07 -04:00
77239122c0 Update and rename 017_update_issues.rb to 017_update_issues_with_vehicles.rb 2016-04-22 12:29:12 -04:00
804b4066ce Added Vehicle ID as a safe attribute to Issues 2016-04-22 12:27:59 -04:00
2cc8c83071 Add vehicle refrence to issues 2016-04-22 12:26:48 -04:00
a7ba05db29 Added Nil check to show 2016-04-22 12:22:33 -04:00
a8c353945d Update vehicles_controller.rb 2016-04-22 12:17:59 -04:00
f90921fb00 Update vehicles_controller.rb 2016-04-22 12:14:44 -04:00
84fd9770c9 Added VIN 2016-04-22 12:12:08 -04:00
f7ee1dbcec Update _details.html.erb 2016-04-22 12:10:28 -04:00
d8d0572a1a Update _details.html.erb 2016-04-22 12:09:39 -04:00
1688ebd327 Update index.html.erb 2016-04-22 12:08:34 -04:00
26d4f09f97 Update index.html.erb 2016-04-22 12:07:55 -04:00
fe831cf259 Update index.html.erb 2016-04-22 12:06:34 -04:00
35e4c5f9da User new vehicle details partial 2016-04-22 12:04:49 -04:00
66779e60f6 Use new vehicle details partial 2016-04-22 12:04:01 -04:00
1e0e608ca1 Create _details.html.erb 2016-04-22 12:02:19 -04:00
fbf074e3c3 Update vehicle.rb 2016-04-22 09:50:32 -04:00
a33a1eeb94 Update _form.html.erb 2016-04-22 09:50:02 -04:00
266a3ed921 Update _form.html.erb 2016-04-22 09:48:27 -04:00
fc0a416175 Update vehicle.rb 2016-04-22 09:47:11 -04:00
e561b52e9b Update index.html.erb
Float left
2016-04-22 09:41:46 -04:00
51586800a0 Update index.html.erb 2016-04-22 09:40:41 -04:00
fec1512930 Update index.html.erb
Display notes
2016-04-22 09:37:59 -04:00
559a846f1e Update vehicles_controller.rb
Change ID to Name
2016-04-22 09:34:32 -04:00
f936e61684 Update vehicles_controller.rb 2016-04-22 09:32:25 -04:00
dfd7dfcf79 Update show.html.erb
Display Notes
2016-04-22 09:31:03 -04:00
a409514467 Update vehicles_controller.rb
Added nil check
2016-04-22 09:28:10 -04:00
8b44e5b51b Update vehicles_controller.rb 2016-04-22 09:26:27 -04:00
e350657d89 Update vehicles_controller.rb 2016-04-22 09:24:34 -04:00
7fea7042a5 Update _form.html.erb 2016-04-22 09:18:50 -04:00
9c57878fd1 Update _form.html.erb 2016-04-22 09:17:01 -04:00
fd6c70860c Update _form.html.erb 2016-04-22 09:12:37 -04:00
48114de428 Update vehicles_controller.rb 2016-04-22 09:10:49 -04:00
7267bac43d Update vehicles_controller.rb 2016-04-22 09:10:01 -04:00
fd92d72ac3 Update _form.html.erb 2016-04-22 09:09:13 -04:00
5457ae51c2 Update index.html.erb 2016-04-22 08:15:45 -04:00
6647e533df Update index.html.erb 2016-04-22 08:14:41 -04:00
6d961addbe Update index.html.erb 2016-04-22 08:08:30 -04:00
af654ef9d0 Update index.html.erb
Floating
2016-04-22 08:06:57 -04:00
3b5f6691fb Update index.html.erb
Strong Customers
2016-04-22 08:03:54 -04:00
aa770bb1f0 Update index.html.erb
Updated formatting
2016-04-22 07:59:50 -04:00
0c2d57c826 More Progress! 2016-04-21 20:44:18 -04:00
fa3322d530 Update new.html.erb
Fixed formatting
2016-04-21 14:35:18 -04:00
3bbc0a16ff Update new.html.erb
Removed Selected Customer
2016-04-21 14:33:50 -04:00
2e7c26d90e Update new.html.erb 2016-04-21 14:32:37 -04:00
75fae59bcf Update new.html.erb 2016-04-21 14:31:09 -04:00
a1b72a1dd0 Update new.html.erb 2016-04-21 14:20:30 -04:00
4c9b48bd91 Update new.html.erb 2016-04-21 14:18:39 -04:00
e3c7047999 Update index.html.erb 2016-04-21 13:29:58 -04:00
07fe12e65b Update vehicles_controller.rb 2016-04-21 13:27:41 -04:00
8955053e64 Update vehicles_controller.rb 2016-04-21 13:23:06 -04:00
b534e94c38 Update vehicles_controller.rb 2016-04-21 12:47:10 -04:00
64a7b4fb29 Update vehicles_controller.rb 2016-04-21 12:44:58 -04:00
a6c88c85c4 Update and rename vehicle_controller.rb to vehicles_controller.rb 2016-04-21 12:33:13 -04:00
bbed60c2ca Update routes.rb 2016-04-21 12:31:07 -04:00
20b31d47be Rename app/views/vehicle/new.html.erb to app/views/vehicles/new.html.erb 2016-04-21 12:30:28 -04:00
b48a21c8fe Rename app/views/vehicle/index.html.erb to app/views/vehicles/index.html.erb 2016-04-21 12:30:06 -04:00
d4930227ba Update index.html.erb 2016-04-21 12:26:50 -04:00
ad27e98e48 Update vehicle_controller.rb 2016-04-21 12:24:18 -04:00
29fa5ff510 Create new.html.erb 2016-04-21 12:23:11 -04:00
b08f3adc39 Update index.html.erb 2016-04-21 12:10:56 -04:00
40f2358c26 Update index.html.erb
New Button!
2016-04-21 12:04:38 -04:00
952baff6f2 Update index.html.erb
Updated Buttons
2016-04-21 12:03:42 -04:00
31797585c8 Update vehicle_controller.rb
Added resourceful methods
2016-04-21 11:56:36 -04:00
2d50c4c454 Update routes.rb
Updated vehicle to use resoruces
2016-04-21 11:49:29 -04:00
ae491e0902 Update index.html.erb 2016-04-21 10:00:20 -04:00
c205479975 Update index.html.erb 2016-04-21 09:59:09 -04:00
ffede26929 Rename app/views/vehicles/index.html.erb to app/views/vehicle/index.html.erb 2016-04-21 09:57:40 -04:00
8a553c0129 Rename app/views/qbo/vehicles/index.html.erb to app/views/vehicles/index.html.erb 2016-04-21 09:51:21 -04:00
d5f9cee2e1 Create 401.html.erb 2016-04-21 09:49:03 -04:00
28d5187d40 Update vehicle_controller.rb 2016-04-21 09:47:40 -04:00
48709cdceb Create auth_helper.rb 2016-04-21 09:46:45 -04:00
22a6492e8b Update routes.rb 2016-04-21 09:44:27 -04:00
82f4ced404 Update routes.rb 2016-04-21 09:40:49 -04:00
3348173cbe Update routes.rb 2016-04-21 09:38:49 -04:00
9d83175bd7 Update routes.rb
Added Vehicle Index
2016-04-21 09:35:27 -04:00
b6f8304d13 Update qbo_customer.rb
Added ownership of vehicles
2016-04-21 09:31:22 -04:00
cd31ecf1f0 Create index.html.erb 2016-04-21 09:30:35 -04:00
15cd8e756c Create vehicle_helper.rb 2016-04-21 09:24:47 -04:00
3caaaa52dd Create vehicle.rb
Initial Vehicle model creation
2016-04-21 09:23:13 -04:00
03b12d08ef Create vehicle_controller.rb
Initial controller creation
2016-04-21 09:17:50 -04:00
a69ad1cef2 Create 016_create_vehicles.rb
Create the vehicle table
2016-04-21 09:09:41 -04:00
eb3d8160a1 Update init.rb 2016-04-18 12:32:37 -04:00
9cd5440bc8 Update init.rb
Check to see if the current user is an admin
2016-04-18 12:30:56 -04:00
f10114d43c Update query_patch.rb 2016-04-18 12:14:14 -04:00
fd8a068f16 Update invoice_controller.rb
Added Document Number to filename
2016-04-18 12:09:41 -04:00
e115e8fe94 Update estimate_controller.rb
Added Document Number to the file name
2016-04-18 12:08:08 -04:00
b4255135c4 Update query_patch.rb
Fixed Filter
2016-04-13 12:21:46 -04:00
9fc94e93c6 Update query_patch.rb 2016-04-13 12:14:12 -04:00
3e50c037e0 Update query_patch.rb
removed typo
2016-04-13 12:13:14 -04:00
dc5b8419a4 Update query_patch.rb
Added Customer Filter
2016-04-13 12:11:52 -04:00
c1002cb93c Merge pull request #1 from rickbarrette/pdf
Pdf
2016-04-13 09:27:39 -04:00
fcaa5f55cf Update pdf_patch.rb
fixed typo
2016-04-13 09:23:47 -04:00
195359ce0b Update init.rb
Added PDF Patch
2016-04-13 09:18:46 -04:00
b5c8823dda Create pdf_patch.rb
Added QBO Customer Name to PDF
2016-04-13 09:17:30 -04:00
d9317e717b Update query_patch.rb
Fixed Formatting
2016-04-13 08:53:39 -04:00
9e9c111256 Added QBO Customer to Issues Query 2016-04-12 23:15:47 -04:00
c254c78ee5 Removed @ from variables 2016-04-09 21:53:38 -04:00
dc1edaa651 Update issues_form_hook_listener.rb
Fixed Typos
2016-04-01 12:29:52 -04:00
028b309a60 0.0.4
Version Bump
2016-04-01 06:39:04 -04:00
e0b07764c0 Update qbo_customer.rb
Removed delete all
2016-04-01 06:37:30 -04:00
73dc8b3b44 Merge branch 'import' 2016-04-01 06:35:02 -04:00
1bc23ab553 Fixed import errors 2016-03-31 09:22:04 -04:00
5be8d987b6 Update qbo_estimate.rb
Added Transaction
2016-03-31 09:10:41 -04:00
f89cdf8ab2 Update qbo_employee.rb
Added Transaction
2016-03-31 09:09:52 -04:00
d33eba2b20 Update qbo_customer.rb
Added Transaction
2016-03-31 09:08:56 -04:00
39a2e1564f Update qbo_invoice.rb
Added Transaction
2016-03-31 09:07:30 -04:00
3070192485 Update qbo_item.rb
Formatting
2016-03-31 09:05:38 -04:00
ed5959d8e0 Added transaction to items 2016-03-31 09:05:04 -04:00
79d990dd01 Added Sorting to drop downs 2016-03-31 09:02:54 -04:00
b1cf8363a9 Update issues_form_hook_listener.rb
Sort the options!
2016-03-29 09:19:39 -04:00
3d251da80b Update index.html.erb
Sort the options!
2016-03-29 09:18:50 -04:00
cc9af5dc36 Added more garbage collection & removed automatic sync from show hook 2016-03-10 21:00:54 -05:00
2c3503f4ac Added garbage colllection for instance variables 2016-03-10 20:38:15 -05:00
5104509106 Update qbo_estimate.rb
Fixed ID
2016-03-10 12:29:21 -05:00
77be0b9d4c Update qbo_item.rb
Fixed ID
2016-03-10 12:28:18 -05:00
897810b029 Update qbo_customer.rb
Fixed ID
2016-03-10 12:27:43 -05:00
37371d2373 Update qbo_employee.rb
Fixed ID
2016-03-10 12:27:16 -05:00
95fbad525d Update qbo_invoice.rb
Fixed id
2016-03-10 12:26:35 -05:00
9ce8fa4661 Update issues_form_hook_listener.rb
Remove automatic sync of items.
2016-03-10 12:24:42 -05:00
c6ac6141d9 Update qbo_item.rb 2016-03-10 12:23:28 -05:00
f25fac1190 Update qbo_estimate.rb 2016-03-10 12:21:49 -05:00
49f2baed9f Update qbo_employee.rb
Fixed noob mistake
2016-03-10 12:20:34 -05:00
9acc33e373 Update qbo_employee.rb
Fixed removal of customers
2016-03-10 12:19:17 -05:00
4f6d194615 Fixed bug where the selected drop down items were not instance variables 2016-03-02 21:43:07 -05:00
0308a67a86 Simplified all quickbooks inporting
no more loops
2016-03-02 21:11:38 -05:00
7b63e64da0 Update qbo_invoice.rb
Loose the loop!
2016-03-02 14:43:22 -05:00
eb8e2fa018 Update qbo_invoice.rb
Added a block to find_or_create_by to succinctly update doc_number
2016-02-29 11:43:10 -05:00
62ac1bf295 Update qbo_estimate.rb
Fixed Loop
2016-02-29 09:42:51 -05:00
d044024981 Update qbo_item.rb
Removed all call
2016-02-29 09:41:48 -05:00
65be0c5f7a Update qbo_item.rb
Simplified Item Deletion
2016-02-29 09:39:33 -05:00
e9db63ea82 Update qbo_estimate.rb
Simplified Estimate Deletion
2016-02-29 09:37:24 -05:00
c8107c418f Update qbo_employee.rb
Simplified Employee Deletion
2016-02-29 09:36:22 -05:00
2d96f6653b Update qbo_customer.rb
Simplified Customer Deletion
2016-02-29 09:33:43 -05:00
b4833d7a5f Fixed destroy call 2016-02-29 09:27:37 -05:00
12cebb1cd1 Update qbo_invoice.rb 2016-02-29 09:15:11 -05:00
ad4ce232b5 Added removal for deleted entery while syncing
Added Invoices & Estimates to QBO#Index
2016-02-28 12:07:58 -05:00
82a273c0c2 Merge branch 'billable-purchases' 2016-02-25 22:53:46 -05:00
88b66c4b41 Fixed Estiamte & Invoice Link
Added Estimate Drop down
Disabled Automatic Estimate Creation
Added Controllers for Estimates & Invoices
2016-02-25 22:51:38 -05:00
e9038a56c1 Updated locale with Estimate 2016-02-25 20:54:20 -05:00
f2df6b5128 Update qbo_purchase.rb
Updated to use qbo_customer_id
2016-01-27 14:33:27 -05:00
b57d51d80a Create 015_update_qbo_purchases.rb 2016-01-27 14:32:44 -05:00
970a2fa681 Update qbo_purchase.rb
Simplified line item detail logic...

untested
2016-01-27 14:14:31 -05:00
3d2176c5bd Update qbo_purchase.rb
WIP Fixing Purchase Sync Methods
2016-01-27 12:42:56 -05:00
baf251e211 Update qbo_purchase.rb
Fixed Typo
2016-01-27 12:33:32 -05:00
def5b72aa3 Update qbo_customer.rb
Added a separate has_many line for purchases
2016-01-27 12:32:18 -05:00
89498c9559 Update qbo_purchase.rb
Added seprate belongs_to line for customer
2016-01-27 12:31:33 -05:00
b28e9b5a5b Update qbo_purchase.rb
Fixed typo for QBO Customer
2016-01-27 12:29:10 -05:00
d529139a9f Update qbo_customer.rb 2016-01-27 09:52:04 -05:00
5155c0bc68 Create 014_update_customers.rb
Added reference to customers for purchases
2016-01-27 09:31:51 -05:00
798bfde516 Update qbo_controller.rb
Added Purchases to sync
2016-01-27 09:21:28 -05:00
d79daa7a28 Fixed migration for purchases 2016-01-26 12:32:49 -05:00
6bcf210f79 Create 013_create_qbo_purchases.rb 2016-01-26 12:24:48 -05:00
7244455bf2 Update README.md
Better Documentation!
2016-01-26 04:42:14 -05:00
e65d78bb25 Create qbo_purchase.rb
Initial & untested commit for billable-purchases.

TODO:
Create database table
Add relationships
Attach to Issues
2016-01-25 12:31:26 -05:00
0b74f2cf52 Added Invoice Support 2016-01-24 18:54:34 -05:00
98b89e7875 Added Patch to Users to add releation ship for Users to Employees 2016-01-24 17:35:07 -05:00
b1996aa309 Update users_show_hook_listener.rb
Cleaned up nil checks
2016-01-22 05:43:06 -05:00
f4712ad849 Update issues_show_hook_listener.rb
Cleaned up nil checks
2016-01-22 05:38:31 -05:00
a8546934ee Cleaned up issue save hook 2016-01-22 05:22:09 -05:00
a7b7db690d Fixed Issue Save Hook 2016-01-22 04:08:21 -05:00
0ed61b191f Update issues_save_hook_listener.rb
Removed un-needed code, and added parenthesis on line 33
2016-01-21 13:37:30 -05:00
0fb4ec1157 Update issues_save_hook_listener.rb
Fixed conventions, Removed explicit non-nil checks, updated comments
2016-01-21 13:27:08 -05:00
d22257e8ab Update issues_form_hook_listener.rb
Fixed conventions, Removed explicit non-nil checks
2016-01-21 13:09:49 -05:00
e1bb565c59 Update qbo_controller.rb
Updating to the following conventions
https://github.com/bbatsov/ruby-style-guide
2016-01-21 12:19:13 -05:00
03e1e7e0b2 Update users_show_hook_listener.rb
Updating to the following conventions
https://github.com/bbatsov/ruby-style-guide
2016-01-21 12:15:20 -05:00
aa3fefd628 Update issues_show_hook_listener.rb
Updating to the following conventions
https://github.com/bbatsov/ruby-style-guide
2016-01-21 12:13:00 -05:00
5e635f9e2b Update issues_form_hook_listener.rb
Updating to the following conventions
https://github.com/bbatsov/ruby-style-guide
2016-01-21 12:09:40 -05:00
2aad7115c4 Update issues_save_hook_listener.rb
Updating to the following conventions
https://github.com/bbatsov/ruby-style-guide
2016-01-21 12:07:36 -05:00
80ee5287a0 Update README.md 2016-01-21 09:52:37 -05:00
26d8d9d3e9 Update README.md 2016-01-21 09:49:29 -05:00
f0c08e155f Update LICENSE
Formating
2016-01-21 06:08:55 -05:00
afb3af18d4 Update README.md 2016-01-20 12:46:24 -05:00
20be533a19 Update issues_save_hook_listener.rb
to ues Qbo.get_base
2016-01-20 12:21:08 -05:00
f07809eacb Update qbo_employee.rb 2016-01-20 12:16:51 -05:00
d1653da540 Update qbo_estimate.rb
to use Qbo.get_base
2016-01-20 12:16:15 -05:00
d9b1b45f89 Update qbo_item.rb
to use Qbo.get_base
2016-01-20 12:15:42 -05:00
2f85d2f56d Updated QBO Customer touse Qbo.get_base 2016-01-20 12:13:44 -05:00
430579d622 Removed nil check 2016-01-20 12:12:37 -05:00
2357b002c6 Update qbo.rb
Added get_base convenience method
2016-01-20 06:39:42 -05:00
191cfd5fff Fixed issue hooks 2016-01-20 06:27:26 -05:00
eb911f195c Removed unneeded code 2016-01-17 10:45:18 -05:00
98cd3d51e9 Estimate PDF is now dowloaded and served
TODO: The routes are somehow messed up and need to be fixed.

example: example.com/redmine/redmine/qbo/estimate/1
in lieu: example.com/redmine/qbo/estimate/1
2016-01-17 10:40:37 -05:00
2365fc2cf8 Corrected get_base to use :customer 2016-01-15 14:26:24 -05:00
6556197dd0 Readded nil checks 2016-01-14 21:49:26 -05:00
e19688a525 Fixed QBO#Index 2016-01-13 21:00:15 -05:00
ec1c263347 Added relationship to issues, renamed qbp_customer, started cleaning up
listeners
2016-01-13 20:37:02 -05:00
6f194e37bd Cleaned up the show_issue hook 2016-01-12 22:39:45 -05:00
135850b74d Estimates are now attached to issues and displayed on the issue 2016-01-12 21:45:56 -05:00
98e94da39b Added qbo_estimate_id to issues safe attribute list 2016-01-12 21:08:04 -05:00
3a4b3c0646 Added qbo_estimate to issues 2016-01-12 21:00:57 -05:00
ddb4f40486 Updated to quickbooks-ruby-base and added QboEstimate 2016-01-12 20:55:56 -05:00
a10b075ab8 Rename columns of QBO table 2016-01-12 20:55:00 -05:00
77448e8dc1 Create table qbo_estimates 2016-01-12 19:40:20 -05:00
cf97b341ab Updated Gemfile to work off my branch 2016-01-12 19:39:30 -05:00
7637a6fa28 Updated Gemfile to use my copy of quickbooks-ruby
Also Added quickbooks-ruby-base
2016-01-12 19:01:33 -05:00
aad4597265 Removed unneeded Code & Fixed Estimate Field Check 2016-01-11 23:37:01 -05:00
f9e271cbcb Added sanity checks for QBO info 2016-01-11 23:24:35 -05:00
2ec9e43951 Added estimate generation capability
TODO: check to see if we can get the PDF link
2016-01-11 23:20:27 -05:00
c2808c7e8f Broke billing of time into a seprate method 2016-01-11 22:18:40 -05:00
58 changed files with 1725 additions and 173 deletions

View File

@@ -1,8 +1,10 @@
source 'https://rubygems.org'
gem 'quickbooks-ruby'#, :git => 'https://github.com/ruckus/quickbooks-ruby.git'
gem 'quickbooks-ruby'
gem 'quickbooks-ruby-base'
gem 'oauth-plugin'#, '~> 0.5.1'
gem 'oauth'
gem 'roxml'
gem 'nokogiri'
gem 'edmunds_vin'
gem 'will_paginate', '~> 3.1.0'

20
LICENSE
View File

@@ -1,9 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 rick barrette
Copyright (c) 2016 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:
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 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.
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.

View File

@@ -4,15 +4,17 @@ A simple 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: This project is under heavy development. Currently the initial functionality goal has been meet, however I am still working on adding other features. Tags should be stable`
####How it works
* A QBO customer and service item can be assigned to a redmine issue.
* A QBO employee can be assigned to a redmine user
* When a issue is closed, the following things happen:
- The plugin checks to see if the user assinged to the issue has a QBO employee assinged to them
- The plugin checks to see if the issue has a QBO customer & service item attached
- If the above statements are true, then a new QBO Time Activity is created
- The total time for the Time Activity will be total spent time.
- The rate will be the set be the service item
* Issues can be assigned to a QBO Customer and QBO Service Item via drop down in issues form
- The `QBO Employee` for the issue is assigned via the assigned redmine user
- IF an `Issue` has been assined a `QBO Customer`, `QBO Service Item` & `QBO Employee` when an `Issue` is closed the following will happen:
- A new `QBO Time Activity` agaist the `QBO Customer` will be created using the total spent hours logged agaist an `Issue`.
- The rate will be the set via the `QBO Service Item` price
* `Issues` with the Tracker `Quote` will generate an estimate based on the estimated hours and `QBO Service Item` cost.
- Needs to have a `QBO Customer` & `QBO Service Item` Assiged
* Users will be assigned a `QBO Employee` via a drop down in the user admistration page.
##Prerequisites
@@ -21,21 +23,40 @@ The goal of this project is to allow redmine to connect with Quickbooks Online t
##The Install
1. To install, clone this repo into your plugin folder
1. To install, clone this repo into your plugin folder
' git clone git@github.com:rickbarrette/redmine_qbo.git '
`git clone git@github.com:rickbarrette/redmine_qbo.git`
2. Migrate your database
' rake redmine:plugins:migrate RAILS_ENV=production '
`rake redmine:plugins:migrate RAILS_ENV=production`
3. Navigate to the plugin configuration page (https://your.redmine.com/settings/plugin/redmine_qbo) and suppy your own OAuth key & secret.
3. Navigate to the plugin configuration page and suppy your own OAuth key & secret.
![Alt plugin_config](/Screenshots/plugin_config.png)
4. After saving your key & secret, you need to click on the Authenticate link on the plugin configuration page to authenticate with QBO.
5. Enjoy
5. Assign an Employee to each of your users via the User Administration Page
Note: Customers, Employees, and Service Items with automaticly update during normal usage of redmine i.e. a page refresh. You can also manualy force redmine to sync its database with QBO clicking the sync link in the Quickbooks top menu page (https://your.redmine.com/redmine/qbo)
![Alt plugin_user_edit](/Screenshots/plugin_user_edit.png)
## Usage
To enable automatic `QBO Time Activity` entries for an `Issue` , you need only to assign a `QBO Customer` and `QBO Item` to an `Issue` via drop downs in the creation/update form.
![Alt plugin_issue-edit](/Screenshots/plugin_issue_edit.png)
Note: Customers, Employees, and Service Items with automaticly update during normal usage of redmine i.e. a page refresh. You can also manualy force redmine to sync its database with QBO clicking the sync link in the Quickbooks top menu page
![Alt plugin_top_menu](/Screenshots/plugin_top_menu.png)
## TODO
* Abiltiy to add line items to a ticket in a dynamic table so they can be added to the invoice upon closing of the issue
* Add a rake file to create required Trackers or statuses required
* Add link Invoice PDF to issue after creation.
* Clean up view hook code, possibly use a controller hook and reder partial views
* Add Setting for Sandbox Mode
##License

View File

@@ -0,0 +1,63 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 CustomersController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
# display a list of all customers
def index
@customers = QboCustomer.paginate(:page => params[:page])
end
def new
end
def create
end
# display a specific customer
def show
@customer = QboCustomer.find_by_id(params[:id])
if @customer
@vehicles = @customer.vehicles.paginate(:page => params[:page])
else
flash[:error] = "Customer Not Found"
render :index
end
end
# return an HTML form for editing a customer
def edit
@customer = QboCustomer.find_by_id(params[:id])
end
# update a specific customer
def update
@customer = QboCustomer.find_by_id(params[:id])
if @customer.update_attributes(params[:customer])
flash[:success] = "Customer updated"
redirect_to @customer
else
render :edit
end
end
def destroy
end
end

View File

@@ -7,23 +7,21 @@
#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 QboCustomers < ActiveRecord::Base
class EstimateController < ApplicationController
unloadable
has_many :issues
attr_accessible :name
validates_presence_of :id, :name
def self.update_all
qbo = Qbo.first
service = Quickbooks::Service::Customer.new(:company_id => qbo.realmId, :access_token => Qbo.get_auth_token)
# Update the customer table
service.all.each { |customer|
qbo_customer = QboCustomers.find_or_create_by(id: customer.id)
qbo_customer.id = customer.id
qbo_customer.name = customer.display_name
qbo_customer.save!
}
include AuthHelper
before_filter :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"
end
end

View File

@@ -0,0 +1,26 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 InvoiceController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
#
# Downloads and forwards the invoice pdf
#
def show
base = QboInvoice.get_base.service
invoice = base.fetch_by_id(params[:id])
@pdf = base.pdf(invoice)
send_data @pdf, filename: "invoice #{invoice.doc_number}.pdf", :disposition => 'inline', :type => "application/pdf"
end
end

View File

@@ -10,18 +10,21 @@
class QboController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
#
# Called when the QBO Top Menu us shown
#
def index
@qbo = Qbo.first
@qbo_customer_count = QboCustomers.count
@qbo_customer_count = QboCustomer.count
@qbo_item_count = QboItem.count
@qbo_employee_count = QboEmployee.count
@selected_customer
@selected_item
@selected_employee
@qbo_invoice_count = QboInvoice.count
@qbo_estimate_count = QboEstimate.count
end
#
@@ -65,10 +68,13 @@ class QboController < ApplicationController
# Synchronizes the QboCustomer table with QBO
#
def sync
if Qbo.exists? then
QboCustomers.update_all
if Qbo.exists?
QboCustomer.update_all
QboItem.update_all
QboEmployee.update_all
QboEstimate.update_all
QboInvoice.update_all
QboPurchase.update_all
end
redirect_to qbo_path(:redmine_qbo), :flash => { :notice => "Successfully synced to Quickbooks" }

View File

@@ -0,0 +1,76 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 VehiclesController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
# display a list of all vehicles
def index
@vehicles = Vehicle.paginate(:page => params[:page])
end
# return an HTML form for creating a new vehicle
def new
@vehicle = Vehicle.new
end
# create a new vehicle
def create
@vehicle = Vehicle.new(params[:vehicle])
@vehicle.save!
redirect_to @vehicle
end
# display a specific vehicle
def show
@vehicle = Vehicle.find_by_id(params[:id])
if @vehicle
@customer = @vehicle.qbo_customer.name if @vehicle.qbo_customer
else
flash[:error] = "Vehicle Not Found"
render :index
end
end
# return an HTML form for editing a vehicle
def edit
@vehicle = Vehicle.find_by_id(params[:id])
@customer = @vehicle.qbo_customer.id if @vehicle.qbo_customer
end
# update a specific vehicle
def update
@vehicle = Vehicle.find_by_id(params[:id])
if @vehicle.update_attributes(params[:vehicle])
flash[:success] = "Vehicle updated"
redirect_to @vehicle
else
render :edit
end
end
# delete a specific vehicle
def destroy
v = Vehicle.find_by_id(params[:id])
if v != nil
v.destroy
flash.now[:notice] = "Vehicle deleted successfully"
else
flash.now[:error] = "No Vehicle Found"
end
redirect_to action: :index
end
end

View File

@@ -0,0 +1,18 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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.
module AuthHelper
def require_user
if !User.current.logged?
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
end
end
end

View File

@@ -0,0 +1,2 @@
module EstimateHelper
end

View File

@@ -0,0 +1,2 @@
module InvoiceHelper
end

View File

@@ -0,0 +1,13 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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.
module VehicleHelper
end

View File

@@ -10,11 +10,12 @@
class Qbo < ActiveRecord::Base
unloadable
validates_presence_of :token, :secret, :realmId, :token_expires_at, :reconnect_token_at
validates_presence_of :qb_token, :qb_secret, :company_id, :token_expires_at, :reconnect_token_at
QB_KEY = Setting.plugin_redmine_qbo['settingsOAuthConsumerKey']
QB_SECRET = Setting.plugin_redmine_qbo['settingsOAuthConsumerSecret']
# Quickbooks Config Info
$qb_oauth_consumer = OAuth::Consumer.new(QB_KEY, QB_SECRET, {
:site => "https://oauth.intuit.com",
:request_token_path => "/oauth/v1/get_request_token",
@@ -22,12 +23,21 @@ class Qbo < ActiveRecord::Base
:access_token_path => "/oauth/v1/get_access_token"
})
def self.get_auth_token
qbo = first
return OAuth::AccessToken.new($qb_oauth_consumer, qbo.token, qbo.secret)
end
# 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'
end
def self.get_oauth_consumer
return $qb_oauth_consumer
# Get a quickbooks base object for type
# @params type of base
def self.get_base(type)
Quickbooks::Base.new(first, type)
end
# Get the QBO account
def self.get_account
first
end
end

128
app/models/qbo_customer.rb Normal file
View File

@@ -0,0 +1,128 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 QboCustomer < ActiveRecord::Base
unloadable
has_many :issues
has_many :qbo_purchases
has_many :vehicles
attr_accessible :name
validates_presence_of :id, :name
after_initialize :get_details
self.primary_key = :id
# returns true if the customer is active
def active?
return @details.active? if @details
end
# returns a human readable string
def to_s
return name
end
# returns the customer's email
def email
begin
return @details.email_address.address
rescue
return nil
end
end
# returns the customer's primary phone
def primary_phone
begin
return @details.primary_phone.free_form_number
rescue
return nil
end
end
# returns the customer's mobile phone
def mobile_phone
begin
return @details.mobile_phone.free_form_number
rescue
return nil
end
end
# returns the customer's notes
def notes
return @details.notes if @details
end
# updates the customer's notes in QBO
def notes=(s)
customer = get_customer(self.id)
customer.notes = s
get_base.update(customer)
end
# returns the bases QBO service for customers
def get_base
Qbo.get_base(:customer)
end
# returns the QBO customer
def get_customer (id)
get_base.find_by_id(id)
end
# proforms a bruteforce sync operation
# This needs to be simplified
def update_all
customers = get_base.service.all
transaction do
# Update the customer table
customers.each { |customer|
qbo_customer = QboCustomer.find_or_create_by(id: customer.id)
# only update if diffrent
if not qbo_customer.name == customer.display_name
qbo_customer.name = customer.display_name
qbo_customer.id = customer.id
qbo_customer.save!
end
}
end
# remove deleted customers
where.not(customers.map(&:id)).destroy_all
end
private
# init details
def get_details
if self.id
@details = get_customer(self.id)
update
end
end
# update's the customers name if updated
def update
begin
if not self.name == @detils.display_name
self.name = @details.display_name
self.save
end
rescue
return nil
end
end
end

View File

@@ -14,16 +14,24 @@ class QboEmployee < ActiveRecord::Base
attr_accessible :name
validates_presence_of :id, :name
def self.update_all
qbo = Qbo.first
service = Quickbooks::Service::Employee.new(:company_id => qbo.realmId, :access_token => Qbo.get_auth_token)
# Update the item table
service.all.each { |employee|
qbo_employee = QboEmployee.find_or_create_by(id: employee.id)
qbo_employee.name = employee.display_name
qbo_employee.id = employee.id
qbo_employee.save!
}
def self.get_base
Qbo.get_base(:employee)
end
end
def self.update_all
employees = get_base.service.all
transaction do
# Update the item table
employees.each { |employee|
qbo_employee = find_or_create_by(id: employee.id)
qbo_employee.name = employee.display_name
qbo_employee.id = employee.id
qbo_employee.save!
}
end
#remove deleted employees
where.not(employees.map(&:id)).destroy_all
end
end

View File

@@ -0,0 +1,45 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 QboEstimate < ActiveRecord::Base
unloadable
has_many :issues
attr_accessible :doc_number
validates_presence_of :id, :doc_number
def self.get_base
Qbo.get_base(:estimate)
end
def self.update_all
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
#remove deleted estimates
where.not(estimates.map(&:id)).destroy_all
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!
end
end

46
app/models/qbo_invoice.rb Normal file
View File

@@ -0,0 +1,46 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 QboInvoice < ActiveRecord::Base
unloadable
has_many :issues
attr_accessible :doc_number
validates_presence_of :id, :doc_number
def self.get_base
Qbo.get_base(:invoice)
end
def self.update_all
#Pull the invoices from the quickbooks server
invoices = get_base.service.all
# Update the invoice table
transaction do
invoices.each { | invoice |
qbo_invoice = find_or_create_by(id: invoice.id)
qbo_invoice.doc_number = invoice.doc_number
qbo_invoice.id = invoice.id
qbo_invoice.save!
}
end
#remove deleted invoices
where.not(invoices.map(&:id)).destroy_all
end
def self.update(id)
# Update the item table
invoice = get_base.service.fetch_by_id(id)
qbo_invoice = find_or_create_by(id: id)
qbo_invoice.doc_number = invoice.doc_number
qbo_invoice.save!
end
end

View File

@@ -14,16 +14,24 @@ class QboItem < ActiveRecord::Base
attr_accessible :name
validates_presence_of :id, :name
def self.get_base
Qbo.get_base(:item)
end
def self.update_all
qbo = Qbo.first
service = Quickbooks::Service::Item.new(:company_id => qbo.realmId, :access_token => Qbo.get_auth_token)
items = get_base.service.find_by(:type, "Service")
transaction do
# Update the item table
items.each { |item|
qbo_item = QboItem.find_or_create_by(id: item.id)
qbo_item.name = item.name
qbo_item.id = item.id
qbo_item.save!
}
end
# Update the item table
service.find_by(:type, "Service").each { |item|
qbo_item = QboItem.find_or_create_by(id: item.id)
qbo_item.name = item.name
qbo_item.id = item.id
qbo_item.save!
}
#remove deleted items
where.not(items.map(&:id)).destroy_all
end
end

View File

@@ -0,0 +1,47 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 QboPurchase < ActiveRecord::Base
unloadable
belongs_to :issues
belongs_to :qbo_customer
attr_accessible :description
validates_presence_of :id, :line_id, :description, :qbo_customer_id
def self.get_base
Qbo.get_base(:purchase)
end
def self.get_purchase(id)
get_base.service.find_by_id(id)
end
def self.update_all
QboPurchase.get_base.service.all.each { |purchase|
purchase.line_items.all? { |line_item|
detail = line_item.account_based_expense_line_detail ? line_item.account_based_expense_line_detail : line_item.item_based_expense_line_detail
if detail.billable_status = "Billable"
qbo_purchase = find_or_create_by(id: purchase.id)
qbo_purchase.line_id = line_item.id
qbo_purchase.description = line_item.description
qbo_purchase.qbo_customer_id = detail.customer_ref
#TODO attach to issues
#qbo_purchase.issue_id = Issue.find_by_invoice()
qbo_purchase.save
end
}
}
end
end

88
app/models/vehicle.rb Normal file
View File

@@ -0,0 +1,88 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 Vehicle < ActiveRecord::Base
unloadable
belongs_to :qbo_customer
attr_accessible :year, :make, :model, :qbo_customer_id, :notes, :vin
validates_presence_of :year, :make, :model, :qbo_customer_id
before_validation :decode_vin
after_initialize :get_details
# returns a human readable string
def to_s
return "#{self.year} #{self.make} #{self.model}"
end
# returns the raw JSON details from EMUNDS
def details
return @details
end
# returns the style of the vehicle
def style
begin
return @details['years'][0]['styles'][0]['name'] if @details
rescue
return nil
end
end
# returns the drive of the vehicle i.e. 2 wheel, 4 wheel, ect.
def drive
return @details['drivenWheels'] if @details
end
# returns the number of doors of the vehicle
def doors
return @details['numOfDoors'] if @details
end
private
# init method to pull JSON details from Edmunds
def get_details
if self.vin?
@details = JSON.parse get_decoder.full(self.vin)
end
end
# returns the Edmunds decoder service
def get_decoder
#TODO API Code via Settings
return decoder = Edmunds::Vin.new('2dheutzvhxs28dzukx5tgu47')
end
# decodes a vin and updates self
def decode_vin
get_details
if self.vin?
details
self.year = @details['years'][0]['year']
self.make = @details['make']['name']
self.model = @details['model']['name']
end
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'
end
v = self.vin[0,11]
return v.slice(0,8) + v.slice(9,11)
end
end

View File

@@ -0,0 +1,35 @@
<table>
<tbody>
<tr>
<th>Customer</th>
<td><%= @customer.name %></td>
</tr>
<tr>
<th>Email</th>
<td><%= @customer.email %></td>
</tr>
<tr>
<th>Primary Phone</th>
<td><%= @customer.primary_phone %></td>
</tr>
<tr>
<th>Mobile Phone</th>
<td><%= @customer.mobile_phone %></td>
</tr>
<tr>
<th>Notes</th>
<td><%= @customer.notes %></td>
</tr>
<tr>
<td/>
<td>
<%= button_to "Edit", edit_customer_path(@customer), method: :get%>
</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,20 @@
<h1>Customers</h1>
<br/>
<% @customers.each do |c| %>
<div class="row">
<div class="span6 columns">
<fieldset>
<% @customer = c %>
<%= render :partial => 'customers/details' %>
<%= button_to "Show", customer_path(c.id), method: :get %>
</fieldset>
</div>
</div>
<% end %>
<br/>
<div class="actions">
<%= will_paginate @customers %>
<%= button_to "New", new_customer_path, method: :get %>
</div>

View File

@@ -0,0 +1,5 @@
<h1>Customer Detail</h1>
<br/>
<%= render :partial => 'customers/details' %>
<br/>
<%= render :partial => 'vehicles/list' %>

View File

@@ -0,0 +1 @@
<%= flash.now[:error] = "Not Authorized" %>

View File

@@ -16,7 +16,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
<div>
<%= f.label "Customer Count:"+@qbo_customer_count.to_s%>
<br/>
<%= f.select :qbo_customer_id, QboCustomers.all.pluck(:name, :id), :selected => @selected_customer, include_blank: true %>
<%= f.select :qbo_customer_id, QboCustomer.all.pluck(:name, :id).sort, :selected => @selected_customer, include_blank: true %>
</div>
<br/>
@@ -24,7 +24,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
<div>
<%= f.label "Item Count: "+@qbo_item_count.to_s %>
<br/>
<%= f.select :qbo_item_id, QboItem.all.pluck(:name, :id).reverse, :selected => @selected_item, include_blank: true %>
<%= f.select :qbo_item_id, QboItem.all.pluck(:name, :id).sort.reverse, :selected => @selected_item, include_blank: true %>
</div>
<br/>
@@ -32,11 +32,24 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
<div>
<%= f.label "Employee Count: "+@qbo_employee_count.to_s %>
<br/>
<%= f.select :qbo_employee_id, QboEmployee.all.pluck(:name, :id), :selected => @selected_employee, include_blank: true %>
<%= f.select :qbo_employee_id, QboEmployee.all.pluck(:name, :id).sort, :selected => @selected_employee, include_blank: true %>
</div>
<% end %>
<p>
<%= f.label "Invoice Count: "+@qbo_invoice_count.to_s %>
<br/>
<%=f.select :qbo_invoice_id, QboInvoice.all.pluck(:doc_number, :id).sort! {|x, y| y <=> x}, :selected => @selected_invoice, include_blank: true%>
</p>
<p>
<%= f.label "Estimate Count: "+@qbo_estimate_count.to_s %>
<br/>
<%=f.select :qbo_estimate_id, QboEstimate.all.pluck(:doc_number, :id).sort! {|x, y| y <=> x}, :selected => @selected_estimate, include_blank: true%>
</p>
<% end %>
<br/>
<br/>
<%= link_to "Sync", qbo_sync_path %>
</body>
</body>

View File

@@ -0,0 +1,46 @@
<table>
<tbody>
<tr>
<th>Customer</th>
<td><%= @customer %></td>
</tr>
<tr>
<th>Vehicle</th>
<td><%= @vehicle.to_s %></td>
</tr>
<tr>
<th>VIN</th>
<td><%= @vehicle.vin %></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>
<td><%= @vehicle.notes %></td>
</tr>
<tr>
<td/>
<td>
<%= button_to "Edit", edit_vehicle_path(@vehicle), method: :get%>
<%= button_to "Delete", @vehicle, method: :delete, data: {confirm: "You sure?"} %>
</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,2 @@
<%= @f.collection_select :vehicle_id, @customer.vehicles.order(:year), :id, :vin, include_blank: true, :selected => @vehicle%>
Partial Test

View File

@@ -0,0 +1,55 @@
<div class="row">
<div class="span6 columns">
<fieldset>
<%= form_for @vehicle do |f| %>
<div class="clearfix">
Customer:
<div class="input">
<%= f.collection_select :qbo_customer_id, QboCustomer.order(:name), :id, :name, include_blank: true, :selected => @customer, :required => true%>
</div>
</div>
<div class="clearfix">
Year:
<div class="input">
<%= f.text_field :year, :required => true %>
</div>
</div>
<div class="clearfix">
Make:
<div class="input">
<%= f.text_field :make, :required => true %>
</div>
</div>
<div class="clearfix">
Model:
<div class="input">
<%= f.text_field :model, :required => true %>
</div>
</div>
<div class="clearfix">
VIN:
<div class="input">
<%= f.text_field :vin %>
</div>
</div>
<div class="clearfix">
Notes:
<div class="input">
<%= f.text_area :notes, :rows => 6, :class => 'wiki-edit', :accesskey => accesskey(:edit), :cols => 60%>
</div>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
</fieldset>
</div>
</div>

View File

@@ -0,0 +1,18 @@
<% @vehicles.each do |vehicle| %>
<div class="row">
<div class="span6 columns">
<fieldset>
<% @customer = vehicle.qbo_customer.name if vehicle.qbo_customer %>
<% @vehicle = vehicle %>
<%= render :partial => 'vehicles/details' %>
</fieldset>
</div>
</div>
<% end %>
<br/>
<div class="actions">
<%= will_paginate @vehicles %>
<%= button_to "New", new_vehicle_path, method: :get %>
</div>

View File

@@ -0,0 +1,3 @@
<h1>Edit Customer Vehicle</h1>
<br/>
<%= render :partial => 'vehicles/form' %>

View File

@@ -0,0 +1,3 @@
<h1>Customer Vehicles</h1>
<br/>
<%= render :partial => 'vehicles/list' %>

View File

@@ -0,0 +1,3 @@
<h1>New Customer Vehicle</h1>
<br/>
<%= render :partial => 'vehicles/form' %>

View File

@@ -0,0 +1,3 @@
<h1>Customer Vehicle</h1>
<br/>
<%= render :partial => 'vehicles/details' %>

View File

@@ -0,0 +1,3 @@
Edmunds::Api.configure do |config|
config.api_key = '2dheutzvhxs28dzukx5tgu47'
end

View File

@@ -14,3 +14,8 @@ en:
field_qbo_customer: "Customer"
field_qbo_item: "Item"
field_qbo_employee: "Employee"
field_qbo_invoice: "Invoice"
field_qbo_estimate: "Estimate"
field_vehicles: "Vehicle"
field_vin: "VIN"
field_notes: "Notes"

View File

@@ -15,4 +15,7 @@ get 'qbo', :to=> 'qbo#index'
get 'qbo/authenticate', :to => 'qbo#authenticate'
get 'qbo/oauth_callback', :to => 'qbo#oauth_callback'
get 'qbo/sync', :to => 'qbo#sync'
get 'qbo/estimate/:id', :to => 'estimate#show', as: :estimate
get 'qbo/invoice/:id', :to => 'invoice#show', as: :invoice
resources :vehicles
resources :customers

View File

@@ -0,0 +1,18 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 CreateQboEstimates < ActiveRecord::Migration
def change
create_table :qbo_estimates, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
t.string :doc_number
end
end
end

View File

@@ -0,0 +1,17 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 UpdateQbos < ActiveRecord::Migration
def change
rename_column :qbos, :token, :qb_token
rename_column :qbos, :secret, :qb_secret
rename_column :qbos, :realmId, :company_id
end
end

View File

@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 UpdateIssuesWithEstimates < ActiveRecord::Migration
def change
add_reference :issues, :qbo_estimate, index: true
end
end

View File

@@ -0,0 +1,18 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 CreateQboInvoices < ActiveRecord::Migration
def change
create_table :qbo_invoices, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
t.string :doc_number
end
end
end

View File

@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 UpdateIssuesWithInvoices< ActiveRecord::Migration
def change
add_reference :issues, :qbo_invoice, index: true
end
end

View File

@@ -0,0 +1,21 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 CreateQboPurchases< ActiveRecord::Migration
def change
create_table :qbo_purchases, id: false do |t|
t.integer :id, :options => 'PRIMARY KEY'
t.integer :line_id
t.string :description
t.integer :customer_id
t.integer :issue_id
end
end
end

View File

@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 UpdateCustomers < ActiveRecord::Migration
def change
add_reference :qbo_customers, :qbo_purchase, index: true
end
end

View File

@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 UpdateQboPurchases < ActiveRecord::Migration
def change
rename_column :qbo_purchases, :customer_id, :qbo_customer_id
end
end

View File

@@ -0,0 +1,24 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 CreateVehicles < ActiveRecord::Migration
def change
create_table :vehicles do |t|
t.integer :year
t.string :make
t.string :model
t.string :vin
t.text :notes
end
add_reference :vehicles, :qbo_customer, index: true
end
end

View File

@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 UpdateIssuesWithVehicles < ActiveRecord::Migration
def change
add_reference :issues, :vehicles, index: true
end
end

View File

@@ -0,0 +1,15 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 UpdateVehicles < ActiveRecord::Migration
def change
add_column :vehicles, :name, :text
end
end

60
init.rb
View File

@@ -10,29 +10,43 @@
Redmine::Plugin.register :redmine_qbo do
require_dependency 'issues_form_hook_listener'
require_dependency 'issues_save_hook_listener'
require_dependency 'issues_show_hook_listener'
require_dependency 'users_show_hook_listener'
# View Hook Listeners
require_dependency 'issues_form_hook_listener'
require_dependency 'issues_save_hook_listener'
require_dependency 'issues_show_hook_listener'
require_dependency 'users_show_hook_listener'
# Patches to the Redmine core. Will not work in development mode
require_dependency 'issue_patch'
require_dependency 'user_patch'
require_dependency 'query_patch'
require_dependency 'pdf_patch'
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.0.2'
url 'https://github.com/rickbarrette/redmine_qbo'
author_url 'http://rickbarrette.org'
settings :default => {'empty' => true}, :partial => 'qbo/settings'
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.0.5'
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 'qbo_customer_id'
Issue.safe_attributes 'qbo_item_id'
User.safe_attributes 'qbo_employee_id'
TimeEntry.safe_attributes 'qbo_billed'
# We are playing in the sandbox
#Quickbooks.sandbox_mode = true
# Add safe attributes
Issue.safe_attributes 'qbo_customer_id'
Issue.safe_attributes 'qbo_item_id'
Issue.safe_attributes 'qbo_estimate_id'
Issue.safe_attributes 'qbo_invoice_id'
Issue.safe_attributes 'vehicles_id'
User.safe_attributes 'qbo_employee_id'
TimeEntry.safe_attributes 'qbo_billed'
# We are playing in the sandbox
#Quickbooks.sandbox_mode = true
# set per_page globally
WillPaginate.per_page = 10
# Register QBO top menu item
menu :top_menu, :qbo, { :controller => 'qbo', :action => 'index' }, :caption => 'Quickbooks'
end
# Register QBO top menu item
menu :top_menu, :qbo, { :controller => :qbo, :action => :index }, :caption => 'Quickbooks', :if => Proc.new { User.current.admin? }
menu :top_menu, :vehicles, { :controller => :vehicles, :action => :index }, :caption => 'Vehicles', :if => Proc.new { User.current.logged? }
menu :top_menu, :customers, { :controller => :customers, :action => :index }, :caption => 'Customers', :if => Proc.new { User.current.logged? }
end

45
lib/issue_patch.rb Normal file
View File

@@ -0,0 +1,45 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 'issue'
# Patches Redmine's Issues dynamically.
# Adds a relationships
module IssuePatch
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
belongs_to :qbo_customer, primary_key: :id
belongs_to :qbo_item, primary_key: :id
belongs_to :qbo_estimate, primary_key: :id
belongs_to :qbo_invoice, primary_key: :id
belongs_to :vehicle, primary_key: :id
end
end
module ClassMethods
end
module InstanceMethods
end
end
# Add module to Issue
Issue.send(:include, IssuePatch)

View File

@@ -9,27 +9,40 @@
#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
# Edit Issue Form
# Show a dropdown for quickbooks contacts
def view_issues_form_details_bottom(context={})
selected = ""
QboCustomers.update_all
QboItem.update_all
f = context[:form]
# Check to see if there is a quickbooks user attached to the issue
if not context[:issue].qbo_customer_id.nil? then
selected_customer = context[:issue].qbo_customer_id
selected_item = context[:issue].qbo_item_id
end
# Generate the drop down list of quickbooks contacts
select_customer = context[:form].select :qbo_customer_id, QboCustomers.all.pluck(:name, :id), :selected => selected_customer, include_blank: true
selected_customer = context[:issue].qbo_customer ? context[:issue].qbo_customer.id : nil
selected_item = context[:issue].qbo_item ? context[:issue].qbo_item.id : nil
selected_invoice = context[:issue].qbo_invoice ? context[:issue].qbo_invoice.id : nil
selected_estimate = context[:issue].qbo_estimate ? context[:issue].qbo_estimate.id : nil
customer = QboCustomer.find_by_id(selected_customer) if selected_customer
vehicle = context[:issue].vehicles_id
# Generate the drop down list of quickbooks customers
select_customer = f.select :qbo_customer_id, QboCustomer.all.pluck(:name, :id).sort, :selected => selected_customer, include_blank: true
# Generate the drop down list of quickbooks contacts
select_item = context[:form].select :qbo_item_id, QboItem.all.pluck(:name, :id).reverse, :selected => selected_item, include_blank: true
return "<p>#{select_customer}</p> <p>#{select_item}</p>"
# Generate the drop down list of quickbooks items
select_item = f.select :qbo_item_id, QboItem.all.pluck(:name, :id).sort, :selected => selected_item, include_blank: true
# Generate the drop down list of quickbooks invoices
select_invoice = f.select :qbo_invoice_id, QboInvoice.all.pluck(:doc_number, :id).sort! {|x, y| y <=> x}, :selected => selected_invoice, include_blank: true
# 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
#@estimates_link = link_to qbo_update_estimates_path
#render_on :view_issues_form_details_bottom, :partial => 'hooks/redmine_qbo/vehicles/dropdown'
vehicles = customer.vehicles.pluck(:name, :id).sort if customer
vehicles = Vehicle.all if not vehicles
vehicle = f.select :vehicles_id, vehicles, include_blank: true, :selected => vehicle
return "<p>#{select_customer}</p> <p>#{select_item}</p> <p>#{select_invoice}</p> <p>#{select_estimate}</p> <p>#{vehicle}</p>"
end
end
end

View File

@@ -10,23 +10,72 @@
class IssuesSaveHookListener < Redmine::Hook::ViewListener
# New Issue Saved
def controller_issues_edit_after_save(context={})
#Before Issue Saved
def controller_issues_edit_before_save(context={})
issue = context[:issue]
qbo = Qbo.first
# Check to see if we have registered with QBO
if not qbo.nil? then
if Qbo.first && issue.qbo_customer && issue.qbo_item
# 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.qbo_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
# Save the etimate to the issue
#issue.qbo_estimate_id = estimate_base.service.create(estimate).id
#issue.save!
end
end
end
# Called After Issue Saved
def controller_issues_edit_after_save(context={})
issue = context[:issue]
employee_id = issue.assigned_to.qbo_employee_id
# Check to see if we have registered with QBO and if the issue is closed.
# If so then we need to create a new billable time activity for the customer
bill_time(issue, employee_id) if Qbo.first && issue.qbo_customer && issue.qbo_item && employee_id && issue.status.is_closed?
end
# Create billable time entries
def bill_time(issue, employee_id)
# Get unbilled time entries
spent_time = issue.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 = Quickbooks::Service::TimeActivity.new(:company_id => qbo.realmId, :access_token => Qbo.get_auth_token)
item_service = Quickbooks::Service::Item.new(:company_id => qbo.realmId, :access_token => Qbo.get_auth_token)
time_service = Qbo.get_base(:time_activity).service
item_service = Qbo.get_base(:item).service
time_entry = Quickbooks::Model::TimeActivity.new
# Get unbilled time entries
spent_time = issue.time_entries.where(qbo_billed: [false, nil])
spent_hours ||= spent_time.sum(:hours) || 0
# Convert float spent time to hours and minutes
hours = spent_hours.to_i
minutesDecimal = (( spent_hours - hours) * 60)
@@ -37,27 +86,21 @@ class IssuesSaveHookListener < Redmine::Hook::ViewListener
entry.qbo_billed = true
entry.save
end
employee_id = User.find_by_id(issue.assigned_to_id).qbo_employee_id
# If the issue is closed, then create a new billable time activty for the customer
# TODO Add configuration settings for employee_id, hourly_rate, item_id
if issue.status.is_closed? and not issue.qbo_customer_id.nil? and not issue.qbo_item_id.nil? and not employee_id.nil? and spent_hours > 0 then
item = item_service.fetch_by_id issue.qbo_item_id
time_entry.description = "#{issue.tracker} ##{issue.id}: #{issue.subject}"
time_entry.employee_id = employee_id
time_entry.customer_id = issue.qbo_customer_id
time_entry.billable_status = "Billable"
time_entry.hours = hours
time_entry.minutes = minutes
time_entry.name_of = "Employee"
time_entry.txn_date = Date.today
time_entry.hourly_rate = item.unit_price
time_entry.item_id = issue.qbo_item_id
time_entry.start_time = issue.start_date
time_entry.end_time = Time.now
time_service.create(time_entry)
end
item = item_service.fetch_by_id issue.qbo_item_id
time_entry.description = "#{issue.tracker} ##{issue.id}: #{issue.subject}"
time_entry.employee_id = employee_id
time_entry.customer_id = issue.qbo_customer_id
time_entry.billable_status = "Billable"
time_entry.hours = hours
time_entry.minutes = minutes
time_entry.name_of = "Employee"
time_entry.txn_date = Date.today
time_entry.hourly_rate = item.unit_price
time_entry.item_id = issue.qbo_item_id
time_entry.start_time = issue.start_date
time_entry.end_time = Time.now
time_service.create(time_entry)
end
end
end

View File

@@ -10,31 +10,82 @@
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={})
value = ""
issue = context[:issue]
# Check to see if there is a quickbooks user attached to the issue
if not context[:issue].qbo_customer_id.nil? then
value = QboCustomers.find_by_id(context[:issue].qbo_customer_id).name
end
output = content_tag(:div, content_tag(:div, content_tag(:div, content_tag(:span,"Customer") + ":", class:"label") + content_tag(:div, value, class:"value") , class:"qbo_customer_id attribute"), class:"attributes")
value = ""
customer = issue.qbo_customer ? issue.qbo_customer.name : nil
# Check to see if there is a quickbooks item attached to the issue
if not context[:issue].qbo_customer_id.nil? then
if not QboItem.find_by_id(context[:issue].qbo_item_id).nil? then
value = QboItem.find_by_id(context[:issue].qbo_item_id).name
end
item = issue.qbo_item ? issue.qbo_item.name : nil
# Estimate Number
if issue.qbo_estimate
estimate = issue.qbo_estimate.doc_number
estimate_link = link_to estimate, "#{Redmine::Utils::relative_url_root}/qbo/estimate/#{issue.qbo_estimate.id}", :target => "_blank"
end
output << content_tag(:div, content_tag(:div, content_tag(:div, content_tag(:span,"Item") + ":", class:"label") + content_tag(:div, value, class:"value") , class:"qbo_item_id attribute"), class:"attributes")
# Display the Customers name in the Issue attributes
return output
end
# Invoice Number
if issue.qbo_invoice
invoice = issue.qbo_invoice.doc_number
invoice_link = link_to invoice, "#{Redmine::Utils::relative_url_root}/qbo/invoice/#{issue.qbo_invoice.id}", :target => "_blank"
end
if issue.vehicles_id
v = Vehicle.find_by_id(issue.vehicles_id)
vehicle = link_to v.to_s, "#{Redmine::Utils::relative_url_root}/vehicles/#{v.id}"
vin = v.vin
notes = v.notes
end
return "
<div class=\"attributes\">
<div class=\"qbo_customer_id attribute\">
<div class=\"label\"><span>Customer</span>:</div>
<div class=\"value\">#{customer}</div>
</div>
<div class=\"qbo_item_id attribute\">
<div class=\"label\"><span>Item</span>:</div>
<div class=\"value\">#{item}</div>
</div>
end
<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>
<br/>
<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\">#{vin}</div>
</div>
<div class=\"vehicle_notes attribute\">
<div class=\"label\"><span>Notes</span>:</div>
<div class=\"value\">#{notes}</div>
</div>
</div>"
end
end

246
lib/pdf_patch.rb Normal file
View File

@@ -0,0 +1,246 @@
require_dependency 'redmine/export/pdf'
require_dependency 'redmine/export/pdf/issues_pdf_helper'
module IssuesPdfHelperPatch
def self.included(base)
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
end
end
module InstanceMethods
def issue_to_pdf_with_patch(issue, assoc={})
pdf = ::Redmine::Export::PDF::ITCPDF.new(current_language)
pdf.set_title("#{issue.project} - #{issue.tracker} ##{issue.id}")
pdf.alias_nb_pages
pdf.footer_date = format_date(Date.today)
pdf.add_page
pdf.SetFontStyle('B',11)
buf = "#{issue.project} - #{issue.tracker} ##{issue.id}"
pdf.RDMMultiCell(190, 5, buf)
pdf.SetFontStyle('',8)
base_x = pdf.get_x
i = 1
issue.ancestors.visible.each do |ancestor|
pdf.set_x(base_x + i)
buf = "#{ancestor.tracker} # #{ancestor.id} (#{ancestor.status.to_s}): #{ancestor.subject}"
pdf.RDMMultiCell(190 - i, 5, buf)
i += 1 if i < 35
end
pdf.SetFontStyle('B',11)
pdf.RDMMultiCell(190 - i, 5, issue.subject.to_s)
pdf.SetFontStyle('',8)
pdf.RDMMultiCell(190, 5, "#{format_time(issue.created_on)} - #{issue.author}")
pdf.ln
left = []
left << [l(:field_status), issue.status]
left << [l(:field_priority), issue.priority]
left << [l(:field_qbo_customer), issue.qbo_customer.name]
left << [l(:field_assigned_to), issue.assigned_to] unless issue.disabled_core_fields.include?('assigned_to_id')
#left << [l(:field_category), issue.category] unless issue.disabled_core_fields.include?('category_id')
#left << [l(:field_fixed_version), issue.fixed_version] unless issue.disabled_core_fields.include?('fixed_version_id')
v = Vehicle.find_by_id(issue.vehicles_id)
vehicle = v ? v.to_s : nil
vin = v ? v.vin : nil
notes = v ? v.notes : nil
left << [l(:field_vehicles), vehicle]
left << [l(:field_vin), vin]
left << [l(:field_notes), notes]
right = []
right << [l(:field_start_date), format_date(issue.start_date)] unless issue.disabled_core_fields.include?('start_date')
right << [l(:field_due_date), format_date(issue.due_date)] unless issue.disabled_core_fields.include?('due_date')
right << [l(:field_done_ratio), "#{issue.done_ratio}%"] unless issue.disabled_core_fields.include?('done_ratio')
right << [l(:field_estimated_hours), l_hours(issue.estimated_hours)] unless issue.disabled_core_fields.include?('estimated_hours')
right << [l(:label_spent_time), l_hours(issue.total_spent_hours)] if User.current.allowed_to?(:view_time_entries, issue.project)
#right << [l(:field_notes), notes]
rows = left.size > right.size ? left.size : right.size
while left.size < rows
left << nil
end
while right.size < rows
right << nil
end
half = (issue.visible_custom_field_values.size / 2.0).ceil
issue.visible_custom_field_values.each_with_index do |custom_value, i|
(i < half ? left : right) << [custom_value.custom_field.name, show_value(custom_value, false)]
end
if pdf.get_rtl
border_first_top = 'RT'
border_last_top = 'LT'
border_first = 'R'
border_last = 'L'
else
border_first_top = 'LT'
border_last_top = 'RT'
border_first = 'L'
border_last = 'R'
end
rows = left.size > right.size ? left.size : right.size
rows.times do |i|
heights = []
pdf.SetFontStyle('B',9)
item = left[i]
heights << pdf.get_string_height(35, item ? "#{item.first}:" : "")
item = right[i]
heights << pdf.get_string_height(35, item ? "#{item.first}:" : "")
pdf.SetFontStyle('',9)
item = left[i]
heights << pdf.get_string_height(60, item ? item.last.to_s : "")
item = right[i]
heights << pdf.get_string_height(60, item ? item.last.to_s : "")
height = heights.max
item = left[i]
pdf.SetFontStyle('B',9)
pdf.RDMMultiCell(35, height, item ? "#{item.first}:" : "", (i == 0 ? border_first_top : border_first), '', 0, 0)
pdf.SetFontStyle('',9)
pdf.RDMMultiCell(60, height, item ? item.last.to_s : "", (i == 0 ? border_last_top : border_last), '', 0, 0)
item = right[i]
pdf.SetFontStyle('B',9)
pdf.RDMMultiCell(35, height, item ? "#{item.first}:" : "", (i == 0 ? border_first_top : border_first), '', 0, 0)
pdf.SetFontStyle('',9)
pdf.RDMMultiCell(60, height, item ? item.last.to_s : "", (i == 0 ? border_last_top : border_last), '', 0, 2)
pdf.set_x(base_x)
end
pdf.SetFontStyle('B',9)
pdf.RDMCell(35+155, 5, l(:field_description), "LRT", 1)
pdf.SetFontStyle('',9)
# Set resize image scale
pdf.set_image_scale(1.6)
text = textilizable(issue, :description,
:only_path => false,
:edit_section_links => false,
:headings => false,
:inline_attachments => false
)
pdf.RDMwriteFormattedCell(35+155, 5, '', '', text, issue.attachments, "LRB")
unless issue.leaf?
truncate_length = (!is_cjk? ? 90 : 65)
pdf.SetFontStyle('B',9)
pdf.RDMCell(35+155,5, l(:label_subtask_plural) + ":", "LTR")
pdf.ln
issue_list(issue.descendants.visible.sort_by(&:lft)) do |child, level|
buf = "#{child.tracker} # #{child.id}: #{child.subject}".
truncate(truncate_length)
level = 10 if level >= 10
pdf.SetFontStyle('',8)
pdf.RDMCell(35+135,5, (level >=1 ? " " * level : "") + buf, border_first)
pdf.SetFontStyle('B',8)
pdf.RDMCell(20,5, child.status.to_s, border_last)
pdf.ln
end
end
relations = issue.relations.select { |r| r.other_issue(issue).visible? }
unless relations.empty?
truncate_length = (!is_cjk? ? 80 : 60)
pdf.SetFontStyle('B',9)
pdf.RDMCell(35+155,5, l(:label_related_issues) + ":", "LTR")
pdf.ln
relations.each do |relation|
buf = relation.to_s(issue) {|other|
text = ""
if Setting.cross_project_issue_relations?
text += "#{relation.other_issue(issue).project} - "
end
text += "#{other.tracker} ##{other.id}: #{other.subject}"
text
}
buf = buf.truncate(truncate_length)
pdf.SetFontStyle('', 8)
pdf.RDMCell(35+155-60, 5, buf, border_first)
pdf.SetFontStyle('B',8)
pdf.RDMCell(20,5, relation.other_issue(issue).status.to_s, "")
pdf.RDMCell(20,5, format_date(relation.other_issue(issue).start_date), "")
pdf.RDMCell(20,5, format_date(relation.other_issue(issue).due_date), border_last)
pdf.ln
end
end
pdf.RDMCell(190,5, "", "T")
pdf.ln
if issue.changesets.any? &&
User.current.allowed_to?(:view_changesets, issue.project)
pdf.SetFontStyle('B',9)
pdf.RDMCell(190,5, l(:label_associated_revisions), "B")
pdf.ln
for changeset in issue.changesets
pdf.SetFontStyle('B',8)
csstr = "#{l(:label_revision)} #{changeset.format_identifier} - "
csstr += format_time(changeset.committed_on) + " - " + changeset.author.to_s
pdf.RDMCell(190, 5, csstr)
pdf.ln
unless changeset.comments.blank?
pdf.SetFontStyle('',8)
pdf.RDMwriteHTMLCell(190,5,'','',
changeset.comments.to_s, issue.attachments, "")
end
pdf.ln
end
end
if assoc[:journals].present?
pdf.SetFontStyle('B',9)
pdf.RDMCell(190,5, l(:label_history), "B")
pdf.ln
assoc[:journals].each do |journal|
pdf.SetFontStyle('B',8)
title = "##{journal.indice} - #{format_time(journal.created_on)} - #{journal.user}"
title << " (#{l(:field_private_notes)})" if journal.private_notes?
pdf.RDMCell(190,5, title)
pdf.ln
pdf.SetFontStyle('I',8)
details_to_strings(journal.visible_details, true).each do |string|
pdf.RDMMultiCell(190,5, "- " + string)
end
if journal.notes?
pdf.ln unless journal.details.empty?
pdf.SetFontStyle('',8)
text = textilizable(journal, :notes,
:only_path => false,
:edit_section_links => false,
:headings => false,
:inline_attachments => false
)
pdf.RDMwriteFormattedCell(190,5,'','', text, issue.attachments, "")
end
pdf.ln
end
end
if issue.attachments.any?
pdf.SetFontStyle('B',9)
pdf.RDMCell(190,5, l(:label_attachment_plural), "B")
pdf.ln
for attachment in issue.attachments
pdf.SetFontStyle('',8)
pdf.RDMCell(80,5, attachment.filename)
pdf.RDMCell(20,5, number_to_human_size(attachment.filesize),0,0,"R")
pdf.RDMCell(25,5, format_date(attachment.created_on),0,0,"R")
pdf.RDMCell(65,5, attachment.author.name,0,0,"R")
pdf.ln
end
end
pdf.output
end
end
end
Redmine::Export::PDF::IssuesPdfHelper.send(:include, IssuesPdfHelperPatch)

62
lib/query_patch.rb Normal file
View File

@@ -0,0 +1,62 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 'issue_query'
module QueryPatch
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
alias_method_chain :available_columns, :qbo
alias_method_chain :available_filters, :qbo
end
end
module ClassMethods
end
module InstanceMethods
def available_columns_with_qbo
unless @available_columns
@available_columns = available_columns_without_qbo
@available_columns << QueryColumn.new(:qbo_customer, :sortable => "#{QboCustomer.table_name}.name", :groupable => true, :caption => :field_qbo_customer)
end
@available_columns
end
def available_filters_with_qbo
unless @available_filters
@available_filters = available_filters_without_qbo
qbo_filters = {
"customer" => {
:name => l(:field_qbo_customer),
:type => :text,
:order => @available_filters.size + 1},
}
@available_filters.merge!(qbo_filters)
end
@available_filters
end
end
end
# Add module to Issue
IssueQuery.send(:include, QueryPatch)

39
lib/user_patch.rb Normal file
View File

@@ -0,0 +1,39 @@
#The MIT License (MIT)
#
#Copyright (c) 2016 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 'user'
# Patches Redmine's User dynamically.
# Adds a relationships
module UserPatch
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
belongs_to :qbo_employee, primary_key: :id
end
end
module ClassMethods
end
module InstanceMethods
end
end
# Add module to Issue
User.send(:include, UserPatch)

View File

@@ -12,16 +12,14 @@ class UsersShowHookListener < Redmine::Hook::ViewListener
# View User
def view_users_form(context={})
selected = ""
# Update the users
QboEmployee.update_all
# Check to see if there is a quickbooks user attached to the issue
if not context[:user].qbo_employee_id.nil? then
selected = context[:user].qbo_employee_id
end
@selected = context[:user].qbo_employee.id if context[:user].qbo_employee
# Generate the drop down list of quickbooks contacts
return "<p>#{context[:form].select :qbo_employee_id, QboEmployee.all.pluck(:name, :id), :selected => selected, include_blank: true}</p>"
return "<p>#{context[:form].select :qbo_employee_id, QboEmployee.all.pluck(:name, :id), :selected => @selected, include_blank: true}</p>"
end
end
end

View File

@@ -0,0 +1,8 @@
require File.expand_path('../../test_helper', __FILE__)
class EstimateControllerTest < ActionController::TestCase
# Replace this with your real tests.
def test_truth
assert true
end
end

View File

@@ -0,0 +1,8 @@
require File.expand_path('../../test_helper', __FILE__)
class InvoiceControllerTest < ActionController::TestCase
# Replace this with your real tests.
def test_truth
assert true
end
end