mirror of
https://github.com/rickbarrette/redmine_qbo_lineitems.git
synced 2026-07-02 17:11:09 -04:00
Compare commits
7 Commits
50a02cc497
...
2026.4.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 0acf5ffca4 | |||
| 5b1d98aa07 | |||
| 3ca45a457f | |||
| c9d2a47a92 | |||
| b939d834e9 | |||
| 9b9a5c3505 | |||
| da49b996da |
@@ -100,8 +100,6 @@ class ItemsController < ApplicationController
|
|||||||
params.require(:item).permit(:name, :description, :sku, :unit_price, :active, :account_id, :type, :taxable)
|
params.require(:item).permit(:name, :description, :sku, :unit_price, :active, :account_id, :type, :taxable)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def log(msg)
|
def log(msg)
|
||||||
Rails.logger.info "[ItemsController] #{msg}"
|
Rails.logger.info "[ItemsController] #{msg}"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
<% if @issue.line_items.any? %>
|
<% if @issue.line_items.any? || @issue.descendant_line_items_total > 0%>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div>
|
<div>
|
||||||
<p><strong><%= t :label_line_items %></strong></p>
|
<p><strong><%= t :label_line_items %></strong></p>
|
||||||
|
|
||||||
|
<% total = 0 %>
|
||||||
|
|
||||||
|
<% if @issue.line_items.any?%>
|
||||||
|
|
||||||
<table class="list line-items-table">
|
<table class="list line-items-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -14,7 +18,6 @@
|
|||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<% total = 0 %>
|
|
||||||
|
|
||||||
<% @issue.line_items.each do |item| %>
|
<% @issue.line_items.each do |item| %>
|
||||||
<% line_total = item.quantity.to_f * item.unit_price.to_f %>
|
<% line_total = item.quantity.to_f * item.unit_price.to_f %>
|
||||||
@@ -29,11 +32,26 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<tfoot>
|
<tfoot>
|
||||||
|
<% if @issue.line_items.any?%>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" style="text-align:right;"><strong><%= t :label_total %></strong></td>
|
<td colspan="3" style="text-align:right;"><strong><%= t :label_total %></strong></td>
|
||||||
<td><strong><%= number_to_currency(total) %></strong></td>
|
<td>
|
||||||
|
<strong><%= number_to_currency(total) %></strong>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if @issue.descendant_line_items_total > 0 %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3" style="text-align:right;"><strong><%= t :label_running_total %></strong></td>
|
||||||
|
<td>
|
||||||
|
<strong>(<%= number_to_currency(@issue.descendant_line_items_total + total) %>)</strong>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ en:
|
|||||||
label_no: "No"
|
label_no: "No"
|
||||||
label_qty: "Quantity"
|
label_qty: "Quantity"
|
||||||
label_remove: "Remove"
|
label_remove: "Remove"
|
||||||
|
label_running_total: "Running Total"
|
||||||
label_sync_now_accounts: "Sync Accounts"
|
label_sync_now_accounts: "Sync Accounts"
|
||||||
label_sync_now_items: "Sync Items"
|
label_sync_now_items: "Sync Items"
|
||||||
label_type: "Type"
|
label_type: "Type"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Redmine::Plugin.register :redmine_qbo_lineitems do
|
|||||||
name 'Redmine QBO Line Items plugin'
|
name 'Redmine QBO Line Items plugin'
|
||||||
author 'Rick Barrette'
|
author 'Rick Barrette'
|
||||||
description 'A plugin for Redmine to extend the capabilitys of the Redmine QuickBooks Online plugin to attach billable line items to an isuue'
|
description 'A plugin for Redmine to extend the capabilitys of the Redmine QuickBooks Online plugin to attach billable line items to an isuue'
|
||||||
version '2026.3.12'
|
version '2026.4.2'
|
||||||
url 'https://github.com/rickbarrette/redmine_qbo_lineitems'
|
url 'https://github.com/rickbarrette/redmine_qbo_lineitems'
|
||||||
author_url 'https://barrettefabrication.com'
|
author_url 'https://barrettefabrication.com'
|
||||||
requires_redmine version_or_higher: '6.1.0'
|
requires_redmine version_or_higher: '6.1.0'
|
||||||
|
|||||||
@@ -10,14 +10,65 @@
|
|||||||
|
|
||||||
module LineItems
|
module LineItems
|
||||||
module Patches
|
module Patches
|
||||||
module IssuePatch
|
module IssuePatch extend ActiveSupport::Concern
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
prepended do
|
prepended do
|
||||||
has_many :line_items, dependent: :destroy
|
has_many :line_items, dependent: :destroy
|
||||||
accepts_nested_attributes_for :line_items,
|
accepts_nested_attributes_for :line_items, allow_destroy: true, reject_if: proc { |attrs| attrs['description'].blank? }
|
||||||
allow_destroy: true,
|
|
||||||
reject_if: proc { |attrs| attrs['description'].blank? }
|
# Returns line items for immediate children
|
||||||
|
def children_line_items
|
||||||
|
LineItem.where(issue_id: self.children.pluck(:id))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calculates the total value of all child line items
|
||||||
|
def children_line_items_total
|
||||||
|
children_line_items.sum(:line_total)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns line items for the entire tree below this issue
|
||||||
|
def descendant_line_items
|
||||||
|
LineItem.where(issue_id: self.descendants.pluck(:id))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calculates the total value of entire tree below this issue
|
||||||
|
def descendant_line_items_total
|
||||||
|
descendant_line_items.sum(:line_total)
|
||||||
|
end
|
||||||
|
|
||||||
|
def line_items_total
|
||||||
|
line_items.sum(:line_total)
|
||||||
|
end
|
||||||
|
|
||||||
|
def line_items_attributes=(attrs)
|
||||||
|
attrs = attrs.stringify_keys
|
||||||
|
|
||||||
|
# IDs submitted in the form
|
||||||
|
submitted_ids = attrs.values.map { |a| a['id'] }.compact.map(&:to_s)
|
||||||
|
|
||||||
|
# Existing IDs in DB
|
||||||
|
existing_ids = line_items.pluck(:id).map(&:to_s)
|
||||||
|
|
||||||
|
# Find missing ones (these would be implicitly deleted by Rails)
|
||||||
|
missing_ids = existing_ids - submitted_ids
|
||||||
|
|
||||||
|
# Re-add missing records so Rails doesn't delete them
|
||||||
|
missing_ids.each do |id|
|
||||||
|
attrs["preserve_#{id}"] = { 'id' => id }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Only allow explicit deletes or valid updates/creates
|
||||||
|
filtered = attrs.select do |_, item_attrs|
|
||||||
|
item_attrs['_destroy'] == '1' ||
|
||||||
|
item_attrs['id'].present? ||
|
||||||
|
item_attrs['description'].present?
|
||||||
|
end
|
||||||
|
|
||||||
|
super(filtered)
|
||||||
|
rescue => e
|
||||||
|
logger.error "Error processing line items attributes: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user