dscf-marketplace 0.13.3 → 0.13.4

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: 475043853266506246b2775c97fc0fb8a4c361fb7e415ae36b0c30c0a36f6a34
4
- data.tar.gz: 5e5045ee415293974c10856a416907a1aeb9434a9e51fed26aecf72ed4ef1339
3
+ metadata.gz: e713d41fece224efb5187e70f38a81a3bcb951579dbab893eb0602abdca2ded8
4
+ data.tar.gz: 1beb16fefbd3e7d674fcf6854063665106d4b8858f015d396f656a23a4d37815
5
5
  SHA512:
6
- metadata.gz: 19eb9d280c9b18f8cf07c1532acff967a2bee651bc930f2c24a5142686999308b176d1622ebdbe9be233662fac3ed99bb4f55f2e50b4e3f4ac3bd29bc2e516ff
7
- data.tar.gz: a907e0a7fa9aba5f8c14b3eaabc4b47224278bfdc32d758300c20744d12747a546aa846a219386f49e1cc6855fd96adebab43274f6835181fb016bcfbb5e0841
6
+ metadata.gz: c48b573dd70627bc33628e66f304325b52c252cf1001fec0788ffc9266f47b3375772286bd9e0754f9f88ad811a6a5001fe6431c63fbb695f00ddc59eebad45a
7
+ data.tar.gz: 8662c81c6b5942193a1b879f107d307666d38328186652d2f10fe6e4028280f86d96fb9b05c54f940c80a1e8af21c783ae033ce349691e8220ccb4f34f78c580
@@ -534,13 +534,15 @@ module Dscf
534
534
  else
535
535
  aggregator_listing = ri[:aggregator_listing]
536
536
  product = aggregator_listing.product
537
- # Order lines from the aggregator feed are auto-sourced to the originating
538
- # AggregatorListing (regardless of source_kind) the aggregator already
539
- # knows the source, so there's no manual pick at split time. The listing's
540
- # source_kind carries who ultimately fulfils it (self / sub-supplier /
541
- # supplier), surfaced via source_name for display and confirmation routing.
537
+ # Order lines from the aggregator feed are auto-sourced so there's
538
+ # no manual pick at split time. A :supplier-kind listing has a real
539
+ # external business behind it source the line straight to that
540
+ # Business so it shows up on the supplier's own confirmations page
541
+ # (same as if the aggregator had manually assigned it there).
542
+ # :catalog / :sub_supplier stay sourced to the AggregatorListing
543
+ # itself (aggregator-managed — see AggregatorListing#confirming_business).
542
544
  order.order_items.build(
543
- source: aggregator_listing,
545
+ source: aggregator_listing.confirming_business || aggregator_listing,
544
546
  product: product,
545
547
  unit: product.unit,
546
548
  quantity: ri[:quantity],
@@ -71,6 +71,17 @@ module Dscf::Marketplace
71
71
  end
72
72
  end
73
73
 
74
+ # The real external business that should confirm an order line placed
75
+ # against this listing on their OWN business dashboard, if any. Only
76
+ # meaningful for :supplier — that business is a genuine third party,
77
+ # unambiguously distinct from the aggregator. :catalog has no external
78
+ # party (the aggregator fulfils it) and :sub_supplier's business is
79
+ # offline/has no login (requirements doc: sub-suppliers "don't act
80
+ # directly on the system"), so both stay aggregator-managed (nil here).
81
+ def confirming_business
82
+ supplier_product&.business if supplier?
83
+ end
84
+
74
85
  def available?
75
86
  active? && quantity > 0
76
87
  end
@@ -275,7 +275,14 @@ module Dscf::Marketplace
275
275
  end
276
276
 
277
277
  def quotation_or_listing_present
278
- unless quotation.present? || listing.present? || order_items.any? { |item| item.source_type == "Dscf::Marketplace::AggregatorListing" }
278
+ # A feed-purchased order has no order.listing (Order#listing is a single
279
+ # FK; nothing to point it at when every item came from the aggregator's
280
+ # feed) but each item's own presence validation already requires it to
281
+ # carry a quotation_item, listing, or assigned source — so any item with
282
+ # an assigned source_type proves the order is legitimately grounded,
283
+ # regardless of whether that source resolved to an AggregatorListing or
284
+ # straight to the fulfilling Business (see AggregatorListing#confirming_business).
285
+ unless quotation.present? || listing.present? || order_items.any? { |item| item.source_type.present? }
279
286
  errors.add(:base, "Either quotation or listing must be present")
280
287
  end
281
288
  end
@@ -57,17 +57,28 @@ module Dscf
57
57
  # any object responding to #price and #quantity works (Listing or
58
58
  # AggregatorListing), since validate_item only reads those two fields.
59
59
  private_class_method def self.find_current_active_listing(item)
60
- # Lines placed from the aggregator feed are sourced to their AggregatorListing —
61
- # validate against that listing's live price/quantity, not a supplier listing.
62
- if item.source.is_a?(AggregatorListing)
63
- return AggregatorListing.active.find_by(id: item.source_id)
64
- end
65
-
66
- # Prefer the original supplier listing if still active
60
+ # Prefer the original supplier listing if still active the most
61
+ # authoritative reference when the item actually has one (a plain
62
+ # Listing-based order line).
67
63
  if item.listing && Listing.active.exists?(id: item.listing.id)
68
64
  return item.listing
69
65
  end
70
66
 
67
+ # A feed-purchased line (no listing_id at all) should validate against
68
+ # the aggregator's own markup price, not a random supplier listing —
69
+ # even after a :supplier-kind item's source has been resolved straight
70
+ # to the fulfilling Business (see AggregatorListing#confirming_business),
71
+ # so this can't just check item.source's class anymore. Does the
72
+ # order's own business (order.ordered_to) have an active aggregator
73
+ # listing for this product at all? If so, that's the reference the
74
+ # retailer actually agreed to pay, regardless of what source is now.
75
+ if item.listing_id.nil? && item.order&.ordered_to.present?
76
+ aggregator_listing = AggregatorListing.active
77
+ .where(aggregator_id: item.order.ordered_to_id)
78
+ .detect { |al| al.product&.id == item.product_id }
79
+ return aggregator_listing if aggregator_listing
80
+ end
81
+
71
82
  # Fallback: find cheapest active listing for the product
72
83
  Listing.active
73
84
  .joins(:supplier_product)
@@ -1,5 +1,5 @@
1
1
  module Dscf
2
2
  module Marketplace
3
- VERSION = "0.13.3".freeze
3
+ VERSION = "0.13.4".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dscf-marketplace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.3
4
+ version: 0.13.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Asrat