mirror of
https://github.com/rickbarrette/redmine_qbo.git
synced 2026-02-13 09:13:58 -05:00
Compare commits
20 Commits
548dc4fba8
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| f0c0a42c96 | |||
| a4b51457bb | |||
| fb4a883b43 | |||
| c24ec93335 | |||
| df49964bf9 | |||
| 502ba94465 | |||
| ff038fe5ae | |||
| 3eed122598 | |||
| d8d34540a9 | |||
| c01cc5ca97 | |||
| 6a2f7a1146 | |||
| f4c844f097 | |||
| 1135c69e1b | |||
| ef86d222cb | |||
| be88a601ae | |||
| e6c4e81df2 | |||
| f4a979672f | |||
| 8a4d64ffc0 | |||
| ac05d38763 | |||
| 5d7d9a81bb |
@@ -1,9 +1,9 @@
|
|||||||
<%= link_to t(:label_appointment), "https://calendar.google.com/calendar/render?action=TEMPLATE&text=#{@customer.name}+-&details=#{ link_to t(:customer_details), "https://#{Setting.host_name}#{customer_path @customer.id}"}%0A#{@customer.primary_phone}&dates=#{Time.now.strftime("%Y%m%d")}T090000/#{Time.now.strftime("%Y%m%d")}T170000", target: :_blank %>
|
<%= link_to t(:label_appointment), "https://calendar.google.com/calendar/render?action=TEMPLATE&text=#{@customer.name}+-&details=#{ link_to t(:customer_details), "https://#{Setting.host_name}#{customer_path @customer.id}"}%0A#{@customer.primary_phone}%3Cbr/%3E+&dates=#{Time.now.strftime("%Y%m%d")}T090000/#{Time.now.strftime("%Y%m%d")}T170000", target: :_blank, id: :appointment_link %>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
<%= button_to t(:label_create_estimate), "https://qbo.intuit.com/app/estimate?nameId=#{@customer.id}", target: :_blank, method: :get %>
|
<%= link_to t(:label_create_estimate), "https://qbo.intuit.com/app/estimate?nameId=#{@customer.id}", target: :_blank %>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<% estimates.sort.reverse.each do |estimate| %>
|
<% estimates.sort.reverse.each do |estimate| %>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<%= check_box_tag "estimate_ids[]", estimate.id, false, onchange: "updateLink()", class: "estimate-checkbox" %>
|
||||||
<b><%= link_to "##{estimate.doc_number}", estimate_path(estimate), target: :_blank %></b> <%= estimate.txn_date %>
|
<b><%= link_to "##{estimate.doc_number}", estimate_path(estimate), target: :_blank %></b> <%= estimate.txn_date %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<% invoices.sort.reverse.each do |invoice| %>
|
<% invoices.sort.reverse.each do |invoice| %>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<%= check_box_tag "invoice_ids[]", invoice.id, false, class: "invoice-checkbox" if invoices.count > 1 %>
|
<%= check_box_tag "invoice_ids[]", invoice.id, false, onchange: "updateLink()", class: "invoice-checkbox" if invoices.count > 1 %>
|
||||||
<b><%= link_to "##{invoice.doc_number}", invoice_path(invoice), target: :_blank %></b> <%= invoice.txn_date %>
|
<b><%= link_to "##{invoice.doc_number}", invoice_path(invoice), target: :_blank %></b> <%= invoice.txn_date %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
31
assets/javascripts/application.js
Normal file
31
assets/javascripts/application.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
function updateLink() {
|
||||||
|
const linkElement = document.getElementById("appointment_link");
|
||||||
|
const regex = /((?:<br\/>|%3Cbr\/?%3E))([\s\S]*?)(&dates)/gi;
|
||||||
|
linkElement.href = linkElement.href.replace(regex, `$1${getSelectedDocs()}$3`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedDocs() {
|
||||||
|
const invoices = document.querySelectorAll('.invoice-checkbox');
|
||||||
|
const estimates = document.querySelectorAll('.estimate-checkbox');
|
||||||
|
|
||||||
|
const invoiceIds = Array.from(invoices)
|
||||||
|
.filter(checkbox => checkbox.checked)
|
||||||
|
.map(checkbox => checkbox.value);
|
||||||
|
|
||||||
|
const estimateIds = Array.from(estimates)
|
||||||
|
.filter(checkbox => checkbox.checked)
|
||||||
|
.map(checkbox => checkbox.value);
|
||||||
|
|
||||||
|
let output = '';
|
||||||
|
|
||||||
|
for (const value of invoiceIds) {
|
||||||
|
output += `%0A<a href="${window.location.origin}/invoices/${value}">Invoice:%20${value}</a>%0A`;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const value of estimateIds) {
|
||||||
|
output += `%0A<a href="${window.location.origin}/estimates/${value}">Estimate:%20${value}</a>%0A`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can return the array or use it as needed
|
||||||
|
return output;
|
||||||
|
}
|
||||||
@@ -100,4 +100,5 @@ en:
|
|||||||
notice_forbidden: "You do not have permission to access this resource"
|
notice_forbidden: "You do not have permission to access this resource"
|
||||||
notice_issue_not_found: "Issue not found"
|
notice_issue_not_found: "Issue not found"
|
||||||
customer_details: "Customer Details"
|
customer_details: "Customer Details"
|
||||||
notice_error_project_nil: "The issue's project is nil, set project to: "
|
notice_error_project_nil: "The issue's project is nil, set project to: "
|
||||||
|
notice_error_tracker_nil: "The issue's tracker is nil, set tracker to: "
|
||||||
2
init.rb
2
init.rb
@@ -14,7 +14,7 @@ Redmine::Plugin.register :redmine_qbo do
|
|||||||
name 'Redmine QBO plugin'
|
name 'Redmine QBO plugin'
|
||||||
author 'Rick Barrette'
|
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'
|
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.0'
|
version '2026.2.4'
|
||||||
url 'https://github.com/rickbarrette/redmine_qbo'
|
url 'https://github.com/rickbarrette/redmine_qbo'
|
||||||
author_url 'https://barrettefabrication.com'
|
author_url 'https://barrettefabrication.com'
|
||||||
settings default: {empty: true}, partial: 'qbo/settings'
|
settings default: {empty: true}, partial: 'qbo/settings'
|
||||||
|
|||||||
@@ -15,16 +15,23 @@ module RedmineQbo
|
|||||||
include IssuesHelper
|
include IssuesHelper
|
||||||
|
|
||||||
# Check the new issue form for a valid project.
|
# Check the new issue form for a valid project.
|
||||||
# This is added to help prevent 422 unprocessable entity errors when creating an issue
|
# This is added to help prevent 422 unprocessable entity errors when creating an issue
|
||||||
# See https://github.com/redmine/redmine/blob/84483d63828d0cb2efbf5bd786a2f0d22e34c93d/app/controllers/issues_controller.rb#L179
|
# See https://github.com/redmine/redmine/blob/84483d63828d0cb2efbf5bd786a2f0d22e34c93d/app/controllers/issues_controller.rb#L179
|
||||||
def controller_issues_new_before_save(context={})
|
def controller_issues_new_before_save(context={})
|
||||||
if context[:issue].project.nil?
|
if context[:issue].project.nil?
|
||||||
context[:issue].project = projects_for_select(context[:issue]).first
|
context[:issue].project = projects_for_select(context[:issue]).first
|
||||||
context[:controller].flash[:error] = I18n.t(:notice_error_project_nil) + context[:issue].project.to_s
|
Rails.logger.error I18n.t(:notice_error_project_nil) + context[:issue].project.to_s
|
||||||
end
|
context[:controller].flash[:error] = I18n.t(:notice_error_project_nil) + context[:issue].project.to_s
|
||||||
|
end
|
||||||
|
|
||||||
return context
|
if context[:issue].tracker.nil?
|
||||||
end
|
context[:issue].tracker = trackers_for_select(context[:issue]).first
|
||||||
|
Rails.logger.error I18n.t(:notice_error_tracker_nil) + context[:issue].tracker.to_s
|
||||||
|
context[:controller].flash[:error] = I18n.t(:notice_error_tracker_nil) + context[:issue].tracker.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
return context
|
||||||
|
end
|
||||||
|
|
||||||
# Edit Issue Form
|
# Edit Issue Form
|
||||||
# Here we build the required form components before passing them to a partial view formatting.
|
# Here we build the required form components before passing them to a partial view formatting.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ module RedmineQbo
|
|||||||
|
|
||||||
module Helper
|
module Helper
|
||||||
def watcher_link(issue, user)
|
def watcher_link(issue, user)
|
||||||
|
link = ''
|
||||||
link = link_to(I18n.t(:label_bill_time), bill_path( issue.id ), method: :get, class: 'icon icon-email-add') if user.admin?
|
link = link_to(I18n.t(:label_bill_time), bill_path( issue.id ), method: :get, class: 'icon icon-email-add') if user.admin?
|
||||||
link << link_to(I18n.t(:label_share), share_path( issue.id ), method: :get, target: :_blank, class: 'icon icon-shared') if user.logged?
|
link << link_to(I18n.t(:label_share), share_path( issue.id ), method: :get, target: :_blank, class: 'icon icon-shared') if user.logged?
|
||||||
link.html_safe + super
|
link.html_safe + super
|
||||||
|
|||||||
Reference in New Issue
Block a user