285 Commits
0.0.4 ... 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
34 changed files with 1029 additions and 68 deletions

View File

@@ -1,8 +1,10 @@
source 'https://rubygems.org'
gem 'quickbooks-ruby', :git => 'https://github.com/rickbarrette/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'

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

@@ -10,13 +10,18 @@
class EstimateController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
#
# Downloads and forwards the estimate pdf
#
def show
base = QboEstimate.get_base.service
@pdf = base.pdf(base.fetch_by_id(params[:id]))
send_data @pdf, filename: "estimate.pdf", :disposition => 'inline', :type => "application/pdf"
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

@@ -10,12 +10,17 @@
class InvoiceController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
#
# Downloads and forwards the invoice pdf
#
def show
base = QboInvoice.get_base.service
@pdf = base.pdf(base.fetch_by_id(params[:id]))
send_data @pdf, filename: "invoice.pdf", :disposition => 'inline', :type => "application/pdf"
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

@@ -11,6 +11,10 @@
class QboController < ApplicationController
unloadable
include AuthHelper
before_filter :require_user
#
# Called when the QBO Top Menu us shown
#

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,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,33 +10,119 @@
class QboCustomer < ActiveRecord::Base
unloadable
has_many :issues
has_many :qbo_purchases
has_many :vehicles
attr_accessible :name
validates_presence_of :id, :name
def self.get_base
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
def self.get_customer (id)
get_base.service.find_by_id(id)
# returns the QBO customer
def get_customer (id)
get_base.find_by_id(id)
end
def self.update_all
# 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

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

@@ -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

@@ -16,3 +16,6 @@ en:
field_qbo_employee: "Employee"
field_qbo_invoice: "Invoice"
field_qbo_estimate: "Estimate"
field_vehicles: "Vehicle"
field_vin: "VIN"
field_notes: "Notes"

View File

@@ -17,3 +17,5 @@ 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,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

13
init.rb
View File

@@ -19,11 +19,13 @@ Redmine::Plugin.register :redmine_qbo do
# 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.4'
version '0.0.5'
url 'https://github.com/rickbarrette/redmine_qbo'
author_url 'http://rickbarrette.org'
settings :default => {'empty' => true}, :partial => 'qbo/settings'
@@ -33,13 +35,18 @@ Redmine::Plugin.register :redmine_qbo do
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
# Register QBO top menu item
menu :top_menu, :qbo, { :controller => 'qbo', :action => 'index' }, :caption => 'Quickbooks'
# set per_page globally
WillPaginate.per_page = 10
# 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

View File

@@ -13,6 +13,7 @@ require_dependency 'issue'
# Patches Redmine's Issues dynamically.
# Adds a relationships
module IssuePatch
def self.included(base) # :nodoc:
base.extend(ClassMethods)
@@ -25,7 +26,9 @@ module IssuePatch
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

View File

@@ -13,32 +13,36 @@ class IssuesFormHookListener < Redmine::Hook::ViewListener
# Edit Issue Form
# Show a dropdown for quickbooks contacts
def view_issues_form_details_bottom(context={})
# Update the customer and item database
#QboCustomer.update_all
#QboItem.update_all
#QboInvoice.update_all
#QboEstimate.update_all
f = context[:form]
# Check to see if there is a quickbooks user attached to the issue
@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
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 = context[:form].select :qbo_customer_id, QboCustomer.all.pluck(:name, :id).sort, :selected => selected_customer, include_blank: true
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 items
@select_item = context[:form].select :qbo_item_id, QboItem.all.pluck(:name, :id).sort, :selected => selected_item, include_blank: true
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 = context[:form].select :qbo_invoice_id, QboInvoice.all.pluck(:doc_number, :id).sort! {|x, y| y <=> x}, :selected => selected_invoice, include_blank: true
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 = context[:form].select :qbo_estimate_id, QboEstimate.all.pluck(:doc_number, :id).sort! {|x, y| y <=> x}, :selected => selected_estimate, include_blank: true
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
return "<p>#{@select_customer}</p> <p>#{@select_item}</p> <p>#{@select_invoice}</p> <p>#{@select_estimate} #{@estimates_link}</p>"
#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

View File

@@ -21,46 +21,69 @@ class IssuesShowHookListener < Redmine::Hook::ViewListener
issue = context[:issue]
# Check to see if there is a quickbooks user attached to the issue
@customer = issue.qbo_customer ? issue.qbo_customer.name : nil
customer = issue.qbo_customer ? issue.qbo_customer.name : nil
# Check to see if there is a quickbooks item attached to the issue
@item = issue.qbo_item ? issue.qbo_item.name : nil
item = issue.qbo_item ? issue.qbo_item.name : nil
@estimate = nil
@estimate_link = 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"
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
@invoice = nil
@invo = nil
# 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"
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
return "<div class=\"attributes\">
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 class=\"value\">#{customer}</div>
</div>
<div class=\"qbo_item_id attribute\">
<div class=\"label\"><span>Item</span>:</div>
<div class=\"value\">#{@item}</div>
<div class=\"value\">#{item}</div>
</div>
<div class=\"qbo_estimate_id attribute\">
<div class=\"label\"><span>Estimate</span>:</div>
<div class=\"value\">#{@estimate_link}</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 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

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)