mirror of
https://github.com/rickbarrette/redmine_qbo.git
synced 2025-11-08 08:54:23 -05:00
Compare commits
337 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d6aebfcb99 | |||
| 2085eb7869 | |||
| c101a86f02 | |||
| 2d32769a59 | |||
| a2f755388e | |||
| 8a8f1af2bd | |||
| 4582b8c5b9 | |||
| f66fbf6656 | |||
| 41d49ccce5 | |||
| c85f450742 | |||
| e314dae10d | |||
| b1192a1912 | |||
| 7cc8a946fd | |||
| 4b34852c72 | |||
| 5d7fc9dabd | |||
| db61952e67 | |||
| 016dca242c | |||
| 983811af97 | |||
| d18a9726ac | |||
| cdef838d3e | |||
| 7703d724e1 | |||
| 94b5efbd00 | |||
| f43020b864 | |||
| 0d0f808305 | |||
| 279e8b15e0 | |||
| 099f729303 | |||
| 5150a31cdb | |||
| b5d17dc862 | |||
| e6c5feb3f3 | |||
| 5573e941c6 | |||
| 29dbca20e0 | |||
| d6c114d52b | |||
| 87b8daf283 | |||
| 719abe20a6 | |||
| 4a5b83265d | |||
| 8d103d3fc6 | |||
| 9310f207a3 | |||
| 000b67b329 | |||
| ebee9395ba | |||
| 2cd6731f0c | |||
| ebdbd25082 | |||
| 18ada91fcd | |||
| 1cf3926585 | |||
| e776deeece | |||
| 8c2f30949a | |||
| 015a989f72 | |||
| 0d4d5a6136 | |||
| 0364989fe1 | |||
| fb47eaba0e | |||
| 725d511be5 | |||
| fd85f296de | |||
| 9549bb8fe2 | |||
| 6a1c8b0551 | |||
| 086632e804 | |||
| d37ff922fc | |||
| 3483efa100 | |||
| f65eea2820 | |||
| a4111e0a11 | |||
| ebe5373d82 | |||
| 5b8c7d42c5 | |||
| b8fc57d583 | |||
| 7c42197cb1 | |||
| cc0ffce892 | |||
| 0fd2abbec3 | |||
| 215b219a6d | |||
| ea71542d81 | |||
| 5dbf486b50 | |||
| b734125d6b | |||
| 06e6295c6e | |||
| fd383ad9d4 | |||
| 4eb6c533f1 | |||
| 5af7d73768 | |||
| 1d0ae34261 | |||
| 21656b3e14 | |||
| 131976cd71 | |||
| 88c1b9c9a2 | |||
| 5ea9aed3cb | |||
| 41e10d9b0e | |||
| 45859bef3e | |||
| f5c40738dc | |||
| bfa37ee634 | |||
| 787b55f3d7 | |||
| 61f882e98c | |||
| 37db0d3d72 | |||
| 4f2dec3069 | |||
| 35a7c3cfeb | |||
| cbbaf5a95c | |||
| 647923e5e6 | |||
| 70ca4e9964 | |||
| 7fb40ad4a8 | |||
| 36083d23a0 | |||
| 2ec57f2bbf | |||
| 278708e566 | |||
| 23f2b92e8d | |||
| 5d92eeddfb | |||
| 384a8c033c | |||
| 32b12b60f9 | |||
| 93db447239 | |||
| 19a6180e15 | |||
| 3408ee173c | |||
| b817e842dd | |||
| 51c3b8338e | |||
| c6a3edfbc1 | |||
| 21d8d90465 | |||
| 04c0fa57c6 | |||
| f5ad761712 | |||
| 9b80485915 | |||
| 87de865c00 | |||
| 1ea27e8511 | |||
| 8f0ca00b09 | |||
| 859a1d505b | |||
| cd109653a2 | |||
| cab723bbcd | |||
| 3dd712629b | |||
| cdf2603e12 | |||
| 5df9d324bc | |||
| f78c0338b4 | |||
| fe6aa7908f | |||
| aa45338e36 | |||
| 213dca2621 | |||
| fee710d717 | |||
| 65eac58f6c | |||
| b4f5112fc3 | |||
| fa5dcbf9a9 | |||
| e0aebb1c23 | |||
| 6d176acc2b | |||
| 9e9b29fef9 | |||
| 1af846537d | |||
| d6c5daff49 | |||
| 61c76ad80a | |||
| 0d514790fd | |||
| 748d431d35 | |||
| 87b8d99c41 | |||
| a0da53b6cf | |||
| 02d630c631 | |||
| 15b214c800 | |||
| 1b5e185087 | |||
| 102309600e | |||
| 6acc7db91b | |||
| 02898883a8 | |||
| ce02b70bc3 | |||
| d4d4a555f8 | |||
| c2663cd0a0 | |||
| d48609361f | |||
| 70995f6e55 | |||
| 05a0472939 | |||
| cff9f3fde3 | |||
| e24b704571 | |||
| 4d99f54c79 | |||
| e65725c334 | |||
| 4829daab7c | |||
| 260e9f3e4a | |||
| e3ce2445b8 | |||
| 2b333667ed | |||
| 1077cf214c | |||
| f27fdf5274 | |||
| 1dbcca4ca0 | |||
| 558e2359f7 | |||
| f99ef648b3 | |||
| 5e4e3329c8 | |||
| b0a66aba0a | |||
| f2dd500536 | |||
| 7412ac4f91 | |||
| 2acb3efe5a | |||
| 2cc0d06bc5 | |||
| 4070cb7c49 | |||
| fcd196355a | |||
| ea502d5b7b | |||
| 1f33009f89 | |||
| 3509ae9725 | |||
| 49858c45c9 | |||
| b78cd44cc9 | |||
| 39fcd6d4dd | |||
| 8838d36793 | |||
| 63fa94e6f2 | |||
| 17183f9643 | |||
| 667d0bfa97 | |||
| 88a6be0d27 | |||
| c3eaddff97 | |||
| f03adad463 | |||
| bd03e3ac32 | |||
| 299a28a0d2 | |||
| cee8ddced1 | |||
| 738cd21b1f | |||
| b8186e4b52 | |||
| d98a8b8cc4 | |||
| dba6c4b131 | |||
| 118812f16f | |||
| 0b96a1412c | |||
| 29de191d26 | |||
| f86af9ca71 | |||
| d25de7b30f | |||
| 273bd3d6be | |||
| ac446723f1 | |||
| c21bc1333f | |||
| 4e4255995e | |||
| c68b540597 | |||
| 1358871ccc | |||
| 908511f299 | |||
| 6260de21f9 | |||
| e2f276097c | |||
| 205bb67a6a | |||
| 05edafec4c | |||
| 4a073d3a71 | |||
| f2cbf31e17 | |||
| 22b22780ea | |||
| 71cfa28817 | |||
| 8b2d88f80b | |||
| eaf0a57e51 | |||
| 512f5ad7ba | |||
| 8d2351d3f9 | |||
| c5a20c9e7f | |||
| 4a3b663333 | |||
| e43635b5d8 | |||
| 7044377f16 | |||
| 7ced1bf942 | |||
| 7ca3315ce5 | |||
| 2b8c4b4d4d | |||
| a359e8815b | |||
| 01cf82813c | |||
| 625e400c48 | |||
| 56793cee7c | |||
| 3ba5337812 | |||
| 129e3d4821 | |||
| 4d524a7d61 | |||
| 429fb920fb | |||
| 77c7f0b6fe | |||
| 1a043bea76 | |||
| e4d770c272 | |||
| fce3931858 | |||
| 43cdade6e1 | |||
| 4374f9436c | |||
| 7c63c3c816 | |||
| b3f491a60b | |||
| 4adcbba840 | |||
| baccb42455 | |||
| d0842dd803 | |||
| 02aabe6045 | |||
| 0e47f9eb5f | |||
| f1d2d63f20 | |||
| f322f9f7ab | |||
| 6db8b76902 | |||
| 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 |
8
Gemfile
8
Gemfile
@@ -1,15 +1,13 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'quickbooks-ruby'
|
||||
gem 'quickbooks-ruby-base'
|
||||
gem 'oauth-plugin'
|
||||
gem 'oauth'
|
||||
gem 'oauth2'
|
||||
gem 'roxml'
|
||||
gem 'edmunds_vin'
|
||||
gem 'nhtsa_vin'
|
||||
gem 'will_paginate'
|
||||
gem 'rails-jquery-autocomplete'
|
||||
gem 'jquery-rails', '~> 3.1.4'
|
||||
gem 'jquery-ui-rails'
|
||||
gem 'faraday_middleware', '1.2.0'
|
||||
|
||||
group :assets do
|
||||
gem 'coffee-rails'
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Rick Barrette
|
||||
Copyright (c) 2022 Rick Barrette
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
18
README.md
18
README.md
@@ -1,14 +1,16 @@
|
||||
#Redmine Quickbooks Online
|
||||
# Redmine Quickbooks Online
|
||||
|
||||
A plugin for Redmine to connect to Quickbooks Online
|
||||
|
||||
The goal of this project is to allow Redmine to connect with Quickbooks Online to create `Time Activity Entries` for completed work when an Issue is closed.
|
||||
|
||||
`Note: Although the core functionality is complete, this project is still under heavy development. I am still working on refining everthing and adding other features. Tags should be stable`
|
||||
#### Disclaimer
|
||||
|
||||
`Note: I am currently using this in a live production enviroment with no issues`
|
||||
Note: Although the core functionality is complete, this project is still under heavy development. I am still working on refining everthing and adding other features. Tags should be stable
|
||||
|
||||
####Features
|
||||
Also worth metioning I am currently using this in a live production enviroment with no issues
|
||||
|
||||
#### Features
|
||||
* Issues can be assigned to a `Customer` via drop down in the edit Issue form
|
||||
* The `Employee` for the Issue is assigned via the assigned Redmine User
|
||||
- This is set via a drop down in the user admistration page.
|
||||
@@ -27,14 +29,14 @@ The goal of this project is to allow Redmine to connect with Quickbooks Online t
|
||||
+ `Invoice` Custom Fields are matched Issue Custom Fileds and are automaticly updated in Quickbooks. For example, this is usefull for extracting the Mileage In / Out from the Issue and updating the Invoice with the information.
|
||||
- `Customers` are automaticly updated in local database
|
||||
|
||||
##Prerequisites
|
||||
## Prerequisites
|
||||
|
||||
* Sign up to become a developer for Intuit https://developer.intuit.com/
|
||||
* Create your own aplication to obtain your API keys
|
||||
* Set up webhook service to https://redmine.yourdomain.com/qbo/webhook
|
||||
- See https://developer.intuit.com/docs/0100_accounting/0300_developer_guides/webhooks
|
||||
|
||||
##The Install
|
||||
## The Install
|
||||
|
||||
1. To install, clone this repo into your plugin folder
|
||||
|
||||
@@ -73,11 +75,11 @@ Note: After the inital synchronization, this plugin will recieve push notificati
|
||||
* Fix Issue sort by Customer
|
||||
* MORE Stuff...
|
||||
|
||||
##License
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 rick barrette
|
||||
Copyright (c) 2020 rick barrette
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 106 KiB |
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -11,7 +11,7 @@
|
||||
# This controller class will handle map management
|
||||
class CustomersController < ApplicationController
|
||||
unloadable
|
||||
|
||||
|
||||
include AuthHelper
|
||||
helper :issues
|
||||
helper :journals
|
||||
@@ -26,18 +26,37 @@ class CustomersController < ApplicationController
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :timelog
|
||||
|
||||
before_filter :require_user, :except => :view
|
||||
skip_before_filter :verify_authenticity_token, :check_if_login_required, :only => [:view]
|
||||
|
||||
|
||||
before_action :add_customer, :only => :new
|
||||
before_action :view_customer, :except => :new
|
||||
skip_before_action :verify_authenticity_token, :check_if_login_required, :only => [:view]
|
||||
|
||||
default_search_scope :names
|
||||
|
||||
autocomplete :customer, :name, :full => false, :extra_data => [:id]
|
||||
|
||||
|
||||
autocomplete :customer, :name, :full => true, :extra_data => [:id]
|
||||
|
||||
def allowed_params
|
||||
params.require(:customer).permit(:name, :email, :primary_phone, :mobile_phone, :phone_number)
|
||||
end
|
||||
|
||||
# getter method for a customer's vehicles
|
||||
# used for customer autocomplete field / issue form
|
||||
def filter_vehicles_by_customer
|
||||
@filtered_vehicles = Vehicle.all.where(customer_id: params[:selected_customer])
|
||||
end
|
||||
|
||||
|
||||
# getter method for a customer's invoices
|
||||
# used for customer autocomplete field / issue form
|
||||
def filter_invoices_by_customer
|
||||
@filtered_invoices = QboInvoice.all.where(customer_id: params[:selected_customer])
|
||||
end
|
||||
|
||||
# getter method for a customer's estimates
|
||||
# used for customer autocomplete field / issue form
|
||||
def filter_estimates_by_customer
|
||||
@filtered_estimates = QboEstimate.all.where(customer_id: params[:selected_customer])
|
||||
end
|
||||
|
||||
# display a list of all customers
|
||||
def index
|
||||
if params[:search]
|
||||
@@ -47,22 +66,24 @@ class CustomersController < ApplicationController
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# initialize a new customer
|
||||
def new
|
||||
@customer = Customer.new
|
||||
end
|
||||
|
||||
|
||||
# create a new customer
|
||||
def create
|
||||
@customer = Customer.new(params[:customer])
|
||||
@customer = Customer.new(allowed_params)
|
||||
if @customer.save
|
||||
flash[:notice] = "New Customer Created"
|
||||
redirect_to @customer
|
||||
else
|
||||
flash[:error] = @customer.errors.full_messages.to_sentence
|
||||
flash[:error] = @customer.errors.full_messages.to_sentence
|
||||
redirect_to new_customer_path
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# display a specific customer
|
||||
def show
|
||||
begin
|
||||
@@ -73,7 +94,7 @@ class CustomersController < ApplicationController
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# return an HTML form for editing a customer
|
||||
def edit
|
||||
begin
|
||||
@@ -82,12 +103,12 @@ class CustomersController < ApplicationController
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# update a specific customer
|
||||
def update
|
||||
begin
|
||||
@customer = Customer.find_by_id(params[:id])
|
||||
if @customer.update_attributes(params[:customer])
|
||||
if @customer.update_attributes(allowed_params)
|
||||
flash[:notice] = "Customer updated"
|
||||
redirect_to @customer
|
||||
else
|
||||
@@ -98,7 +119,8 @@ class CustomersController < ApplicationController
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# delete a customer
|
||||
def destroy
|
||||
begin
|
||||
Customer.find_by_id(params[:id]).destroy
|
||||
@@ -108,12 +130,12 @@ class CustomersController < ApplicationController
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
# Customer view for an issue
|
||||
|
||||
# displays an issue for a customer with a provided security CustomerToken
|
||||
def view
|
||||
|
||||
|
||||
User.current = User.find_by lastname: 'Anonymous'
|
||||
|
||||
|
||||
@token = CustomerToken.where("token = ? and expires_at > ?", params[:token], Time.now)
|
||||
@token = @token.first
|
||||
if @token
|
||||
@@ -128,10 +150,10 @@ class CustomersController < ApplicationController
|
||||
Journal.preload_journals_details_custom_fields(@journals)
|
||||
@journals.select! {|journal| journal.notes? || journal.visible_details.any?}
|
||||
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
|
||||
|
||||
@changesets = @issue.changesets.visible.preload(:repository, :user).to_a
|
||||
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
|
||||
|
||||
@relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
@priorities = IssuePriority.active
|
||||
@@ -141,9 +163,21 @@ class CustomersController < ApplicationController
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
# redmine permission - add customers
|
||||
def add_customer
|
||||
global_check_permission(:add_customers)
|
||||
end
|
||||
|
||||
# redmine permission - view customers
|
||||
def view_customer
|
||||
global_check_permission(:view_customers)
|
||||
end
|
||||
|
||||
# checks to see if there is only one item in an array
|
||||
# @return true if array only has one item
|
||||
def only_one_non_zero?( array )
|
||||
found_non_zero = false
|
||||
array.each do |val|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -12,16 +12,34 @@ class EstimateController < ApplicationController
|
||||
|
||||
include AuthHelper
|
||||
|
||||
before_filter :require_user
|
||||
before_action :require_user
|
||||
|
||||
#
|
||||
# Downloads and forwards the estimate pdf
|
||||
#
|
||||
def show
|
||||
base = QboEstimate.get_base.service
|
||||
estimate = base.fetch_by_id(params[:id])
|
||||
@pdf = base.pdf(estimate)
|
||||
send_data @pdf, filename: "estimate #{estimate.doc_number}.pdf", :disposition => 'inline', :type => "application/pdf"
|
||||
e = QboEstimate.find_by_id(params[:id]) if params[:id]
|
||||
e = QboEstimate.find_by_doc_number(params[:search]) if params[:search]
|
||||
|
||||
begin
|
||||
send_data e.pdf, filename: "estimate #{e.doc_number}.pdf", :disposition => 'inline', :type => "application/pdf"
|
||||
rescue
|
||||
redirect_to :back, :flash => { :error => "Estimate not found" }
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Downloads estimate by document number
|
||||
#
|
||||
def doc
|
||||
e = QboEstimate.find_by_doc_number(params[:id]) if params[:id]
|
||||
e = QboEstimate.find_by_doc_number(params[:search]) if params[:search]
|
||||
|
||||
begin
|
||||
send_data e.pdf, filename: "estimate #{e.doc_number}.pdf", :disposition => 'inline', :type => "application/pdf"
|
||||
rescue
|
||||
redirect_to :back, :flash => { :error => "Estimate not found" }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -12,8 +12,8 @@ class InvoiceController < ApplicationController
|
||||
|
||||
include AuthHelper
|
||||
|
||||
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? }
|
||||
before_action :require_user, :unless => proc {|c| session[:token].nil? }
|
||||
skip_before_action :verify_authenticity_token, :check_if_login_required, :unless => proc {|c| session[:token].nil? }
|
||||
|
||||
#
|
||||
# Downloads and forwards the invoice pdf
|
||||
|
||||
94
app/controllers/line_items_controler.rb
Normal file
94
app/controllers/line_items_controler.rb
Normal file
@@ -0,0 +1,94 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# This controller class will handle map management
|
||||
class LineItemsController < ApplicationController
|
||||
unloadable
|
||||
|
||||
include AuthHelper
|
||||
|
||||
before_action :require_user
|
||||
|
||||
# display all line items for an issue
|
||||
def index
|
||||
if params[:issue_id]
|
||||
begin
|
||||
@line_items = Issue.find_by_id(params[:issue_id]).line_items
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# return an HTML form for creating a new line item
|
||||
def new
|
||||
@line_item = LineItem.new
|
||||
end
|
||||
|
||||
# create a new line item
|
||||
def create
|
||||
@line_item = LineItem.new(params[:line_item])
|
||||
if @line_item.save
|
||||
flash[:notice] = "New Line Item Created"
|
||||
redirect_to @line_item.issue
|
||||
else
|
||||
flash[:error] = @line_item.errors.full_messages.to_sentence
|
||||
redirect_to new_line_item_path
|
||||
end
|
||||
end
|
||||
|
||||
# display a specific line item
|
||||
def show
|
||||
begin
|
||||
@line_item = LineItem.find_by_id(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
# return an HTML form for editing a line item
|
||||
def edit
|
||||
begin
|
||||
@line_item = LineItem.find_by_id(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
# update a specific line item
|
||||
def update
|
||||
begin
|
||||
@line_item = LineItem.find_by_id(params[:id])
|
||||
if @line_item.update_attributes(params[:line_item])
|
||||
flash[:notice] = "Line Item updated"
|
||||
redirect_to @line_item
|
||||
else
|
||||
flash[:error] = @line_item.errors.full_messages.to_sentence if @line_item.errors
|
||||
redirect_to edit_line_item_path
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
# delete a specific line item
|
||||
def destroy
|
||||
begin
|
||||
line_item = LineItem.find_by_id(params[:id])
|
||||
issue = line_item.issue
|
||||
line_item.destroy
|
||||
flash[:notice] = "Line Item deleted successfully"
|
||||
redirect_to issue
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -12,16 +12,16 @@ class PaymentsController < ApplicationController
|
||||
|
||||
include AuthHelper
|
||||
|
||||
before_filter :require_user
|
||||
|
||||
before_action :check_permissions
|
||||
|
||||
def new
|
||||
@payment = Payment.new
|
||||
|
||||
@customers = Customer.all.sort_by &:name
|
||||
|
||||
@accounts = Qbo.get_base(:account).service.query("SELECT Id, Name FROM Account WHERE AccountType = 'Bank' Order By Name")
|
||||
@accounts = Qbo.get_base(:account).query("SELECT Id, Name FROM Account WHERE AccountType = 'Bank' Order By Name")
|
||||
|
||||
@payment_methods = Qbo.get_base(:payment_method).service.all
|
||||
@payment_methods = Qbo.get_base(:payment_method).all
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -32,10 +32,16 @@ class PaymentsController < ApplicationController
|
||||
else
|
||||
flash[:error] = @payment.errors.full_messages.to_sentence
|
||||
redirect_to new_customer_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_permissions
|
||||
if !allowed_to?(:add_payments)
|
||||
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||
end
|
||||
end
|
||||
|
||||
def only_one_non_zero?( array )
|
||||
found_non_zero = false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -15,8 +15,8 @@ class QboController < ApplicationController
|
||||
|
||||
include AuthHelper
|
||||
|
||||
before_filter :require_user, :except => :qbo_webhook
|
||||
skip_before_filter :verify_authenticity_token, :check_if_login_required, :only => [:qbo_webhook]
|
||||
before_action :require_user, :except => :qbo_webhook
|
||||
skip_before_action :verify_authenticity_token, :check_if_login_required, :only => [:qbo_webhook]
|
||||
|
||||
#
|
||||
# Called when the QBO Top Menu us shown
|
||||
@@ -34,32 +34,43 @@ class QboController < ApplicationController
|
||||
# Called when the user requests that Redmine to connect to QBO
|
||||
#
|
||||
def authenticate
|
||||
callback = qbo_oauth_callback_url
|
||||
token = Qbo.get_oauth_consumer.get_request_token(:oauth_callback => callback)
|
||||
session[:qb_request_token] = Marshal.dump(token)
|
||||
redirect_to("https://appcenter.intuit.com/Connect/Begin?oauth_token=#{token.token}") and return
|
||||
oauth2_client = Qbo.get_client
|
||||
callback = Setting.host_name + "/qbo/oauth_callback/"
|
||||
#callback = qbo_oauth_callback_url
|
||||
grant_url = oauth2_client.auth_code.authorize_url(redirect_uri: callback, response_type: "code", state: SecureRandom.hex(12), scope: "com.intuit.quickbooks.accounting")
|
||||
redirect_to grant_url
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Called by QBO after authentication has been processed
|
||||
#
|
||||
def oauth_callback
|
||||
at = Marshal.load(session[:qb_request_token]).get_access_token(:oauth_verifier => params[:oauth_verifier])
|
||||
|
||||
#There can only be one...
|
||||
Qbo.destroy_all
|
||||
|
||||
# Save the authentication information
|
||||
qbo = Qbo.new
|
||||
qbo.qb_token = at.token
|
||||
qbo.qb_secret = at.secret
|
||||
qbo.token_expires_at = 6.months.from_now.utc
|
||||
qbo.reconnect_token_at = 5.months.from_now.utc
|
||||
qbo.company_id = params['realmId']
|
||||
if qbo.save!
|
||||
redirect_to qbo_sync_path, :flash => { :notice => "Successfully connected to Quickbooks" }
|
||||
else
|
||||
redirect_to plugin_settings_path(:redmine_qbo), :flash => { :error => "Error" }
|
||||
if params[:state].present?
|
||||
oauth2_client = Qbo.get_client
|
||||
# use the state value to retrieve from your backend any information you need to identify the customer in your system
|
||||
#redirect_uri = qbo_oauth_callback_url
|
||||
redirect_uri = Setting.host_name + "/qbo/oauth_callback/"
|
||||
if resp = oauth2_client.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
|
||||
|
||||
# Remove the last authentication information
|
||||
Qbo.delete_all
|
||||
|
||||
# Save the authentication information
|
||||
qbo = Qbo.new
|
||||
qbo.company_id = params[:realmId]
|
||||
|
||||
# Generate Access Token & Serialize it into the database
|
||||
access_token = OAuth2::AccessToken.new(oauth2_client, resp.token, refresh_token: resp.refresh_token)
|
||||
qbo.token = access_token.to_hash
|
||||
qbo.expire = 1.hour.from_now.utc
|
||||
|
||||
if qbo.save!
|
||||
redirect_to qbo_sync_path, :flash => { :notice => "Successfully connected to Quickbooks" }
|
||||
else
|
||||
redirect_to plugin_settings_path(:redmine_qbo), :flash => { :error => "Error" }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -76,6 +87,8 @@ class QboController < ApplicationController
|
||||
|
||||
# Quickbooks Webhook Callback
|
||||
def qbo_webhook
|
||||
|
||||
logger.debug "Quickbooks is calling webhook"
|
||||
|
||||
# check the payload
|
||||
signature = request.headers['intuit-signature']
|
||||
@@ -99,10 +112,12 @@ class QboController < ApplicationController
|
||||
|
||||
# TODO rename all other models!
|
||||
name.prepend("Qbo") if not name.eql? "Customer"
|
||||
|
||||
|
||||
logger.debug "Casting #{name.constantize} to obj"
|
||||
|
||||
# Magicly initialize the correct class
|
||||
obj = name.constantize
|
||||
|
||||
|
||||
# for merge events
|
||||
obj.destroy(entity['deletedId']) if entity['deletedId']
|
||||
|
||||
@@ -111,7 +126,13 @@ class QboController < ApplicationController
|
||||
obj.destroy(id)
|
||||
#if not then update!
|
||||
else
|
||||
obj.sync_by_id(id)
|
||||
begin
|
||||
obj.sync_by_id(id)
|
||||
rescue => e
|
||||
logger.error "Failed to call sync_by_id on obj"
|
||||
logger.error e.message
|
||||
logger.error e.backtrace.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -123,20 +144,23 @@ class QboController < ApplicationController
|
||||
else
|
||||
render nothing: true, status: 400
|
||||
end
|
||||
|
||||
logger.debug "Quickbooks webhook complete"
|
||||
end
|
||||
|
||||
#
|
||||
# Synchronizes the QboCustomer table with QBO
|
||||
#
|
||||
def sync
|
||||
logger.debug "Syncing EVERYTHING"
|
||||
# Update info in background
|
||||
Thread.new do
|
||||
if Qbo.exists?
|
||||
Customer.sync
|
||||
QboInvoice.sync
|
||||
QboItem.sync
|
||||
QboEmployee.sync
|
||||
QboEstimate.sync
|
||||
QboInvoice.sync
|
||||
|
||||
# Record the last sync time
|
||||
Qbo.update_time_stamp
|
||||
@@ -144,6 +168,6 @@ class QboController < ApplicationController
|
||||
ActiveRecord::Base.connection.close
|
||||
end
|
||||
|
||||
redirect_to qbo_path(:redmine_qbo), :flash => { :notice => "Successfully synced to Quickbooks" }
|
||||
redirect_to :home, :flash => { :notice => "Successfully synced to Quickbooks" }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -11,11 +11,15 @@
|
||||
# This controller class will handle map management
|
||||
class VehiclesController < ApplicationController
|
||||
unloadable
|
||||
|
||||
|
||||
include AuthHelper
|
||||
|
||||
before_filter :require_user
|
||||
|
||||
|
||||
before_action :require_user
|
||||
|
||||
def allowed_params
|
||||
params.require(:vehicle).permit(:year, :make, :model, :customer_id, :notes, :vin)
|
||||
end
|
||||
|
||||
# display a list of all vehicles
|
||||
def index
|
||||
if params[:customer_id]
|
||||
@@ -25,7 +29,8 @@ class VehiclesController < ApplicationController
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# search for a vehicle by vin
|
||||
if params[:search]
|
||||
@vehicles = Vehicle.search(params[:search]).paginate(:page => params[:page])
|
||||
if only_one_non_zero?(@vehicles)
|
||||
@@ -37,58 +42,58 @@ class VehiclesController < ApplicationController
|
||||
# return an HTML form for creating a new vehicle
|
||||
def new
|
||||
@vehicle = Vehicle.new
|
||||
@customers = Customer.all.order(:name)
|
||||
@customer = params[:customer_id] if params[:customer_id]
|
||||
@customer = Customer.find_by_id(params[:customer_id]) if params[:customer_id]
|
||||
end
|
||||
|
||||
# create a new vehicle
|
||||
def create
|
||||
@vehicle = Vehicle.new(params[:vehicle])
|
||||
@vehicle = Vehicle.new(allowed_params)
|
||||
if @vehicle.save
|
||||
flash[:notice] = "New Vehicle Created"
|
||||
redirect_to @vehicle
|
||||
else
|
||||
flash[:error] = @vehicle.errors.full_messages.to_sentence
|
||||
redirect_to new_vehicle_path
|
||||
flash[:error] = @vehicle.errors.full_messages.to_sentence
|
||||
redirect_to Vehicle.find_by_vin @vehicle.vin
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# display a specific vehicle
|
||||
def show
|
||||
begin
|
||||
@vehicle = Vehicle.find_by_id(params[:id])
|
||||
@vin = @vehicle.vin.scan(/.{1,9}/) if @vehicle.vin
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# return an HTML form for editing a vehicle
|
||||
def edit
|
||||
begin
|
||||
@vehicle = Vehicle.find_by_id(params[:id])
|
||||
@customer = @vehicle.customer.id
|
||||
@customers = Customer.all.order(:name)
|
||||
@customer = @vehicle.customer
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# update a specific vehicle
|
||||
def update
|
||||
@customer = params[:customer]
|
||||
begin
|
||||
begin
|
||||
@vehicle = Vehicle.find_by_id(params[:id])
|
||||
if @vehicle.update_attributes(params[:vehicle])
|
||||
if @vehicle.update_attributes(allowed_params)
|
||||
flash[:notice] = "Vehicle updated"
|
||||
redirect_to @vehicle
|
||||
else
|
||||
flash[:error] = @vehicle.errors.full_messages.to_sentence if @vehicle.errors
|
||||
redirect_to edit_vehicle_path
|
||||
end
|
||||
#show any errors anyways
|
||||
flash[:error] = @vehicle.errors.full_messages.to_sentence unless @vehicle.errors.empty?
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# delete a specific vehicle
|
||||
def destroy
|
||||
@@ -100,18 +105,11 @@ class VehiclesController < ApplicationController
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
# returns a dynamic list of vehicles owned by a customer
|
||||
def update_vehicles
|
||||
@vehicles = Customer.find_by(customer_id: params[:customer_id].to_i).vehicles
|
||||
respond_to do |format|
|
||||
format.html { render(:text => "not implemented") }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
# checks to see if there is only one item in an array
|
||||
# @return true if array only has one item
|
||||
def only_one_non_zero?( array )
|
||||
found_non_zero = false
|
||||
array.each do |val|
|
||||
@@ -123,4 +121,4 @@ class VehiclesController < ApplicationController
|
||||
found_non_zero
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -16,4 +16,38 @@ module AuthHelper
|
||||
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||
end
|
||||
end
|
||||
|
||||
def allowed_to?(action)
|
||||
return false if User.current.nil?
|
||||
project = Project.find(params[:project_id])
|
||||
return false if project.nil?
|
||||
return true if User.current.allowed_to?(action, project)
|
||||
false
|
||||
end
|
||||
|
||||
def check_permission(permission)
|
||||
if !allowed_to?(permission)
|
||||
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def global_check_permission(permission)
|
||||
if !globaly_allowed_to?(permission)
|
||||
render :file => "public/401.html.erb", :status => :unauthorized, :layout =>true
|
||||
end
|
||||
end
|
||||
|
||||
def globaly_allowed_to?( action)
|
||||
return false if User.current.nil?
|
||||
|
||||
projects = Project.all
|
||||
projects.each { |p|
|
||||
if User.current.allowed_to?(action, p)
|
||||
return true
|
||||
end
|
||||
}
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -13,9 +13,11 @@ class Customer < ActiveRecord::Base
|
||||
|
||||
has_many :issues
|
||||
has_many :qbo_purchases
|
||||
has_many :qbo_invoices
|
||||
has_many :qbo_estimates
|
||||
has_many :vehicles
|
||||
|
||||
attr_accessible :name, :notes, :email, :primary_phone, :mobile_phone
|
||||
#attr_accessible :name, :notes, :email, :primary_phone, :mobile_phone, :phone_number
|
||||
validates_presence_of :id, :name
|
||||
|
||||
self.primary_key = :id
|
||||
@@ -61,6 +63,8 @@ class Customer < ActiveRecord::Base
|
||||
pn = Quickbooks::Model::TelephoneNumber.new
|
||||
pn.free_form_number = n
|
||||
@details.primary_phone = pn
|
||||
#update our locally stored number too
|
||||
update_phone_number
|
||||
end
|
||||
|
||||
# Convenience Method
|
||||
@@ -81,6 +85,26 @@ class Customer < ActiveRecord::Base
|
||||
pn = Quickbooks::Model::TelephoneNumber.new
|
||||
pn.free_form_number = n
|
||||
@details.mobile_phone = pn
|
||||
#update our locally stored number too
|
||||
update_mobile_phone_number
|
||||
end
|
||||
|
||||
# update the localy stored phone number as a plain string with no special chars
|
||||
def update_phone_number
|
||||
begin
|
||||
self.phone_number = self.primary_phone.tr('^0-9', '')
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
# update the localy stored phone number as a plain string with no special chars
|
||||
def update_mobile_phone_number
|
||||
begin
|
||||
self.mobile_phone_number = self.mobile_phone.tr('^0-9', '')
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
# Convenience Method
|
||||
@@ -112,7 +136,7 @@ class Customer < ActiveRecord::Base
|
||||
# proforms a bruteforce sync operation
|
||||
# This needs to be simplified
|
||||
def self.sync
|
||||
service = Qbo.get_base(:customer).service
|
||||
service = Qbo.get_base(:customer)
|
||||
|
||||
# Sync ALL customers if the database is empty
|
||||
#if count == 0
|
||||
@@ -140,26 +164,16 @@ class Customer < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
# Searchs the database for a customer by name
|
||||
# Searchs the database for a customer by name or phone number with out special chars
|
||||
def self.search(search)
|
||||
customers = where("name LIKE ?", "%#{search}%")
|
||||
|
||||
#if customers.empty?
|
||||
# service = Qbo.get_base(:customer).service
|
||||
# results = service.query("Select Id From Customer Where PrimaryPhone LIKE '%#{search}%' AND Mobile LIKE '%#{search}%'")
|
||||
|
||||
# results.each do |customer|
|
||||
# customers << Customer.find_by_id(customer.id)
|
||||
# end
|
||||
#end
|
||||
|
||||
customers = where("name LIKE ? OR phone_number LIKE ? OR mobile_phone_number LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
|
||||
return customers.order(:name)
|
||||
end
|
||||
|
||||
# proforms a bruteforce sync operation
|
||||
# This needs to be simplified
|
||||
def self.sync_by_id(id)
|
||||
service = Qbo.get_base(:customer).service
|
||||
service = Qbo.get_base(:customer)
|
||||
|
||||
customer = service.fetch_by_id(id)
|
||||
qbo_customer = Customer.find_or_create_by(id: customer.id)
|
||||
@@ -179,7 +193,7 @@ class Customer < ActiveRecord::Base
|
||||
# Push the updates
|
||||
def save_with_push
|
||||
begin
|
||||
@details = Qbo.get_base(:customer).service.update(@details)
|
||||
@details = Qbo.get_base(:customer).update(@details)
|
||||
#raise "QBO Fault" if @details.fault?
|
||||
self.id = @details.id
|
||||
rescue Exception => e
|
||||
@@ -197,7 +211,7 @@ class Customer < ActiveRecord::Base
|
||||
def pull
|
||||
begin
|
||||
raise Exception unless self.id
|
||||
@details = Qbo.get_base(:customer).find_by_id(self.id)
|
||||
@details = Qbo.get_base(:customer).fetch_by_id(self.id)
|
||||
rescue Exception => e
|
||||
@details = Quickbooks::Model::Customer.new
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -11,7 +11,7 @@
|
||||
class CustomerToken < ActiveRecord::Base
|
||||
unloadable
|
||||
has_many :issues
|
||||
attr_accessible :token, :expires_at, :issue_id
|
||||
#attr_accessible :token, :expires_at, :issue_id
|
||||
validates_presence_of :expires_at, :issue_id
|
||||
before_create :generate_token
|
||||
|
||||
|
||||
34
app/models/line_item.rb
Normal file
34
app/models/line_item.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class LineItem < ActiveRecord::Base
|
||||
|
||||
unloadable
|
||||
|
||||
belongs_to :issue
|
||||
|
||||
#attr_accessible :amount, :description, :unit_price, :quantity, :item_id
|
||||
validates_presence_of :amount, :description, :unit_price, :quantity
|
||||
|
||||
def add_to_invoice(invoice)
|
||||
line_item = Quickbooks::Model::InvoiceLineItem.new
|
||||
line_item.amount = amount
|
||||
line_item.description = description
|
||||
line_item.sales_item! do |detail|
|
||||
detail.unit_price = unit_price
|
||||
detail.quantity = quantity
|
||||
detail.item_id = item_id # Item ID here... Where do i get this???
|
||||
end
|
||||
|
||||
invoice.line_items << line_item
|
||||
|
||||
return invoice
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2020 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -23,7 +23,7 @@ class Payment
|
||||
payment.deposit_to_account_id = @account_id.to_i
|
||||
payment.payment_method_id = @payment_method_id.to_i
|
||||
payment.total = @total_amount
|
||||
Qbo.get_base(:payment).service.update(payment)
|
||||
Qbo.get_base(:payment).update(payment)
|
||||
end
|
||||
|
||||
def save!
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2020 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -10,34 +10,76 @@
|
||||
|
||||
class Qbo < ActiveRecord::Base
|
||||
unloadable
|
||||
validates_presence_of :qb_token, :qb_secret, :company_id, :token_expires_at, :reconnect_token_at
|
||||
|
||||
#validates_presence_of :qb_token, :qb_secret, :company_id, :token_expires_at, :reconnect_token_at
|
||||
validates_presence_of :token, :company_id, :expire
|
||||
serialize :token
|
||||
|
||||
OAUTH_CONSUMER_KEY = Setting.plugin_redmine_qbo['settingsOAuthConsumerKey']
|
||||
OAUTH_CONSUMER_SECRET = Setting.plugin_redmine_qbo['settingsOAuthConsumerSecret']
|
||||
|
||||
$qb_oauth_consumer = OAuth::Consumer.new(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, {
|
||||
:site => "https://oauth.intuit.com",
|
||||
:request_token_path => "/oauth/v1/get_request_token",
|
||||
:authorize_url => "https://appcenter.intuit.com/Connect/Begin",
|
||||
:access_token_path => "/oauth/v1/get_access_token"
|
||||
})
|
||||
|
||||
# Configure quickbooks-ruby-base to access our database
|
||||
Quickbooks::Base.configure do |c|
|
||||
c.persistent_token = 'qb_token'
|
||||
c.persistent_secret = 'qb_secret'
|
||||
c.persistent_company_id = 'company_id'
|
||||
#
|
||||
# Getter for quickbooks OAuth2 client
|
||||
#
|
||||
def self.get_client
|
||||
oauth_params = {
|
||||
site: "https://appcenter.intuit.com/connect/oauth2",
|
||||
authorize_url: "https://appcenter.intuit.com/connect/oauth2",
|
||||
token_url: "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
|
||||
}
|
||||
return OAuth2::Client.new(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, oauth_params)
|
||||
end
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Getter for oauth consumer
|
||||
#
|
||||
def self.get_oauth_consumer
|
||||
# Quickbooks Config Info
|
||||
return $qb_oauth_consumer
|
||||
end
|
||||
|
||||
# Get a quickbooks base object for type
|
||||
#
|
||||
# Get a quickbooks base service object for type
|
||||
# @params type of base
|
||||
#
|
||||
def self.get_base(type)
|
||||
Quickbooks::Base.new(first, type)
|
||||
# lets getnourbold access token from the database
|
||||
oauth2_client = get_client
|
||||
qbo = self.first
|
||||
access_token = OAuth2::AccessToken.from_hash(oauth2_client, qbo.token)
|
||||
|
||||
# check to see if we need to refresh the acesstoken
|
||||
if qbo.expire.to_time.utc.past?
|
||||
puts "Updating access token"
|
||||
new_access_token_object = access_token.refresh!
|
||||
qbo.token = new_access_token_object.to_hash
|
||||
qbo.expire = 1.hour.from_now.utc
|
||||
qbo.save!
|
||||
access_token = new_access_token_object
|
||||
else
|
||||
puts "Using current token"
|
||||
end
|
||||
|
||||
# build the reqiested service
|
||||
case type
|
||||
when :item
|
||||
return Quickbooks::Service::Item.new(:company_id => qbo.company_id, :access_token => access_token)
|
||||
when :time_activity
|
||||
return Quickbooks::Service::TimeActivity.new(:company_id => qbo.company_id, :access_token => access_token)
|
||||
when :customer
|
||||
return Quickbooks::Service::Customer.new(:company_id => qbo.company_id, :access_token => access_token)
|
||||
when :invoice
|
||||
return Quickbooks::Service::Invoice.new(:company_id => qbo.company_id, :access_token => access_token)
|
||||
when :estimate
|
||||
return Quickbooks::Service::Estimate.new(:company_id => qbo.company_id, :access_token => access_token)
|
||||
when :account
|
||||
return Quickbooks::Service::Account.new(:company_id => qbo.company_id, :access_token => access_token)
|
||||
when :employee
|
||||
return Quickbooks::Service:: Employee.new(:company_id => qbo.company_id, :access_token => access_token)
|
||||
else
|
||||
return access_token
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Get the QBO account
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -11,7 +11,7 @@
|
||||
class QboEmployee < ActiveRecord::Base
|
||||
unloadable
|
||||
has_many :users
|
||||
attr_accessible :name
|
||||
#attr_accessible :name
|
||||
validates_presence_of :id, :name
|
||||
|
||||
def self.get_base
|
||||
@@ -19,7 +19,7 @@ class QboEmployee < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.sync
|
||||
employees = get_base.service.all
|
||||
employees = get_base.all
|
||||
|
||||
transaction do
|
||||
# Update the item table
|
||||
@@ -33,7 +33,7 @@ class QboEmployee < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.sync_by_id(id)
|
||||
employee = get_base.service.fetch_by_id(id)
|
||||
employee = get_base.fetch_by_id(id)
|
||||
qbo_employee = find_or_create_by(id: employee.id)
|
||||
qbo_employee.name = employee.display_name
|
||||
qbo_employee.id = employee.id
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -10,44 +10,57 @@
|
||||
|
||||
class QboEstimate < ActiveRecord::Base
|
||||
unloadable
|
||||
has_many :issues
|
||||
attr_accessible :doc_number
|
||||
validates_presence_of :id, :doc_number
|
||||
|
||||
has_and_belongs_to_many :issues
|
||||
belongs_to :customer
|
||||
#attr_accessible :doc_number, :id
|
||||
validates_presence_of :doc_number, :id
|
||||
self.primary_key = :id
|
||||
|
||||
# return the QBO Estimate service
|
||||
def self.get_base
|
||||
Qbo.get_base(:estimate)
|
||||
end
|
||||
|
||||
# sync all estimates
|
||||
def self.sync
|
||||
estimates = get_base.service.all
|
||||
|
||||
# Update the item table
|
||||
transaction do
|
||||
estimates.each { |estimate|
|
||||
qbo_estimate = QboEstimate.find_or_create_by(id: estimate.id)
|
||||
qbo_estimate.doc_number = estimate.doc_number
|
||||
qbo_estimate.id = estimate.id
|
||||
qbo_estimate.save!
|
||||
}
|
||||
end
|
||||
|
||||
estimates = get_base.all
|
||||
estimates.each { |estimate|
|
||||
process_estimate(estimate)
|
||||
}
|
||||
|
||||
#remove deleted estimates
|
||||
where.not(estimates.map(&:id)).destroy_all
|
||||
end
|
||||
|
||||
# sync only one estimate
|
||||
def self.sync_by_id(id)
|
||||
estimate = get_base.service.fetch_by_id(id)
|
||||
qbo_estimate = QboEstimate.find_or_create_by(id: estimate.id)
|
||||
process_estimate(get_base.fetch_by_id(id))
|
||||
end
|
||||
|
||||
# update an estimate
|
||||
def self.update(id)
|
||||
# Update the item table
|
||||
estimate = get_base.fetch_by_id(id)
|
||||
qbo_estimate = find_or_create_by(id: id)
|
||||
qbo_estimate.doc_number = estimate.doc_number
|
||||
qbo_estimate.id = estimate.id
|
||||
qbo_estimate.save!
|
||||
end
|
||||
|
||||
def self.update(id)
|
||||
# Update the item table
|
||||
estimate = get_base.service.fetch_by_id(id)
|
||||
qbo_estimate = QboEstimate.find_or_create_by(id: id)
|
||||
qbo_estimate.doc_number = estimate.doc_number
|
||||
qbo_estimate.save!
|
||||
# process an estimate into the database
|
||||
def self.process_estimate(estimate)
|
||||
qbo_estimate = find_or_create_by(id: estimate.id)
|
||||
qbo_estimate.doc_number = estimate.doc_number
|
||||
qbo_estimate.customer_id = estimate.customer_ref.value
|
||||
qbo_estimate.id = estimate.id
|
||||
qbo_estimate.save!
|
||||
end
|
||||
|
||||
# download the pdf from quickbooks
|
||||
def pdf
|
||||
base = QboEstimate.get_base
|
||||
estimate = base.fetch_by_id(id)
|
||||
return base.pdf(estimate)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -12,16 +12,18 @@ class QboInvoice < ActiveRecord::Base
|
||||
unloadable
|
||||
|
||||
has_and_belongs_to_many :issues
|
||||
attr_accessible :doc_number, :id
|
||||
belongs_to :customer
|
||||
#attr_accessible :doc_number, :id
|
||||
validates_presence_of :doc_number, :id
|
||||
self.primary_key = :id
|
||||
|
||||
def self.get_base
|
||||
Qbo.get_base(:invoice).service
|
||||
Qbo.get_base(:invoice)
|
||||
end
|
||||
|
||||
# sync ALL the invoices
|
||||
def self.sync
|
||||
logger.debug "Syncing all invoices"
|
||||
last = Qbo.first.last_sync
|
||||
|
||||
query = "SELECT Id, DocNumber FROM Invoice"
|
||||
@@ -41,6 +43,7 @@ class QboInvoice < ActiveRecord::Base
|
||||
|
||||
#sync by invoice ID
|
||||
def self.sync_by_id(id)
|
||||
logger.debug "Syncing invoice #{id}"
|
||||
#update the information in the database
|
||||
invoice = get_base.fetch_by_id(id)
|
||||
process_invoice invoice
|
||||
@@ -55,10 +58,13 @@ class QboInvoice < ActiveRecord::Base
|
||||
# skip this issue if the issue customer is not the same as the invoice customer
|
||||
return if issue.customer_id != invoice.customer_ref.value.to_i
|
||||
|
||||
logger.debug "Attaching invoice #{invoice.id} to issue #{issue.id}"
|
||||
|
||||
# Load the invoice into the database
|
||||
qbo_invoice = QboInvoice.find_or_create_by(id: invoice.id)
|
||||
qbo_invoice.doc_number = invoice.doc_number
|
||||
qbo_invoice.id = invoice.id
|
||||
qbo_invoice.customer_id = invoice.customer_ref
|
||||
qbo_invoice.save!
|
||||
|
||||
unless issue.qbo_invoices.include?(qbo_invoice)
|
||||
@@ -71,6 +77,7 @@ class QboInvoice < ActiveRecord::Base
|
||||
|
||||
# processes the invoice into the system
|
||||
def self.process_invoice(invoice)
|
||||
logger.debug "Processing invoice"
|
||||
# Check the private notes
|
||||
if not invoice.private_note.nil?
|
||||
invoice.private_note.scan(/#(\w+)/).flatten.each { |issue|
|
||||
@@ -103,6 +110,7 @@ class QboInvoice < ActiveRecord::Base
|
||||
break if vin.nil?
|
||||
if not cf.string_value.to_s.eql? vin
|
||||
cf.string_value = vin.to_s
|
||||
logger.debug "VIN has changed"
|
||||
is_changed = true
|
||||
end
|
||||
end
|
||||
@@ -125,19 +133,17 @@ class QboInvoice < ActiveRecord::Base
|
||||
cf.string_value = value.value.to_s
|
||||
is_changed = true
|
||||
end
|
||||
end
|
||||
|
||||
# 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?
|
||||
cf.string_value = value.value.to_s
|
||||
is_changed = true
|
||||
end
|
||||
else
|
||||
# Everything else
|
||||
cf.string_value = value.value.to_s
|
||||
is_changed = true
|
||||
end
|
||||
|
||||
# Everything else
|
||||
cf.string_value = value.value.to_s
|
||||
is_changed = true
|
||||
end
|
||||
end
|
||||
rescue
|
||||
@@ -148,7 +154,15 @@ class QboInvoice < ActiveRecord::Base
|
||||
# TODO Add some hooks here
|
||||
|
||||
# Push updates
|
||||
get_base.update(invoice) if is_changed
|
||||
#invoice.sync_token += 1 if is_changed
|
||||
begin
|
||||
logger.debug "Trying to update invoice"
|
||||
get_base.update(invoice) if is_changed
|
||||
rescue
|
||||
# Do nothing, probaly too many vehicles on the invoice. This is a problem with how it's billed
|
||||
# TODO Add notes in memo area
|
||||
logger.error "Failed to update invoice"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -11,7 +11,7 @@
|
||||
class QboItem < ActiveRecord::Base
|
||||
unloadable
|
||||
has_many :issues
|
||||
attr_accessible :name
|
||||
#attr_accessible :name
|
||||
validates_presence_of :id, :name
|
||||
|
||||
self.primary_key = :id
|
||||
@@ -27,9 +27,9 @@ class QboItem < ActiveRecord::Base
|
||||
query << " AND Metadata.LastUpdatedTime >= '#{last.iso8601}' " if last
|
||||
|
||||
if count == 0
|
||||
items = get_base.service.all
|
||||
items = get_base.all
|
||||
else
|
||||
items = get_base.service.query(query)
|
||||
items = get_base.query(query)
|
||||
end
|
||||
|
||||
unless items.count = 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -12,7 +12,7 @@ class QboPurchase < ActiveRecord::Base
|
||||
unloadable
|
||||
belongs_to :issues
|
||||
belongs_to :qbo_customer
|
||||
attr_accessible :description
|
||||
#attr_accessible :description
|
||||
validates_presence_of :id, :line_id, :description, :qbo_customer_id
|
||||
|
||||
def self.get_base
|
||||
@@ -20,11 +20,11 @@ class QboPurchase < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def get_purchase(id)
|
||||
get_base.service.find_by_id(id)
|
||||
get_base.find_by_id(id)
|
||||
end
|
||||
|
||||
def self.sync
|
||||
QboPurchase.get_base.service.all.each { |purchase|
|
||||
QboPurchase.get_base.all.each { |purchase|
|
||||
|
||||
purchase.line_items.all? { |line_item|
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -12,36 +12,39 @@ class Vehicle < ActiveRecord::Base
|
||||
|
||||
unloadable
|
||||
|
||||
API_KEY = Setting.plugin_redmine_qbo['settingsEdmundsAPIKey']
|
||||
|
||||
belongs_to :customer
|
||||
has_many :issues, :foreign_key => 'vehicles_id'
|
||||
|
||||
attr_accessible :year, :make, :model, :customer_id, :notes, :vin
|
||||
#attr_accessible :year, :make, :model, :customer_id, :notes, :vin
|
||||
|
||||
validates_presence_of :customer
|
||||
validates :vin, uniqueness: true
|
||||
#validates :year, numericality: { only_integer: true }
|
||||
|
||||
before_save :decode_vin
|
||||
after_initialize :get_details
|
||||
#after_find :get_details
|
||||
|
||||
self.primary_key = :id
|
||||
|
||||
# returns a human readable string
|
||||
def to_s
|
||||
return "#{year} #{make} #{model}"
|
||||
if year.nil? or make.nil? or model.nil?
|
||||
return "#{vin}"
|
||||
else
|
||||
split_vin = vin.scan(/.{1,9}/)
|
||||
return "#{year} #{make} #{model} - #{split_vin[1]}"
|
||||
end
|
||||
end
|
||||
|
||||
# returns the raw JSON details from EMUNDS
|
||||
def details
|
||||
get_details if @details.nil?
|
||||
return @details
|
||||
end
|
||||
|
||||
# returns the style of the vehicle
|
||||
def style
|
||||
get_details if @details.nil?
|
||||
begin
|
||||
return @details['years'][0]['styles'][0]['name'] if @details
|
||||
return @details.trim if @details
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
@@ -49,21 +52,24 @@ class Vehicle < ActiveRecord::Base
|
||||
|
||||
# returns the drive of the vehicle i.e. 2 wheel, 4 wheel, ect.
|
||||
def drive
|
||||
return @details['drivenWheels'].to_s.upcase if @details
|
||||
#todo fix this
|
||||
#return @details.drive_type if @details
|
||||
return nil
|
||||
end
|
||||
|
||||
# returns the number of doors of the vehicle
|
||||
def doors
|
||||
return @details['numOfDoors'] if @details
|
||||
get_details if @details.nil?
|
||||
return @details.doors if @details
|
||||
end
|
||||
|
||||
# Force Upper Case for VIN numbers
|
||||
# Force Upper Case for make numbers
|
||||
def make=(val)
|
||||
# The to_s is in case you get nil/non-string
|
||||
write_attribute(:make, val.to_s.titleize)
|
||||
end
|
||||
|
||||
# Force Upper Case for VIN numbers
|
||||
# Force Upper Case for model numbers
|
||||
def model=(val)
|
||||
# The to_s is in case you get nil/non-string
|
||||
write_attribute(:model, val.to_s.titleize)
|
||||
@@ -71,44 +77,24 @@ class Vehicle < ActiveRecord::Base
|
||||
|
||||
# Force Upper Case for VIN numbers
|
||||
def vin=(val)
|
||||
# The to_s is in case you get nil/non-string
|
||||
write_attribute(:vin, val.to_s.scan(/^[A-Za-z0-9]+$/).join.upcase)
|
||||
#strip VIN of all illegal chars (for barcode scanner)
|
||||
val = val.to_s.upcase.gsub(/[^A-HJ-NPR-Za-hj-npr-z\d]+/,"")
|
||||
write_attribute(:vin, val)
|
||||
end
|
||||
|
||||
# search for a vin
|
||||
def self.search(search)
|
||||
where("vin LIKE ?", "%#{search}%")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# init method to pull JSON details from Edmunds
|
||||
def get_details
|
||||
if self.vin?
|
||||
begin
|
||||
@details = JSON.parse get_decoder.full(self.vin)
|
||||
raise @details['message'] if @details['status'].to_s.eql? "NOT_FOUND"
|
||||
raise @details['message'] if @details['status'].to_s.eql? "BAD_REQUEST"
|
||||
rescue Exception => e
|
||||
errors.add(:vin, e.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# returns the Edmunds decoder service
|
||||
def get_decoder
|
||||
#TODO API Code via Settings
|
||||
return decoder = Edmunds::Vin.new(API_KEY)
|
||||
end
|
||||
|
||||
|
||||
# decodes a vin and updates self
|
||||
def decode_vin
|
||||
get_details
|
||||
if @details
|
||||
begin
|
||||
self.year = @details['years'][0]['year']
|
||||
self.make = @details['make']['name']
|
||||
self.model = @details['model']['name']
|
||||
self.year = @details.year unless @details.year.nil?
|
||||
self.make = @details.make unless @details.make.nil?
|
||||
self.model = @details.model unless @details.model.nil?
|
||||
rescue Exception => e
|
||||
errors.add(:vin, e.message)
|
||||
end
|
||||
@@ -116,15 +102,24 @@ class Vehicle < ActiveRecord::Base
|
||||
self.name = to_s
|
||||
end
|
||||
|
||||
# makes a squishvin
|
||||
# https://api.edmunds.com/api/vehicle/v2/squishvins/#{vin}/?fmt=json&api_key=#{ENV['edmunds_key']}
|
||||
def vin_squish
|
||||
if not self.vin? or self.vin.size < 11
|
||||
# this is to go ahead and query the API, letting them handle the error. :P
|
||||
return '1000000000A'
|
||||
private
|
||||
|
||||
# init method to pull JSON details from Edmunds
|
||||
def get_details
|
||||
if self.vin?
|
||||
#validate the vin before calling a remote server
|
||||
validation = NhtsaVin.validate(self.vin)
|
||||
begin
|
||||
#if the vin validation failed, raise an exception and exit
|
||||
raise RuntimeError, validation.error unless validation.valid?
|
||||
# query NHTSA for details on the vin
|
||||
query = NhtsaVin.get(self.vin)
|
||||
raise RuntimeError, query.error unless query.valid?
|
||||
@details = query.response
|
||||
rescue Exception => e
|
||||
errors.add(:vin, e.message)
|
||||
end
|
||||
end
|
||||
v = self.vin[0,11]
|
||||
return v.slice(0,8) + v.slice(9,11)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<th><%=t(:label_email)%></th>
|
||||
<td><%= customer.email %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Primary Phone</th>
|
||||
<th><%=t(:label_primary_phone)%></th>
|
||||
<td><%= number_to_phone(customer.primary_phone.gsub(/[^\d]/, '').to_i, area_code: true) if customer.primary_phone %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Mobile Phone</th>
|
||||
<th><%=t(:label_mobile_phone)%></th>
|
||||
<td><%= number_to_phone(customer.mobile_phone.gsub(/[^\d]/, '').to_i, area_code: true) if customer.mobile_phone %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Bill Address</th>
|
||||
<th><%=t(:label_billing_address)%></th>
|
||||
<td><%= customer.billing_address %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Shipping Address</th>
|
||||
<th><%=t(:label_shipping_address)%></th>
|
||||
<td><%= customer.shipping_address %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Issues</th>
|
||||
<th><%=t(:issues)%></th>
|
||||
<td><%= customer.issues.count %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Account Balance</th>
|
||||
<th><%=t(:label_account_balance)%></th>
|
||||
<td>$<%= customer.balance %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Balance With Jobs</th>
|
||||
<th><%=t(:label_balance_with_jobs)%></th>
|
||||
<td>$<%= customer.balance_with_jobs %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Notes</th>
|
||||
<th><%=t(:field_notes)%></th>
|
||||
<td><%= customer.notes %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<%= button_to "Edit Customer", edit_customer_path(customer), method: :get%>
|
||||
<%= button_to t(:label_edit_customer), edit_customer_path(customer), method: :get%>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -5,35 +5,35 @@
|
||||
<%= form_for @customer do |f| %>
|
||||
|
||||
<div class="clearfix">
|
||||
Display Name:
|
||||
<%=t(:label_display_name)%>
|
||||
<div class="input">
|
||||
<%= f.text_field :name, :required => true %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Phone Number:
|
||||
<%=t(:label_primary_phone)%>
|
||||
<div class="input">
|
||||
<%= f.telephone_field :primary_phone %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Mobile Phone Number:
|
||||
<%=t(:label_mobile_phone)%>:
|
||||
<div class="input">
|
||||
<%= f.telephone_field :mobile_phone %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Email:
|
||||
<%=t(:label_email)%>:
|
||||
<div class="input">
|
||||
<%= f.email_field :email %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Notes:
|
||||
<%=t(:field_notes)%>:
|
||||
<div class="input">
|
||||
<p>
|
||||
<%= link_to_function content_tag(:span, l(:button_edit), :class => 'icon icon-edit'), '$(this).hide(); $("#issue_description_and_toolbar").show()' unless @customer.new_record? %>
|
||||
|
||||
6
app/views/customers/_search.html.erb
Normal file
6
app/views/customers/_search.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<%= form_tag(customers_path, :method => "get", id: "search-form") do %>
|
||||
<%= text_field_tag :search, params[:search], placeholder: t(:label_search_customers) %>
|
||||
<%= submit_tag t(:label_search) %>
|
||||
<% end %>
|
||||
<%= button_to t(:label_new_customer), new_customer_path, method: :get%>
|
||||
<%= button_to t(:label_sync), qbo_sync_path, method: :get%>
|
||||
2
app/views/customers/_sidebar.html.erb
Normal file
2
app/views/customers/_sidebar.html.erb
Normal file
@@ -0,0 +1,2 @@
|
||||
<h3><%=t(:label_customers)%></h3>
|
||||
<%= render :partial => 'customers/search' %>
|
||||
@@ -1,3 +1,3 @@
|
||||
<h1>Edit Customer</h1>
|
||||
<h1><%=t(:label_edit_customer)%></h1>
|
||||
<br/>
|
||||
<%= render :partial => 'customers/form' %>
|
||||
|
||||
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 +1 @@
|
||||
$('select#issue_vehicles_id').html('<%= j options_from_collection_for_select(@filtered_vehicles, :id, :to_s) %>');
|
||||
$('select#issue_vehicles_id').html('<%= j content_tag(:option,'',:value=>"")+options_from_collection_for_select(@filtered_vehicles, :id, :to_s) %>');
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
<h1>Customers</h1>
|
||||
<br/>
|
||||
<%= form_tag(customers_path, :method => "get", id: "search-form") do %>
|
||||
<%= text_field_tag :search, params[:search], placeholder: "Search Customers" %>
|
||||
<%= submit_tag "Search" %>
|
||||
<% end %>
|
||||
<br/>
|
||||
<h2><%=t(:field_customers)%> <span style="float:right"> <%= render :partial => 'customers/search' %> </span> </h2>
|
||||
<% if @customers.present? %>
|
||||
<br/>
|
||||
<% @customers.each do |c| %>
|
||||
@@ -15,14 +9,16 @@
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<p><%=t(:label_matching)%> <%= @customers.count %> <%=t(:field_customers)%> </p>
|
||||
|
||||
<div class="actions">
|
||||
<%= will_paginate @customers %>
|
||||
</div>
|
||||
|
||||
<% else %>
|
||||
<p>There are no customers containing the term(s) <%= params[:search] %>.</p>
|
||||
<p><%=t(:label_no_customers)%> <%= params[:search] %>.</p>
|
||||
<% end %>
|
||||
|
||||
<div>
|
||||
<%= Customer.count %> Customers - <b>Last Sync: </b> <%= Qbo.last_sync if Qbo.exists? %>
|
||||
<%= render :partial => 'qbo/stats' %>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<h1>New Customer</h1>
|
||||
<h2><%=t(:label_new_customer)%></h2>
|
||||
<br/>
|
||||
<%= render :partial => 'customers/form' %>
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
<div id="content">
|
||||
<h2>Customer #<%= @customer.id %></h2>
|
||||
<br/>
|
||||
|
||||
<h2><%=t(:field_customer)%> #<%= @customer.id %> - <%= @customer.name %> </h2>
|
||||
<br/>
|
||||
|
||||
<div class="subject">
|
||||
<div><h3><%= @customer.name %></h3></div>
|
||||
<div><h3><%=t(:label_details)%>:</h3></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="attributes">
|
||||
|
||||
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<h4>Details:</h4>
|
||||
<%= render :partial => 'customers/details', locals: {customer: @customer} %>
|
||||
</div>
|
||||
<div class="splitcontentleft">
|
||||
<h4>Vehicles:</h4>
|
||||
<h4><%=t(:field_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} %>
|
||||
<h2><%=t(:label_open_issues)%>:</h2>
|
||||
<%= render :partial => 'issues/list_simple', locals: {issues: @issues.open} %>
|
||||
|
||||
<h2><%=t(:label_closed_issues)%>:</h2>
|
||||
<%= render :partial => 'issues/list_simple', locals: {issues: (@issues - @issues.open)} %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<div class="subject">
|
||||
<%= render_issue_subject_with_tree(@issue) %>
|
||||
This customer link expires in <%= distance_of_time_in_words(Time.now, @token.expires_at) %>
|
||||
<%=t(:label_customer_link_expires)%> <%= distance_of_time_in_words(Time.now, @token.expires_at) %>
|
||||
</div>
|
||||
<p class="author">
|
||||
<%= authoring @issue.created_on, @issue.author %>.
|
||||
@@ -48,7 +48,7 @@ This customer link expires in <%= distance_of_time_in_words(Time.now, @token.exp
|
||||
end
|
||||
#end
|
||||
end %>
|
||||
<%= render_custom_fields_rows(@issue) %>
|
||||
<%= render_full_width_custom_fields_rows(@issue) %>
|
||||
<%= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
|
||||
</div>
|
||||
|
||||
|
||||
4
app/views/estimates/_search.html.erb
Normal file
4
app/views/estimates/_search.html.erb
Normal file
@@ -0,0 +1,4 @@
|
||||
<%= form_tag("/qbo/estimate/doc", :method => "get", id: "est-search-form") do %>
|
||||
<%= text_field_tag :search, params[:search], placeholder: t(:label_search_estimates) %>
|
||||
<%= submit_tag t(:label_search), :formtarget => "_blank" %>
|
||||
<% end %>
|
||||
2
app/views/estimates/_sidebar.html.erb
Normal file
2
app/views/estimates/_sidebar.html.erb
Normal file
@@ -0,0 +1,2 @@
|
||||
<h3><%=t(:label_estimates) %></h3>
|
||||
<%= render :partial => 'estimates/search' %>
|
||||
29
app/views/issues/_list_simple.html.erb
Normal file
29
app/views/issues/_list_simple.html.erb
Normal file
@@ -0,0 +1,29 @@
|
||||
<% if issues && issues.any? %>
|
||||
<%= form_tag({}) do %>
|
||||
<table class="list issues">
|
||||
<thead><tr>
|
||||
<th>#</th>
|
||||
<th><%=l(:field_project)%></th>
|
||||
<th><%=l(:field_tracker)%></th>
|
||||
<th><%=l(:field_subject)%></th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<% for issue in issues %>
|
||||
<tr id="issue-<%= h(issue.id) %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>">
|
||||
<td class="id">
|
||||
<%= check_box_tag("ids[]", issue.id, false, :style => 'display:none;', :id => nil) %>
|
||||
<%= link_to(issue.id, issue_path(issue)) %>
|
||||
</td>
|
||||
<td class="project"><%= link_to_project(issue.project) %></td>
|
||||
<td class="tracker"><%= issue.tracker %></td>
|
||||
<td class="subject">
|
||||
<%= link_to(issue.subject.truncate(60), issue_path(issue)) %> (<%= issue.status %>)
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||
<% end %>
|
||||
@@ -5,28 +5,28 @@
|
||||
<%= form_for @payment do |f| %>
|
||||
|
||||
<div class="clearfix">
|
||||
Customer:
|
||||
<%=t(:field_customer)%>:
|
||||
<div class="input">
|
||||
<%= f.collection_select :customer_id, @customers, :id, :name, include_blank: true, :selected => @customer, :required => true%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Deposit to Account:
|
||||
<%=t(:label_deposit_into)%>:
|
||||
<div class="input">
|
||||
<%= f.collection_select :account_id, @accounts, :id, :name, include_blank: true, :selected => @account, :required => true%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Payment Method:
|
||||
<%=t(:label_payment_method)%>:
|
||||
<div class="input">
|
||||
<%= f.collection_select :payment_method_id, @payment_methods, :id, :name, include_blank: true, :selected => @payment_method, :required => true%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Amount:
|
||||
<%=t(:label_amount)%>:
|
||||
<div class="input">
|
||||
<%= f.number_field :total_amount %>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<h1>New Payment</h1>
|
||||
<h1><%=t(:label_new_payment)%></h1>
|
||||
<br/>
|
||||
<%= render :partial => 'payments/form' %>
|
||||
|
||||
@@ -1 +1 @@
|
||||
<%= flash.now[:error] = "Not Authorized" %>
|
||||
<%= flash.now[:error] = t(:label_401) %>
|
||||
|
||||
35
app/views/qbo/_issues_show_details.html.erb
Normal file
35
app/views/qbo/_issues_show_details.html.erb
Normal file
@@ -0,0 +1,35 @@
|
||||
<div class="splitcontent">
|
||||
<div class="splitcontentleft">
|
||||
<div class="customer_id attribute">
|
||||
<div class="label"><span><%=t(:field_customer)%></span>:</div>
|
||||
<div class="value"><%= customer %></div>
|
||||
</div>
|
||||
|
||||
<div class="qbo_estimate_id attribute">
|
||||
<div class="label"><span><%=t(:field_qbo_estimate)%></span>:</div>
|
||||
<div class="value"><%= estimate_link %></div>
|
||||
</div>
|
||||
|
||||
<div class="qbo_invoice_id attribute">
|
||||
<div class="label"><span><%=t(:field_qbo_invoice)%></span>:</div>
|
||||
<div class="value"><%= invoice_link %></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="splitcontentleft">
|
||||
<div class="vehicle attribute">
|
||||
<div class="label"><span><%=t(:field_vehicle)%></span>:</div>
|
||||
<div class="value"><%= vehicle %></div>
|
||||
</div>
|
||||
|
||||
<div class="vehicle_vin attribute">
|
||||
<div class="label"><span><%=t(:field_vin)%></span>:</div>
|
||||
<div class="value"><%=split_vin[0] if split_vin%><b><%=split_vin[1] if split_vin%></b></div>
|
||||
</div>
|
||||
|
||||
<div class="vehicle_notes attribute">
|
||||
<div class="label"><span><%=t(:field_notes)%></span>:</div>
|
||||
<div class="value"><%=notes%></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
1
app/views/qbo/_last_sync.html.erb
Normal file
1
app/views/qbo/_last_sync.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<b><%=t(:label_last_sync)%>: </b> <%= Qbo.last_sync if Qbo.exists? %>
|
||||
@@ -1,7 +1,7 @@
|
||||
<!--
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 rick barrette
|
||||
Copyright (c) 2020 rick barrette
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
@@ -15,22 +15,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
<!-- configure the Intuit object: 'grantUrl' is a URL in your application which kicks off the flow, see below -->
|
||||
<script>
|
||||
intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_authenticate_url %>'});
|
||||
intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= Setting.host_name %>/qbo/authenticate'});
|
||||
</script>
|
||||
|
||||
<table >
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Edmunds API Key</th>
|
||||
<td>
|
||||
<input type="text" style="width:350px" id="settingsEdmundsAPIKey"
|
||||
value="<%= settings['settingsEdmundsAPIKey'] %>"
|
||||
name="settings[settingsEdmundsAPIKey]" >
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Intuit QBO OAuth Consumer Key</th>
|
||||
<th><%=t(:label_client_id)%></th>
|
||||
<td>
|
||||
<input type="text" style="width:350px" id="settingsOAuthConsumerKey"
|
||||
value="<%= settings['settingsOAuthConsumerKey'] %>"
|
||||
@@ -39,7 +31,7 @@ intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_au
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Intuit QBO OAuth Consumer Secret</th>
|
||||
<th><%=t(:label_client_secret)%></th>
|
||||
<td>
|
||||
<input type="text" style="width:350px" id="settingsOAuthConsumerSecret"
|
||||
value="<%= settings['settingsOAuthConsumerSecret'] %>"
|
||||
@@ -48,7 +40,7 @@ intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_au
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Intuit QBO Webhook Token</th>
|
||||
<th><%=t(:label_webhook_token)%></th>
|
||||
<td>
|
||||
<input type="text" style="width:350px" id="settingsWebhookToken"
|
||||
value="<%= settings['settingsWebhookToken'] %>"
|
||||
@@ -57,20 +49,15 @@ intuit.ipp.anywhere.setup({menuProxy: '/path/to/blue-dot', grantUrl: '<%= qbo_au
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Token Expires At</th>
|
||||
<td><%= if Qbo.exists? then Qbo.first.token_expires_at end %>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Reconnect Token At</th>
|
||||
<td><%= if Qbo.exists? then Qbo.first.reconnect_token_at end %>
|
||||
<th><%=t(:label_oauth_expires)%></th>
|
||||
<td><%= if Qbo.exists? then Qbo.first.expire end %>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
Note: You need to authenticate after saving your key and secret above
|
||||
<%=t(:label_oauth_note)%>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
@@ -81,27 +68,27 @@ Note: You need to authenticate after saving your key and secret above
|
||||
<br/>
|
||||
|
||||
<div>
|
||||
<b>Customer Count:</b> <%= Customer.count%>
|
||||
<b><%=t(:label_customer_count)%>:</b> <%= Customer.count%>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Item Count:</b> <%= QboItem.count %>
|
||||
<b><%=t(:label_item_count)%>:</b> <%= QboItem.count %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Employee Count:</b> <%= QboEmployee.count %>
|
||||
<b><%=t(:label_employee_count)%>:</b> <%= QboEmployee.count %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Invoice Count:</b> <%= QboInvoice.count %>
|
||||
<b><%=t(:label_invoice_count)%>:</b> <%= QboInvoice.count %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Estimate Count:</b> <%= QboEstimate.count %>
|
||||
<b><%=t(:label_estimate_count)%>:</b> <%= QboEstimate.count %>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div>
|
||||
<b>Last Sync: </b> <%= Qbo.last_sync if Qbo.exists? %> <%= link_to " Sync Now", qbo_sync_path %>
|
||||
<b><%=t(:label_last_sync)%> </b> <%= Qbo.last_sync if Qbo.exists? %> <%= link_to " Sync Now", qbo_sync_path %>
|
||||
</div>
|
||||
|
||||
2
app/views/qbo/_sidebar.html.erb
Normal file
2
app/views/qbo/_sidebar.html.erb
Normal file
@@ -0,0 +1,2 @@
|
||||
<%= render :partial => 'customers/sidebar' %>
|
||||
<%= render :partial => 'estimates/sidebar' %>
|
||||
1
app/views/qbo/_stats.html.erb
Normal file
1
app/views/qbo/_stats.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= Customer.count %> <%=t(:field_customers)%> - <%= render :partial => 'qbo/last_sync' %>
|
||||
@@ -11,32 +11,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
-->
|
||||
|
||||
<body>
|
||||
<h1> Redmine Quickbooks</h1>
|
||||
<h1><%=t(:label_redmine_qbo)%></h1>
|
||||
|
||||
<div>
|
||||
<b>Customer Count:</b> <%= @customer_count.to_s%>
|
||||
<b><%=t(:label_customer_count)%>:</b> <%= @customer_count.to_s%>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Item Count:</b> <%= @qbo_item_count.to_s %>
|
||||
<b><%=t(:label_item_count)%>:</b> <%= @qbo_item_count.to_s %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Employee Count:</b> <%= @qbo_employee_count.to_s %>
|
||||
<b><%=t(:label_employee_count)%>:</b> <%= @qbo_employee_count.to_s %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Invoice Count:</b> <%= @qbo_invoice_count.to_s %>
|
||||
<b><%=t(:label_invoice_count)%>:</b> <%= @qbo_invoice_count.to_s %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<b>Estimate Count:</b> <%= @qbo_estimate_count.to_s %>
|
||||
<b><%=t(:label_estimate_count)%>:</b> <%= @qbo_estimate_count.to_s %>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div>
|
||||
<b>Last Sync: </b> <%= Qbo.last_sync if Qbo.exists? %>
|
||||
<b><%=t(:label_last_sync)%>: </b> <%= Qbo.last_sync if Qbo.exists? %>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -2,52 +2,34 @@
|
||||
<tbody>
|
||||
|
||||
<tr>
|
||||
<th>Customer</th>
|
||||
<th><%= t(:field_customer)%></th>
|
||||
<td><%= link_to vehicle.customer.name, customer_path(vehicle.customer) %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Vehicle</th>
|
||||
<th><%= t(:field_vehicle) %></th>
|
||||
<td><%= vehicle.to_s %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>VIN</th>
|
||||
<td><%= vehicle.vin %></td>
|
||||
<th><%= t(:field_vin) %></th>
|
||||
<td><%= @vin[0] if @vin %><b><%=@vin[1] if @vin%></b></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Style</th>
|
||||
<td><%= vehicle.style %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Drive</th>
|
||||
<td><%= vehicle.drive %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Doors</th>
|
||||
<td><%= vehicle.doors %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Notes</th>
|
||||
<th><%= t(:field_notes) %></th>
|
||||
<td><%= vehicle.notes %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Issues</th>
|
||||
<th> <%= t(:issues) %> </th>
|
||||
<td><%= vehicle.issues.count %></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td/>
|
||||
<td>
|
||||
|
||||
<%= button_to "New Issue", new_issue_path(:vehicle_id => vehicle.id, :customer_id => vehicle.customer.id), method: :get%>
|
||||
<%= button_to "Edit", edit_vehicle_path(vehicle), method: :get%>
|
||||
<%= button_to "Delete", vehicle, method: :delete, data: {confirm: "You sure?"} %>
|
||||
<%= button_to t(:label_edit), edit_vehicle_path(vehicle), method: :get%>
|
||||
<%= button_to t(:label_delete), vehicle, method: :delete, data: {confirm: t(:warn_ru_sure)} %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -4,51 +4,45 @@
|
||||
|
||||
<%= form_for @vehicle do |f| %>
|
||||
<div class="clearfix">
|
||||
Customer:
|
||||
<div class="input">
|
||||
<%= f.collection_select :customer_id, @customers, :id, :name, include_blank: true, :selected => @customer, :required => true%>
|
||||
</div>
|
||||
<%=t(:field_customer)%>:
|
||||
<div class="input">
|
||||
<%= f.autocomplete_field :customer, autocomplete_customer_name_customers_path, :value => @customer.name, :update_elements => {:id => '#customer_id', :value => '#issue_customer'}, :required => true %>
|
||||
<%= f.hidden_field :customer_id, :id => "customer_id", :value => @customer.id %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Year:
|
||||
<%=t(:label_year)%>:
|
||||
<div class="input">
|
||||
<%= f.number_field :year %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Make:
|
||||
<%=t(:label_make)%>:
|
||||
<div class="input">
|
||||
<%= f.text_field :make %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Model:
|
||||
<%=t(:label_model)%>:
|
||||
<div class="input">
|
||||
<%= f.text_field :model %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
VIN:
|
||||
<%=t(:field_vin)%>:
|
||||
<div class="input">
|
||||
<%= f.text_field :vin , :autofocus => true %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
Notes:
|
||||
<%=t(:field_notes)%>:
|
||||
<div class="input">
|
||||
<p>
|
||||
<%= content_tag 'span', :id => "issue_description_and_toolbar", :style => (@vehicle.new_record? ? nil : 'display:none') do %>
|
||||
<%= f.text_area :notes,
|
||||
:cols => 60,
|
||||
:rows => 10,
|
||||
:no_label => true %>
|
||||
<% end %>
|
||||
</p>
|
||||
<%= f.text_area :notes, :cols => 60, :rows => 10, :no_label => true %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
<%= will_paginate @vehicles %>
|
||||
</div>
|
||||
|
||||
<p><%=t(:label_matching)%> <%=@vehicles.count%> <%=t(:field_vehicles) %> </p>
|
||||
|
||||
<% else %>
|
||||
<p>There are no vehicles containing the term(s) <%= params[:search] %>.</p>
|
||||
<p><%=t(:label_no_vehicles)%> <%= params[:search] %>.</p>
|
||||
<% end %>
|
||||
|
||||
4
app/views/vehicles/_search.html.erb
Normal file
4
app/views/vehicles/_search.html.erb
Normal file
@@ -0,0 +1,4 @@
|
||||
<%= form_tag(vehicles_path, :method => "get", id: "search-form") do %>
|
||||
<%= text_field_tag :search, params[:search], placeholder: t(:label_seach_vin) %>
|
||||
<%= submit_tag t(:label_search) %>
|
||||
<% end %>
|
||||
@@ -1,3 +1,3 @@
|
||||
<h1>Edit Customer Vehicle</h1>
|
||||
<h1><%=t(:label_edit_customer_vehicle)%></h1>
|
||||
<br/>
|
||||
<%= render :partial => 'vehicles/form' %>
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
<h1>Customer Vehicles</h1>
|
||||
<h2><%=t(:label_cusomer_vehicles)%> <span style="float:right"> <%= render :partial => 'vehicles/search' %> </span> </h2>
|
||||
<br/>
|
||||
|
||||
<%= form_tag(vehicles_path, :method => "get", id: "search-form") do %>
|
||||
<%= text_field_tag :search, params[:search], placeholder: "Search Vehicles by VIN" %>
|
||||
<%= submit_tag "Search" %>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => 'vehicles/list' %>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<h1>New Customer Vehicle</h1>
|
||||
<h2><%=t(:label_new_vehicle)%></h2>
|
||||
<br/>
|
||||
<%= render :partial => 'vehicles/form' %>
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
<h1>Vehicle #<%=@vehicle.id%> </h1>
|
||||
<br/>
|
||||
<h2><%=t(:field_vehicle)%> #<%=@vehicle.id%> <span style="float:right"> <%= render :partial => 'customers/search' %> </span> </h2>
|
||||
<br/>
|
||||
|
||||
<div style="text-align: left; width:90%;">
|
||||
<%= render :partial => 'vehicles/details', locals: {vehicle: @vehicle} %>
|
||||
|
||||
<%= render :partial => 'issues/list_simple', locals: {issues: @vehicle.issues} %>
|
||||
<p> <b> <%=t(:label_open_issues)%> </b> </p>
|
||||
|
||||
<%= render :partial => 'issues/list_simple', locals: {issues: @vehicle.issues.open} %>
|
||||
|
||||
<p> <b> <%=t(:label_closed_issues)%> </b> </p>
|
||||
|
||||
<%= render :partial => 'issues/list_simple', locals: {issues: (@vehicle.issues - @vehicle.issues.open)} %>
|
||||
</div>
|
||||
|
||||
@@ -5,5 +5,19 @@ $(function() {
|
||||
type: "GET",
|
||||
data: { selected_customer: $("input#issue_customer_id").val() }
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: "/filter_estimates_by_customer",
|
||||
type: "GET",
|
||||
data: { selected_customer: $("input#issue_customer_id").val() }
|
||||
});
|
||||
});
|
||||
|
||||
$("input#project_customer_id").on("change", function() {
|
||||
$.ajax({
|
||||
url: "/filter_vehicles_by_customer",
|
||||
type: "GET",
|
||||
data: { selected_customer: $("input#project_customer_id").val() }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
Edmunds::Api.configure do |config|
|
||||
config.api_key = '2dheutzvhxs28dzukx5tgu47'
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -9,6 +9,7 @@
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
# English strings go here for Rails i18n
|
||||
# Usage t(:label)
|
||||
en:
|
||||
# my_label: "My label"
|
||||
field_customer: "Customer"
|
||||
@@ -16,8 +17,60 @@ en:
|
||||
field_qbo_employee: "Employee"
|
||||
field_qbo_invoice: "Invoice"
|
||||
field_qbo_estimate: "Estimate"
|
||||
field_vehicles: "Vehicle"
|
||||
field_vehicles: "Vehicles"
|
||||
field_vehicle: "Vehicle"
|
||||
field_vin: "VIN"
|
||||
field_notes: "Notes"
|
||||
field_qbo_billed: "Billed"
|
||||
label_week: "Week"
|
||||
label_search_estimates: "Search Estimates"
|
||||
label_search: "Search"
|
||||
label_estimates: "Estimates"
|
||||
label_401: "Not Authorized"
|
||||
warn_ru_sure: "You sure?"
|
||||
label_delete: "Delete"
|
||||
label_edit: "Edit"
|
||||
label_year: "Year"
|
||||
label_make: " Make"
|
||||
label_model: "Model"
|
||||
label_no_vehicles: "There are no vehicles containing the term(s)"
|
||||
label_no_customers: "There are no customers containing the term(s)"
|
||||
label_matching: "Matching "
|
||||
label_search_vin: "Search Vehicles by VIN"
|
||||
label_edit_customer_vehicle: "Edit Customer Vehicle"
|
||||
label_cusomer_vehicles: "Customer Vehicles"
|
||||
label_new_vehicle: "New Customer Vehicle"
|
||||
label_open_issues: "Open Issues"
|
||||
label_closed_issues: "Closed Issues"
|
||||
label_sync: "Sync"
|
||||
label_new_customer: "New Customer"
|
||||
label_search_customers: "Search Customers"
|
||||
label_customers: "Customers"
|
||||
label_edit_customer: "Edit Customer"
|
||||
label_email: "Email"
|
||||
label_primary_phone: "Primary Phone"
|
||||
label_mobile_phone: "Mobile Phone"
|
||||
label_billing_address: "Billing Address"
|
||||
label_shipping_address: "Shipping Address"
|
||||
label_account_balance: "Account Balance"
|
||||
label_balance_with_jobs: "Balance With Jobs"
|
||||
label_display_name: "Display Name"
|
||||
label_details: "Details"
|
||||
label_customer_link_expires: "This customer link expires in"
|
||||
label_new_payment: "New Payment"
|
||||
label_amount: "Amount"
|
||||
label_payment_method: "Payment Method"
|
||||
label_deposit_into: "Deposit to Account"
|
||||
label_last_sync: "Last Sync"
|
||||
label_redmine_qbo: "Redmine Quickbooks"
|
||||
label_customer_count: "Customer Count"
|
||||
label_invoice_count: "Invoice Count"
|
||||
label_estimate_count: "Estimate Count"
|
||||
label_item_count: "Item Count"
|
||||
label_employee_count: "Employee Count"
|
||||
label_client_id: "Intuit QBO OAuth2 Client ID"
|
||||
label_client_secret: "Intuit QBO OAuth2 Client Secret"
|
||||
label_webhook_token: "Intuit QBO Webhook Token"
|
||||
label_oauth_expires: "OAuth2 Access Token Expires At"
|
||||
label_oauth_note: "Note: You need to authenticate with Quickbooks after saving your key and secret above"
|
||||
field_customers: "Customers"
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -20,6 +20,7 @@ get 'qbo/sync', :to => 'qbo#sync'
|
||||
|
||||
# Estimate & Invoice PDF
|
||||
get 'qbo/estimate/:id', :to => 'estimate#show', as: :estimate
|
||||
get 'qbo/estimate/doc/:id', :to => 'estimate#doc', as: :estimate_doc
|
||||
get 'qbo/invoice/:id', :to => 'invoice#show', as: :invoice
|
||||
|
||||
#manual billing
|
||||
@@ -34,15 +35,18 @@ resources :payments
|
||||
#webhook
|
||||
post 'qbo/webhook', :to => 'qbo#qbo_webhook'
|
||||
|
||||
#ajax
|
||||
#java script routes
|
||||
get 'filter_vehicles_by_customer' => 'customers#filter_vehicles_by_customer'
|
||||
get 'filter_estimates_by_customer' => 'customers#filter_estimates_by_customer'
|
||||
get 'filter_invoices_by_customer' => 'customers#filter_invoices_by_customer'
|
||||
|
||||
# Nest Vehicles under customers
|
||||
resources :customers do
|
||||
resources :vehicles
|
||||
get :autocomplete_customer_name, :on => :collection
|
||||
get :autocomplete_customer_vehicles, :on => :collection
|
||||
end
|
||||
|
||||
#allow for just vehicles too
|
||||
resources :vehicles
|
||||
|
||||
#resources :qbo_estimates
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateQbos < ActiveRecord::Migration
|
||||
class CreateQbos < ActiveRecord::Migration[5.1]
|
||||
|
||||
def change
|
||||
create_table :qbos do |t|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateQboCustomers < ActiveRecord::Migration
|
||||
class CreateQboCustomers < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :qbo_customers, id: false do |t|
|
||||
t.integer :id, :options => 'PRIMARY KEY'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateIssues < ActiveRecord::Migration
|
||||
class UpdateIssues < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :issues, :qbo_customer, index: true
|
||||
add_reference :issues, :qbo_item, index: true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateQboItems < ActiveRecord::Migration
|
||||
class CreateQboItems < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :qbo_items, id: false do |t|
|
||||
t.integer :id, :options => 'PRIMARY KEY'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateQboEmployees < ActiveRecord::Migration
|
||||
class CreateQboEmployees < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :qbo_employees, id: false do |t|
|
||||
t.integer :id, :options => 'PRIMARY KEY'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateUsers < ActiveRecord::Migration
|
||||
class UpdateUsers < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :users, :qbo_employee, index: true
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateTimeEntries < ActiveRecord::Migration
|
||||
class UpdateTimeEntries < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :time_entries, :qbo_billed, :boolean, :default => false
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateQboEstimates < ActiveRecord::Migration
|
||||
class CreateQboEstimates < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :qbo_estimates, id: false do |t|
|
||||
t.integer :id, :options => 'PRIMARY KEY'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateQbos < ActiveRecord::Migration
|
||||
class UpdateQbos < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
rename_column :qbos, :token, :qb_token
|
||||
rename_column :qbos, :secret, :qb_secret
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateIssuesWithEstimates < ActiveRecord::Migration
|
||||
class UpdateIssuesWithEstimates < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :issues, :qbo_estimate, index: true
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateQboInvoices < ActiveRecord::Migration
|
||||
class CreateQboInvoices < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :qbo_invoices, id: false do |t|
|
||||
t.integer :id, :options => 'PRIMARY KEY'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateIssuesWithInvoices< ActiveRecord::Migration
|
||||
class UpdateIssuesWithInvoices< ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :issues, :qbo_invoice, index: true
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateQboPurchases< ActiveRecord::Migration
|
||||
class CreateQboPurchases< ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :qbo_purchases, id: false do |t|
|
||||
t.integer :id, :options => 'PRIMARY KEY'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateCustomers < ActiveRecord::Migration
|
||||
class UpdateCustomers < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :qbo_customers, :qbo_purchase, index: true
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateQboPurchases < ActiveRecord::Migration
|
||||
class UpdateQboPurchases < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
rename_column :qbo_purchases, :customer_id, :qbo_customer_id
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateVehicles < ActiveRecord::Migration
|
||||
class CreateVehicles < ActiveRecord::Migration[5.1]
|
||||
|
||||
def change
|
||||
create_table :vehicles do |t|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateIssuesWithVehicles < ActiveRecord::Migration
|
||||
class UpdateIssuesWithVehicles < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :issues, :vehicles, index: true
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateVehicles < ActiveRecord::Migration
|
||||
class UpdateVehicles < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :vehicles, :name, :text
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class QbocustomersToCustomers< ActiveRecord::Migration
|
||||
class QbocustomersToCustomers< ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
rename_table :qbo_customers, :customers
|
||||
rename_column :issues, :qbo_customer_id, :customer_id
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateQbosTimeStamp < ActiveRecord::Migration
|
||||
class UpdateQbosTimeStamp < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :qbos, :last_sync, :datetime
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class AddIssuesQboInvoices < ActiveRecord::Migration
|
||||
class AddIssuesQboInvoices < ActiveRecord::Migration[5.1]
|
||||
def self.up
|
||||
create_table :issues_qbo_invoices, :id => false do |t|
|
||||
t.references :issue
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateIssuesRemoveInvoice < ActiveRecord::Migration
|
||||
class UpdateIssuesRemoveInvoice < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
remove_reference :issues, :qbo_invoice
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateCustomerTokens < ActiveRecord::Migration
|
||||
class CreateCustomerTokens < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :customer_tokens do |t|
|
||||
t.string :token
|
||||
|
||||
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) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateInvoicesAndEstimates < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :qbo_invoices, :customer, index: true
|
||||
add_reference :qbo_estimates, :customer, index: true
|
||||
end
|
||||
end
|
||||
16
db/migrate/025_update_projects.rb
Normal file
16
db/migrate/025_update_projects.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateProjects < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_reference :projects, :customer, index: true
|
||||
add_reference :projects, :vehicle, index: true
|
||||
end
|
||||
end
|
||||
26
db/migrate/026_create_line_items.rb
Normal file
26
db/migrate/026_create_line_items.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
#The License
|
||||
#
|
||||
#Copyright (c) 2022 Rick Barrette - All Rights Reserved
|
||||
#
|
||||
#Unauthorized copying of this software and associated documentation files (the "Software"), via any medium is strictly prohibited.
|
||||
#
|
||||
#Proprietary and confidential
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class CreateLineItems < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
create_table :line_items do |t|
|
||||
t.integer :item_id
|
||||
t.float :amount
|
||||
t.string :description
|
||||
t.float :unit_price
|
||||
t.float :quantity
|
||||
t.boolean :billed
|
||||
end
|
||||
|
||||
add_reference :line_items, :issues, index: true
|
||||
end
|
||||
end
|
||||
15
db/migrate/027_add_customers_phone_number.rb
Normal file
15
db/migrate/027_add_customers_phone_number.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class AddCustomersPhoneNumber < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :customers, :phone_number, :string
|
||||
end
|
||||
end
|
||||
15
db/migrate/028_add_customers_mobile_phone_number.rb
Normal file
15
db/migrate/028_add_customers_mobile_phone_number.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class AddCustomersMobilePhoneNumber < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
add_column :customers, :mobile_phone_number, :string
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -8,11 +8,10 @@
|
||||
#
|
||||
#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
|
||||
class UpdateQbosTypes < ActiveRecord::Migration[5.1]
|
||||
|
||||
def perform()
|
||||
# email something
|
||||
def change
|
||||
change_column :qbos, :qb_token, :text
|
||||
change_column :qbos, :qb_secret, :text
|
||||
end
|
||||
end
|
||||
17
db/migrate/030_update_qbos_token.rb
Normal file
17
db/migrate/030_update_qbos_token.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class UpdateQbosToken < ActiveRecord::Migration[5.1]
|
||||
|
||||
def change
|
||||
add_column :qbos, :token, :text
|
||||
add_column :qbos, :expire, :datetime
|
||||
end
|
||||
end
|
||||
18
db/migrate/031_remove_qbos_keys.rb
Normal file
18
db/migrate/031_remove_qbos_keys.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class RemoveQbosKeys < ActiveRecord::Migration[5.1]
|
||||
def change
|
||||
remove_column :qbos, :qb_secret
|
||||
remove_column :qbos, :token_expires_at
|
||||
remove_column :qbos, :reconnect_token_at
|
||||
remove_column :qbos, :qb_token
|
||||
end
|
||||
end
|
||||
36
init.rb
36
init.rb
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -16,19 +16,23 @@ Redmine::Plugin.register :redmine_qbo do
|
||||
require_dependency 'issues_show_hook_listener'
|
||||
require_dependency 'users_show_hook_listener'
|
||||
require_dependency 'header_footer_hook_listener'
|
||||
|
||||
require_dependency 'projects_form_hook_listener'
|
||||
require_dependency 'view_hook_listener'
|
||||
|
||||
# Patches to the Redmine core. Will not work in development mode
|
||||
require_dependency 'issue_patch'
|
||||
require_dependency 'project_patch'
|
||||
require_dependency 'user_patch'
|
||||
require_dependency 'query_patch'
|
||||
require_dependency 'time_entry_query_patch'
|
||||
require_dependency 'pdf_patch'
|
||||
require_dependency 'attachments_controller_patch'
|
||||
|
||||
# About
|
||||
name 'Redmine Quickbooks Online plugin'
|
||||
author 'Rick Barrette'
|
||||
description 'This is a plugin for Redmine to intergrate with Quickbooks Online to allow for seamless intergration CRM and invoicing of completed issues'
|
||||
version '0.4.2'
|
||||
version '1.0.0'
|
||||
url 'https://github.com/rickbarrette/redmine_qbo'
|
||||
author_url 'http://rickbarrette.org'
|
||||
settings :default => {'empty' => true}, :partial => 'qbo/settings'
|
||||
@@ -41,24 +45,24 @@ Redmine::Plugin.register :redmine_qbo do
|
||||
Issue.safe_attributes 'vehicles_id'
|
||||
User.safe_attributes 'qbo_employee_id'
|
||||
TimeEntry.safe_attributes 'qbo_billed'
|
||||
|
||||
Project.safe_attributes 'customer_id'
|
||||
Project.safe_attributes 'vehicle_id'
|
||||
|
||||
# We are playing in the sandbox
|
||||
#Quickbooks.sandbox_mode = true
|
||||
|
||||
# set per_page globally
|
||||
WillPaginate.per_page = 10
|
||||
|
||||
WillPaginate.per_page = 20
|
||||
|
||||
# Permissions for security
|
||||
permission :view_customers, :customers => :index, :public => false
|
||||
permission :add_customers, :customers => :new, :public => false
|
||||
permission :view_payments, :payments => :index, :public => false
|
||||
permission :add_payments, :payments => :new, :public => false
|
||||
permission :view_vehicles, :payments => :new, :public => false
|
||||
|
||||
# Register QBO top menu item
|
||||
#menu :top_menu, :qbo, { :controller => :qbo, :action => :index }, :caption => 'Quickbooks', :if => Proc.new { User.current.admin? }
|
||||
menu :top_menu, :customers, { :controller => :customers, :action => :index }, :caption => 'Customers', :if => Proc.new { User.current.logged? }
|
||||
menu :top_menu, :customers, { :controller => :customers, :action => :index }, :caption => 'Customers', :if => Proc.new {User.current.logged?}
|
||||
menu :top_menu, :vehicles, { :controller => :vehicles, :action => :index }, :caption => 'Vehicles', :if => Proc.new { User.current.logged? }
|
||||
|
||||
menu :application_menu, :new_customer, { :controller => :customers, :action => :new }, :caption => 'New Customer', :if => Proc.new { User.current.logged? }
|
||||
menu :application_menu, :new_payment, { :controller => :payments, :action => :new }, :caption => 'New Payment', :if => Proc.new { User.current.logged? }
|
||||
|
||||
permission :customers, { :customers => [:index, :new] }, :public => false
|
||||
menu :project_menu, :customers, { :controller => 'customers', :action => 'new' }, :caption => 'New Customer', :after => :new_issue, :param => :project_id
|
||||
|
||||
permission :payments, { :payments => [:index, :new] }, :public => false
|
||||
menu :project_menu, :payments, { :controller => 'payments', :action => 'new' }, :caption => 'New Payment', :after => :customers, :param => :project_id
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2020 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -41,37 +41,47 @@ module IssuePatch
|
||||
|
||||
# Create billable time entries
|
||||
def bill_time
|
||||
|
||||
|
||||
# Check to see if we have everything we need to bill the customer
|
||||
#return unless status.is_closed?
|
||||
return if assigned_to.nil?
|
||||
return unless Qbo.first
|
||||
return unless customer
|
||||
|
||||
# Get unbilled time entries
|
||||
spent_time = time_entries.where(qbo_billed: [false, nil])
|
||||
spent_hours ||= spent_time.sum(:hours) || 0
|
||||
|
||||
if spent_hours > 0 then
|
||||
|
||||
|
||||
# Prepare to create a new Time Activity
|
||||
time_service = Qbo.get_base(:time_activity).service
|
||||
item_service = Qbo.get_base(:item).service
|
||||
time_service = Qbo.get_base(:time_activity)
|
||||
item_service = Qbo.get_base(:item)
|
||||
time_entry = Quickbooks::Model::TimeActivity.new
|
||||
|
||||
# Lets total up each activity before billing.
|
||||
# This will simpify the invoicing with a single billable time entry per time activity
|
||||
h = Hash.new(0)
|
||||
spent_time.each do |entry|
|
||||
# Lets tottal up each activity
|
||||
h[entry.activity.name] += entry.hours
|
||||
# update time entries billed status
|
||||
entry.qbo_billed = true
|
||||
entry.save
|
||||
end
|
||||
|
||||
# Now letes upload our totals for each activity as their own billable time entry
|
||||
h.each do |key, val|
|
||||
|
||||
# Convert float spent time to hours and minutes
|
||||
hours = val.to_i
|
||||
minutesDecimal = (( val - hours) * 60)
|
||||
minutes = minutesDecimal.to_i
|
||||
|
||||
|
||||
# Lets match the activity to an qbo item
|
||||
item = item_service.query("SELECT * FROM Item WHERE Name = '#{key}' ").first
|
||||
next if item.nil?
|
||||
|
||||
# Create the new billable time entry and upload it
|
||||
time_entry.description = "#{tracker} ##{id}: #{subject} #{"(Partial @ #{done_ratio}%)" if not closed?}"
|
||||
# TODO entry.user.qbo_employee.id
|
||||
time_entry.employee_id = assigned_to.qbo_employee_id
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -9,40 +9,59 @@
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
class IssuesFormHookListener < Redmine::Hook::ViewListener
|
||||
|
||||
|
||||
# Load the javascript
|
||||
def view_layouts_base_html_head(context = {})
|
||||
js = javascript_include_tag 'application', :plugin => 'redmine_qbo'
|
||||
js += javascript_include_tag 'autocomplete-rails', :plugin => 'redmine_qbo'
|
||||
return js
|
||||
end
|
||||
|
||||
|
||||
# Edit Issue Form
|
||||
# Show a dropdown for quickbooks contacts
|
||||
def view_issues_form_details_bottom(context={})
|
||||
f = context[:form]
|
||||
|
||||
|
||||
#check project level customer/vehicle ownership first
|
||||
if context[:project]
|
||||
selected_customer = context[:project].customer ? context[:project].customer.id : nil
|
||||
selected_vehicle = context[:project].vehicle ? context[:project].vehicle.id : nil
|
||||
end
|
||||
|
||||
# Check to see if there is a quickbooks user attached to the issue
|
||||
selected_customer = context[:issue].customer ? context[:issue].customer.id : nil
|
||||
selected_estimate = context[:issue].qbo_estimate ? context[:issue].qbo_estimate.id : nil
|
||||
selected_vehicle = context[:issue].vehicles_id ? context[:issue].vehicles_id : nil
|
||||
|
||||
|
||||
# Load customer information
|
||||
customer = Customer.find_by_id(selected_customer) if selected_customer
|
||||
search_customer = f.autocomplete_field :customer, autocomplete_customer_name_customers_path, :selected => selected_customer, :update_elements => {:id => '#issue_customer_id', :value => '#issue_customer'}
|
||||
customer_id = f.hidden_field :customer_id, :id => "issue_customer_id"
|
||||
|
||||
# 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
|
||||
|
||||
customer = Customer.find_by_id(selected_customer) if selected_customer
|
||||
|
||||
search_customer = f.autocomplete_field :customer,
|
||||
autocomplete_customer_name_customers_path,
|
||||
:selected => selected_customer,
|
||||
:update_elements => { :id => '#issue_customer_id', :value => '#issue_customer' }
|
||||
|
||||
customer_id = f.hidden_field :customer_id,
|
||||
:id => "issue_customer_id",
|
||||
:onchange => "updateIssueFrom('/issues/#{context[:issue].id}/edit.js', this)"
|
||||
|
||||
if context[:issue].customer
|
||||
vehicles = customer.vehicles.pluck(:name, :id).sort!
|
||||
if customer.vehicles
|
||||
vehicles = customer.vehicles.pluck(:name, :id)
|
||||
else
|
||||
vehicles = [nil].compact
|
||||
end
|
||||
estimates = customer.qbo_estimates.pluck(:doc_number, :id).sort! {|x, y| y <=> x}
|
||||
else
|
||||
vehicles = [nil].compact
|
||||
estimates = [nil].compact
|
||||
end
|
||||
|
||||
|
||||
# Generate the drop down list of quickbooks extimates
|
||||
select_estimate = f.select :qbo_estimate_id, estimates, :selected => selected_estimate, include_blank: true
|
||||
|
||||
vehicle = f.select :vehicles_id, vehicles, :selected => selected_vehicle, include_blank: true
|
||||
|
||||
|
||||
return "<p><label for=\"issue_customer\">Customer</label>#{search_customer} #{customer_id}</p> <p>#{select_estimate}</p> <p>#{vehicle}</p>"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -10,47 +10,16 @@
|
||||
|
||||
class IssuesSaveHookListener < Redmine::Hook::ViewListener
|
||||
|
||||
#Before Issue Saved
|
||||
# Called Before Issue Saved
|
||||
def controller_issues_edit_before_save(context={})
|
||||
issue = context[:issue]
|
||||
|
||||
# Check to see if we have registered with QBO
|
||||
if Qbo.first && issue.customer && issue. qbo_item_id
|
||||
|
||||
# if this is a quote, lets create a new estimate based off estimated hours
|
||||
if issue.tracker.name = "Quote" && issue.status.name = "New" && issue.qbo_estimate
|
||||
|
||||
# Get QBO Services
|
||||
item_service = QboItem.get_base.service
|
||||
estimate_base = QboEstimate.get_base
|
||||
|
||||
# Create the estimate
|
||||
estimate = estimate_base.qr_model(:estimate)
|
||||
estimate.customer_id = issue.customer_id
|
||||
estimate.txn_date = Date.today
|
||||
|
||||
# Create the line item for labor
|
||||
item = item_service.fetch_by_id(issue.qbo_item_id)
|
||||
|
||||
line_item = Quickbooks::Model::InvoiceLineItem.new
|
||||
line_item.amount = item.unit_price * issue.estimated_hours
|
||||
line_item.description = issue.subject
|
||||
|
||||
line_item.sales_item! do |detail|
|
||||
detail.unit_price = item.unit_price
|
||||
detail.quantity = issue.estimated_hours
|
||||
detail.item_id = issue.qbo_item_id
|
||||
end
|
||||
|
||||
# Add the line items to the estimate
|
||||
estimate.line_items << line_item
|
||||
end
|
||||
end
|
||||
issue.subject = issue.subject.titleize
|
||||
end
|
||||
|
||||
# Called After Issue Saved
|
||||
# Called After Issue Saved
|
||||
def controller_issues_edit_after_save(context={})
|
||||
issue = context[:issue]
|
||||
issue.bill_time if Qbo.first && issue.customer && issue.status.is_closed?
|
||||
issue.bill_time if issue.status.is_closed?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2017 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -10,11 +10,6 @@
|
||||
|
||||
class IssuesShowHookListener < Redmine::Hook::ViewListener
|
||||
|
||||
# Additional context fields
|
||||
# :issue => the issue this is edited
|
||||
# :f => the form object to create additional fields
|
||||
#render_on :view_issues_show_details_bottom, :partial => 'hooks/redmine_qbo/_view_issues_show_details_bottom.html.erb'
|
||||
|
||||
# View Issue
|
||||
# Display the quickbooks contact in the issue
|
||||
def view_issues_show_details_bottom(context={})
|
||||
@@ -37,6 +32,7 @@ class IssuesShowHookListener < Redmine::Hook::ViewListener
|
||||
issue.qbo_invoice_ids.each do |i|
|
||||
invoice = QboInvoice.find i
|
||||
invoice_link = invoice_link + link_to( invoice.doc_number, "#{Redmine::Utils::relative_url_root}/qbo/invoice/#{i}", :target => "_blank").to_s + " "
|
||||
invoice_link = invoice_link.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,46 +46,20 @@ class IssuesShowHookListener < Redmine::Hook::ViewListener
|
||||
end
|
||||
|
||||
split_vin = vin.scan(/.{1,9}/) if vin
|
||||
|
||||
return "
|
||||
<div class=\"splitcontent\">
|
||||
|
||||
<div class=\"splitcontentleft\">
|
||||
<div class=\"customer_id attribute\">
|
||||
<div class=\"label\"><span>Customer</span>:</div>
|
||||
<div class=\"value\">#{customer}</div>
|
||||
</div>
|
||||
|
||||
<div class=\"qbo_estimate_id attribute\">
|
||||
<div class=\"label\"><span>Estimate</span>:</div>
|
||||
<div class=\"value\">#{estimate_link}</div>
|
||||
</div>
|
||||
|
||||
<div class=\"qbo_invoice_id attribute\">
|
||||
<div class=\"label\"><span>Invoice</span>:</div>
|
||||
<div class=\"value\">#{invoice_link}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=\"splitcontentleft\">
|
||||
<div class=\"vehicle attribute\">
|
||||
<div class=\"label\"><span>Vehicle</span>:</div>
|
||||
<div class=\"value\">#{vehicle}</div>
|
||||
</div>
|
||||
|
||||
<div class=\"vehicle_vin attribute\">
|
||||
<div class=\"label\"><span>VIN</span>:</div>
|
||||
<div class=\"value\">#{split_vin[0] if split_vin}<b>#{split_vin[1] if split_vin}</b></div>
|
||||
</div>
|
||||
|
||||
<div class=\"vehicle_notes attribute\">
|
||||
<div class=\"label\"><span>Notes</span>:</div>
|
||||
<div class=\"value\">#{notes}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>"
|
||||
|
||||
context[:controller].send(:render_to_string, {
|
||||
:partial => 'qbo/issues_show_details',
|
||||
locals: {
|
||||
customer: customer,
|
||||
estimate_link: estimate_link,
|
||||
invoice_link: invoice_link,
|
||||
vehicle: vehicle,
|
||||
split_vin: split_vin,
|
||||
notes: notes
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
def view_issues_show_description_bottom(context={})
|
||||
bill_button = button_to "Bill Time", "#{Redmine::Utils::relative_url_root}/qbo/bill/#{context[:issue].id}", method: :get if User.current.admin?
|
||||
share_button = button_to "Share", "#{Redmine::Utils::relative_url_root}/customers/view/#{context[:issue].share_token.token}", method: :get if User.current.logged?
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
require_dependency 'redmine/export/pdf'
|
||||
require_dependency 'redmine/export/pdf/issues_pdf_helper'
|
||||
|
||||
@@ -7,7 +17,9 @@ module IssuesPdfHelperPatch
|
||||
base.send(:include, InstanceMethods)
|
||||
base.class_eval do
|
||||
unloadable # Send unloadable so it will not be unloaded in development
|
||||
alias_method_chain :issue_to_pdf, :patch
|
||||
alias_method :issue_to_pdf, :issue_to_pdf_with_patch
|
||||
alias_method :issue_to_pdf_with_patch, :issue_to_pdf
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
40
lib/project_patch.rb
Normal file
40
lib/project_patch.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
#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 'project'
|
||||
|
||||
# Patches Redmine's Projects dynamically.
|
||||
# Adds a relationships
|
||||
module ProjectPatch
|
||||
|
||||
def self.included(base) # :nodoc:
|
||||
base.extend(ClassMethods)
|
||||
|
||||
base.send(:include, InstanceMethods)
|
||||
|
||||
# Same as typing in the class
|
||||
base.class_eval do
|
||||
unloadable # Send unloadable so it will not be unloaded in development
|
||||
belongs_to :customer, primary_key: :id
|
||||
belongs_to :vehicle, primary_key: :id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
end
|
||||
|
||||
# Add module to Project
|
||||
Project.send(:include, ProjectPatch)
|
||||
36
lib/projects_form_hook_listener.rb
Normal file
36
lib/projects_form_hook_listener.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
#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 ProjectsFormHookListener < Redmine::Hook::ViewListener
|
||||
|
||||
# Edit Project Form
|
||||
def view_projects_form(context={})
|
||||
f = context[:form]
|
||||
|
||||
# Check to see if there is a quickbooks user attached to the issue
|
||||
selected_customer = context[:project].customer ? context[:project].customer : nil
|
||||
selected_vehicle = context[:project].vehicle_id ? context[:project].vehicle_id : nil
|
||||
|
||||
# Load customer information
|
||||
customer = Customer.find_by_id(selected_customer) if selected_customer
|
||||
search_customer = f.autocomplete_field :customer, autocomplete_customer_name_customers_path, :selected => selected_customer, :update_elements => {:id => '#project_customer_id', :value => '#project_customer'}
|
||||
customer_id = f.hidden_field :customer_id, :id => "project_customer_id"
|
||||
|
||||
if context[:project].customer
|
||||
vehicles = customer.vehicles.pluck(:name, :id).sort!
|
||||
else
|
||||
vehicles = [nil].compact
|
||||
end
|
||||
|
||||
vehicle = f.select :vehicle_id, vehicles, :selected => selected_vehicle, include_blank: true
|
||||
|
||||
return "<p><label for=\"project_customer\">Customer</label>#{search_customer} #{customer_id}</p> <p>#{vehicle}</p>"
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
#The MIT License (MIT)
|
||||
#
|
||||
#Copyright (c) 2016 rick barrette
|
||||
#Copyright (c) 2022 rick barrette
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
@@ -11,62 +11,24 @@
|
||||
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
|
||||
|
||||
# Add qbo options to the aviable columns
|
||||
def available_columns
|
||||
unless @available_columns
|
||||
@available_columns = self.class.available_columns.dup
|
||||
@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}.qbo_billed", :groupable => true, :caption => :field_qbo_billed)
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def available_columns_with_qbo
|
||||
unless @available_columns
|
||||
@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(:qbo_billed, :sortable => "#{TimeEntry.table_name}.qbo_billed", :groupable => true, :caption => :field_qbo_billed)
|
||||
end
|
||||
@available_columns
|
||||
end
|
||||
|
||||
def available_filters_with_qbo
|
||||
unless @available_filters
|
||||
@available_filters = available_filters_without_qbo
|
||||
|
||||
#qbo_filters = {
|
||||
# :customer => {
|
||||
# :id => l(:field_customer),
|
||||
# :type => :integer,
|
||||
# :order => @available_filters.size + 1},
|
||||
#}
|
||||
|
||||
qbo_filters = {
|
||||
"customer_id" => {
|
||||
:id => :customer_id,
|
||||
:type => :list_optional,
|
||||
:order => @available_filters.size + 1,
|
||||
#:values => Customer.find(:all).collect { |c| [c.name, c.id.to_s]}
|
||||
}
|
||||
}
|
||||
|
||||
@available_filters.merge!(qbo_filters)
|
||||
end
|
||||
@available_filters
|
||||
end
|
||||
# Add customers to filters
|
||||
def initialize_available_filters
|
||||
add_available_filter "customer", :type => :text
|
||||
super
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Add module to Issue
|
||||
IssueQuery.send(:include, QueryPatch)
|
||||
IssueQuery.send(:prepend, QueryPatch)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user