mirror of
https://github.com/rickbarrette/redmine_qbo.git
synced 2026-04-02 16:21:58 -04:00
Compare commits
4 Commits
2026.2.14
...
5d858ae186
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d858ae186 | |||
| b38f850df3 | |||
| 138e55933b | |||
| 5fbc169ade |
@@ -51,7 +51,7 @@ class CustomersController < ApplicationController
|
||||
# display a list of all customers
|
||||
def index
|
||||
if params[:search]
|
||||
@customers = Customer.search(params[:search]).paginate(page: params[:page])
|
||||
@customers = Customer.search(params[:search]).order(:name).paginate(page: params[:page])
|
||||
if only_one_non_zero?(@customers)
|
||||
redirect_to @customers.first
|
||||
end
|
||||
|
||||
@@ -30,6 +30,8 @@ class Customer < ActiveRecord::Base
|
||||
:type => :to_s,
|
||||
:description => Proc.new {|o| "#{I18n.t :label_primary_phone}: #{o.phone_number} #{I18n.t:label_mobile_phone}: #{o.mobile_phone_number}"},
|
||||
:datetime => Proc.new {|o| o.updated_at || o.created_at}
|
||||
|
||||
#default_scope { order(name: :asc) }
|
||||
|
||||
# Convenience Method
|
||||
# returns the customer's email
|
||||
@@ -181,24 +183,10 @@ class Customer < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
# Seach for customers by name or phone number
|
||||
def self.search(search)
|
||||
return all if search.blank?
|
||||
|
||||
# 1. Clean the input: Remove existing stars and special Boolean operators
|
||||
# to prevent "red**" or syntax errors from hyphens/plus signs.
|
||||
clean_search = search.gsub(/[*+\-><()~]/, '')
|
||||
|
||||
# 2. Add a single trailing wildcard for partial matching
|
||||
ft_query = "#{clean_search}*"
|
||||
|
||||
# 3. Use the exact column list from your migration
|
||||
# Using a hybrid approach to ensure "Jonh" still finds "John"
|
||||
where(
|
||||
"MATCH(name, phone_number, mobile_phone_number) AGAINST(? IN BOOLEAN MODE) OR
|
||||
SOUNDEX(SUBSTRING_INDEX(name, ' ', 1)) = SOUNDEX(?) OR
|
||||
name LIKE ?",
|
||||
ft_query, clean_search, "%#{sanitize_sql_like(clean_search)}%"
|
||||
).order(Arel.sql("MATCH(name, phone_number, mobile_phone_number) AGAINST(#{connection.quote(clean_search)}) DESC"))
|
||||
search = sanitize_sql_like(search)
|
||||
where("name LIKE ? OR phone_number LIKE ? OR mobile_phone_number LIKE ?", "%#{search}%", "%#{search}%", "%#{search}%")
|
||||
end
|
||||
|
||||
# Override the defult redmine seach method to rank results by id
|
||||
@@ -208,14 +196,11 @@ class Customer < ActiveRecord::Base
|
||||
scope = self.all
|
||||
|
||||
tokens.each do |token|
|
||||
q = "%#{sanitize_sql_like(token)}%"
|
||||
scope = where("name LIKE ? OR phone_number LIKE ? OR mobile_phone_number LIKE ?", "%#{q}%", "%#{q}%", "%#{q}%")
|
||||
scope = scope.search(token)
|
||||
end
|
||||
|
||||
ids = scope.distinct.limit(options[:limit] || 100).pluck(:id)
|
||||
|
||||
# Assign simple uniform ranking
|
||||
ids.each_with_object({}) { |id, h| h[id] = id }
|
||||
ids.index_with { |id| id }
|
||||
end
|
||||
|
||||
# proforms a bruteforce sync operation
|
||||
@@ -249,6 +234,30 @@ class Customer < ActiveRecord::Base
|
||||
def to_s
|
||||
return "#{self[:name]} - #{phone_number.split(//).last(4).join unless phone_number.nil?}"
|
||||
end
|
||||
|
||||
# Push the updates
|
||||
def save_with_push
|
||||
begin
|
||||
qbo = Qbo.first
|
||||
@details = qbo.perform_authenticated_request do |access_token|
|
||||
service = Quickbooks::Service::Customer.new(
|
||||
company_id: qbo.realm_id,
|
||||
access_token: access_token
|
||||
)
|
||||
service.update(@details)
|
||||
end
|
||||
|
||||
self.id = @details.id
|
||||
rescue => e
|
||||
errors.add(:base, e.message)
|
||||
return false
|
||||
end
|
||||
|
||||
save_without_push
|
||||
end
|
||||
|
||||
alias_method :save_without_push, :save
|
||||
alias_method :save, :save_with_push
|
||||
|
||||
private
|
||||
|
||||
@@ -265,24 +274,5 @@ class Customer < ActiveRecord::Base
|
||||
@details = Quickbooks::Model::Customer.new
|
||||
end
|
||||
end
|
||||
|
||||
# Push the updates
|
||||
def save_with_push
|
||||
begin
|
||||
qbo = Qbo.first
|
||||
@details = qbo.perform_authenticated_request do |access_token|
|
||||
service = Quickbooks::Service::Customer.new(company_id: qbo.realm_id, access_token: access_token)
|
||||
service.update(@details)
|
||||
end
|
||||
#raise "QBO Fault" if @details.fault?
|
||||
self.id = @details.id
|
||||
rescue Exception => e
|
||||
errors.add(e.message)
|
||||
end
|
||||
save_without_push
|
||||
end
|
||||
|
||||
alias_method :save_without_push, :save
|
||||
alias_method :save, :save_with_push
|
||||
|
||||
end
|
||||
|
||||
2
init.rb
2
init.rb
@@ -14,7 +14,7 @@ Redmine::Plugin.register :redmine_qbo do
|
||||
name 'Redmine QBO plugin'
|
||||
author 'Rick Barrette'
|
||||
description 'A pluging for Redmine to connect with QuickBooks Online to create Time Activity Entries for billable hours logged when an Issue is closed'
|
||||
version '2026.2.14'
|
||||
version '2026.2.15'
|
||||
url 'https://github.com/rickbarrette/redmine_qbo'
|
||||
author_url 'https://barrettefabrication.com'
|
||||
settings default: {empty: true}, partial: 'qbo/settings'
|
||||
|
||||
Reference in New Issue
Block a user