effective_qb_online 0.9.8 → 0.9.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c795cfdd9e5caa950820b5e5dc0757ee4b3fe583dd635baed5bcf37b08271206
4
- data.tar.gz: 8ad4fec36e7d4fd79ff82036030f95c43cf5ef7ba0e776fa27a9780155bbae4c
3
+ metadata.gz: e6a3e221e9f86bab6fec4bbdf698d486a12924850960c797e897a79a9dde137e
4
+ data.tar.gz: eceb1df9ab98fd686e43e23572ef6be5ace97720bddaf35df4878dee8c5fafbe
5
5
  SHA512:
6
- metadata.gz: a4b15a1601cc2cf2e7dc9de3ea14b8f8402aefa0ac0eb755a270ab0796c5860dbefc249559fc3ec968196049776e57869e38dde5983541dcf025a60237affbe4
7
- data.tar.gz: 5415027204b5a1deb9d3d0ce48ec2601da0d4ed2e928f39d421079389def6d72a87bfb3cdd1862c368fcf128d4cc0b5003bd74f4433698d77d4d7bbdb97941f2
6
+ metadata.gz: 481a68ddeda1c7dd2fc07f6c5a44758df77f7bed84a84313f8f33850c3b061a59444c5f3f9654e35f114677752e12b750909f0fb45e5298a8d6a7282e59a19ab
7
+ data.tar.gz: 6840d8757d7d237283957334a868f447348395972f42e09c036bd6b6f16ac6e7baf5b84dea43419d9653e2e9968527c8dfba2a10424ee4d41f87978c1800fa2c
@@ -66,6 +66,12 @@ module Effective
66
66
  sales_receipt = Effective::QbSalesReceipt.build_from_receipt!(self, api: api)
67
67
  sales_receipt = api.create_sales_receipt(sales_receipt: sales_receipt)
68
68
 
69
+ # The SalesReceipt now exists in QuickBooks. Persist its id immediately so a
70
+ # later failure (e.g. the total sanity checks below) doesn't orphan it. Without
71
+ # this, a re-sync would try to create it again and QuickBooks rejects the
72
+ # reused DocNumber with a Duplicate Document Number Error.
73
+ update_column(:sales_receipt_id, sales_receipt.id)
74
+
69
75
  # Sanity check
70
76
  if EffectiveOrders.try(:credit_card_surcharge_qb_item_name).present? && !EffectiveOrders.try(:fee_saver?)
71
77
  if (expected = api.price_to_amount(order.total)) != sales_receipt.total
@@ -38,8 +38,11 @@ module Effective
38
38
  end
39
39
 
40
40
  receipt.qb_receipt_items.each do |receipt_item|
41
+ # The purchasable may have been deleted. When it's missing we can't auto-match
42
+ # the QuickBooks item from its qb_item_id/qb_item_name, so we fall back to the
43
+ # QbReceiptItem's item_id (mapped manually in the admin). The SalesReceipt line
44
+ # items are built from the OrderItem, so a missing purchasable is not fatal.
41
45
  purchasable = receipt_item.order_item.purchasable
42
- raise("Expected a purchasable for Effective::OrderItem #{receipt_item.order_item.id}") unless purchasable.present?
43
46
 
44
47
  # Either of these could match
45
48
  purchasable_id_name = [
@@ -59,7 +62,7 @@ module Effective
59
62
 
60
63
  if item.blank?
61
64
  purchasable_id_name = [purchasable.try(:qb_item_id), purchasable.try(:qb_item_name)].compact
62
- raise("Unknown Item #{purchasable_id_name.join(' or ')} from #{purchasable} (#{purchasable.class.name} ##{purchasable.id})")
65
+ raise("Unknown Item #{purchasable_id_name.join(' or ')} from #{purchasable} (#{purchasable.class.name} ##{purchasable&.id})")
63
66
  end
64
67
 
65
68
  receipt_item.update!(item_id: item.id)
@@ -100,7 +103,7 @@ module Effective
100
103
 
101
104
  receipt.qb_receipt_items.each do |receipt_item|
102
105
  order_item = receipt_item.order_item
103
- line_item = Quickbooks::Model::Line.new(amount: api.price_to_amount(order_item.subtotal), description: order_item.name)
106
+ line_item = Quickbooks::Model::Line.new(amount: api.price_to_amount(order_item.subtotal), description: strip_html(order_item.name))
104
107
 
105
108
  line_item.sales_item! do |line|
106
109
  line.item_id = receipt_item.item_id
@@ -161,5 +164,15 @@ module Effective
161
164
  value.to_s.downcase.strip
162
165
  end
163
166
 
167
+ # Order item names may contain HTML (e.g. an EventRegistrant's "Member" badge).
168
+ # QuickBooks line item descriptions are plain text, so strip the markup while keeping
169
+ # the badge text. Convert line breaks to spaces first so adjacent text doesn't run together.
170
+ def self.strip_html(value)
171
+ return value if value.blank?
172
+
173
+ text = value.to_s.gsub(/<br\s*\/?>/i, ' ')
174
+ ActionView::Base.full_sanitizer.sanitize(text).squish
175
+ end
176
+
164
177
  end
165
178
  end
@@ -28,7 +28,7 @@
28
28
  = f.fields_for :qb_receipt_items do |fi|
29
29
  %tr
30
30
  %td= fi.object.order_item_id
31
- %td= fi.object.order_item
31
+ %td= fi.object.order_item.to_s.html_safe
32
32
  %td
33
33
  - if fi.object.item_id.present?
34
34
  - existing = items.find { |(name, id)| id == fi.object.item_id }&.first
@@ -12,7 +12,7 @@
12
12
  = @order.billing_name
13
13
  %p
14
14
  - @order.order_items.each do |oi|
15
- = "#{oi.name} (#{oi.try(:qb_item_name)})"
15
+ = oi.to_s.html_safe
16
16
  %br
17
17
 
18
18
  %p
@@ -1,3 +1,3 @@
1
1
  module EffectiveQbOnline
2
- VERSION = '0.9.8'.freeze
2
+ VERSION = '0.9.10'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_qb_online
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.8
4
+ version: 0.9.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-12 00:00:00.000000000 Z
11
+ date: 2026-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails