mirror of
https://github.com/rickbarrette/redmine_qbo.git
synced 2025-11-09 09:24:23 -05:00
Compare commits
250 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61adce1299 | |||
| daffb3719e | |||
| 1b8626d28f | |||
| b119344fad | |||
| 4381d403d4 | |||
| 26bfaca1d6 | |||
| 0c68d8094a | |||
| 6230175ba5 | |||
| 5dc4dc5637 | |||
| ac15307fb8 | |||
| ec5ce497d8 | |||
| 01fe52157d | |||
| 75737cf2fd | |||
| 7824edf5aa | |||
| 6b70b447a5 | |||
| 5a6b679099 | |||
| 72835dcf65 | |||
| b9e2349983 | |||
| ef13ec7e11 | |||
| 00b40da8c4 | |||
| 2be25adf18 | |||
| 5ab9a777f6 | |||
| 7fbb1d6ba3 | |||
| 786c80609c | |||
| efb554824d | |||
| c615abc896 | |||
| 8ecc3414da | |||
| 505def8d23 | |||
| da155de514 | |||
| 7d727e1ad8 | |||
| 3dcb5155fc | |||
| 4424593e63 | |||
| 8eae838ef8 | |||
| d5e8b4bbc4 | |||
| fc8efa53e9 | |||
| 15ea3aeaa2 | |||
| 35bf300f2d | |||
| 72bf10680f | |||
| bd8706deee | |||
| e8619529d4 | |||
| fd3c8e15e6 | |||
| 166c1d3002 | |||
| 773d60fb23 | |||
| cc46902095 | |||
| acb2628c7a | |||
| e4914590f8 | |||
| e3a8e464ae | |||
| 8a6bb45b6a | |||
| 3decf83a7b | |||
| 1b7b286d1b | |||
| a8804f6704 | |||
| 5d03e261d1 | |||
| 1ae766b8bd | |||
| 119c36569f | |||
| 3be69d5efd | |||
| b55dd99efd | |||
| eff1f97ab2 | |||
| 06050bd139 | |||
| a48840ddfb | |||
| 9b9aabee11 | |||
| 7782627286 | |||
| 41a113dc59 | |||
| b84e249dfb | |||
| 6b45f767a4 | |||
| a34b6a07fc | |||
| 2ce811bbbf | |||
| 02153de8b0 | |||
| 68be20459b | |||
| bbd03cc337 | |||
| 4fc71a93f2 | |||
| 8e7e1908e4 | |||
| 89fba883ef | |||
| 15f317fba1 | |||
| 894ee9abfd | |||
| ca17807117 | |||
| a70ba2f164 | |||
| 78ac97298c | |||
| 72cd349c1b | |||
| 6fc1d27dca | |||
| 525c6b99d6 | |||
| 3eaff0ab30 | |||
| 85b40bc9cf | |||
| 37a2b95447 | |||
| 33feb91713 | |||
| f7357f30ce | |||
| c0ae01018b | |||
| 4353e910c8 | |||
| bef9774c4e | |||
| 863437b1b7 | |||
| 7cfa15910a | |||
| 2154a3d001 | |||
| fdab090a3d | |||
| 3f32b7fef1 | |||
| 14422bc549 | |||
| 6bb66597e8 | |||
| 32b750b545 | |||
| 5fd3141746 | |||
| 2c38361234 | |||
| 81b7b1492d | |||
| 57ef1ac5a1 | |||
| 6597c5a13c | |||
| 8af97072fb | |||
| 48b6df0cef | |||
| 853b7ad804 | |||
| 6a74baff5e | |||
| 8b21b0ff75 | |||
| d22a6303cd | |||
| 807d6643f4 | |||
| c725c2774c | |||
| ae0abae333 | |||
| fed2282212 | |||
| 545960e676 | |||
| 66781f0625 | |||
| 504b9b93e4 | |||
| b71bba473c | |||
| aef3c453c4 | |||
| 6de3ed94dc | |||
| daada08ea7 | |||
| fa37c98500 | |||
| 0ee59704b3 | |||
| a22cbb9520 | |||
| c0d3f64d82 | |||
| 66d2bf4aa4 | |||
| 2b90c953ba | |||
| 0d5e5d679e | |||
| 4da891cc07 | |||
| d3475a9b53 | |||
| eb583f78ec | |||
| 47bebf0a1a | |||
| f9bd149f21 | |||
| 5371b0f193 | |||
| 95497e5514 | |||
| 1a74abe76c | |||
| 7f11d3cdc4 | |||
| da01d79325 | |||
| 82807cfede | |||
| a268d10819 | |||
| ba4bdd9ecb | |||
| 0a72e05e03 | |||
| 8d143ff06d | |||
| 3ddb585a58 | |||
| 1606ceb743 | |||
| 97578f8380 | |||
| 32beae70ef | |||
| 13fbc9e14f | |||
| c57a45c85e | |||
| 3711a9ca43 | |||
| d0c1693f38 | |||
| 36534ee129 | |||
| 188c460054 | |||
| d9e3cb096b | |||
| b57b19493f | |||
| 8c569db541 | |||
| 997257f42d | |||
| f9f1af17bc | |||
| f1f44d0048 | |||
| 7e8511090d | |||
| 4ca6a3138b | |||
| 21e1132e0e | |||
| dc15424014 | |||
| f90cdcd86b | |||
| 5e53c18098 | |||
| 52d13ea7bc | |||
| 5e24c5084e | |||
| abdb61cc41 | |||
| 03556cc670 | |||
| 7f6cd99aba | |||
| ba513fb950 | |||
| 837ddd722c | |||
| f2b0cd3748 | |||
| f2a8878af4 | |||
| 13fccec54b | |||
| eca2b986a9 | |||
| a06599b7f9 | |||
| 7fda4dc577 | |||
| 9e47152e12 | |||
| 83d21da41a | |||
| a692f03bfa | |||
| 994cdf908f | |||
| b022d17fc0 | |||
| 644899c0b5 | |||
| be3a3b920d | |||
| d546eb026f | |||
| fdc59feb13 | |||
| 186b726a7b | |||
|
|
fa362bad55 | ||
|
|
fcf55bb504 | ||
|
|
2185667665 | ||
|
|
772483817e | ||
|
|
178ddd32c7 | ||
| 08e047c90e | |||
| b3c3314385 | |||
| 9fd5e01bb4 | |||
| cd62f65fcd | |||
| fb40833abd | |||
| 6aae155933 | |||
| f9e0ae8fef | |||
| 489e335ca4 | |||
| 874d0b4db9 | |||
| 49e8f70b46 | |||
| 77ea20171e | |||
| 11d4034c37 | |||
| 64369470de | |||
| 7b483f3290 | |||
| 32bec79c28 | |||
| dfd9622ab7 | |||
| 334d3c930b | |||
| 8cf2f370bf | |||
| 3965bed6c4 | |||
| 52396eb384 | |||
| 9cfab7bea1 | |||
| c8ef3bbd4e | |||
| 39e7d3c062 | |||
| 6fa96e11df | |||
| ecde64193a | |||
| f701af9a4d | |||
| 6d99702a11 | |||
| 138f8f2c2f | |||
| 61ddf7378d | |||
| f5b72f30be | |||
| 1863b33955 | |||
| a4573fce1c | |||
| 0461801ee0 | |||
| 4c2eaac013 | |||
| 7ca56ccd2e | |||
| 915a59afa4 | |||
| ac61950d48 | |||
| b257fef563 | |||
| 504c27c197 | |||
| a7a5e2c731 | |||
| 21d72dcc33 | |||
| da7ba40e61 | |||
| b4d6fc55ea | |||
| 515b8feff7 | |||
| 8bc05db033 | |||
| 34cd6b08dc | |||
| 41195dc095 | |||
| 33a83c8f76 | |||
| 4f613d3fe1 | |||
| 1c7cdec600 | |||
| 7ae60c0e62 | |||
| 5dd04925e0 | |||
| 92eedbd4d3 | |||
| 5545d72adf | |||
| 226d44cd28 | |||
| b7152d6124 | |||
| f3e9b58c87 | |||
| 5209315236 | |||
| f38a9e1ff0 | |||
| 80fb296e24 |
5
Gemfile
5
Gemfile
@@ -6,7 +6,10 @@ gem 'oauth-plugin'
|
|||||||
gem 'oauth'
|
gem 'oauth'
|
||||||
gem 'roxml'
|
gem 'roxml'
|
||||||
gem 'edmunds_vin'
|
gem 'edmunds_vin'
|
||||||
gem 'will_paginate', '~> 3.1.0'
|
gem 'will_paginate'
|
||||||
|
gem 'rails-jquery-autocomplete'
|
||||||
|
gem 'jquery-rails', '~> 3.1.4'
|
||||||
|
gem 'jquery-ui-rails'
|
||||||
|
|
||||||
group :assets do
|
group :assets do
|
||||||
gem 'coffee-rails'
|
gem 'coffee-rails'
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016 Rick Barrette
|
Copyright (c) 2017 Rick Barrette
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
12
README.md
12
README.md
@@ -1,4 +1,4 @@
|
|||||||
#Redmine Quickbooks Online
|
# Redmine Quickbooks Online
|
||||||
|
|
||||||
A plugin for Redmine to connect to Quickbooks Online
|
A plugin for Redmine to connect to Quickbooks Online
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ The goal of this project is to allow Redmine to connect with Quickbooks Online t
|
|||||||
|
|
||||||
`Note: I am currently using this in a live production enviroment with no issues`
|
`Note: I am currently using this in a live production enviroment with no issues`
|
||||||
|
|
||||||
####Features
|
#### Features
|
||||||
* Issues can be assigned to a `Customer` via drop down in the edit Issue form
|
* Issues can be assigned to a `Customer` via drop down in the edit Issue form
|
||||||
* The `Employee` for the Issue is assigned via the assigned Redmine User
|
* The `Employee` for the Issue is assigned via the assigned Redmine User
|
||||||
- This is set via a drop down in the user admistration page.
|
- This is set via a drop down in the user admistration page.
|
||||||
@@ -27,14 +27,14 @@ The goal of this project is to allow Redmine to connect with Quickbooks Online t
|
|||||||
+ `Invoice` Custom Fields are matched Issue Custom Fileds and are automaticly updated in Quickbooks. For example, this is usefull for extracting the Mileage In / Out from the Issue and updating the Invoice with the information.
|
+ `Invoice` Custom Fields are matched Issue Custom Fileds and are automaticly updated in Quickbooks. For example, this is usefull for extracting the Mileage In / Out from the Issue and updating the Invoice with the information.
|
||||||
- `Customers` are automaticly updated in local database
|
- `Customers` are automaticly updated in local database
|
||||||
|
|
||||||
##Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
* Sign up to become a developer for Intuit https://developer.intuit.com/
|
* Sign up to become a developer for Intuit https://developer.intuit.com/
|
||||||
* Create your own aplication to obtain your API keys
|
* Create your own aplication to obtain your API keys
|
||||||
* Set up webhook service to https://redmine.yourdomain.com/qbo/webhook
|
* Set up webhook service to https://redmine.yourdomain.com/qbo/webhook
|
||||||
- See https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/webhooks
|
- See https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/webhooks
|
||||||
|
|
||||||
##The Install
|
## The Install
|
||||||
|
|
||||||
1. To install, clone this repo into your plugin folder
|
1. To install, clone this repo into your plugin folder
|
||||||
|
|
||||||
@@ -73,11 +73,11 @@ Note: After the inital synchronization, this plugin will recieve push notificati
|
|||||||
* Fix Issue sort by Customer
|
* Fix Issue sort by Customer
|
||||||
* MORE Stuff...
|
* MORE Stuff...
|
||||||
|
|
||||||
##License
|
## License
|
||||||
|
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2016 rick barrette
|
Copyright (c) 2017 rick barrette
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 106 KiB |
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
@@ -27,11 +27,26 @@ class CustomersController < ApplicationController
|
|||||||
include SortHelper
|
include SortHelper
|
||||||
helper :timelog
|
helper :timelog
|
||||||
|
|
||||||
before_filter :require_user, :except => :view
|
before_filter :add_customer, :only => :new
|
||||||
|
before_filter :view_customer, :except => :new
|
||||||
skip_before_filter :verify_authenticity_token, :check_if_login_required, :only => [:view]
|
skip_before_filter :verify_authenticity_token, :check_if_login_required, :only => [:view]
|
||||||
|
|
||||||
default_search_scope :names
|
default_search_scope :names
|
||||||
|
|
||||||
|
autocomplete :customer, :name, :full => false, :extra_data => [:id]
|
||||||
|
|
||||||
|
def filter_vehicles_by_customer
|
||||||
|
@filtered_vehicles = Vehicle.all.where(customer_id: params[:selected_customer])
|
||||||
|
end
|
||||||
|
|
||||||
|
def filter_invoices_by_customer
|
||||||
|
@filtered_invoices = QboInvoice.all.where(customer_id: params[:selected_customer])
|
||||||
|
end
|
||||||
|
|
||||||
|
def filter_estimates_by_customer
|
||||||
|
@filtered_estimates = QboEstimate.all.where(customer_id: params[:selected_customer])
|
||||||
|
end
|
||||||
|
|
||||||
# display a list of all customers
|
# display a list of all customers
|
||||||
def index
|
def index
|
||||||
if params[:search]
|
if params[:search]
|
||||||
@@ -105,9 +120,14 @@ class CustomersController < ApplicationController
|
|||||||
|
|
||||||
# Customer view for an issue
|
# Customer view for an issue
|
||||||
def view
|
def view
|
||||||
token = CustomerToken.where("token = ? and expires_at > ?", params[:token], Time.now)
|
|
||||||
if token.first
|
User.current = User.find_by lastname: 'Anonymous'
|
||||||
@issue = Issue.find token.first.issue_id
|
|
||||||
|
@token = CustomerToken.where("token = ? and expires_at > ?", params[:token], Time.now)
|
||||||
|
@token = @token.first
|
||||||
|
if @token
|
||||||
|
session[:token] = @token.token
|
||||||
|
@issue = Issue.find @token.issue_id
|
||||||
@journals = @issue.journals.
|
@journals = @issue.journals.
|
||||||
preload(:details).
|
preload(:details).
|
||||||
preload(:user => :email_address).
|
preload(:user => :email_address).
|
||||||
@@ -133,6 +153,14 @@ class CustomersController < ApplicationController
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def add_customer
|
||||||
|
global_check_permission(:add_customers)
|
||||||
|
end
|
||||||
|
|
||||||
|
def view_customer
|
||||||
|
global_check_permission(:view_customers)
|
||||||
|
end
|
||||||
|
|
||||||
def only_one_non_zero?( array )
|
def only_one_non_zero?( array )
|
||||||
found_non_zero = false
|
found_non_zero = false
|
||||||
array.each do |val|
|
array.each do |val|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -12,7 +12,8 @@ class InvoiceController < ApplicationController
|
|||||||
|
|
||||||
include AuthHelper
|
include AuthHelper
|
||||||
|
|
||||||
before_filter :require_user
|
before_filter :require_user, :unless => proc {|c| session[:token].nil? }
|
||||||
|
skip_before_filter :verify_authenticity_token, :check_if_login_required, :unless => proc {|c| session[:token].nil? }
|
||||||
|
|
||||||
#
|
#
|
||||||
# Downloads and forwards the invoice pdf
|
# Downloads and forwards the invoice pdf
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -12,7 +12,7 @@ class PaymentsController < ApplicationController
|
|||||||
|
|
||||||
include AuthHelper
|
include AuthHelper
|
||||||
|
|
||||||
before_filter :require_user
|
before_filter :check_permissions
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@payment = Payment.new
|
@payment = Payment.new
|
||||||
@@ -32,11 +32,17 @@ class PaymentsController < ApplicationController
|
|||||||
else
|
else
|
||||||
flash[:error] = @payment.errors.full_messages.to_sentence
|
flash[:error] = @payment.errors.full_messages.to_sentence
|
||||||
redirect_to new_customer_path
|
redirect_to new_customer_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def check_permissions
|
||||||
|
if !allowed_to?(:add_payments)
|
||||||
|
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def only_one_non_zero?( array )
|
def only_one_non_zero?( array )
|
||||||
found_non_zero = false
|
found_non_zero = false
|
||||||
array.each do |val|
|
array.each do |val|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
@@ -66,8 +66,12 @@ class QboController < ApplicationController
|
|||||||
# Manual Billing
|
# Manual Billing
|
||||||
def bill
|
def bill
|
||||||
i = Issue.find_by_id params[:id]
|
i = Issue.find_by_id params[:id]
|
||||||
|
if i.customer
|
||||||
i.bill_time
|
i.bill_time
|
||||||
redirect_to i, :flash => { :notice => "Successfully Billed #{i.customer.name}" }
|
redirect_to i, :flash => { :notice => "Successfully Billed #{i.customer.name}" }
|
||||||
|
else
|
||||||
|
redirect_to i, :flash => { :error => "Cannot bill without a customer assigned" }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Quickbooks Webhook Callback
|
# Quickbooks Webhook Callback
|
||||||
@@ -129,10 +133,10 @@ class QboController < ApplicationController
|
|||||||
Thread.new do
|
Thread.new do
|
||||||
if Qbo.exists?
|
if Qbo.exists?
|
||||||
Customer.sync
|
Customer.sync
|
||||||
|
QboInvoice.sync
|
||||||
QboItem.sync
|
QboItem.sync
|
||||||
QboEmployee.sync
|
QboEmployee.sync
|
||||||
QboEstimate.sync
|
QboEstimate.sync
|
||||||
QboInvoice.sync
|
|
||||||
|
|
||||||
# Record the last sync time
|
# Record the last sync time
|
||||||
Qbo.update_time_stamp
|
Qbo.update_time_stamp
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
@@ -57,6 +57,7 @@ class VehiclesController < ApplicationController
|
|||||||
def show
|
def show
|
||||||
begin
|
begin
|
||||||
@vehicle = Vehicle.find_by_id(params[:id])
|
@vehicle = Vehicle.find_by_id(params[:id])
|
||||||
|
@vin = @vehicle.vin.scan(/.{1,9}/) if @vehicle.vin
|
||||||
rescue ActiveRecord::RecordNotFound
|
rescue ActiveRecord::RecordNotFound
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
@@ -101,15 +102,6 @@ class VehiclesController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# returns a dynamic list of vehicles owned by a customer
|
|
||||||
def update_vehicles
|
|
||||||
@vehicles = Customer.find_by(customer_id: params[:customer_id].to_i).vehicles
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { render(:text => "not implemented") }
|
|
||||||
format.js
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def only_one_non_zero?( array )
|
def only_one_non_zero?( array )
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -11,8 +11,43 @@
|
|||||||
module AuthHelper
|
module AuthHelper
|
||||||
|
|
||||||
def require_user
|
def require_user
|
||||||
|
return unless session[:token].nil?
|
||||||
if !User.current.logged?
|
if !User.current.logged?
|
||||||
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def allowed_to?(action)
|
||||||
|
return false if User.current.nil?
|
||||||
|
project = Project.find(params[:project_id])
|
||||||
|
return false if project.nil?
|
||||||
|
return true if User.current.allowed_to?(action, project)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_permission(permission)
|
||||||
|
if !allowed_to?(permission)
|
||||||
|
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def global_check_permission(permission)
|
||||||
|
if !globaly_allowed_to?(permission)
|
||||||
|
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def globaly_allowed_to?( action)
|
||||||
|
return false if User.current.nil?
|
||||||
|
|
||||||
|
projects = Project.all
|
||||||
|
projects.each { |p|
|
||||||
|
if User.current.allowed_to?(action, p)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
}
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -13,6 +13,8 @@ class Customer < ActiveRecord::Base
|
|||||||
|
|
||||||
has_many :issues
|
has_many :issues
|
||||||
has_many :qbo_purchases
|
has_many :qbo_purchases
|
||||||
|
has_many :qbo_invoices
|
||||||
|
has_many :qbo_estimates
|
||||||
has_many :vehicles
|
has_many :vehicles
|
||||||
|
|
||||||
attr_accessible :name, :notes, :email, :primary_phone, :mobile_phone
|
attr_accessible :name, :notes, :email, :primary_phone, :mobile_phone
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -15,7 +15,7 @@ class CustomerToken < ActiveRecord::Base
|
|||||||
validates_presence_of :expires_at, :issue_id
|
validates_presence_of :expires_at, :issue_id
|
||||||
before_create :generate_token
|
before_create :generate_token
|
||||||
|
|
||||||
OAUTH_CONSUMER_SECRET = Setting.plugin_redmine_qbo['settingsOAuthConsumerSecret']
|
OAUTH_CONSUMER_SECRET = Setting.plugin_redmine_qbo['settingsOAuthConsumerSecret'] || 'CONFIGURE_QBO__' + SecureRandom.uuid
|
||||||
|
|
||||||
def generate_token
|
def generate_token
|
||||||
self.token = SecureRandom.base64(15).tr('+/=lIO0', OAUTH_CONSUMER_SECRET)
|
self.token = SecureRandom.base64(15).tr('+/=lIO0', OAUTH_CONSUMER_SECRET)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -10,44 +10,49 @@
|
|||||||
|
|
||||||
class QboEstimate < ActiveRecord::Base
|
class QboEstimate < ActiveRecord::Base
|
||||||
unloadable
|
unloadable
|
||||||
has_many :issues
|
|
||||||
attr_accessible :doc_number
|
|
||||||
validates_presence_of :id, :doc_number
|
|
||||||
|
|
||||||
|
has_and_belongs_to_many :issues
|
||||||
|
belongs_to :customer
|
||||||
|
attr_accessible :doc_number, :id
|
||||||
|
validates_presence_of :doc_number, :id
|
||||||
|
self.primary_key = :id
|
||||||
|
|
||||||
|
# return the QBO Estimate service
|
||||||
def self.get_base
|
def self.get_base
|
||||||
Qbo.get_base(:estimate)
|
Qbo.get_base(:estimate).service
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# sync all estimates
|
||||||
def self.sync
|
def self.sync
|
||||||
estimates = get_base.service.all
|
estimates = get_base.all
|
||||||
|
|
||||||
# Update the item table
|
|
||||||
transaction do
|
|
||||||
estimates.each { |estimate|
|
estimates.each { |estimate|
|
||||||
qbo_estimate = QboEstimate.find_or_create_by(id: estimate.id)
|
process_estimate(estimate)
|
||||||
qbo_estimate.doc_number = estimate.doc_number
|
|
||||||
qbo_estimate.id = estimate.id
|
|
||||||
qbo_estimate.save!
|
|
||||||
}
|
}
|
||||||
end
|
|
||||||
|
|
||||||
#remove deleted estimates
|
#remove deleted estimates
|
||||||
where.not(estimates.map(&:id)).destroy_all
|
where.not(estimates.map(&:id)).destroy_all
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# sync only one estimate
|
||||||
def self.sync_by_id(id)
|
def self.sync_by_id(id)
|
||||||
estimate = get_base.service.fetch_by_id(id)
|
process_estimate(get_base.fetch_by_id(id))
|
||||||
qbo_estimate = QboEstimate.find_or_create_by(id: estimate.id)
|
end
|
||||||
|
|
||||||
|
# update an estimate
|
||||||
|
def self.update(id)
|
||||||
|
# Update the item table
|
||||||
|
estimate = get_base.fetch_by_id(id)
|
||||||
|
qbo_estimate = find_or_create_by(id: id)
|
||||||
qbo_estimate.doc_number = estimate.doc_number
|
qbo_estimate.doc_number = estimate.doc_number
|
||||||
qbo_estimate.id = estimate.id
|
|
||||||
qbo_estimate.save!
|
qbo_estimate.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.update(id)
|
# process an estimate into the database
|
||||||
# Update the item table
|
def self.process_estimate(estimate)
|
||||||
estimate = get_base.service.fetch_by_id(id)
|
qbo_estimate = find_or_create_by(id: estimate.id)
|
||||||
qbo_estimate = QboEstimate.find_or_create_by(id: id)
|
|
||||||
qbo_estimate.doc_number = estimate.doc_number
|
qbo_estimate.doc_number = estimate.doc_number
|
||||||
|
qbo_estimate.customer_id = estimate.customer_ref.value
|
||||||
|
qbo_estimate.id = estimate.id
|
||||||
qbo_estimate.save!
|
qbo_estimate.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -12,6 +12,7 @@ class QboInvoice < ActiveRecord::Base
|
|||||||
unloadable
|
unloadable
|
||||||
|
|
||||||
has_and_belongs_to_many :issues
|
has_and_belongs_to_many :issues
|
||||||
|
belongs_to :customer
|
||||||
attr_accessible :doc_number, :id
|
attr_accessible :doc_number, :id
|
||||||
validates_presence_of :doc_number, :id
|
validates_presence_of :doc_number, :id
|
||||||
self.primary_key = :id
|
self.primary_key = :id
|
||||||
@@ -46,41 +47,65 @@ class QboInvoice < ActiveRecord::Base
|
|||||||
process_invoice invoice
|
process_invoice invoice
|
||||||
end
|
end
|
||||||
|
|
||||||
# processes the invoice into the system
|
private
|
||||||
def self.process_invoice(invoice)
|
|
||||||
|
|
||||||
is_changed = false
|
# Attach the invoice to the issue
|
||||||
|
def self.attach_to_issue(issue, invoice)
|
||||||
|
return if issue.nil?
|
||||||
|
|
||||||
# Scan the line items for hashtags and attach to the applicable issues
|
# skip this issue if the issue customer is not the same as the invoice customer
|
||||||
invoice.line_items.each { |line|
|
return if issue.customer_id != invoice.customer_ref.value.to_i
|
||||||
if line.description
|
|
||||||
line.description.scan(/#(\w+)/).flatten.each { |issue|
|
|
||||||
i = Issue.find_by_id(issue.to_i)
|
|
||||||
|
|
||||||
# Load the invoice into the database
|
# Load the invoice into the database
|
||||||
qbo_invoice = QboInvoice.find_or_create_by(id: invoice.id)
|
qbo_invoice = QboInvoice.find_or_create_by(id: invoice.id)
|
||||||
qbo_invoice.doc_number = invoice.doc_number
|
qbo_invoice.doc_number = invoice.doc_number
|
||||||
qbo_invoice.id = invoice.id
|
qbo_invoice.id = invoice.id
|
||||||
|
qbo_invoice.customer_id = invoice.customer_ref
|
||||||
qbo_invoice.save!
|
qbo_invoice.save!
|
||||||
|
|
||||||
# Attach the invoice to the issue
|
unless issue.qbo_invoices.include?(qbo_invoice)
|
||||||
unless i.qbo_invoices.include?(qbo_invoice)
|
issue.qbo_invoices << qbo_invoice
|
||||||
i.qbo_invoices << qbo_invoice
|
issue.save!
|
||||||
i.save!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
compare_custom_fields(issue, invoice)
|
||||||
|
end
|
||||||
|
|
||||||
|
# processes the invoice into the system
|
||||||
|
def self.process_invoice(invoice)
|
||||||
|
# Check the private notes
|
||||||
|
if not invoice.private_note.nil?
|
||||||
|
invoice.private_note.scan(/#(\w+)/).flatten.each { |issue|
|
||||||
|
attach_to_issue(Issue.find_by_id(issue.to_i), invoice)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Scan the line items for hashtags and attach to the applicable issues
|
||||||
|
invoice.line_items.each { |line|
|
||||||
|
if line.description
|
||||||
|
line.description.scan(/#(\w+)/).flatten.each { |issue|
|
||||||
|
attach_to_issue(Issue.find_by_id(issue.to_i), invoice)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.compare_custom_fields(issue, invoice)
|
||||||
|
is_changed = false
|
||||||
|
|
||||||
# update the invoive custom fields with infomation from the work ticket if available
|
# update the invoive custom fields with infomation from the work ticket if available
|
||||||
invoice.custom_fields.each { |cf|
|
invoice.custom_fields.each { |cf|
|
||||||
|
|
||||||
|
# TODO Add some hooks here
|
||||||
|
|
||||||
# VIN from the attached vehicle
|
# VIN from the attached vehicle
|
||||||
begin
|
begin
|
||||||
if cf.name.eql? "VIN"
|
if cf.name.eql? "VIN"
|
||||||
vin = Vehicle.find(i.vehicles_id).vin
|
vin = Vehicle.find(issue.vehicles_id).vin
|
||||||
break if vin.nil?
|
break if vin.nil?
|
||||||
if not cf.string_value.to_s.eql? vin
|
if not cf.string_value.to_s.eql? vin
|
||||||
cf.string_value = vin.to_s
|
cf.string_value = vin.to_s
|
||||||
is_changed = true
|
is_changed = true
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
@@ -89,7 +114,7 @@ class QboInvoice < ActiveRecord::Base
|
|||||||
|
|
||||||
# Custom Values
|
# Custom Values
|
||||||
begin
|
begin
|
||||||
value = i.custom_values.find_by(custom_field_id: CustomField.find_by_name(cf.name).id)
|
value = issue.custom_values.find_by(custom_field_id: CustomField.find_by_name(cf.name).id)
|
||||||
|
|
||||||
# Check to see if the value is blank...
|
# Check to see if the value is blank...
|
||||||
if not value.value.to_s.blank?
|
if not value.value.to_s.blank?
|
||||||
@@ -102,32 +127,28 @@ class QboInvoice < ActiveRecord::Base
|
|||||||
cf.string_value = value.value.to_s
|
cf.string_value = value.value.to_s
|
||||||
is_changed = true
|
is_changed = true
|
||||||
end
|
end
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
# Use the max milage
|
# Use the max milage
|
||||||
if cf.name.eql? "Mileage Out"
|
elsif cf.name.eql? "Mileage Out"
|
||||||
if cf.string_value.to_i < value.value.to_i or cf.string_value.blank?
|
if cf.string_value.to_i < value.value.to_i or cf.string_value.blank?
|
||||||
cf.string_value = value.value.to_s
|
cf.string_value = value.value.to_s
|
||||||
is_changed = true
|
is_changed = true
|
||||||
end
|
end
|
||||||
break
|
else
|
||||||
end
|
|
||||||
|
|
||||||
# Everything else
|
# Everything else
|
||||||
cf.string_value = value.value.to_s
|
cf.string_value = value.value.to_s
|
||||||
is_changed = true
|
is_changed = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
rescue
|
rescue
|
||||||
# Nothing to do here, there is no match
|
# Nothing to do here, there is no match
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
}
|
|
||||||
end
|
# TODO Add some hooks here
|
||||||
}
|
|
||||||
|
|
||||||
# Push updates
|
# Push updates
|
||||||
|
#invoice.sync_token += 1 if is_changed
|
||||||
get_base.update(invoice) if is_changed
|
get_base.update(invoice) if is_changed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
|
||||||
<th>Customer</th>
|
|
||||||
<td><%= customer.name %></td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<td><%= customer.email %></td>
|
<td><%= customer.email %></td>
|
||||||
|
|||||||
1
app/views/customers/filter_estimates_by_customer.js.erb
Normal file
1
app/views/customers/filter_estimates_by_customer.js.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
$('select#issue_qbo_estimate_id').html('<%= j content_tag(:option,'',:value=>"")+options_from_collection_for_select(@filtered_estimates, :id, :doc_number) %>');
|
||||||
1
app/views/customers/filter_vehicles_by_customer.js.erb
Normal file
1
app/views/customers/filter_vehicles_by_customer.js.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
$('select#issue_vehicles_id').html('<%= j content_tag(:option,'',:value=>"")+options_from_collection_for_select(@filtered_vehicles, :id, :to_s) %>');
|
||||||
@@ -1,12 +1,27 @@
|
|||||||
<h1>Customer #<%= @customer.id %></h1>
|
<div id="content">
|
||||||
<br/>
|
<h2>Customer #<%= @customer.id %></h2>
|
||||||
<h2>Details:</h2>
|
<br/>
|
||||||
<%= render :partial => 'customers/details', locals: {customer: @customer} %>
|
|
||||||
<br/>
|
<div class="subject">
|
||||||
<h2>Vehicles:</h2>
|
<div><h3><%= @customer.name %></h3></div>
|
||||||
<%= render :partial => 'vehicles/list' %>
|
</div>
|
||||||
<%= button_to "New Vehicle", new_customer_vehicle_path(@customer), method: :get %>
|
|
||||||
<br/>
|
<div class="attributes">
|
||||||
<br/>
|
|
||||||
<h2>Issues:</h2>
|
<div class="splitcontent">
|
||||||
<%= render :partial => 'issues/list_simple', locals: {issues: @issues} %>
|
<div class="splitcontentleft">
|
||||||
|
<h4>Details:</h4>
|
||||||
|
<%= render :partial => 'customers/details', locals: {customer: @customer} %>
|
||||||
|
</div>
|
||||||
|
<div class="splitcontentleft">
|
||||||
|
<h4>Vehicles:</h4>
|
||||||
|
<%= render :partial => 'vehicles/list' %>
|
||||||
|
<%= button_to "New Vehicle", new_customer_vehicle_path(@customer), method: :get %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<h2>Issues:</h2>
|
||||||
|
<%= render :partial => 'issues/list_simple', locals: {issues: @issues} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
<div class="subject">
|
<div class="subject">
|
||||||
<%= render_issue_subject_with_tree(@issue) %>
|
<%= render_issue_subject_with_tree(@issue) %>
|
||||||
|
This customer link expires in <%= distance_of_time_in_words(Time.now, @token.expires_at) %>
|
||||||
</div>
|
</div>
|
||||||
<p class="author">
|
<p class="author">
|
||||||
<%= authoring @issue.created_on, @issue.author %>.
|
<%= authoring @issue.created_on, @issue.author %>.
|
||||||
@@ -41,11 +42,11 @@
|
|||||||
rows.right l(:field_estimated_hours), issue_estimated_hours_details(@issue), :class => 'estimated-hours'
|
rows.right l(:field_estimated_hours), issue_estimated_hours_details(@issue), :class => 'estimated-hours'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if User.current.allowed_to_view_all_time_entries?(@project)
|
#if User.current.allowed_to_view_all_time_entries?(@project)
|
||||||
if @issue.total_spent_hours > 0
|
if @issue.total_spent_hours > 0
|
||||||
rows.right l(:label_spent_time), issue_spent_hours_details(@issue), :class => 'spent-time'
|
rows.right l(:label_spent_time), issue_spent_hours_details(@issue), :class => 'spent-time'
|
||||||
end
|
end
|
||||||
end
|
#end
|
||||||
end %>
|
end %>
|
||||||
<%= render_custom_fields_rows(@issue) %>
|
<%= render_custom_fields_rows(@issue) %>
|
||||||
<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
|
<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>VIN</th>
|
<th>VIN</th>
|
||||||
<td><%= vehicle.vin %></td>
|
<td><%= @vin[0] if @vin %><b><%=@vin[1] if @vin%></b></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -41,14 +41,7 @@
|
|||||||
<div class="clearfix">
|
<div class="clearfix">
|
||||||
Notes:
|
Notes:
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<p>
|
<%= f.text_area :notes, :cols => 60, :rows => 10, :no_label => true %>
|
||||||
<%= content_tag 'span', :id => "issue_description_and_toolbar", :style => (@vehicle.new_record? ? nil : 'display:none') do %>
|
|
||||||
<%= f.text_area :notes,
|
|
||||||
:cols => 60,
|
|
||||||
:rows => 10,
|
|
||||||
:no_label => true %>
|
|
||||||
<% end %>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
18
app/workers/email_worker.rb
Normal file
18
app/workers/email_worker.rb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#The MIT License (MIT)
|
||||||
|
#
|
||||||
|
#Copyright (c) 2017 rick barrette
|
||||||
|
#
|
||||||
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
# This sidekiq worker class will handle emailing weekly time reports
|
||||||
|
class EmailWorker
|
||||||
|
include Sidekiq::Worker
|
||||||
|
|
||||||
|
def perform()
|
||||||
|
# email something
|
||||||
|
end
|
||||||
|
end
|
||||||
15
assets/javascripts/application.js
Normal file
15
assets/javascripts/application.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
$(function() {
|
||||||
|
$("input#issue_customer_id").on("change", function() {
|
||||||
|
$.ajax({
|
||||||
|
url: "/filter_vehicles_by_customer",
|
||||||
|
type: "GET",
|
||||||
|
data: { selected_customer: $("input#issue_customer_id").val() }
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "/filter_estimates_by_customer",
|
||||||
|
type: "GET",
|
||||||
|
data: { selected_customer: $("input#issue_customer_id").val() }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
1
assets/javascripts/autocomplete-rails.js
Normal file
1
assets/javascripts/autocomplete-rails.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
!function(t){t.fn.railsAutocomplete=function(e){var a=function(){this.railsAutoCompleter||(this.railsAutoCompleter=new t.railsAutocomplete(this))};if(void 0!==t.fn.on){if(!e)return;return t(document).on("focus",e,a)}return this.live("focus",a)},t.railsAutocomplete=function(t){var e=t;this.init(e)},t.railsAutocomplete.options={showNoMatches:!0,noMatchesLabel:"no existing match"},t.railsAutocomplete.fn=t.railsAutocomplete.prototype={railsAutocomplete:"0.0.1"},t.railsAutocomplete.fn.extend=t.railsAutocomplete.extend=t.extend,t.railsAutocomplete.fn.extend({init:function(e){function a(t){return t.split(e.delimiter)}function i(t){return a(t).pop().replace(/^\s+/,"")}e.delimiter=t(e).attr("data-delimiter")||null,e.min_length=t(e).attr("data-min-length")||t(e).attr("min-length")||2,e.append_to=t(e).attr("data-append-to")||null,e.autoFocus=t(e).attr("data-auto-focus")||!1,t(e).autocomplete({appendTo:e.append_to,autoFocus:e.autoFocus,delay:t(e).attr("delay")||0,source:function(a,r){var n=this.element[0],o={term:i(a.term)};t(e).attr("data-autocomplete-fields")&&t.each(t.parseJSON(t(e).attr("data-autocomplete-fields")),function(e,a){o[e]=t(a).val()}),t.getJSON(t(e).attr("data-autocomplete"),o,function(){var a={};t.extend(a,t.railsAutocomplete.options),t.each(a,function(i,r){if(a.hasOwnProperty(i)){var n=t(e).attr("data-"+i);a[i]=n?n:r}}),0==arguments[0].length&&t.inArray(a.showNoMatches,[!0,"true"])>=0&&(arguments[0]=[],arguments[0][0]={id:"",label:a.noMatchesLabel}),t(arguments[0]).each(function(a,i){var r={};r[i.id]=i,t(e).data(r)}),r.apply(null,arguments),t(n).trigger("railsAutocomplete.source",arguments)})},change:function(e,a){if(t(this).is("[data-id-element]")&&""!==t(t(this).attr("data-id-element")).val()&&(t(t(this).attr("data-id-element")).val(a.item?a.item.id:"").trigger("change"),t(this).attr("data-update-elements"))){var i=t.parseJSON(t(this).attr("data-update-elements")),r=a.item?t(this).data(a.item.id.toString()):{};if(i&&""===t(i.id).val())return;for(var n in i){var o=t(i[n]);o.is(":checkbox")?null!=r[n]&&o.prop("checked",r[n]):o.val(a.item?r[n]:"").trigger("change")}}},search:function(){var t=i(this.value);return t.length<e.min_length?!1:void 0},focus:function(){return!1},select:function(i,r){if(r.item.value=r.item.value.toString(),-1!=r.item.value.toLowerCase().indexOf("no match")||-1!=r.item.value.toLowerCase().indexOf("too many results"))return t(this).trigger("railsAutocomplete.noMatch",r),!1;var n=a(this.value);if(n.pop(),n.push(r.item.value),null!=e.delimiter)n.push(""),this.value=n.join(e.delimiter);else if(this.value=n.join(""),t(this).attr("data-id-element")&&t(t(this).attr("data-id-element")).val(r.item.id).trigger("change"),t(this).attr("data-update-elements")){var o=r.item,l=-1!=r.item.value.indexOf("Create New")?!0:!1,u=t.parseJSON(t(this).attr("data-update-elements"));for(var s in u)"checkbox"===t(u[s]).attr("type")?o[s]===!0||1===o[s]?t(u[s]).attr("checked","checked"):t(u[s]).removeAttr("checked"):l&&o[s]&&-1==o[s].indexOf("Create New")||!l?t(u[s]).val(o[s]).trigger("change"):t(u[s]).val("").trigger("change")}var c=this.value;return t(this).bind("keyup.clearId",function(){t.trim(t(this).val())!=t.trim(c)&&(t(t(this).attr("data-id-element")).val("").trigger("change"),t(this).unbind("keyup.clearId"))}),t(e).trigger("railsAutocomplete.select",r),!1}}),t(e).trigger("railsAutocomplete.init")}}),t(document).ready(function(){t("input[data-autocomplete]").railsAutocomplete("input[data-autocomplete]")})}(jQuery);
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
$("#issue_vehicles_id").empty()
|
|
||||||
.append("<%= escape_javascript(render(:partial => @vehicles)) %>")
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
|
|
||||||
function customerSelected() {
|
|
||||||
customer_id = $('issue_customer_id').getValue();
|
|
||||||
console.log(customer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.observe('dom:loaded', function() {
|
|
||||||
customerSelected();
|
|
||||||
$('issue_customer_id').observe('change', customerSelected);
|
|
||||||
});
|
|
||||||
@@ -34,12 +34,15 @@ resources :payments
|
|||||||
#webhook
|
#webhook
|
||||||
post 'qbo/webhook', :to => 'qbo#qbo_webhook'
|
post 'qbo/webhook', :to => 'qbo#qbo_webhook'
|
||||||
|
|
||||||
#ajax
|
#java script routes
|
||||||
get "update_vehicles" => 'vehicles#update_vehicles', as: 'update_vehicles'
|
get 'filter_vehicles_by_customer' => 'customers#filter_vehicles_by_customer'
|
||||||
|
get 'filter_estimates_by_customer' => 'customers#filter_estimates_by_customer'
|
||||||
|
get 'filter_invoices_by_customer' => 'customers#filter_invoices_by_customer'
|
||||||
|
|
||||||
# Nest Vehicles under customers
|
# Nest Vehicles under customers
|
||||||
resources :customers do
|
resources :customers do
|
||||||
resources :vehicles
|
resources :vehicles
|
||||||
|
get :autocomplete_customer_name, :on => :collection
|
||||||
end
|
end
|
||||||
|
|
||||||
#allow for just vehicles too
|
#allow for just vehicles too
|
||||||
|
|||||||
16
db/migrate/024_update_invoices_and_estimates.rb
Normal file
16
db/migrate/024_update_invoices_and_estimates.rb
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#The MIT License (MIT)
|
||||||
|
#
|
||||||
|
#Copyright (c) 2017 rick barrette
|
||||||
|
#
|
||||||
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
class UpdateInvoicesAndEstimates < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_reference :qbo_invoices, :customer, index: true
|
||||||
|
add_reference :qbo_estimates, :customer, index: true
|
||||||
|
end
|
||||||
|
end
|
||||||
26
init.rb
26
init.rb
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -23,15 +23,12 @@ Redmine::Plugin.register :redmine_qbo do
|
|||||||
require_dependency 'query_patch'
|
require_dependency 'query_patch'
|
||||||
require_dependency 'time_entry_query_patch'
|
require_dependency 'time_entry_query_patch'
|
||||||
require_dependency 'pdf_patch'
|
require_dependency 'pdf_patch'
|
||||||
|
require_dependency 'attachments_controller_patch'
|
||||||
Rails.configuration.to_prepare do
|
|
||||||
Redmine::Search.available_search_types << 'customers'
|
|
||||||
end
|
|
||||||
|
|
||||||
name 'Redmine Quickbooks Online plugin'
|
name 'Redmine Quickbooks Online plugin'
|
||||||
author 'Rick Barrette'
|
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'
|
description 'This is a plugin for Redmine to intergrate with Quickbooks Online to allow for seamless intergration CRM and invoicing of completed issues'
|
||||||
version '0.4.1'
|
version '0.5.0'
|
||||||
url 'https://github.com/rickbarrette/redmine_qbo'
|
url 'https://github.com/rickbarrette/redmine_qbo'
|
||||||
author_url 'http://rickbarrette.org'
|
author_url 'http://rickbarrette.org'
|
||||||
settings :default => {'empty' => true}, :partial => 'qbo/settings'
|
settings :default => {'empty' => true}, :partial => 'qbo/settings'
|
||||||
@@ -51,17 +48,20 @@ Redmine::Plugin.register :redmine_qbo do
|
|||||||
# set per_page globally
|
# set per_page globally
|
||||||
WillPaginate.per_page = 10
|
WillPaginate.per_page = 10
|
||||||
|
|
||||||
|
permission :view_customers, :customers => :index, :public => false
|
||||||
|
permission :add_customers, :customers => :new, :public => false
|
||||||
|
permission :view_payments, :payments => :index, :public => false
|
||||||
|
permission :add_payments, :payments => :new, :public => false
|
||||||
|
permission :view_vehicles, :payments => :new, :public => false
|
||||||
|
|
||||||
# Register QBO top menu item
|
# Register QBO top menu item
|
||||||
#menu :top_menu, :qbo, { :controller => :qbo, :action => :index }, :caption => 'Quickbooks', :if => Proc.new { User.current.admin? }
|
#menu :top_menu, :qbo, { :controller => :qbo, :action => :index }, :caption => 'Quickbooks', :if => Proc.new { User.current.admin? }
|
||||||
menu :top_menu, :customers, { :controller => :customers, :action => :index }, :caption => 'Customers', :if => Proc.new { User.current.logged? }
|
menu :top_menu, :customers, { :controller => :customers, :action => :index }, :caption => 'Customers', :if => Proc.new {User.current.logged?}
|
||||||
menu :top_menu, :vehicles, { :controller => :vehicles, :action => :index }, :caption => 'Vehicles', :if => Proc.new { User.current.logged? }
|
menu :top_menu, :vehicles, { :controller => :vehicles, :action => :index }, :caption => 'Vehicles', :if => Proc.new { User.current.allowed_to?(:view_vehicles, @project) }
|
||||||
|
|
||||||
menu :application_menu, :new_customer, { :controller => :customers, :action => :new }, :caption => 'New Customer', :if => Proc.new { User.current.logged? }
|
menu :application_menu, :new_customer, { :controller => :customers, :action => :new }, :caption => 'New Customer', :if => Proc.new { User.current.allowed_to?(:add_customers, @project) }
|
||||||
menu :application_menu, :new_payment, { :controller => :payments, :action => :new }, :caption => 'New Payment', :if => Proc.new { User.current.logged? }
|
menu :application_menu, :new_payment, { :controller => :payments, :action => :new }, :caption => 'New Payment', :if => Proc.new { User.current.allowed_to?(:add_payments, @project)}
|
||||||
|
|
||||||
permission :customers, { :customers => [:index, :new] }, :public => false
|
|
||||||
menu :project_menu, :customers, { :controller => 'customers', :action => 'new' }, :caption => 'New Customer', :after => :new_issue, :param => :project_id
|
menu :project_menu, :customers, { :controller => 'customers', :action => 'new' }, :caption => 'New Customer', :after => :new_issue, :param => :project_id
|
||||||
|
|
||||||
permission :payments, { :payments => [:index, :new] }, :public => false
|
|
||||||
menu :project_menu, :payments, { :controller => 'payments', :action => 'new' }, :caption => 'New Payment', :after => :customers, :param => :project_id
|
menu :project_menu, :payments, { :controller => 'payments', :action => 'new' }, :caption => 'New Payment', :after => :customers, :param => :project_id
|
||||||
end
|
end
|
||||||
|
|||||||
38
lib/attachments_controller_patch.rb
Normal file
38
lib/attachments_controller_patch.rb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#The MIT License (MIT)
|
||||||
|
#
|
||||||
|
#Copyright (c) 2017 rick barrette
|
||||||
|
#
|
||||||
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
require_dependency 'attachments_controller'
|
||||||
|
|
||||||
|
module AttachmentsControllerPatch
|
||||||
|
|
||||||
|
def self.included(base) # :nodoc:
|
||||||
|
base.extend(ClassMethods)
|
||||||
|
|
||||||
|
base.send(:include, InstanceMethods)
|
||||||
|
|
||||||
|
# Same as typing in the class
|
||||||
|
base.class_eval do
|
||||||
|
unloadable # Send unloadable so it will not be unloaded in development
|
||||||
|
|
||||||
|
skip_before_action :read_authorize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module InstanceMethods
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add module to AttachmentsController
|
||||||
|
AttachmentsController.send(:include, AttachmentsControllerPatch)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
@@ -72,7 +72,7 @@ module IssuePatch
|
|||||||
item = item_service.query("SELECT * FROM Item WHERE Name = '#{key}' ").first
|
item = item_service.query("SELECT * FROM Item WHERE Name = '#{key}' ").first
|
||||||
next if item.nil?
|
next if item.nil?
|
||||||
|
|
||||||
time_entry.description = "#{tracker} ##{id}: #{subject} #{"(Partial)" if not closed?}"
|
time_entry.description = "#{tracker} ##{id}: #{subject} #{"(Partial @ #{done_ratio}%)" if not closed?}"
|
||||||
# TODO entry.user.qbo_employee.id
|
# TODO entry.user.qbo_employee.id
|
||||||
time_entry.employee_id = assigned_to.qbo_employee_id
|
time_entry.employee_id = assigned_to.qbo_employee_id
|
||||||
time_entry.customer_id = customer_id
|
time_entry.customer_id = customer_id
|
||||||
@@ -93,7 +93,7 @@ module IssuePatch
|
|||||||
|
|
||||||
# Create a shareable link for a customer
|
# Create a shareable link for a customer
|
||||||
def share_token
|
def share_token
|
||||||
CustomerToken.create(:expires_at => Time.now + 24.hours, :issue_id => id)
|
CustomerToken.create(:expires_at => Time.now + 1.month, :issue_id => id)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
#
|
#
|
||||||
@@ -12,8 +12,8 @@ class IssuesFormHookListener < Redmine::Hook::ViewListener
|
|||||||
|
|
||||||
# Load the javascript
|
# Load the javascript
|
||||||
def view_layouts_base_html_head(context = {})
|
def view_layouts_base_html_head(context = {})
|
||||||
js = javascript_include_tag 'vehicles', :plugin => 'redmine_qbo'
|
js = javascript_include_tag 'application', :plugin => 'redmine_qbo'
|
||||||
#js += javascript_include_tag 'update_vehicles', :plugin => 'redmine_qbo'
|
js += javascript_include_tag 'autocomplete-rails', :plugin => 'redmine_qbo'
|
||||||
return js
|
return js
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -27,25 +27,24 @@ class IssuesFormHookListener < Redmine::Hook::ViewListener
|
|||||||
selected_estimate = context[:issue].qbo_estimate ? context[:issue].qbo_estimate.id : nil
|
selected_estimate = context[:issue].qbo_estimate ? context[:issue].qbo_estimate.id : nil
|
||||||
selected_vehicle = context[:issue].vehicles_id ? context[:issue].vehicles_id : nil
|
selected_vehicle = context[:issue].vehicles_id ? context[:issue].vehicles_id : nil
|
||||||
|
|
||||||
# Load customer information without callbacks
|
# Load customer information
|
||||||
customer = Customer.find_by_id(selected_customer) if selected_customer
|
customer = Customer.find_by_id(selected_customer) if selected_customer
|
||||||
select_customer = f.select :customer_id,
|
search_customer = f.autocomplete_field :customer, autocomplete_customer_name_customers_path, :selected => selected_customer, :update_elements => {:id => '#issue_customer_id', :value => '#issue_customer'}
|
||||||
Customer.all.pluck(:name, :id).sort,
|
customer_id = f.hidden_field :customer_id, :id => "issue_customer_id"
|
||||||
:selected => selected_customer,
|
|
||||||
include_blank: true,
|
|
||||||
onchange: "$customerSelected;"
|
|
||||||
|
|
||||||
# Generate the drop down list of quickbooks extimates
|
|
||||||
select_estimate = f.select :qbo_estimate_id, QboEstimate.all.pluck(:doc_number, :id).sort! {|x, y| y <=> x}, :selected => selected_estimate, include_blank: true
|
|
||||||
|
|
||||||
if context[:issue].customer
|
if context[:issue].customer
|
||||||
vehicles = customer.vehicles.pluck(:name, :id).sort!
|
vehicles = customer.vehicles.pluck(:name, :id).sort!
|
||||||
|
estimates = customer.qbo_estimates.pluck(:doc_number, :id).sort! {|x, y| y <=> x}
|
||||||
else
|
else
|
||||||
vehicles = Vehicle.all.order(:name).pluck(:name, :id)
|
vehicles = [nil].compact
|
||||||
|
estimates = [nil].compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Generate the drop down list of quickbooks extimates
|
||||||
|
select_estimate = f.select :qbo_estimate_id, estimates, :selected => selected_estimate, include_blank: true
|
||||||
|
|
||||||
vehicle = f.select :vehicles_id, vehicles, :selected => selected_vehicle, include_blank: true
|
vehicle = f.select :vehicles_id, vehicles, :selected => selected_vehicle, include_blank: true
|
||||||
|
|
||||||
return "<p>#{select_customer}</p> <p>#{select_estimate}</p> <p>#{vehicle}</p>"
|
return "<p><label for=\"issue_customer\">Customer</label>#{search_customer} #{customer_id}</p> <p>#{select_estimate}</p> <p>#{vehicle}</p>"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ module IssuesPdfHelperPatch
|
|||||||
vin = v ? v.vin : nil
|
vin = v ? v.vin : nil
|
||||||
notes = v ? v.notes : nil
|
notes = v ? v.notes : nil
|
||||||
left << [l(:field_vehicles), vehicle]
|
left << [l(:field_vehicles), vehicle]
|
||||||
left << [l(:field_vin), vin.gsub(/(.{9})/, '\1 ')]
|
left << [l(:field_vin), vin ? vin.gsub(/(.{9})/, '\1 ') : nil]
|
||||||
#left << [l(:field_notes), notes]
|
#left << [l(:field_notes), notes]
|
||||||
|
|
||||||
right = []
|
right = []
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
@@ -36,7 +36,7 @@ module QueryPatch
|
|||||||
unless @available_columns
|
unless @available_columns
|
||||||
@available_columns = available_columns_without_qbo
|
@available_columns = available_columns_without_qbo
|
||||||
@available_columns << QueryColumn.new(:customer, :sortable => "#{Customer.table_name}.name", :groupable => true, :caption => :field_customer)
|
@available_columns << QueryColumn.new(:customer, :sortable => "#{Customer.table_name}.name", :groupable => true, :caption => :field_customer)
|
||||||
@available_columns << QueryColumn.new(:qbo_billed, :sortable => "#{TimeEntry.table_name}.name", :groupable => true, :caption => :field_qbo_billed)
|
@available_columns << QueryColumn.new(:qbo_billed, :sortable => "#{TimeEntry.table_name}.qbo_billed", :groupable => true, :caption => :field_qbo_billed)
|
||||||
end
|
end
|
||||||
@available_columns
|
@available_columns
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#The MIT License (MIT)
|
#The MIT License (MIT)
|
||||||
#
|
#
|
||||||
#Copyright (c) 2016 rick barrette
|
#Copyright (c) 2017 rick barrette
|
||||||
#
|
#
|
||||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
#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:
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user