Lookup backorder for updates with saved link

This commit is contained in:
Maikel Linke
2024-10-31 17:37:52 +11:00
parent 4610141ed8
commit a8fb6492f4
6 changed files with 213 additions and 137 deletions

View File

@@ -28,7 +28,7 @@ class AmendBackorderJob < ApplicationJob
urls = FdcUrlBuilder.new(reference_link)
orderer = FdcBackorderer.new(user, urls)
backorder = orderer.find_open_order
backorder = orderer.find_open_order(order)
variants = order_cycle.variants_distributed_by(distributor)
adjust_quantities(order_cycle, user, backorder, urls, variants)

View File

@@ -71,6 +71,7 @@ module Spree
has_one :exchange, ->(order) {
outgoing.to_enterprise(order.distributor)
}, through: :order_cycle, source: :exchanges
has_many :semantic_links, through: :exchange
belongs_to :distributor, class_name: 'Enterprise', optional: true
belongs_to :customer, optional: true

View File

@@ -10,7 +10,7 @@ class FdcBackorderer
end
def find_or_build_order(ofn_order)
find_open_order || build_new_order(ofn_order)
find_open_order(ofn_order) || build_new_order(ofn_order)
end
def build_new_order(ofn_order)
@@ -19,7 +19,37 @@ class FdcBackorderer
end
end
def find_open_order
# Try the new method and fall back to old method.
def find_open_order(ofn_order)
lookup_open_order(ofn_order) || find_last_open_order
end
def lookup_open_order(ofn_order)
# There should be only one link at the moment but we may support
# ordering from multiple suppliers one day.
semantic_ids = ofn_order.semantic_links.pluck(:semantic_id)
semantic_ids.lazy
# Make sure we select an order from the right supplier:
.select { |id| id.starts_with?(urls.orders_url) }
# Fetch the order from the remote DFC server, lazily:
.map { |id| find_order(id) }
.compact
# Just in case someone completed the order without updating our database:
.select { |o| o.orderStatus[:path] == "Held" }
.first
# The DFC Connector doesn't recognise status values properly yet.
# So we are overriding the value with something that can be exported.
&.tap { |o| o.orderStatus = "dfc-v:Held" }
end
# DEPRECATED
#
# We now store links to orders we placed. So we don't need to search
# through all orders and pick a random open one.
# But for compatibility with currently open order cycles that don't have
# a stored link yet, we keep this method as well.
def find_last_open_order
graph = import(urls.orders_url)
open_orders = graph&.select do |o|
o.semanticType == "dfc-b:Order" && o.orderStatus[:path] == "Held"

File diff suppressed because one or more lines are too long

View File

@@ -7,6 +7,7 @@ RSpec.describe Spree::Order do
let(:order) { build(:order, user:) }
it { is_expected.to have_one :exchange }
it { is_expected.to have_many :semantic_links }
describe "#errors" do
it "provides friendly error messages" do

View File

@@ -27,7 +27,7 @@ RSpec.describe FdcBackorderer do
# After closing the order at the end, the test can be repeated live again.
# Build a new order when no open one is found:
order.order_cycle = build(:order_cycle)
order.order_cycle = create(:order_cycle, distributors: [order.distributor])
backorder = subject.find_or_build_order(order)
expect(backorder.semanticId).to eq urls.orders_url
expect(backorder.lines).to eq []
@@ -50,10 +50,19 @@ RSpec.describe FdcBackorderer do
expect(found_backorder.lines.count).to eq 1
expect(found_backorder.lines[0].quantity.to_i).to eq 3
# Without a stored semantic link, it can't look it up directly though:
found_backorder = subject.lookup_open_order(order)
expect(found_backorder).to eq nil
# But with a semantic link, it works:
order.exchange.semantic_links.create!(semantic_id: placed_order.semanticId)
found_backorder = subject.lookup_open_order(order)
expect(found_backorder.semanticId).to eq placed_order.semanticId
# And close the order again:
subject.complete_order(placed_order)
remaining_open_order = subject.find_or_build_order(order)
expect(remaining_open_order.semanticId).not_to eq placed_order.semanticId
expect(remaining_open_order.semanticId).to eq urls.orders_url
end
describe "#find_or_build_order" do