Compare commits

...

6 Commits

5 changed files with 44 additions and 15 deletions

View File

@@ -80,16 +80,31 @@ class CustomersController < ApplicationController
def show def show
@customer = Customer.find_by_id(params[:id]) @customer = Customer.find_by_id(params[:id])
return render_404 unless @customer return render_404 unless @customer
@issues = @customer.issues&.order(id: :desc)
@billing_address = address_to_s(@customer.billing_address) @open_issues = @customer.issues
@shipping_address = address_to_s(@customer.shipping_address) .joins(:status)
@closed_issues = (@issues - @issues.open) .includes(:status, :project, :tracker, :priority)
@hours = 0 .where(issue_statuses: { is_closed: false })
@closed_hours = 0 .order(id: :desc)
@issues.open.each { |i| @hours+= i.total_spent_hours }
@closed_issues.each { |i| @closed_hours+= i.total_spent_hours } @closed_issues = @customer.issues
.joins(:status)
.includes(:status, :project, :tracker, :priority)
.where(issue_statuses: { is_closed: true })
.order(id: :desc)
@hours = TimeEntry
.joins(:issue)
.where(issues: { id: @open_issues.select(:id) })
.sum(:hours)
@closed_hours = TimeEntry
.joins(:issue)
.where(issues: { id: @closed_issues.select(:id) })
.sum(:hours)
rescue => e rescue => e
log "Failed to load customer ##{params[:id]}: #{e.message}" Rails.logger.error "Failed to load customer ##{params[:id]}: #{e.message}\n#{e.backtrace.join("\n")}"
flash[:error] = e.message flash[:error] = e.message
render_404 render_404
end end

View File

@@ -35,7 +35,20 @@ class Customer < ActiveRecord::Base
# Returns the details of the customer. If the details have already been fetched, it returns the cached version. Otherwise, it fetches the details from QuickBooks Online and caches them for future use. This method is used to access the customer's information in a way that minimizes unnecessary API calls to QBO, improving performance and reducing latency. # Returns the details of the customer. If the details have already been fetched, it returns the cached version. Otherwise, it fetches the details from QuickBooks Online and caches them for future use. This method is used to access the customer's information in a way that minimizes unnecessary API calls to QBO, improving performance and reducing latency.
def details def details
@details ||= fetch_details return Quickbooks::Model::Customer.new unless id.present?
@details ||= begin
xml = Rails.cache.fetch(details_cache_key, expires_in: 10.minutes) do
fetch_details.to_xml_ns
end
Quickbooks::Model::Customer.from_xml(xml)
end
end
# Generates a unique cache key for storing this customer's QBO details.
def details_cache_key
"customer:#{id}:qbo_details:#{updated_at.to_i}"
end end
# Returns the customer's email address # Returns the customer's email address
@@ -49,6 +62,7 @@ class Customer < ActiveRecord::Base
details details
@details.email_address = s @details.email_address = s
end end
# Returns the last sync time formatted for display. If no sync has occurred, returns a default message. # Returns the last sync time formatted for display. If no sync has occurred, returns a default message.
def self.last_sync def self.last_sync
@@ -167,6 +181,7 @@ class Customer < ActiveRecord::Base
log "Starting push for customer ##{self.id}..." log "Starting push for customer ##{self.id}..."
qbo = QboConnectionService.current! qbo = QboConnectionService.current!
CustomerService.new(qbo: qbo, customer: self).push() CustomerService.new(qbo: qbo, customer: self).push()
Rails.cache.delete(details_cache_key)
save_without_push save_without_push
end end

View File

@@ -46,8 +46,8 @@
</div> </div>
<br/> <br/>
<h3><%=@issues.open.count%> <%=t(:label_open_issues)%> - <%=@hours.round(1)%> <%=t(:label_hours)%></h3> <h3><%=@open_issues.count%> <%=t(:label_open_issues)%> - <%=@hours.round(1)%> <%=t(:label_hours)%></h3>
<%= render partial: 'issues/list_simple', locals: {issues: @issues.open} %> <%= render partial: 'issues/list_simple', locals: {issues: @open_issues.open} %>
<h3><%=@closed_issues.count%> <%=t(:label_closed_issues)%> - <%= @closed_hours.round(1)%> <%=t(:label_hours)%></h3> <h3><%=@closed_issues.count%> <%=t(:label_closed_issues)%> - <%= @closed_hours.round(1)%> <%=t(:label_hours)%></h3>
<%= render partial: 'issues/list_simple', locals: {issues: @closed_issues} %> <%= render partial: 'issues/list_simple', locals: {issues: @closed_issues} %>

View File

@@ -21,8 +21,6 @@ module RedmineQbo
f = context[:form] f = context[:form]
issue = context[:issue] issue = context[:issue]
project = context[:project] project = context[:project]
log issue.inspect
log project.inspect
# Customer Name Text Box with database backed autocomplete # Customer Name Text Box with database backed autocomplete
# onchange event will update the hidden customer_id field # onchange event will update the hidden customer_id field

View File

@@ -260,8 +260,9 @@ module RedmineQbo
# Check to see if there is an estimate attached, then combine them # Check to see if there is an estimate attached, then combine them
if issue.estimate if issue.estimate
e_pdf, ref = EstimatePdfService.new(qbo: QboConnectionService.current!).fetch_pdf(doc_ids: [issue.estimate.id])
pdf = CombinePDF.parse(pdf.output, allow_optional_content: true) pdf = CombinePDF.parse(pdf.output, allow_optional_content: true)
pdf << CombinePDF.parse(issue.estimate.pdf) pdf << CombinePDF.parse(e_pdf)
return pdf.to_pdf return pdf.to_pdf
end end